qt/LedOK/gutil/cpp.h

324 lines
8.8 KiB
C
Raw Normal View History

2023-09-19 11:49:20 +08:00
#ifndef CPP_H
#define CPP_H
2023-07-21 17:40:49 +08:00
#include <chrono>
#include <unordered_map>
2024-01-28 20:28:02 +08:00
inline int64_t steady_milli() {
2023-07-21 17:40:49 +08:00
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
}
2024-01-28 20:28:02 +08:00
inline int64_t system_milli() {
2023-07-21 17:40:49 +08:00
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
}
2024-01-28 20:28:02 +08:00
inline int64_t steady_micro() {
2023-07-21 17:40:49 +08:00
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
}
2024-01-28 20:28:02 +08:00
inline int64_t system_micro() {
2023-07-21 17:40:49 +08:00
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
}
template <class T>
struct SharedData {
2023-09-19 11:49:20 +08:00
size_t cnt{1};
2023-07-21 17:40:49 +08:00
T data;
};
template <class T>
class SharedPtr {
public:
SharedPtr(SharedData<T> *ptr = 0) : ptr{ptr} {}
~SharedPtr() {
if(ptr==0) return;
if(ptr->cnt > 1) ptr->cnt--;
else delete ptr;
}
2023-09-19 11:49:20 +08:00
SharedPtr(const SharedPtr &other) : ptr{other.ptr} {
if(ptr) ptr->cnt++;
}
2023-07-21 17:40:49 +08:00
SharedPtr &operator=(const SharedPtr &other) {
this->~SharedPtr();
new (this) SharedPtr(other);
return *this;
}
2023-09-19 11:49:20 +08:00
SharedPtr(SharedPtr &&other) noexcept : ptr(other.ptr) {
other.ptr = 0;
}
SharedPtr &operator=(SharedPtr &&other) noexcept {
auto aaa = ptr;
2023-10-23 11:44:22 +08:00
ptr = other.ptr;
2023-09-19 11:49:20 +08:00
other.ptr = aaa;
return *this;
}
2023-07-21 17:40:49 +08:00
2023-09-19 11:49:20 +08:00
bool isNull() const noexcept {return ptr==0;}
bool empty() const noexcept {
return ptr ? ptr->data.empty() : true;
}
size_t size() const noexcept {
return ptr ? ptr->data.size() : 0;
}
T &operator*() const {
2023-07-21 17:40:49 +08:00
if(ptr==0) ptr = new SharedData<T>;
return ptr->data;
}
2023-09-19 11:49:20 +08:00
T *operator->() const {
2023-07-21 17:40:49 +08:00
if(ptr==0) ptr = new SharedData<T>;
return &ptr->data;
}
2023-09-19 11:49:20 +08:00
bool operator==(const SharedPtr &other) const {
if(ptr==other.ptr) return true;
auto siz = size();
if(siz!=other.size()) return false;
if(siz==0) return true;
return ptr->data==other.ptr->data;
2023-07-21 17:40:49 +08:00
}
2023-09-19 11:49:20 +08:00
bool operator!=(const SharedPtr &other) const {
return ! (*this==other);
2023-07-21 17:40:49 +08:00
}
2023-09-19 11:49:20 +08:00
mutable SharedData<T> *ptr = 0;
2023-07-21 17:40:49 +08:00
};
template <class V>
class Vector : public SharedPtr<std::vector<V>> {
public:
using SharedPtr<std::vector<V>>::SharedPtr;
2024-08-08 16:52:25 +08:00
typedef typename std::vector<V>::iterator iterator;
2023-07-21 17:40:49 +08:00
Vector(std::initializer_list<V> _Ilist) {
2023-09-19 11:49:20 +08:00
this->ptr = new SharedData<std::vector<V>>{1, _Ilist};
2023-07-21 17:40:49 +08:00
}
2023-09-19 11:49:20 +08:00
Vector &append(const V &val) {
(*this)->push_back(val);
return *this;
2023-07-21 17:40:49 +08:00
}
2023-09-19 11:49:20 +08:00
Vector &append(V&& val) {
2024-08-08 16:52:25 +08:00
(*this)->push_back(std::move(val));
2023-09-19 11:49:20 +08:00
return *this;
2023-07-21 17:40:49 +08:00
}
2023-09-19 11:49:20 +08:00
Vector &operator<<(const V &val) {
(*this)->push_back(val);
return *this;
}
Vector &operator<<(V&& val) {
2024-08-08 16:52:25 +08:00
(*this)->push_back(std::move(val));
2023-07-21 17:40:49 +08:00
return *this;
}
2023-09-19 11:49:20 +08:00
2023-07-21 17:40:49 +08:00
V &operator[](const uint64_t pos) noexcept {
return (**this)[pos];
}
const V &operator[](const uint64_t pos) const noexcept {
2023-09-19 11:49:20 +08:00
return (**this)[pos];
2023-07-21 17:40:49 +08:00
}
2023-09-19 11:49:20 +08:00
iterator begin() const noexcept {
return this->ptr ? this->ptr->data.begin() : iterator();
2023-07-21 17:40:49 +08:00
}
2023-09-19 11:49:20 +08:00
iterator end() const noexcept {
return this->ptr ? this->ptr->data.end() : iterator();
2023-07-21 17:40:49 +08:00
}
};
struct NodeBase {
2024-08-08 16:52:25 +08:00
NodeBase *next = this;
NodeBase *prev = this;
2023-07-21 17:40:49 +08:00
};
2023-09-19 11:49:20 +08:00
template <class P>
2023-07-21 17:40:49 +08:00
struct _Node : NodeBase {
2023-09-19 11:49:20 +08:00
P value;
2023-07-21 17:40:49 +08:00
~_Node() {
2023-09-19 11:49:20 +08:00
if(next) delete (_Node<P>*) next;
2023-07-21 17:40:49 +08:00
}
};
2023-09-19 11:49:20 +08:00
template <class P>
2023-07-21 17:40:49 +08:00
class LinkedMapIterator {
public:
2023-09-19 11:49:20 +08:00
LinkedMapIterator(_Node<P> *node) : node(node) {}
bool operator==(const LinkedMapIterator& other) const noexcept {
return node == other.node;
2023-07-21 17:40:49 +08:00
}
2023-09-19 11:49:20 +08:00
bool operator!=(const LinkedMapIterator& other) const noexcept {
return node != other.node;
2023-07-21 17:40:49 +08:00
}
LinkedMapIterator& operator++() {
2023-09-19 11:49:20 +08:00
node = (_Node<P>*) node->next;
2023-07-21 17:40:49 +08:00
return *this;
}
LinkedMapIterator& operator--() {
2023-09-19 11:49:20 +08:00
node = (_Node<P>*) node->prev;
2023-07-21 17:40:49 +08:00
return *this;
}
2023-09-19 11:49:20 +08:00
const LinkedMapIterator operator++(int) {
auto rtn = *this;
node = (_Node<P>*) node->next;
return rtn;
}
const LinkedMapIterator operator--(int) {
auto rtn = *this;
node = (_Node<P>*) node->prev;
return rtn;
}
P &operator*() const noexcept {
2023-07-21 17:40:49 +08:00
return node->value;
}
2023-09-19 11:49:20 +08:00
P *operator->() const noexcept {
2023-07-21 17:40:49 +08:00
return &node->value;
}
2023-09-19 11:49:20 +08:00
_Node<P> *node{0};
2023-07-21 17:40:49 +08:00
};
template <class K, class V>
struct LinkedMapPri : NodeBase {
2023-09-19 11:49:20 +08:00
size_t cnt = 1;
2023-07-21 17:40:49 +08:00
std::unordered_map<K, _Node<std::pair<K, V>>*> map;
~LinkedMapPri() {
if(prev) prev->next = 0;
if(next) delete (_Node<std::pair<K, V>>*) next;
}
};
template <class K, class V>
class LinkedMap {
public:
using Node = _Node<std::pair<K, V>>;
using iterator = LinkedMapIterator<std::pair<K, V>>;
using const_iterator = LinkedMapIterator<std::pair<K, V>>;
LinkedMap() {}
LinkedMap(std::initializer_list<std::pair<K, V>> pairs) : _pri{new LinkedMapPri<K, V>} {
2024-01-28 20:28:02 +08:00
for(auto &pair : pairs) insert(pair.first, pair.second);
2023-07-21 17:40:49 +08:00
}
LinkedMap(std::unordered_map<K, Node*> &&map) : _pri{new LinkedMapPri<K, V>{0, 0, map}} {
_pri->next = _pri->prev = _pri;
}
~LinkedMap() {
if(_pri==0) return;
if(_pri->cnt > 1) _pri->cnt--;
else delete _pri;
}
2023-09-19 11:49:20 +08:00
LinkedMap(const LinkedMap &other) : _pri{other._pri} {
if(_pri) _pri->cnt++;
}
2023-07-21 17:40:49 +08:00
LinkedMap &operator=(const LinkedMap &other) {
this->~LinkedMap();
new (this) LinkedMap(other);
return *this;
}
2023-09-19 11:49:20 +08:00
LinkedMap(LinkedMap &&other) noexcept : _pri(other._pri) {
other._pri = 0;
}
LinkedMap &operator=(LinkedMap &&other) noexcept {
auto aaa = _pri;
_pri = other._pri;
other._pri = aaa;
return *this;
}
bool empty() const noexcept {
return _pri==0 || _pri->map.empty();
}
size_t size() const noexcept {
return _pri ? _pri->map.size() : 0;
}
iterator find(const K &k) const {
if(_pri==0) return iterator((Node*) _pri);
auto it = _pri->map.find(k);
if(it==_pri->map.end()) return iterator((Node*) _pri);
return iterator(it->second);
}
const V operator()(const K &k) const {
return (*this)[k];
}
2023-07-21 17:40:49 +08:00
const V operator[](const K &k) const {
if(_pri==0) return V();
auto it = _pri->map.find(k);
if(it==_pri->map.end()) return V();
return it->second->value.second;
}
2023-09-19 11:49:20 +08:00
V &operator[](const K &k) {
if(_pri==0) _pri = new LinkedMapPri<K, V>;
auto pair = _pri->map.emplace(k, nullptr);
if(pair.second) {
auto node = new Node{_pri, _pri->prev, {k, V()}};
_pri->prev->next = node;
_pri->prev = node;
pair.first->second = node;
}
return pair.first->second->value.second;
}
2023-07-21 17:40:49 +08:00
LinkedMap &insert(const K &k, const V &v) {
if(_pri==0) _pri = new LinkedMapPri<K, V>;
auto pair = _pri->map.emplace(k, nullptr);
if(pair.second) {
auto node = new Node{_pri, _pri->prev, {k, v}};
_pri->prev->next = node;
_pri->prev = node;
pair.first->second = node;
} else pair.first->second->value.second = v;
return *this;
}
2024-01-28 20:28:02 +08:00
V remove(const K& k) {
if(_pri==0) return V();
auto it = _pri->map.find(k);
if(it==_pri->map.end()) return V();
auto node = it->second;
_pri->map.erase(it);
node->prev->next = node->next;
node->next->prev = node->prev;
node->next = 0;
node->prev = 0;
auto v = node->value.second;
delete node;
return v;
}
2023-07-21 17:40:49 +08:00
void erase(const K& k) {
if(_pri==0) return;
auto it = _pri->map.find(k);
if(it==_pri->map.end()) return;
auto node = it->second;
_pri->map.erase(it);
node->prev->next = node->next;
node->next->prev = node->prev;
node->next = 0;
node->prev = 0;
delete node;
}
2023-09-19 11:49:20 +08:00
bool operator==(const LinkedMap &other) const {
if(_pri==other._pri) return true;
auto siz = size();
if(siz!=other.size()) return false;
if(siz==0) return true;
auto aaa = begin();
auto bbb = other.begin();
while(aaa!=end()) {
if(aaa->first != bbb->first || aaa->second != bbb->second) return false;
++aaa;
++bbb;
}
return true;
}
bool operator!=(const LinkedMap &other) const {
return ! (*this==other);
2023-07-21 17:40:49 +08:00
}
2023-09-19 11:49:20 +08:00
iterator begin() const {
return iterator((Node*) (_pri ? _pri->next : 0));
2023-07-21 17:40:49 +08:00
}
2023-09-19 11:49:20 +08:00
iterator end() const {
return iterator((Node*) _pri);
2023-07-21 17:40:49 +08:00
}
2023-09-19 11:49:20 +08:00
LinkedMapPri<K, V> *_pri = 0;
2023-07-21 17:40:49 +08:00
};
2023-09-19 11:49:20 +08:00
#endif // CPP_H