util
This commit is contained in:
parent
8bf38c468d
commit
4411e50aee
|
@ -2,19 +2,18 @@
|
|||
#define CPP_H
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
inline long long steady_milli() {
|
||||
inline int64_t steady_milli() {
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
|
||||
}
|
||||
inline long long system_milli() {
|
||||
inline int64_t system_milli() {
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
}
|
||||
inline long long steady_micro() {
|
||||
inline int64_t steady_micro() {
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
|
||||
}
|
||||
inline long long system_micro() {
|
||||
inline int64_t system_micro() {
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
}
|
||||
|
||||
|
@ -195,7 +194,7 @@ public:
|
|||
|
||||
LinkedMap() {}
|
||||
LinkedMap(std::initializer_list<std::pair<K, V>> pairs) : _pri{new LinkedMapPri<K, V>} {
|
||||
for(auto pair : pairs) insert(pair.first, pair.second);
|
||||
for(auto &pair : pairs) insert(pair.first, pair.second);
|
||||
}
|
||||
LinkedMap(std::unordered_map<K, Node*> &&map) : _pri{new LinkedMapPri<K, V>{0, 0, map}} {
|
||||
_pri->next = _pri->prev = _pri;
|
||||
|
@ -269,6 +268,20 @@ public:
|
|||
} else pair.first->second->value.second = v;
|
||||
return *this;
|
||||
}
|
||||
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;
|
||||
}
|
||||
void erase(const K& k) {
|
||||
if(_pri==0) return;
|
||||
auto it = _pri->map.find(k);
|
||||
|
|
|
@ -27,10 +27,10 @@ inline QString gUrlSuffix(const QString &url, int size, bool withDot = false) {
|
|||
}
|
||||
|
||||
inline QString byteSizeStr(double size) {
|
||||
const char *units[]{"B", "KB", "MB", "GB", "TB", "PB"};
|
||||
const char *units[]{"B", "KB", "MB", "GB", "TB", "PB", "EB"};
|
||||
auto i = 0;
|
||||
for(; size >= 1024 && i < 5; i++) size /= 1024;
|
||||
return QString::number(size, 'g', 3)+" "+units[i];
|
||||
for(; size >= 1024 && i < 7; i++) size /= 1024;
|
||||
return (size > 99 ? QString::number(size, 'f', 0) : QString::number(size, 'g', 3))+" "+units[i];
|
||||
}
|
||||
|
||||
inline void wait(int msec, QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents) {
|
||||
|
|
|
@ -36,13 +36,14 @@ bool TreeWidget::eventFilter(QObject *watched, QEvent *event) {
|
|||
if(event->type()==QEvent::Resize) {
|
||||
auto eve = (QResizeEvent *) event;
|
||||
if(eve->size().width() != eve->oldSize().width()) adjSections(-1, 0);
|
||||
return true;
|
||||
} else if(isSectionResized && event->type()==QEvent::Leave) {
|
||||
isSectionResized = false;
|
||||
auto item = headerItem();
|
||||
for(int cc=0; cc<columnCount(); cc++) if(item->data(cc, WidthRole).isValid()) item->setData(cc, WidthRole, header()->sectionSize(cc));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QTreeWidget::eventFilter(watched, event);
|
||||
}
|
||||
void TreeWidget::rowsInserted(const QModelIndex &parent, int start, int end) {
|
||||
|
@ -214,13 +215,14 @@ bool TableWidget::eventFilter(QObject *watched, QEvent *event) {
|
|||
if(event->type()==QEvent::Resize) {
|
||||
auto eve = (QResizeEvent *) event;
|
||||
if(eve->size().width() != eve->oldSize().width()) adjSections(-1, 0);
|
||||
return true;
|
||||
} else if(isSectionResized && event->type()==QEvent::Leave) {
|
||||
isSectionResized = false;
|
||||
QTableWidgetItem *item;
|
||||
for(int cc=0; cc<columnCount(); cc++) if((item = horizontalHeaderItem(cc)) && item->data(WidthRole).isValid()) item->setData(WidthRole, horizontalHeader()->sectionSize(cc));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QTableWidget::eventFilter(watched, event);
|
||||
}
|
||||
void TableWidget::onSectionResized(int logicalIndex, int oldSize, int newSize) {
|
||||
|
|
|
@ -147,9 +147,9 @@ public:
|
|||
Grid(QSplitter *splitter) : QGridLayout(new QWidget) {
|
||||
splitter->addWidget(parentWidget());
|
||||
};
|
||||
QLabel *addLabel(const QString& text) {
|
||||
QLabel *addLabel(const QString& text, int row, int column, Qt::Alignment align = Qt::Alignment()) {
|
||||
auto lb = new QLabel(text);
|
||||
addWidget(lb);
|
||||
addWidget(lb, row, column, align);
|
||||
return lb;
|
||||
}
|
||||
};
|
||||
|
@ -274,6 +274,7 @@ public:
|
|||
int sizeHintForColumn(int column) const override {
|
||||
return QTreeWidget::sizeHintForColumn(column);
|
||||
}
|
||||
bool adjSections(int index, int size);
|
||||
signals:
|
||||
void updGeos();
|
||||
protected:
|
||||
|
@ -285,7 +286,6 @@ protected:
|
|||
void rowsInserted(const QModelIndex &parent, int start, int end) override;
|
||||
void drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const override;
|
||||
void onSectionResized(int logicalIndex, int oldSize, int newSize);
|
||||
bool adjSections(int index, int size);
|
||||
bool noStretch = true;
|
||||
bool noMargin = true;
|
||||
bool isSectionResized = false;
|
||||
|
|
|
@ -16,10 +16,10 @@ JValue JParser::readValue() {
|
|||
while(ch==',');
|
||||
if(ch=='}') return obj;
|
||||
QString key;
|
||||
if(ch == '"') key = readStr();
|
||||
if(ch=='"') key = readStr();
|
||||
else if(ch!='n' || readOne()!='u' || readOne()!='l' || readOne()!='l') throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting double-quote to start field name or null";
|
||||
skipSpace();
|
||||
if(ch != ':') throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting a colon to separate field name and value";
|
||||
if(ch!=':') throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting a colon to separate field name and value";
|
||||
skipSpace();
|
||||
obj.insert(key, readValue());
|
||||
skipSpace(); //ch有两种可能
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "QtCore/qhashfunctions.h"
|
||||
#include <QDataStream>
|
||||
#include <QTextStream>
|
||||
|
||||
class JValue;
|
||||
using JObj = LinkedMap<QString, JValue>;
|
||||
using JArray = Vector<JValue>;
|
||||
|
@ -13,7 +14,7 @@ QDebug operator<<(QDebug debug, const JValue &val);
|
|||
|
||||
class JValue {
|
||||
public:
|
||||
long long data = 0;
|
||||
int64_t data = 0;
|
||||
enum Type {
|
||||
Null, Long, Ulong, Double, Bool, Obj, Array, Str
|
||||
};
|
||||
|
@ -119,10 +120,17 @@ public:
|
|||
const JValue operator[](const QString &key) const {
|
||||
return type==Obj ? (*(const JObj*) &data)[key] : JValue();
|
||||
}
|
||||
const JValue operator[](int i) const {
|
||||
const JValue operator[](uint64_t i) const {
|
||||
return type==Array ? (*(const JArray*) &data)[i] : JValue();
|
||||
}
|
||||
|
||||
JValue &ref(const QString &key) {
|
||||
return (*(JObj*) &data)[key];
|
||||
}
|
||||
JValue &ref(uint64_t i) {
|
||||
return (*(JArray*) &data)[i];
|
||||
}
|
||||
|
||||
JArray::iterator begin() const noexcept {
|
||||
return type==Array ? ((const JArray*) &data)->begin() : JArray::iterator();
|
||||
}
|
||||
|
@ -167,6 +175,7 @@ private:
|
|||
class JParser {
|
||||
public:
|
||||
JParser(QDataStream &in) : in(in) {}
|
||||
|
||||
JValue read() {
|
||||
in >> ch;
|
||||
if(ch==0) throw "Unexpected end-of-input";
|
||||
|
@ -182,6 +191,7 @@ protected:
|
|||
in >> ch;
|
||||
return ch;
|
||||
}
|
||||
|
||||
QDataStream ∈
|
||||
unsigned char ch{0}, bk{0};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user