Zen
A cross-platform functional programming language
|
00001 00005 #pragma once 00006 00007 // All Qt headers must be included in the pch.hpp file at this point 00008 #ifndef PCH_INCLUDED 00009 #error PCH file not included 00010 #endif 00011 00014 #define unused Q_UNUSED 00015 00017 #define assert(c) {if(!(c)) abort();} 00018 00020 #define registerMetatype(T) Q_DECLARE_METATYPE(T) 00021 00023 namespace zd { 00025 00033 struct counted { 00037 explicit inline counted(const char* n) : name(n), cnt(0) {} 00038 00041 inline ~counted() { 00042 qDebug() << name << cnt; 00043 } 00044 00046 const char* name; 00047 00049 int cnt; 00050 }; 00051 00053 00058 struct counter { 00064 explicit inline counter(counted& fn) : _fn(fn) { 00065 tmr.start(); 00066 } 00067 00072 inline ~counter() { 00073 _fn.cnt += tmr.elapsed(); 00074 } 00075 00077 QTime tmr; 00078 00080 counted& _fn; 00081 }; 00082 } 00083 00085 00089 template <typename T> 00090 inline T* ptr(T& t) { 00091 assert(0 != &t); 00092 return &t; 00093 } 00094 00096 00100 template <typename T> 00101 inline T& ref(T* t) { 00102 assert(t); 00103 return *t; 00104 } 00105 00107 00111 template <typename T> 00112 inline const T* ptr(const T& t) { 00113 assert(0 != &t); 00114 return &t; 00115 } 00116 00118 00122 template <typename T> 00123 inline const T& ref(const T* t) { 00124 assert(t); 00125 return *t; 00126 } 00127 00130 typedef char byte; 00131 00133 typedef long long int64; 00134 00137 namespace z { 00139 00141 class date { 00142 public: 00148 explicit inline date(const int& yy, const int& mm, const int& dd) : _val(yy, mm, dd){} 00149 00150 public: 00154 inline QDate& get() const {return const_cast<QDate&>(_val);} 00155 00156 private: 00158 QDate _val; 00159 }; 00160 00162 00164 class time { 00165 public: 00171 explicit inline time(const int& hh, const int& mm, const int& ss) : _val(hh, mm, ss){} 00172 00173 public: 00177 inline QTime& get() const {return const_cast<QTime&>(_val);} 00178 00179 private: 00181 QTime _val; 00182 }; 00183 00185 00187 class datetime { 00188 public: 00193 explicit inline datetime(const date& dd, const time& tt) : _val(dd.get(), tt.get()){} 00194 00195 public: 00199 inline QDateTime& get() const {return const_cast<QDateTime&>(_val);} 00200 00201 private: 00203 QDateTime _val; 00204 }; 00205 00208 class any; 00209 00211 00213 class string { 00214 public: 00217 explicit inline string(){} 00218 00222 inline string(const char* val) : _val(val) {} 00223 00227 explicit inline string(const QString& val) : _val(val) {} 00228 00229 public: 00233 inline string& operator =(const char* val) {_val = val; return ref(this);} 00234 00238 inline string& operator =(const string& val) {_val = val._val; return ref(this);} 00239 00243 inline string& operator+=(const int& chr) {_val.append(QChar(chr)); return ref(this);} 00244 00248 inline string& operator+=(const string& src) {_val += src._val; return ref(this);} 00249 00253 inline string& operator+=(const char* src) {_val += src; return ref(this);} 00254 00255 public: 00259 inline bool operator==(const string& src) const {return _val == src._val;} 00260 00264 inline bool operator==(const char* src) const {return _val == src;} 00265 00269 inline bool operator!=(const string& src) const {return _val != src._val;} 00270 00274 inline bool operator!=(const char* src) const {return _val != src;} 00275 00279 inline bool operator< (const string& src) const {return _val < src._val;} 00280 00284 inline string operator+ (const string& src) const {return string(_val + src._val);} 00285 00289 inline string operator+ (const char* src) const {return string(_val + src);} 00290 00291 public: 00295 inline int at(const int& idx) const {return _val.at(idx).unicode();} 00296 00300 inline bool has(const int& ch) const {return _val.contains(QChar(ch));} 00301 00305 inline int find(const z::string& sub) const {return _val.indexOf(sub.get());} 00306 00311 inline string mid(const int& start, const int& len = -1) const {return string(_val.mid(start, len));} 00312 00315 inline long toLong() const {return _val.toLong();} 00316 00320 inline string leftJustified(const int& w) const {return string(_val.leftJustified(w));} 00321 00324 inline int length() const {return _val.length();} 00325 00329 inline void replace(const int& ch, const int& with) {_val.replace(QChar(ch), QChar(with));} 00330 00331 public: 00336 inline const char* toUtf8(char buf[], const int& len) const { 00337 QByteArray arr = _val.toUtf8(); 00338 for(int i = 0; (i < arr.size()) && (i < (len-1)); ++i) { 00339 buf[i] = arr.at(i); 00340 buf[i+1] = 0; 00341 } 00342 return buf; 00343 } 00344 00345 public: 00349 inline QString& get() const {return const_cast<QString&>(_val);} 00350 00351 public: 00354 class creator { 00355 public: 00359 inline creator(const string& val) : _val(val.get()) {} 00360 00361 public: 00366 inline creator& arg(const z::any& key, const z::any& val); 00367 00370 inline z::string value() {return string(_val);} 00371 00372 private: 00374 QString _val; 00375 }; 00376 00377 private: 00379 QString _val; 00380 }; 00381 00387 inline z::string operator+(const char* src, const z::string& dst) { 00388 return z::string(src + dst.get()); 00389 } 00390 00396 inline QDebug operator<<(QDebug db, const z::string& ss) { 00397 db << ss.get(); 00398 return db; 00399 } 00400 00405 inline uint qHash(const z::string& key) {return qHash(key.get());} 00406 00411 inline uint qHash(const double& key) {return ::qHash((qlonglong)(key*100));} 00412 00414 00416 template<typename T> 00417 class sharedptr { 00418 public: 00422 explicit inline sharedptr(T* t) : _ptr(t) {} 00423 00426 inline T& operator*() const {return *_ptr;} 00427 00428 private: 00430 QSharedPointer<T> _ptr; 00431 }; 00432 00434 00437 template<typename T> 00438 class autoptr { 00439 public: 00442 explicit inline autoptr() : _ptr(0) {} 00443 00447 explicit inline autoptr(T* t) : _ptr(t) {} 00448 00451 inline ~autoptr() {delete _ptr;} 00452 00453 public: 00456 inline void operator=(T* t) {_ptr = t;} 00457 00460 inline T& operator*() const {return ref(_ptr);} 00461 00464 inline T* operator->() const {return _ptr;} 00465 00468 inline T* data() const {return _ptr;} 00469 00472 inline bool isNull() const {return (0 == _ptr);} 00473 00477 inline T* take() {T* t = _ptr; _ptr = 0; return t;} 00478 00483 inline T* reset(T* n) {T* t = _ptr; _ptr = n; return t;} 00484 00485 private: 00487 T* _ptr; 00488 }; 00489 00491 00493 template<typename T> 00494 class scopedptr { 00495 public: 00498 explicit inline scopedptr() : _ptr() {} 00499 00503 explicit inline scopedptr(T* t) : _ptr(t) {} 00504 00505 public: 00508 inline T& operator*() const {return *_ptr;} 00509 00512 inline T* operator->() const {return _ptr.data();} 00513 00516 inline T* data() const {return _ptr.data();} 00517 00520 inline bool isNull() const {return _ptr.isNull();} 00521 00525 inline T* take() {return _ptr.take();} 00526 00531 inline void reset(T* t) {return _ptr.reset(t);} 00532 00533 private: 00535 QScopedPointer<T> _ptr; 00536 }; 00537 00539 00543 template<typename V> 00544 class owner { 00545 public: 00548 inline V& insert() { 00549 V* v = new V(); 00550 _list.insert(v); 00551 return ref(v); 00552 } 00553 00556 inline void remove(V& v) { 00557 typename List::iterator it = _list.find(ptr(v)); 00558 assert(it != _list.end()); 00559 V* o = *it; 00560 assert(o == ptr(v)); 00561 _list.erase(it); 00562 delete o; 00563 } 00564 00565 private: 00567 typedef QSet<V*> List; 00568 00570 List _list; 00571 }; 00572 00574 00579 template<typename V> 00580 class holder { 00581 public: 00586 inline V& insert(V* v) { 00587 _list.insert(v); 00588 return ref(v); 00589 } 00590 00594 inline void remove(V& v) { 00595 typename List::iterator it = _list.find(ptr(v)); 00596 assert(it != _list.end()); 00597 V* o = *it; 00598 assert(o == ptr(v)); 00599 _list.erase(it); 00600 delete o; 00601 } 00602 00603 private: 00605 typedef QSet<V*> List; 00606 00608 List _list; 00609 }; 00610 00612 00616 template<typename iterT, typename V> 00617 class iteratorbase { 00618 public: 00622 explicit inline iteratorbase(const iterT& iter) : _iter(iter) {} 00623 00624 public: 00627 inline bool begin() const {return !_iter.hasPrevious();} 00628 00631 inline bool end() const {return !_iter.hasNext();} 00632 00636 inline bool operator!=(const iteratorbase& src) const {return _iter != src._iter;} 00637 00641 inline bool operator==(const iteratorbase& src) const {return _iter == src._iter;} 00642 00644 inline void toBack() {return _iter.toBack();} 00645 00646 protected: 00648 iterT _iter; 00649 }; 00650 00652 00654 template<typename iterT, typename V> 00655 class iteratorbaseL : public iteratorbase<iterT, V> { 00656 private: 00658 typedef iteratorbase<iterT, V> baseT; 00659 00660 public: 00664 explicit inline iteratorbaseL(const iterT& iter) : baseT(iter) {} 00665 00666 public: 00669 inline const V& operator++() {return baseT::_iter.next();} 00670 00673 inline const V& operator--() {return baseT::_iter.previous();} 00674 00677 inline const V& operator*() const {return baseT::_iter.peekNext();} 00678 }; 00679 00681 00683 template<typename iterT, typename K, typename V> 00684 class iteratorbaseD : public iteratorbase<iterT, V> { 00685 private: 00687 typedef iteratorbase<iterT, V> baseT; 00688 00689 public: 00693 explicit inline iteratorbaseD(const iterT& iter) : baseT(iter) {} 00694 00695 public: 00698 inline const V& operator++() {return baseT::_iter.next().value();} 00699 00702 inline const V& operator--() {return baseT::_iter.previous().value();} 00703 00706 inline const V& operator*() const {return baseT::_iter.peekNext().value();} 00707 00710 inline const K& key() const {return baseT::_iter.peekNext().key();} 00711 00712 public: 00716 inline bool find(const K& key) const {return !baseT::_iter.findNext(key);} 00717 }; 00718 00720 00722 template<typename listT> 00723 class containerbase { 00724 protected: 00727 explicit inline containerbase() {} 00728 00732 explicit inline containerbase(const containerbase& src) : _list(src._list) {} 00733 00734 public: 00737 inline int size() const {return _list.size();} 00738 00739 protected: 00741 listT _list; 00742 }; 00743 00745 00747 template<typename derT, typename listT, typename iterT, typename V> 00748 class listbase : public containerbase<listT> { 00749 private: 00751 typedef containerbase<listT> baseT; 00752 00753 public: 00756 class iterator : public iteratorbaseL<iterT, V> { 00757 public: 00761 inline iterator(const derT& list) : iteratorbaseL<iterT, V>(list._list) {} 00762 }; 00763 00764 public: 00767 class creator { 00768 public: 00771 inline creator() {} 00772 00773 public: 00777 inline creator& add(const V& val) {_list.append(val);return ref(this);} 00778 00781 inline derT& value() {return _list;} 00782 00783 private: 00785 derT _list; 00786 }; 00787 00788 public: 00792 inline V& operator[](const int& key) {return baseT::_list[key];} 00793 00794 public: 00797 inline bool empty() const {return baseT::_list.isEmpty();} 00798 00800 inline void clear() {baseT::_list.clear();} 00801 00804 inline void append(const V& v) {baseT::_list.append(v);} 00805 00808 inline void appendList(const derT& v) {baseT::_list.append(v._list);} 00809 00813 inline const V& at(const int& idx) const {return baseT::_list.at(idx);} 00814 00818 inline int indexOf(const V& v) const {return baseT::_list.indexOf(v);} 00819 00822 inline V& front() {return baseT::_list.front();} 00823 00826 inline const V& front() const {return baseT::_list.front();} 00827 00830 inline V& last() {return baseT::_list.last();} 00831 00834 inline const V& last() const {return baseT::_list.last();} 00835 00839 inline derT& operator<<(const V& val) {append(val); return static_cast<derT&>(ref(this));} 00840 }; 00841 00843 00845 template<typename V> 00846 class list : public listbase<list<V>, QList<V>, QListIterator<V>, V> { 00847 private: 00849 typedef listbase<list<V>, QList<V>, QListIterator<V>, V> baseT; 00850 }; 00851 00853 00855 template<typename V> 00856 class set : public listbase<set<V>, QSet<V>, QSetIterator<V>, V> { 00857 private: 00859 typedef listbase<set<V>, QSet<V>, QSetIterator<V>, V> baseT; 00860 00861 public: 00864 inline void insert(const V& v) {baseT::_list.insert(v);} 00865 00869 inline bool has(const V& v) const { return baseT::_list.contains(v);} 00870 }; 00871 00873 00875 template<typename V> 00876 class stack : public listbase<stack<V>, QStack<V>, QVectorIterator<V>, V> { 00877 private: 00879 typedef listbase<stack<V>, QStack<V>, QVectorIterator<V>, V> baseT; 00880 00881 public: 00884 inline V& top() {return baseT::_list.top();} 00885 00888 inline const V& top() const {return baseT::_list.top();} 00889 00892 inline void push(const V& v) {baseT::_list.push(v);} 00893 00896 inline V pop() { return baseT::_list.pop();} 00897 }; 00898 00900 00902 template<typename V> 00903 class queue : public listbase<queue<V>, QQueue<V>, QListIterator<V>, V> { 00904 public: 00906 typedef listbase<queue<V>, QQueue<V>, QListIterator<V>, V> baseT; 00907 00908 public: 00911 inline V& head() {return baseT::_list.head();} 00912 00915 inline void enque(const V& v) {baseT::_list.enqueue(v);} 00916 00919 inline V deque() { return baseT::_list.dequeue();} 00920 }; 00921 00923 00925 template<typename derT, typename K, typename V> 00926 class dictbase : public containerbase< QMap<K, V> > { 00927 private: 00929 typedef containerbase< QMap<K, V> > baseT; 00930 00931 public: 00934 class iterator : public iteratorbaseD<QMapIterator<K, V>, K, V> { 00935 private: 00937 typedef iteratorbaseD<QMapIterator<K, V>, K, V> baseT; 00938 00939 public: 00943 inline iterator(const derT& list) : baseT(list._list) {} 00944 }; 00945 00946 public: 00949 class found { 00950 public: 00955 inline found(typename QMap<K, V>::const_iterator iter, typename QMap<K, V>::const_iterator end) : _found(iter != end), _iter(iter) {} 00956 00957 public: 00960 inline operator bool() const {return _found;} 00961 00964 inline const V& operator*() const {return _iter.value();} 00965 00966 private: 00968 bool _found; 00969 00971 typename QMap<K, V>::const_iterator _iter; 00972 }; 00973 00974 public: 00978 inline void insert(const K& k, const V& v) {baseT::_list.insert(k, v);} 00979 00983 inline bool has(const K& k) const { return baseT::_list.contains(k);} 00984 00988 inline found find(const K& k) const { return found(baseT::_list.find(k), baseT::_list.end());} 00989 00990 public: 00994 inline const QMap<K,V>& get() const {return baseT::_list;} 00995 00996 public: 01000 inline V& at(const K& key) { 01001 assert(has(key)); 01003 //V& v = baseT::_list.value(key); 01004 V& v = baseT::_list[key]; 01005 return v; 01006 } 01007 01008 public: 01012 inline V& operator[](const K& key) {return baseT::_list[key];} 01013 01014 public: 01017 class creator { 01018 public: 01021 inline creator() {} 01022 01023 public: 01028 inline creator& add(const K& key, const V& val) {_list[key] = val;return ref(this);} 01029 01032 inline derT& value() {return _list;} 01033 01034 private: 01036 derT _list; 01037 }; 01038 }; 01039 01041 01043 template<typename K, typename V> 01044 class dict : public dictbase< dict<K, V>, K, V > { 01045 private: 01047 typedef dictbase< dict<K, V>, K, V > baseT; 01048 }; 01049 01052 class key; 01053 01055 01057 class tree : public dictbase< tree, key, any > { 01058 private: 01060 typedef dictbase< tree, key, any > baseT; 01061 01062 public: 01065 inline tree() {} 01066 }; 01067 01069 01071 class stringset { 01072 public: 01075 explicit inline stringset() {} 01076 01077 public: 01079 inline void clear() {_list.clear();} 01080 01083 inline void insert(const string& v) {_list.insert(v.get());} 01084 01088 inline bool has(const string& v) const { return _list.contains(v.get());} 01089 01090 private: 01092 QSet<QString> _list; 01093 }; 01094 01096 01098 class stringlist : public z::list<z::string> { 01099 public: 01103 inline z::string join(const z::string& sep) const { 01104 z::string s; 01105 z::string sep1; 01106 for(z::list<string>::iterator it(ref(this)); !it.end(); ++it) { 01107 s += sep1; 01108 s += *it; 01109 sep1 = sep; 01110 } 01111 return s; 01112 } 01113 01116 inline void append(const string& v) {z::list<z::string>::append(v);} 01117 01120 inline void append(const stringlist& v) {z::list<z::string>::appendList(v);} 01121 }; 01122 01124 01126 class buffer { 01127 public: 01131 inline QByteArray& get() { return _val;} 01132 01136 inline const QByteArray& get() const { return _val;} 01137 01138 public: 01141 inline int size() const {return _val.size();} 01142 01143 public: 01148 class iterator { 01149 public: 01153 inline iterator(const buffer& buf) : _buf(buf), _pos(0) {} 01154 01155 public: 01158 inline iterator& operator++() {++_pos; return ref(this);} 01159 01162 inline int operator*() {return _buf.get().at(_pos);} 01163 01166 inline bool end() {return (_pos >= _buf.size());} 01167 01168 private: 01170 const buffer& _buf; 01171 01173 int _pos; 01174 }; 01175 01176 public: 01180 explicit inline buffer(const int& size) : _val(size, 0) {} 01181 01185 explicit inline buffer(const QByteArray& src) : _val(src) {} 01186 01187 public: 01191 inline int operator[](const int& idx) { return _val.at(idx);} 01192 01193 private: 01195 QByteArray _val; 01196 }; 01197 01199 01201 class fileinfo { 01202 public: 01206 explicit inline fileinfo(const string& filename) : _val(filename.get()) {} 01207 01212 explicit inline fileinfo(const string& dir, const string& filename) : _val(dir.get(), filename.get()) {} 01213 01214 public: 01217 inline string getAbsoluteFilePath() const { return string(_val.absoluteFilePath()); } 01218 01221 inline string getBaseName() const { return string(_val.baseName()); } 01222 01225 inline string getAbsolutePath() const { return string(_val.absolutePath()); } 01226 01229 inline string getFilePath() const { return string(_val.filePath()); } 01230 01233 inline string getFileName() const { return string(_val.fileName()); } 01234 01237 inline string getSuffix() const { return string(_val.suffix()); } 01238 01241 inline string getPath() const { return string(_val.path()); } 01242 01243 public: 01246 inline bool exists() const { return _val.exists();} 01247 01250 inline bool isAbsolute() const { return _val.isAbsolute();} 01251 01252 public: 01256 static inline string getCanonicalDirPath(const string& file) {return string(QDir(file.get()).canonicalPath());} 01257 01261 static inline string getCanonicalFilePath(const string& file) {return string(QFileInfo(file.get()).canonicalFilePath());} 01262 01263 public: 01267 static inline bool isAbsolute(const string& file) { return fileinfo(file).isAbsolute();} 01268 01272 static inline string getNativeSeparator(const string& file) { return string(QDir::toNativeSeparators(file.get())); } 01273 01277 static inline string getAbsolutePath(const string& file) { return fileinfo(file).getAbsolutePath(); } 01278 01282 static inline string getAbsoluteFilePath(const string& file) { return fileinfo(file).getAbsoluteFilePath(); } 01283 01288 static inline string getRelativeFilePath(const string& dir, const string& file) { return string(QDir(dir.get()).relativeFilePath(file.get())); } 01289 01292 static inline string getTempPath() { return string(QDir::tempPath()); } 01293 01296 static inline string getCwd() { return string(QDir::currentPath()); } 01297 01302 static inline bool copy(const string& src, const string& dst) {return QFile::copy(src.get(), dst.get());} 01303 01307 static inline bool exists(const string& file) {return QFile::exists(file.get());} 01308 01312 static inline bool existsDir(const string& file) {return QDir(file.get()).exists();} 01313 01317 static inline bool mkdir(const string& file) {return QDir().mkdir(QDir::cleanPath(file.get()));} 01318 01322 static inline bool remove(const string& file) {return QFile::remove(file.get());} 01323 01328 static bool rmdir(const string& file, const bool& recursive); 01329 01330 private: 01332 QFileInfo _val; 01333 }; 01334 01336 01338 class file { 01339 public: 01342 explicit inline file() {} 01343 01347 explicit inline file(const z::string& filename) : _val(filename.get()) {} 01348 01352 inline file(const file& src) : _val(src._val.fileName()) {assert(!src._val.isOpen());} 01353 01354 public: 01358 inline QFile& get() { return _val;} 01359 01360 public: 01363 inline void setFileName(const z::string& filename) {return _val.setFileName(filename.get());} 01364 01367 inline string getFileName() const {return string(_val.fileName());} 01368 01372 inline bool open(int flags) { return _val.open((QIODevice::OpenModeFlag)flags); } 01373 01375 inline void close() { return _val.close(); } 01376 01379 inline bool isOpen() const { return _val.isOpen(); } 01380 01381 private: 01383 QFile _val; 01384 }; 01385 01387 01389 class stream { 01390 public: 01393 inline stream() {} 01394 01398 inline stream(const stream& src) {unused(src);} 01399 01400 public: 01404 explicit inline stream(const z::string& txt) : _val(&(txt.get())) {} 01405 01410 explicit inline stream(FILE* file, QIODevice::OpenModeFlag flags) : _val(file, flags) {} 01411 01412 public: 01416 inline stream(file& f) : _val(&(f.get())) {} 01417 01418 public: 01422 inline QTextStream& get() {return _val;} 01423 01424 public: 01427 inline int pos() {return (int)_val.pos();} 01428 01431 inline bool end() {return _val.atEnd();} 01432 01435 inline void seek(const int& pos) {_val.seek(pos);} 01436 01438 inline void flush() {return _val.flush();} 01439 01442 inline void setDevice(z::file& file) {_val.setDevice(&(file.get()));} 01443 01446 inline const QString& getString() const {QString* str = _val.string(); assert(str); return *str;} 01447 01448 public: 01451 inline int getChar() { 01452 QChar ch; 01453 _val >> ch; 01454 return ch.unicode(); 01455 } 01456 01457 private: 01459 QTextStream _val; 01460 }; 01461 01463 01468 inline z::stream& operator<<(z::stream& ss, const int& val) { 01469 ss.get() << val; 01470 return ss; 01471 } 01472 01478 inline z::stream& operator<<(z::stream& ss, const char* val) { 01479 ss.get() << val; 01480 return ss; 01481 } 01482 01488 inline z::stream& operator<<(z::stream& ss, const QString& val) { 01489 ss.get() << val; 01490 return ss; 01491 } 01492 01498 inline z::stream& operator<<(z::stream& ss, const z::string& val) { 01499 ss.get() << val.get(); 01500 return ss; 01501 } 01502 01510 template<typename derT, typename listT, typename iterT, typename V> 01511 inline z::stream& operator<<(z::stream& ss, const z::listbase<derT, listT, iterT, V>& val) { 01512 for(typename derT::iterator it(static_cast<const derT&>(val)); !it.end(); ++it) { 01513 const V& v = *it; 01514 ss << v; 01515 } 01516 return ss; 01517 } 01518 01520 01527 template<typename derT, typename K, typename V> 01528 inline z::stream& operator<<(z::stream& ss, const z::dictbase<derT, K, V>& val) { 01529 ss << "{"; 01530 z::string sep; 01531 for(typename derT::iterator it(static_cast<const derT&>(val)); !it.end(); ++it) { 01532 const K& k = it.key(); 01533 const V& v = *it; 01534 ss << sep << k << ":" << v; 01535 sep = ", "; 01536 } 01537 ss << "}"; 01538 return ss; 01539 } 01540 01542 01544 class filestream : public stream { 01545 public: 01548 explicit filestream() {} 01549 01553 explicit filestream(file& f) : stream(f) {} 01554 01559 explicit filestream(FILE* file, QIODevice::OpenModeFlag flags) : stream(file, flags) {} 01560 }; 01561 01563 01565 class stringstream : public stream { 01566 public: 01570 explicit stringstream(const z::string& txt) : stream(txt) {} 01571 }; 01572 01574 01576 class nullstream : public stream { 01577 public: 01580 explicit nullstream() {} 01581 }; 01582 01587 class end { 01588 }; 01589 01595 inline z::stream& operator<<(z::stream& ss, const z::end& e) { 01596 unused(e); 01597 ss.get() << endl; 01598 return ss; 01599 } 01600 01602 01604 class exception { 01605 public: 01608 explicit inline exception(){} 01609 01613 explicit inline exception(const z::string& msg) : _msg(msg) { 01614 QTextStream(stderr, QIODevice::WriteOnly) << _msg.get() << endl; 01615 } 01616 01617 public: 01620 inline const z::string& toString() const {return _msg;} 01621 01622 private: 01624 z::string _msg; 01625 }; 01626 01628 01630 class application { 01631 public: 01636 inline application(int argc, char* argv[]) {unused(argc); unused(argv);} 01637 01638 public: 01641 static inline z::string path() {return z::string(QCoreApplication::applicationDirPath());} 01642 01643 public: 01648 static inline z::string getEnv(const z::string& key, const z::string& val = z::string("")) { 01649 return z::string(QProcessEnvironment::systemEnvironment().value(key.get(), val.get())); 01650 } 01651 }; 01652 01654 01656 class process { 01657 public: 01662 inline process(const bool& log, z::stream& ss) : _log(log), _ss(ss) {} 01663 01664 public: 01667 inline void addArg(const z::string& arg) {_qargs.append(arg.get());} 01668 01671 inline void setWorkingDirectory(const z::string& pwd) {_p.setWorkingDirectory(pwd.get());} 01672 01675 inline z::string getWorkingDirectory() const {return z::string(_p.workingDirectory());} 01676 01677 private: 01679 inline void write(bool error) { 01680 if((!error) && (!_log)) 01681 return; 01682 01683 if(_p.canReadLine()) { 01684 z::string s(QString(_p.readAll())); 01685 if(s.length() > 0) { 01686 _ss << s; 01687 } 01688 } 01689 01690 if(_p.exitCode()) { 01691 _ss << z::string(_p.errorString()); 01692 } 01693 _ss.flush(); 01694 } 01695 01696 public: 01700 inline int execute(const z::string& prog) { 01701 _p.setProcessChannelMode(QProcess::MergedChannels); 01702 _p.start(prog.get(), _qargs); 01703 01704 if(!_p.waitForStarted()) { 01705 write(true); 01706 if(_p.exitCode() == 0) 01707 return -1; 01708 return _p.exitCode(); 01709 } 01710 01711 while(_p.waitForReadyRead(-1)) { 01712 write(false); 01713 } 01714 01715 write(_p.exitCode() != 0); 01716 return _p.exitCode(); 01717 } 01718 01719 private: 01721 QStringList _qargs; 01722 01724 bool _log; 01725 01727 z::stream& _ss; 01728 01730 QProcess _p; 01731 }; 01732 01734 01736 class timer { 01737 public: 01741 explicit inline timer(const bool& start = false) {if(start) {_val.start();}} 01742 01743 public: 01746 inline int getElapsed() const {return _val.elapsed();} 01747 01748 private: 01750 QTime _val; 01751 }; 01752 01754 01756 class mutex { 01757 public: 01760 explicit inline mutex() {} 01761 01762 public: 01766 inline QMutex& get() {return _val;} 01767 01768 private: 01770 QMutex _val; 01771 }; 01772 01774 01776 class mutexlocker { 01777 public: 01781 explicit inline mutexlocker(mutex& mx) : _val(&(mx.get())) {} 01782 01783 private: 01785 QMutexLocker _val; 01786 }; 01787 01790 01792 class database { 01793 public: 01796 database(); 01797 01800 ~database(); 01801 01802 public: 01807 bool open(const z::string& type, const z::string& name); 01808 01814 bool create(const z::string& type, const z::string& name, const char* schema[]); 01815 01817 inline void close() {return _val.close();} 01818 01821 inline bool begin() {return _val.transaction();} 01822 01825 inline bool commit() {return _val.commit();} 01826 01829 inline bool rollback() {return _val.rollback();} 01830 01831 public: 01835 inline QSqlDatabase& get() {return _val;} 01836 private: 01838 QSqlDatabase _val; 01839 }; 01840 01842 01846 class transaction { 01847 public: 01851 explicit inline transaction(database& db) : _db(db), _committed(false) { 01852 _db.begin(); 01853 } 01854 01857 inline ~transaction() { 01858 if(!_committed) 01859 _db.rollback(); 01860 } 01861 01863 inline void commit() { 01864 _db.commit(); 01865 _committed = true; 01866 } 01867 01868 private: 01870 database& _db; 01871 01873 bool _committed; 01874 }; 01875 01877 01879 class statement { 01880 public: 01885 explicit inline statement(database& db, const z::string& sql) : _db(db), _val(sql.get(), db.get()) {} 01886 01887 public: 01890 inline bool next() {return _val.next();} 01891 01894 inline bool exec() {return _val.exec();} 01895 01897 inline void finish() {return _val.finish();} 01898 01899 public: 01902 int insert(); 01903 01904 public: 01908 void bind(const z::string& key, const z::any& val); 01909 01910 public: 01914 any getVar(const int& idx); 01915 01916 private: 01918 database& _db; 01919 01921 QSqlQuery _val; 01922 }; 01923 01926 01930 class data : public tree { 01931 public: 01934 inline data() : _id(0) {} 01935 01936 public: 01939 inline void setId(const int64& id) {assert(_id == 0); assert(id); _id = id;} 01940 01943 inline const int64& id() const {return _id;} 01944 01945 private: 01947 int64 _id; 01948 }; 01949 01952 01954 class qexpr { 01955 protected: 01958 explicit inline qexpr() {} 01959 01960 public: 01963 virtual ~qexpr(){} 01964 01965 public: 01967 class visitor; 01968 01971 virtual void visit(visitor& v) const = 0; 01972 }; 01973 01976 class qid; 01977 01979 class qint; 01980 01982 class qstring; 01983 01985 class qval; 01986 01988 class qbinary; 01989 01991 class qnot; 01992 01994 class qpair; 01995 01997 class query; 01998 02001 class qexpr::visitor { 02002 public: 02006 virtual void visit(const qval& qe) = 0; 02007 02011 virtual void visit(const qid& qe) = 0; 02012 02016 virtual void visit(const qint& qe) = 0; 02017 02021 virtual void visit(const qstring& qe) = 0; 02022 02026 virtual void visit(const qbinary& qe) = 0; 02027 02031 virtual void visit(const qnot& qe) = 0; 02032 02036 virtual void visit(const qpair& qe) = 0; 02037 02041 virtual void visit(const query& qe) = 0; 02042 }; 02043 02045 02047 template <typename T> 02048 class qvisitorT : public qexpr { 02049 public: 02052 explicit inline qvisitorT() {} 02053 02054 public: 02057 virtual void visit(qexpr::visitor& v) const {v.visit(static_cast<const T&>(ref(this)));} 02058 }; 02059 02061 02063 template <typename T, typename qT> 02064 class qconstant : public qvisitorT< qT > { 02065 public: 02069 explicit inline qconstant(const T& val) : _val(val) {} 02070 02071 private: 02073 const T& _val; 02074 }; 02075 02077 02079 class qstring : public qvisitorT<qstring> { 02080 public: 02084 explicit inline qstring(const z::string& val) : _val(val) {} 02085 02086 public: 02089 inline const z::string& getVal() const {return _val;} 02090 02091 private: 02093 const z::string _val; 02094 }; 02095 02097 02099 class qid : public qvisitorT<qint> { 02100 public: 02103 explicit inline qid() : _val(0) {} 02104 02108 explicit inline qid(const int64& val) : _val(val) {} 02109 02110 public: 02113 inline const int64& getVal() const {return _val;} 02114 02119 inline qid& operator=(const qid& src) {_val = src._val; return ref(this);} 02120 02121 private: 02123 int64 _val; 02124 }; 02125 02127 02132 inline z::stream& operator<<(z::stream& ss, const z::qid& val) { 02133 ss << val.getVal(); 02134 return ss; 02135 } 02136 02138 02140 class qint : public qvisitorT<qint> { 02141 public: 02145 explicit inline qint(const int& val) : _val(val) {} 02146 02147 public: 02150 inline const int& getVal() const {return _val;} 02151 02152 private: 02154 const int _val; 02155 }; 02156 02158 02160 class qval : public qvisitorT<qval> { 02161 public: 02164 explicit inline qval() {} 02165 }; 02166 02168 02170 class qbinary : public qvisitorT<qbinary> { 02171 public: 02177 explicit inline qbinary(const qexpr& lhs, const z::string& op, const qexpr& rhs) : _lhs(lhs), _op(op), _rhs(rhs) {} 02178 02179 public: 02182 inline const qexpr& getLhs() const {return _lhs;} 02183 02186 inline const z::string& getOp() const {return _op;} 02187 02190 inline const qexpr& getRhs() const {return _rhs;} 02191 02192 private: 02194 const qexpr& _lhs; 02195 02197 const z::string _op; 02198 02200 const qexpr& _rhs; 02201 }; 02202 02204 02206 class qnot : public qvisitorT<qnot> { 02207 public: 02211 explicit inline qnot(const qexpr& rhs) : _rhs(rhs) {} 02212 02213 public: 02216 inline const qexpr& getRhs() const {return _rhs;} 02217 02218 private: 02220 const qexpr& _rhs; 02221 }; 02222 02224 02226 class qpair : public qvisitorT<qpair> { 02227 public: 02232 explicit inline qpair(const qexpr& lhs, const qexpr& rhs) : _lhs(lhs), _rhs(rhs) {} 02233 02234 public: 02237 inline const qexpr& getLhs() const {return _lhs;} 02238 02241 inline const qexpr& getRhs() const {return _rhs;} 02242 02243 private: 02245 const qexpr& _lhs; 02246 02248 const qexpr& _rhs; 02249 }; 02250 02252 02254 class query : public qvisitorT<query> { 02255 public: 02259 explicit inline query(const qexpr& expr) : _expr(expr) {} 02260 02261 public: 02264 inline const qexpr& getExpr() const {return _expr;} 02265 02266 private: 02268 const qexpr& _expr; 02269 }; 02270 02272 02274 class result : public z::list< z::data > { 02275 }; 02276 02278 02280 class store { 02281 public: 02284 explicit inline store() {} 02285 02289 explicit inline store(const z::string& path) : _path(path) {} 02290 02291 public: 02295 inline store(const store& src) : _path(src._path), _db(src._db) {} 02296 02297 public: 02300 inline const string& getPath() const {return _path;} 02301 02304 inline database& get() {return _db;} 02305 02306 private: 02308 string _path; 02309 02311 database _db; 02312 }; 02313 02318 inline uint qHash(const z::qid& key) {return qHash(key.getVal());} 02319 02324 template <typename T> 02325 inline QVariant getQVar(const T& v) { 02326 QVariant qv; 02327 qv.setValue(v); 02328 return qv; 02329 } 02330 02332 02334 class any { 02335 public: 02337 02339 class base { 02340 public: 02343 virtual ~base(){} 02344 02347 virtual base* clone() const = 0; 02348 02351 virtual void write(z::stream& os) const = 0; 02352 02355 virtual QVariant getVar() const = 0; 02356 }; 02357 02359 02361 template <typename T> 02362 class impl : public base { 02363 public: 02367 inline impl(const T& val) : _val(val) {} 02368 02369 public: 02373 inline const T& get() const {return _val;} 02374 02375 public: 02378 virtual base* clone() const {return new impl<T>(_val);} 02379 02382 virtual void write(z::stream& os) const { 02383 os << _val; 02384 } 02385 02388 virtual QVariant getVar() const {return getQVar<T>(_val);} 02389 02390 private: 02392 T _val; 02393 }; 02394 02395 public: 02400 inline any() : _val(0) { 02401 _val = new impl<int>(0); 02402 } 02403 02407 inline any(const any& src) : _val(0) { 02408 _val = ref( src._val).clone(); 02409 } 02410 02413 inline ~any() {delete _val;} 02414 02415 public: 02418 template <typename T> 02419 explicit inline any(const T& val) : _val(0) { 02420 _val = new impl<T>(val); 02421 } 02422 02425 inline any(const char* val) : _val(0) { 02426 _val = new impl<z::string>(val); 02427 } 02428 02429 public: 02434 inline any& operator=(const any& src) { 02435 delete _val; 02436 _val = ref( src._val).clone(); 02437 return ref(this); 02438 } 02439 02440 public: 02444 virtual void write(z::stream& os) const { 02445 ref(_val).write(os); 02446 } 02447 02451 inline QVariant getVar() const {return ref(_val).getVar();} 02452 02453 public: 02457 template <typename T> 02458 inline bool is() const { 02459 impl<T>* p = dynamic_cast<impl<T>*>(_val); 02460 return (0 != p); 02461 } 02462 02463 public: 02467 template <typename T> 02468 inline const T& get() const { 02469 impl<T>* p = dynamic_cast<impl<T>*>(_val); 02470 if(!p) { 02471 throw z::exception(z::string::creator("Type mismatch (any)").value()); 02472 } 02473 return ref(p).get(); 02474 } 02475 02476 private: 02478 base* _val; 02479 }; 02480 02482 02486 inline z::any getVar(const QVariant& v); 02487 02492 template <> 02493 inline QVariant getQVar(const z::string& v) {return QVariant(v.get());} 02494 02496 02501 inline z::stream& operator<<(z::stream& ss, const z::any& val) { 02502 val.write(ss); 02503 return ss; 02504 } 02505 02507 02509 class key { 02510 public: 02513 explicit inline key() { 02514 } 02515 02519 inline key(const any& val) : _val(val) { 02520 } 02521 02525 inline key(const key& src) : _val(src._val) { 02526 } 02527 02528 public: 02533 inline key& operator=(const z::any& rhs) { 02534 _val = rhs; 02535 return ref(this); 02536 } 02537 02538 public: 02543 template <typename T> 02544 inline key& operator=(const T& rhs) { 02545 _val = z::any(rhs); 02546 return ref(this); 02547 } 02548 02549 public: 02553 inline const any& get() const { 02554 return _val; 02555 } 02556 02557 public: 02561 inline uint getHash() const { 02562 if(_val.is<int>()) { 02563 return ::qHash(_val.get<int>()); 02564 } 02565 02566 if(_val.is<long>()) { 02567 return ::qHash(_val.get<long>()); 02568 } 02569 02570 if(_val.is<double>()) { 02571 return qHash(_val.get<double>()); 02572 } 02573 02574 if(_val.is<z::string>()) { 02575 return qHash(_val.get<z::string>()); 02576 } 02577 02578 throw z::exception(z::string::creator("Unhandled key type: xx").value()); 02579 } 02580 02581 private: 02583 z::any _val; 02584 }; 02585 02591 inline bool operator<(const key& lhs, const key& rhs) { 02592 return lhs.getHash() < rhs.getHash(); 02593 } 02594 02600 inline uint getTypeHash(const z::string& name, const int64& p) { 02601 z::string s = z::string::creator("_ztype_%{name}_%{val}_") 02602 .arg(z::any("name"), z::any(name)) 02603 .arg(z::any("val"), z::any(p)) 02604 .value(); 02605 02606 return ::qHash(s.get()); 02607 } 02608 02610 02615 inline z::stream& operator<<(z::stream& ss, const z::key& val) { 02616 val.get().write(ss); 02617 return ss; 02618 } 02619 02620 #if !defined(ZEN_NO_GUI) 02621 02622 02624 class property { 02625 public: 02630 inline property(QDeclarativeItem* val, const z::string& idx) : _val(val), _idx(idx) {} 02631 02632 public: 02636 inline QVariant getValue() const { 02637 QVariant v = ref(_val).property(_idx.get().toUtf8().constData()); 02638 if(!v.isValid()) { 02639 throw z::exception(z::string::creator("Unknown property: %{idx}").arg(z::any("idx"), z::any(_idx)).value()); 02640 } 02641 return v; 02642 } 02643 02644 private: 02649 inline property& setString(const QString& rhs) { 02650 ref(_val).setProperty(_idx.get().toUtf8().constData(), rhs); 02651 return ref(this); 02652 } 02653 02654 public: 02659 inline property& operator=(const z::string& rhs) { 02660 return setString(rhs.get()); 02661 } 02662 02667 inline property& operator=(const char* rhs) { 02668 return setString(QString(rhs)); 02669 } 02670 02675 inline property& operator=(const z::property& rhs) { 02676 const QVariant v = rhs.getValue(); 02677 if(v.type() == QVariant::String) { 02678 return setString(v.toString()); 02679 } 02680 return ref(this); 02681 } 02682 02683 private: 02688 inline property& appendString(const QString& rhs) { 02689 QString op = getValue().toString(); 02690 op += rhs; 02691 ref(_val).setProperty(_idx.get().toUtf8().constData(), op); 02692 return ref(this); 02693 } 02694 02695 public: 02700 inline property& operator+=(const z::string& rhs) { 02701 return appendString(rhs.get()); 02702 } 02703 02708 inline property& operator+=(const char* rhs) { 02709 return appendString(QString(rhs)); 02710 } 02711 02716 inline property& operator+=(const z::property& rhs) { 02717 const QVariant v = rhs.getValue(); 02718 if(v.type() == QVariant::String) { 02719 return appendString(v.toString()); 02720 } 02721 return ref(this); 02722 } 02723 02724 public: 02728 inline operator string() const { 02729 const QVariant v = getValue(); 02730 if(v.type() == QVariant::String) { 02731 return z::string(v.toString()); 02732 } 02733 02734 throw z::exception(z::string::creator("Unable to convert property to string: %{idx} type: %{type}").arg(z::any("idx"), z::any(_idx)).arg(z::any("type"), z::any(v.typeName())).value()); 02735 } 02736 02737 private: 02739 QDeclarativeItem* _val; 02740 02742 const z::string _idx; 02743 }; 02744 02747 02751 class widget { 02752 public: 02755 inline widget() : _val(0) {} 02756 02760 inline widget(QDeclarativeItem* val) : _val(val) {} 02761 02765 inline widget(const widget& src) : _val(src._val) {} 02766 02767 public: 02770 void show() const; 02771 02772 public: 02776 inline QDeclarativeItem& get() const {return ref(_val);} 02777 02778 public: 02783 inline property operator[](const z::string& idx) const { 02784 assert(_val); 02785 return property(_val, idx); 02786 } 02787 private: 02789 QDeclarativeItem* _val; 02790 }; 02791 02793 02797 class view { 02798 public: 02801 inline view() : _val(0) {} 02802 02806 inline view(const view& src) : _val(src._val) {} 02807 02810 inline ~view() {} 02811 02816 inline view& operator=(const view& src) {_val = src._val; return ref(this);} 02817 02818 public: 02822 inline view& clear() {delete _val; return ref(this);} 02823 02828 inline view& set(QDeclarativeView* val) {clear(); _val = val; return ref(this);} 02829 02833 inline QDeclarativeView& get() {return ref(_val);} 02834 02835 public: 02840 inline view& load(const z::string& filename) { 02841 set(new QDeclarativeView()); 02842 get().setSource(QUrl::fromLocalFile(filename.get())); 02843 return ref(this); 02844 } 02845 02851 inline view& setCallback(const z::string& name, QObject* obj) { 02852 ref(_val).rootContext()->setContextProperty(name.get(), obj); 02853 return ref(this); 02854 } 02855 02859 inline view& show() {ref(_val).show(); return ref(this);} 02860 02861 public: 02866 inline widget operator[](const z::string& idx) const { 02867 assert(_val); 02868 QGraphicsObject* rootObject = ref(_val).rootObject(); 02869 QDeclarativeItem* w = rootObject->findChild<QDeclarativeItem*>(idx.get()); 02870 return widget(w); 02871 } 02872 private: 02874 QDeclarativeView* _val; 02875 }; 02876 #endif 02877 } 02878 02880 02883 registerMetatype(z::key); 02884 02886 02889 registerMetatype(z::qid); 02890 02892 02895 registerMetatype(z::tree); 02896 02899 inline z::any z::getVar(const QVariant& v) { 02900 switch(v.type()) { 02901 case QVariant::Invalid: 02902 return z::any(); 02903 case QVariant::Int: 02904 return z::any(v.toInt()); 02905 case QVariant::LongLong: 02906 return z::any(v.toLongLong()); 02907 case QVariant::Double: 02908 return z::any(v.toDouble()); 02909 case QVariant::String: 02910 return z::any(z::string(v.toString())); 02911 default: 02912 break; 02913 } 02914 02915 throw z::exception(z::string::creator("Unhandled variant type: %{type}").arg(z::any("type"), z::any(v.typeName())).value()); 02916 } 02917 02919 02924 inline QDebug operator<<(QDebug db, const z::any& val) { 02925 z::string s; 02926 z::stringstream ss(s); 02927 ss << val; 02928 db << s; 02929 return db; 02930 } 02931 02933 // this string method needs to be defined here because it uses any. 02935 inline z::string::creator& z::string::creator::arg(const z::any& key, const z::any& val) { 02936 QString keyx = QString("%{%1}").arg(key.get<z::string>().get()); 02937 z::string s; 02938 z::stringstream ss(s); 02939 ss << val; 02940 // QString valx = val.getVar().toString(); 02941 // _val.replace(keyx, valx); 02942 // qDebug() << "***: keyx =" << keyx << ", _val=" << _val << ", val=" << ss.getString(); 02943 _val.replace(keyx, ss.getString()); 02944 02945 return ref(this); 02946 } 02947 02950 02958 template <typename ToT, typename FromT> 02959 inline ToT* dcast(FromT* from, const z::string& msg) { 02960 assert(from); 02961 ToT* to = dynamic_cast<ToT*>(from); 02962 if(0 == to) { 02963 throw z::exception(z::string::creator("Error: %{msg}").arg(z::any("msg"), z::any(msg)).value()); 02964 } 02965 return to; 02966 } 02967 02969 02974 template <typename ToT, typename FromT> 02975 inline ToT& dcast(FromT& from, const z::string& msg) { 02976 FromT* fromp = ptr(from); 02977 ToT* to = dcast<ToT, FromT>(fromp, msg); 02978 assert(to); 02979 return ref(to); 02980 }