ptypes.h (47627B)
1 /* 2 * 3 * C++ Portable Types Library (PTypes) 4 * Version 2.1.1 Released 27-Jun-2007 5 * 6 * Copyright (C) 2001-2007 Hovik Melikyan 7 * 8 * http://www.melikyan.com/ptypes/ 9 * 10 */ 11 12 #ifndef __PTYPES_H__ 13 #define __PTYPES_H__ 14 15 16 #ifndef __PPORT_H__ 17 #include "pport.h" 18 #endif 19 20 #include <string.h> 21 22 23 namespace ptypes { 24 25 26 #ifdef _MSC_VER 27 #pragma pack(push, 4) 28 // disable "non dll-interface class '...' used as base for dll-interface class '...'" warning 29 #pragma warning(disable : 4275) 30 // disable "conditional expression constant" warning 31 #pragma warning(push) 32 #pragma warning(disable : 4127) 33 #endif 34 35 36 ptpublic int __PFASTCALL pincrement(int* target); 37 ptpublic int __PFASTCALL pdecrement(int* target); 38 ptpublic int __PFASTCALL pexchange(int* target, int value); 39 ptpublic void* __PFASTCALL pexchange(void** target, void* value); 40 41 template <class T> inline T* tpexchange(T** target, T* value) 42 { return (T*)pexchange((void**)target, (void*)value); } 43 44 45 #if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ == 4) || defined(__hpux) 46 # define VARIANT_TYPECAST_HACK 47 #endif 48 49 50 // -------------------------------------------------------------------- // 51 // --- string class --------------------------------------------------- // 52 // -------------------------------------------------------------------- // 53 54 // dynamic string class with thread-safe ref-counted buffer 55 56 struct _strrec 57 { 58 int refcount; 59 int length; 60 #ifdef __EMSCRIPTEN__ 61 int _padding0; 62 int _padding1; 63 #endif 64 }; 65 typedef _strrec* _pstrrec; 66 67 68 #define STR_BASE(x) (_pstrrec(x)-1) 69 #define STR_REFCOUNT(x) (STR_BASE(x)->refcount) 70 #define STR_LENGTH(x) (STR_BASE(x)->length) 71 72 #define PTR_TO_PSTRING(p) (pstring(&(p))) 73 #define PTR_TO_STRING(p) (*PTR_TO_PSTRING(p)) 74 75 76 ptpublic extern char* emptystr; 77 78 class ptpublic variant; 79 80 81 class ptpublic string 82 { 83 friend class variant; 84 85 protected: 86 char* data; 87 88 static void idxerror(); 89 90 void _alloc(int); 91 void _realloc(int); 92 void _free(); 93 94 void initialize() { data = emptystr; } 95 void initialize(const char*, int); 96 void initialize(const char*); 97 void initialize(char); 98 void initialize(const string& s); 99 void initialize(const char*, int, const char*, int); 100 void initialize(const variant&); 101 void finalize(); 102 103 void assign(const char*, int); 104 void assign(const char*); 105 void assign(const string&); 106 void assign(char); 107 108 #ifdef CHECK_BOUNDS 109 void idx(int index) const { if (unsigned(index) >= unsigned(STR_LENGTH(data))) idxerror(); } 110 #else 111 void idx(int) const { } 112 #endif 113 114 string(const char* s1, int len1, const char* s2, int len2) { initialize(s1, len1, s2, len2); } 115 116 public: 117 friend int length(const string& s); 118 friend int refcount(const string& s); 119 friend void assign(string& s, const char* buf, int len); 120 friend void clear(string& s); 121 friend bool isempty(const string& s); 122 ptpublic friend char* ptdecl setlength(string&, int); 123 ptpublic friend char* ptdecl unique(string&); 124 ptpublic friend void ptdecl concat(string& s, const char* sc, int catlen); 125 ptpublic friend void ptdecl concat(string& s, const char* s1); 126 ptpublic friend void ptdecl concat(string& s, char s1); 127 ptpublic friend void ptdecl concat(string& s, const string& s1); 128 ptpublic friend string ptdecl copy(const string& s, int from, int cnt); 129 ptpublic friend string ptdecl copy(const string& s, int from); 130 ptpublic friend void ptdecl ins(const char* s1, int s1len, string& s, int at); 131 ptpublic friend void ptdecl ins(const char* s1, string& s, int at); 132 ptpublic friend void ptdecl ins(char s1, string& s, int at); 133 ptpublic friend void ptdecl ins(const string& s1, string& s, int at); 134 ptpublic friend void ptdecl del(string& s, int at, int cnt); 135 ptpublic friend void ptdecl del(string& s, int at); 136 ptpublic friend int ptdecl pos(const char* s1, const string& s); 137 ptpublic friend int ptdecl pos(char s1, const string& s); 138 friend int pos(const string& s1, const string& s); 139 ptpublic friend int ptdecl rpos(char s1, const string& s); 140 ptpublic friend bool ptdecl contains(const char* s1, int len, const string& s, int at); 141 ptpublic friend bool ptdecl contains(const char* s1, const string& s, int at); 142 ptpublic friend bool ptdecl contains(char s1, const string& s, int at); 143 ptpublic friend bool ptdecl contains(const string& s1, const string& s, int at); 144 ptpublic friend string ptdecl dup(const string& s); 145 146 string() { initialize(); } 147 string(const char* sc, int initlen) { initialize(sc, initlen); } 148 string(const char* sc) { initialize(sc); } 149 string(char c) { initialize(c); } 150 string(const string& s) { initialize(s); } 151 ~string() { finalize(); } 152 153 #ifdef VARIANT_TYPECAST_HACK 154 string(const variant& v) { initialize(v); } 155 #endif 156 157 string& operator= (const char* sc) { assign(sc); return *this; } 158 string& operator= (char c) { assign(c); return *this; } 159 string& operator= (const string& s) { assign(s); return *this; } 160 string& operator+= (const char* sc) { concat(*this, sc); return *this; } 161 string& operator+= (char c) { concat(*this, c); return *this; } 162 string& operator+= (const string& s) { concat(*this, s); return *this; } 163 164 string operator+ (const char* sc) const; 165 string operator+ (char c) const; 166 string operator+ (const string& s) const; 167 168 ptpublic friend string ptdecl operator+ (const char* sc, const string& s); 169 ptpublic friend string ptdecl operator+ (char c, const string& s); 170 171 bool operator== (const char* sc) const { return strcmp(data, sc) == 0; } 172 bool operator== (char) const; 173 bool operator== (const string&) const; 174 bool operator!= (const char* sc) const { return !(*this == sc); } 175 bool operator!= (char c) const { return !(*this == c); } 176 bool operator!= (const string& s) const { return !(*this == s); } 177 178 friend bool operator== (const char*, const string&); 179 friend bool operator== (char, const string&); 180 friend bool operator!= (const char*, const string&); 181 friend bool operator!= (char, const string&); 182 183 operator const char*() const { return data; } 184 operator const uchar*() const { return (uchar*)data; } 185 186 char& operator[] (int i) { idx(i); return unique(*this)[i]; } 187 const char& operator[] (int i) const { idx(i); return data[i]; } 188 189 friend void initialize(string& s); 190 friend void initialize(string& s, const string& s1); 191 friend void initialize(string& s, const char* s1); 192 friend void finalize(string& s); 193 }; 194 195 196 typedef string* pstring; 197 198 inline int length(const string& s) { return STR_LENGTH(s.data); } 199 inline int refcount(const string& s) { return STR_REFCOUNT(s.data); } 200 inline void assign(string& s, const char* buf, int len) { s.assign(buf, len); } 201 inline void clear(string& s) { s.finalize(); } 202 inline bool isempty(const string& s) { return length(s) == 0; } 203 inline int pos(const string& s1, const string& s) { return pos(s1.data, s); } 204 inline bool operator== (const char* sc, const string& s){ return s == sc; } 205 inline bool operator== (char c, const string& s) { return s == c; } 206 inline bool operator!= (const char* sc, const string& s){ return s != sc; } 207 inline bool operator!= (char c, const string& s) { return s != c; } 208 inline void initialize(string& s) { s.initialize(); } 209 inline void initialize(string& s, const string& s1) { s.initialize(s1); } 210 inline void initialize(string& s, const char* s1) { s.initialize(s1); } 211 inline void finalize(string& s) { s.finalize(); } 212 213 214 ptpublic extern int stralloc; 215 216 ptpublic extern string nullstring; 217 218 219 // -------------------------------------------------------------------- // 220 // --- string utilities ----------------------------------------------- // 221 // -------------------------------------------------------------------- // 222 223 224 ptpublic string ptdecl fill(int width, char pad); 225 ptpublic string ptdecl pad(const string& s, int width, char c, bool left = true); 226 227 ptpublic string ptdecl itostring(large value, int base, int width = 0, char pad = 0); 228 ptpublic string ptdecl itostring(ularge value, int base, int width = 0, char pad = 0); 229 ptpublic string ptdecl itostring(int value, int base, int width = 0, char pad = 0); 230 ptpublic string ptdecl itostring(unsigned value, int base, int width = 0, char pad = 0); 231 ptpublic string ptdecl itostring(large v); 232 ptpublic string ptdecl itostring(ularge v); 233 ptpublic string ptdecl itostring(int v); 234 ptpublic string ptdecl itostring(unsigned v); 235 236 ptpublic large ptdecl stringtoi(const char*); 237 ptpublic large ptdecl stringtoie(const char*); 238 ptpublic ularge ptdecl stringtoue(const char*, int base); 239 240 ptpublic string ptdecl lowercase(const char* s); 241 ptpublic string ptdecl lowercase(const string& s); 242 243 char hex4(char c); 244 245 inline char locase(char c) 246 { if (c >= 'A' && c <= 'Z') return char(c + 32); return c; } 247 248 inline char upcase(char c) 249 { if (c >= 'a' && c <= 'z') return char(c - 32); return c; } 250 251 inline int hstrlen(const char* p) // some Unix systems do not accept NULL 252 { return p == nil ? 0 : (int)strlen(p); } 253 254 255 256 257 // -------------------------------------------------------------------- // 258 // --- character set -------------------------------------------------- // 259 // -------------------------------------------------------------------- // 260 261 262 const int _csetbits = 256; 263 const int _csetbytes = _csetbits / 8; 264 const int _csetwords = _csetbytes / sizeof(int); 265 const char _csetesc = '~'; 266 267 268 class ptpublic cset 269 { 270 protected: 271 char data[_csetbytes]; 272 273 void assign(const cset& s) { memcpy(data, s.data, _csetbytes); } 274 void assign(const char* setinit); 275 void clear() { memset(data, 0, _csetbytes); } 276 void fill() { memset(data, -1, _csetbytes); } 277 void include(char b) { data[uchar(b) / 8] |= uchar(1 << (uchar(b) % 8)); } 278 void include(char min, char max); 279 void exclude(char b) { data[uchar(b) / 8] &= uchar(~(1 << (uchar(b) % 8))); } 280 void unite(const cset& s); 281 void subtract(const cset& s); 282 void intersect(const cset& s); 283 void invert(); 284 bool contains(char b) const { return (data[uchar(b) / 8] & (1 << (uchar(b) % 8))) != 0; } 285 bool eq(const cset& s) const { return memcmp(data, s.data, _csetbytes) == 0; } 286 bool le(const cset& s) const; 287 288 public: 289 cset() { clear(); } 290 cset(const cset& s) { assign(s); } 291 cset(const char* setinit) { assign(setinit); } 292 293 cset& operator= (const cset& s) { assign(s); return *this; } 294 cset& operator+= (const cset& s) { unite(s); return *this; } 295 cset& operator+= (char b) { include(b); return *this; } 296 cset operator+ (const cset& s) const { cset t = *this; return t += s; } 297 cset operator+ (char b) const { cset t = *this; return t += b; } 298 cset& operator-= (const cset& s) { subtract(s); return *this; } 299 cset& operator-= (char b) { exclude(b); return *this; } 300 cset operator- (const cset& s) const { cset t = *this; return t -= s; } 301 cset operator- (char b) const { cset t = *this; return t -= b; } 302 cset& operator*= (const cset& s) { intersect(s); return *this; } 303 cset operator* (const cset& s) const { cset t = *this; return t *= s; } 304 cset operator! () const { cset t = *this; t.invert(); return t; } 305 bool operator== (const cset& s) const { return eq(s); } 306 bool operator!= (const cset& s) const { return !eq(s); } 307 bool operator<= (const cset& s) const { return le(s); } 308 bool operator>= (const cset& s) const { return s.le(*this); } 309 310 friend cset operator+ (char b, const cset& s); 311 friend bool operator& (char b, const cset& s); 312 friend void assign(cset& s, const char* setinit); 313 friend void clear(cset& s); 314 friend void fill(cset& s); 315 friend void include(cset& s, char b); 316 friend void include(cset& s, char min, char max); 317 friend void exclude(cset& s, char b); 318 319 ptpublic friend string ptdecl asstring(const cset& s); 320 }; 321 322 323 inline cset operator+ (char b, const cset& s) { return s + b; } 324 inline bool operator& (char b, const cset& s) { return s.contains(b); } 325 inline void assign(cset& s, const char* setinit) { s.assign(setinit); } 326 inline void clear(cset& s) { s.clear(); } 327 inline void fill(cset& s) { s.fill(); } 328 inline void include(cset& s, char b) { s.include(b); } 329 inline void include(cset& s, char min, char max) { s.include(min, max); } 330 inline void exclude(cset& s, char b) { s.exclude(b); } 331 332 333 // -------------------------------------------------------------------- // 334 // --- basic abstract classes ----------------------------------------- // 335 // -------------------------------------------------------------------- // 336 337 // basic class with virtual destructor; historically was used as a base 338 // for all list items. also helps to count the number of created and 339 // destroyed objects in a program (objalloc global) in DEBUG mode, to 340 // detect memory leaks. most classes in ptypes are derived from unknown. 341 342 ptpublic extern int objalloc; 343 344 class ptpublic unknown 345 { 346 private: 347 // make all classes non-copyable by default 348 unknown(const unknown&); 349 const unknown& operator= (const unknown&); 350 public: 351 #ifdef COUNT_OBJALLOC 352 unknown() { pincrement(&objalloc); } 353 virtual ~unknown() { pdecrement(&objalloc); } 354 #else 355 unknown() { } 356 virtual ~unknown() { } 357 #endif 358 }; 359 360 typedef unknown* punknown; 361 362 363 // provide non-copyable base for all classes that are 364 // not derived from 'unknown' 365 366 class ptpublic noncopyable 367 { 368 private: 369 noncopyable(const noncopyable&); 370 const noncopyable& operator= (const noncopyable&); 371 public: 372 noncopyable() {} 373 ~noncopyable() {} 374 }; 375 376 377 378 // -------------------------------------------------------------------- // 379 // --- exception ------------------------------------------------------ // 380 // -------------------------------------------------------------------- // 381 382 // the basic exception class. NOTE: the library always throws dynamically 383 // allocated exception objects. 384 385 class ptpublic exception: public unknown 386 { 387 protected: 388 string message; 389 public: 390 exception(const char* imsg); 391 exception(const string& imsg); 392 virtual ~exception(); 393 virtual const string& get_message() const { return message; } 394 }; 395 396 397 // conversion exception class for stringtoie() and stringtoue() 398 399 class ptpublic econv: public exception 400 { 401 public: 402 econv(const char* msg): exception(msg) {} 403 econv(const string& msg): exception(msg) {} 404 virtual ~econv(); 405 }; 406 407 408 // -------------------------------------------------------------------- // 409 // --- tpodlist ------------------------------------------------------- // 410 // -------------------------------------------------------------------- // 411 412 // _podlist implements dynamic array of small POD structures; it serves 413 // as a basis for all list types in the library. this class is undocumented. 414 // tpodlist template must be used instead. 415 416 class ptpublic _podlist: public noncopyable 417 { 418 protected: 419 void* list; // pointer to the array 420 int count; // number of items in the list 421 int capacity; // allocated for the list 422 int itemsize; // list item size 423 424 static void idxerror(); 425 426 _podlist& operator =(const _podlist& t); 427 428 void grow(); 429 void* doins(int index); 430 void doins(int index, const _podlist&); 431 void* doget(int index) const { return (char*)list + index * itemsize; } 432 void dodel(int index); 433 void dodel(int index, int count); 434 void dopop(); 435 436 #ifdef CHECK_BOUNDS 437 void idx(int index) const { if (unsigned(index) >= unsigned(count)) idxerror(); } 438 void idxa(int index) const { if (unsigned(index) > unsigned(count)) idxerror(); } 439 #else 440 void idx(int) const { } 441 void idxa(int) const { } 442 #endif 443 444 public: 445 _podlist(int itemsize); 446 ~_podlist(); 447 448 int get_count() const { return count; } 449 void set_count(int newcount, bool zero = false); 450 int get_capacity() const { return capacity; } 451 void set_capacity(int newcap); 452 void clear() { set_count(0); } 453 void pack() { set_capacity(count); } 454 void* ins(int index) { idxa(index); return doins(index); } 455 void ins(int index, const _podlist& t) { idxa(index); doins(index, t); } 456 void* add(); 457 void add(const _podlist& t); 458 void* operator [](int index) { idx(index); return doget(index); } 459 void* top() { return operator [](count - 1); } 460 void del(int index) { idx(index); dodel(index); } 461 void del(int index, int count) { idx(index); dodel(index, count); } 462 void pop() { idx(0); dopop(); } 463 }; 464 465 466 // tpodlist is a fully-inlined template based on _podlist 467 468 template <class X, bool initzero = false> class tpodlist: public _podlist 469 { 470 protected: 471 X& dozero(X& t) { if (initzero) memset(&t, 0, sizeof(X)); return t; } 472 X& doget(int index) const { return ((X*)list)[index]; } 473 X& doins(int index) { X& t = *(X*)_podlist::doins(index); return dozero(t); } 474 void doins(int index, const X& item) { *(X*)_podlist::doins(index) = item; } 475 476 public: 477 tpodlist(): _podlist(sizeof(X)) {} 478 tpodlist<X, initzero>& operator =(const tpodlist<X, initzero>& t) 479 { _podlist::operator =(t); return *this; } 480 481 void set_count(int newcount) { _podlist::set_count(newcount, initzero); } 482 X& ins(int index) { idxa(index); return doins(index); } 483 void ins(int index, const X& item) { idxa(index); doins(index, item); } 484 void ins(int index, const tpodlist<X, initzero>& t) 485 { _podlist::ins(index, t); } 486 X& add() { grow(); return dozero(doget(count++)); } 487 void add(const X& item) { grow(); doget(count++) = item; } 488 void add(const tpodlist<X, initzero>& t) 489 { _podlist::add(t); } 490 X& operator [](int index) { idx(index); return doget(index); } 491 const X& operator [](int index) const { idx(index); return doget(index); } 492 X& top() { idx(0); return doget(count - 1); } 493 }; 494 495 496 // -------------------------------------------------------------------- // 497 // --- tobjlist ------------------------------------------------------- // 498 // -------------------------------------------------------------------- // 499 500 // _objlist is a base for the tobjlist template, don't use it directly. 501 // also, _objlist is a base for _strlist and derivatives. 502 503 class ptpublic _objlist: public unknown, protected tpodlist<void*, true> 504 { 505 protected: 506 struct 507 { 508 unsigned ownobjects :1; // list is responsible for destroying the items; used in _objlist 509 unsigned ownslobjects :1; // same but for _strlist items (in _stritem structure) 510 unsigned sorted :1; // sorted list (_objlist+) 511 unsigned duplicates :1; // sorted: allows duplicate keys (_objlist+) 512 unsigned casesens :1; // sorted: string comparison is case sensitive (_strlist+) 513 unsigned _reserved :27; 514 } config; 515 516 _objlist(bool ownobjects); // we hide this ctor, since _objlist actually can't free objects 517 518 void* doget(int index) const { return ((void**)list)[index]; } 519 void doput(int index, void* obj); 520 void dodel(int index); 521 void dodel(int index, int count); 522 void* dopop(); 523 void dofree(int index, int count); 524 525 virtual void dofree(void* obj); // pure method; defined in tobjlist instances 526 virtual int compare(const void* key, const void* obj) const; // pure method; defined in _strlist 527 528 public: 529 _objlist(); 530 virtual ~_objlist(); 531 532 int get_count() const { return count; } 533 void set_count(int newcount); 534 int get_capacity() const { return capacity; } 535 void set_capacity(int newcap) { tpodlist<void*,true>::set_capacity(newcap); } 536 void clear() { set_count(0); } 537 void pack() { tpodlist<void*,true>::pack(); } 538 void ins(int index, void* obj) { tpodlist<void*,true>::ins(index, obj); } 539 void add(void* obj) { tpodlist<void*,true>::add(obj); } 540 void put(int index, void* obj) { idx(index); doput(index, obj); } 541 void* operator [](int index) const { idx(index); return doget(index); } 542 void* top() const { idx(0); return doget(count - 1); } 543 void* pop() { idx(0); return dopop(); } 544 void del(int index) { idx(index); dodel(index); } 545 void del(int index, int count) { idx(index); dodel(index, count); } 546 int indexof(void* obj) const; 547 bool search(const void* key, int& index) const; 548 }; 549 550 551 // the tobjlist template implements a list of pointers to arbitrary 552 // structures. optionally can automatically free objects (ownobjects) 553 // when removed from a list. only 2 virtual functions are being 554 // instantiated by this template, the rest is static code in _objlist. 555 556 template <class X> class tobjlist: public _objlist 557 { 558 protected: 559 X* doget(int index) const { return (X*)_objlist::doget(index); } 560 virtual void dofree(void* obj); 561 562 public: 563 tobjlist(bool ownobjects = false): _objlist(ownobjects) {} 564 virtual ~tobjlist(); 565 566 bool get_ownobjects() const { return config.ownobjects; } 567 void set_ownobjects(bool newval) { config.ownobjects = newval; } 568 void ins(int index, X* obj) { _objlist::ins(index, obj); } 569 void add(X* obj) { _objlist::add(obj); } 570 void put(int index, X* obj) { _objlist::put(index, obj); } 571 X* operator [](int index) const { idx(index); return (X*)doget(index); } 572 X* top() const { return (X*)_objlist::top(); } 573 X* pop() { return (X*)_objlist::pop(); } 574 int indexof(X* obj) const { return _objlist::indexof(obj); } 575 576 #ifdef PTYPES19_COMPAT 577 friend inline void ins(tobjlist& s, int i, X* obj) { s.ins(i, obj); } 578 friend inline int add(tobjlist& s, X* obj) { s.add(obj); return s.get_count() - 1; } 579 friend inline void put(tobjlist& s, int i, X* obj) { s.put(i, obj); } 580 friend inline int indexof(const tobjlist& s, X* obj) { return s.indexof(obj); } 581 friend inline int push(tobjlist& s, X* obj) { s.add(obj); return s.get_count() - 1; } 582 friend inline X* pop(tobjlist& s) { return (X*)s.pop(); } 583 friend inline X* top(const tobjlist& s) { return (X*)s.top(); } 584 friend inline X* get(const tobjlist& s, int i) { return (X*)s[i]; } 585 #endif 586 }; 587 588 589 template <class X> void tobjlist<X>::dofree(void* item) 590 { 591 delete (X*)item; 592 } 593 594 595 template <class X> tobjlist<X>::~tobjlist() 596 { 597 set_count(0); 598 } 599 600 601 // -------------------------------------------------------------------- // 602 // --- tstrlist ------------------------------------------------------- // 603 // -------------------------------------------------------------------- // 604 605 // _strlist is a base for the tstrlist template 606 607 608 typedef int slflags; // left for compatibility 609 610 #define SL_SORTED 1 611 #define SL_DUPLICATES 2 612 #define SL_CASESENS 4 613 #define SL_OWNOBJECTS 8 614 615 616 struct _stritem 617 { 618 string key; 619 void* obj; 620 621 _stritem(const string& ikey, void* iobj) 622 : key(ikey), obj(iobj) {} 623 }; 624 625 626 class ptpublic _strlist: protected tobjlist<_stritem> 627 { 628 protected: 629 static void sortederror(); 630 static void notsortederror(); 631 static void duperror(); 632 633 virtual void dofree(void* item); 634 virtual int compare(const void* key, const void* item) const; 635 virtual void dofreeobj(void* obj); // pure; tstrlist overrides it 636 637 const string& dogetkey(int index) const { return doget(index)->key; } 638 void* dogetobj(int index) const { return doget(index)->obj; } 639 void doins(int index, const string& key, void* obj); 640 void doput(int index, const string& key, void* obj); 641 void doput(int index, void* obj); 642 643 public: 644 _strlist(int flags = 0); 645 virtual ~_strlist(); 646 647 int get_count() const { return count; } 648 void set_count(int newcount) { tobjlist<_stritem>::set_count(newcount); } 649 int get_capacity() const { return capacity; } 650 void set_capacity(int newcap) { tobjlist<_stritem>::set_capacity(newcap); } 651 void clear() { tobjlist<_stritem>::clear(); } 652 void pack() { tobjlist<_stritem>::pack(); } 653 bool get_sorted() const { return config.sorted; } 654 bool get_duplicates() const { return config.duplicates; } 655 bool get_casesens() const { return config.casesens; } 656 bool get_ownobjects() const { return config.ownslobjects; } 657 void set_ownobjects(bool newval) { config.ownslobjects = newval; } 658 void ins(int index, const string& key, void* obj) { idxa(index); doins(index, key, obj); } 659 void put(int index, const string& key, void* obj) { idx(index); doput(index, key, obj); } 660 void put(int index, void* obj) { idx(index); doput(index, obj); } 661 int put(const string& key, void* obj); 662 int add(const string& key, void* obj); 663 void* operator [](int index) const { idx(index); return dogetobj(index); } 664 void* operator [](const char* key) const; 665 const string& getkey(int index) const { idx(index); return dogetkey(index); } 666 bool search(const char* key, int& index) const { return _objlist::search(key, index); } 667 void del(int index) { idx(index); dodel(index); } 668 void del(int index, int delcount) { idx(index); dodel(index, delcount); } 669 void del(const char* key) { put(key, nil); } 670 int indexof(const char* key) const; 671 int indexof(void* obj) const; 672 }; 673 674 675 // the tstrlist template implements a list of string/object pairs, 676 // optionally sorted for fast searching by string key. 677 678 template <class X> class tstrlist: public _strlist 679 { 680 protected: 681 virtual void dofreeobj(void* obj); 682 683 public: 684 tstrlist(int flags = 0): _strlist(flags) {} 685 virtual ~tstrlist(); 686 687 void ins(int index, const string& key, X* obj) { _strlist::ins(index, key, obj); } 688 void put(int index, const string& key, X* obj) { _strlist::put(index, key, obj); } 689 void put(int index, X* obj) { _strlist::put(index, obj); } 690 int put(const string& key, X* obj) { return _strlist::put(key, obj); } 691 int add(const string& key, X* obj) { return _strlist::add(key, obj); } 692 X* operator [](int index) const { return (X*)_strlist::operator [](index); } 693 X* operator [](const char* key) const { return (X*)_strlist::operator [](key); } 694 int indexof(X* obj) const { return _strlist::indexof(obj); } 695 int indexof(const char* key) const { return _strlist::indexof(key); } 696 697 #ifdef PTYPES19_COMPAT 698 // pre-2.0 interface for backwards compatibility 699 friend inline void ins(tstrlist& s, int i, const string& str, X* obj) { s.ins(i, str, obj); } 700 friend inline int add(tstrlist& s, const string& str, X* obj) { return s.add(str, obj); } 701 friend inline void put(tstrlist& s, int i, const string& str, X* obj) { s.put(i, str, obj); } 702 friend inline void put(tstrlist& s, int i, X* obj) { s.put(i, obj); } 703 friend inline int indexof(const tstrlist& s, X* obj) { return s.indexof(obj); } 704 friend inline X* get(const tstrlist& s, int i) { return (X*)s[i]; } 705 #endif 706 }; 707 708 709 template <class X> void tstrlist<X>::dofreeobj(void* obj) 710 { 711 delete (X*)obj; 712 } 713 714 715 template <class X> tstrlist<X>::~tstrlist() 716 { 717 set_count(0); 718 } 719 720 721 // -------------------------------------------------------------------- // 722 // --- textmap -------------------------------------------------------- // 723 // -------------------------------------------------------------------- // 724 725 // textmap is a list of string pairs (key/value) 726 727 struct _textitem 728 { 729 string key; 730 string value; 731 732 _textitem(const string& ikey, const string& ivalue) 733 : key(ikey), value(ivalue) {} 734 }; 735 736 737 class ptpublic textmap: protected tobjlist<_textitem> 738 { 739 protected: 740 virtual int compare(const void* key, const void* item) const; 741 const string& dogetvalue(int index) const { return doget(index)->value; } 742 const string& dogetkey(int index) const { return doget(index)->key; } 743 744 public: 745 textmap(bool casesens = false); 746 virtual ~textmap(); 747 748 int get_count() const { return tobjlist<_textitem>::get_count(); } 749 void pack() { tobjlist<_textitem>::pack(); } 750 void clear() { tobjlist<_textitem>::clear(); } 751 int put(const string& key, const string& value); 752 void del(int index) { idx(index); dodel(index); } 753 void del(const char* key) { put(key, nullstring); } 754 const string& get(int index) const { idx(index); return dogetvalue(index); } 755 const string& getkey(int index) const { idx(index); return dogetkey(index); } 756 const string& get(const char* key) const; 757 const string& operator [](int index) const { return get(index); } 758 const string& operator [](const char* key) const { return get(key); } 759 int indexof(const char* key) const; 760 }; 761 762 763 // -------------------------------------------------------------------- // 764 // --- component ------------------------------------------------------ // 765 // -------------------------------------------------------------------- // 766 767 // the component class is an abstract class that provides reference 768 // counting and delete notification mechanisms. all stream classes 769 // in ptypes are derived from component. 770 771 // class ID's for all basic types: the first byte (least significant) 772 // contains the base ID, the next is for the second level of inheritance, 773 // etc. total of 4 levels allowed for basic types. call classid() for an 774 // object, mask out first N bytes of interest and compare with a CLASS_XXX 775 // value. f.ex. to determine whether an object is of type infile or any 776 // derivative: (o->classid() & 0xffff) == CLASS2_INFILE. this scheme is for 777 // internal use by PTypes and Objection; partly replaces the costly C++ RTTI 778 // system. 779 780 // first level of inheritance 781 const int CLASS_UNDEFINED = 0x00000000; 782 const int CLASS_INSTM = 0x00000001; 783 const int CLASS_OUTSTM = 0x00000002; 784 const int CLASS_UNIT = 0x00000003; 785 786 // second level of inheritance 787 const int CLASS2_INFILE = 0x00000100 | CLASS_INSTM; 788 const int CLASS2_INMEMORY = 0x00000200 | CLASS_INSTM; 789 const int CLASS2_FDX = 0x00000300 | CLASS_INSTM; 790 const int CLASS2_OUTFILE = 0x00000100 | CLASS_OUTSTM; 791 const int CLASS2_OUTMEMORY = 0x00000200 | CLASS_OUTSTM; 792 793 // third level of inheritance 794 const int CLASS3_LOGFILE = 0x00010000 | CLASS2_OUTFILE; 795 const int CLASS3_IPSTM = 0x00020000 | CLASS2_FDX; 796 const int CLASS3_NPIPE = 0x00030000 | CLASS2_FDX; 797 798 799 class ptpublic component: public unknown 800 { 801 protected: 802 int refcount; // reference counting, used by addref() and release() 803 tobjlist<component>* freelist; // list of components to notify about destruction, safer alternative to ref-counting 804 void* typeinfo; // reserved for future use 805 806 virtual void freenotify(component* sender); 807 808 public: 809 component(); 810 virtual ~component(); 811 void addnotification(component* obj); 812 void delnotification(component* obj); 813 814 ptpublic friend component* ptdecl addref(component*); 815 ptpublic friend bool ptdecl release(component*); 816 friend int refcount(component* c); 817 818 virtual int classid(); 819 820 void set_typeinfo(void* t) { typeinfo = t; } 821 void* get_typeinfo() { return typeinfo; } 822 }; 823 824 typedef component* pcomponent; 825 826 827 inline int refcount(component* c) { return c->refcount; } 828 829 component* ptdecl addref(component* c ); 830 831 template <class T> inline T* taddref(T* c) 832 { return (T*)addref((component*)c); } 833 834 835 template <class T> class compref 836 { 837 protected: 838 T* ref; 839 public: 840 compref() { ref = 0; } 841 compref(const compref<T>& r) { ref = taddref<T>(r.ref); } 842 compref(T* c) { ref = taddref<T>(c); } 843 ~compref() { release(ref); } 844 compref<T>& operator =(T* c); 845 compref<T>& operator =(const compref<T>& r) { return operator =(r.ref); } 846 T& operator *() const { return *ref; } 847 T* operator ->() const { return ref; } 848 bool operator ==(const compref<T>& r) const { return ref == r.ref; } 849 bool operator ==(T* c) const { return ref == c; } 850 bool operator !=(const compref<T>& r) const { return ref != r.ref; } 851 bool operator !=(T* c) const { return ref != c; } 852 operator T*() const { return ref; } 853 }; 854 855 856 template <class T> compref<T>& compref<T>::operator =(T* c) 857 { 858 release(tpexchange<T>(&ref, taddref<T>(c))); 859 return *this; 860 } 861 862 863 // -------------------------------------------------------------------- // 864 // --- variant -------------------------------------------------------- // 865 // -------------------------------------------------------------------- // 866 867 868 enum { 869 VAR_NULL, 870 VAR_INT, 871 VAR_BOOL, 872 VAR_FLOAT, 873 VAR_STRING, 874 VAR_ARRAY, 875 VAR_OBJECT, 876 877 VAR_COMPOUND = VAR_STRING 878 }; 879 880 881 class ptpublic _varray; 882 883 884 class ptpublic variant 885 { 886 friend class string; 887 friend class _varray; 888 889 protected: 890 int tag; // VAR_XXX 891 union { 892 large i; // 64-bit int value 893 bool b; // bool value 894 double f; // double value 895 char* s; // string object; can't declare as string because of the union 896 _varray* a; // pointer to a reference-counted _strlist object 897 component* o; // pointer to a reference-counted component object (or derivative) 898 } value; // we need this name to be able to copy the entire union in some situations 899 900 void initialize() { tag = VAR_NULL; } 901 void initialize(large v) { tag = VAR_INT; value.i = v; } 902 void initialize(bool v) { tag = VAR_BOOL; value.b = v; } 903 void initialize(double v) { tag = VAR_FLOAT; value.f = v; } 904 void initialize(const char* v) { tag = VAR_STRING; ptypes::initialize(PTR_TO_STRING(value.s), v); } 905 void initialize(const string& v) { tag = VAR_STRING; ptypes::initialize(PTR_TO_STRING(value.s), v); } 906 void initialize(_varray* a); 907 void initialize(component* o); 908 void initialize(const variant& v); 909 void finalize(); 910 911 void assign(large); 912 void assign(bool); 913 void assign(double); 914 void assign(const char*); 915 void assign(const string&); 916 void assign(_varray*); 917 void assign(component*); 918 void assign(const variant&); 919 920 bool equal(const variant& v) const; 921 922 variant(_varray* a) { initialize(a); } 923 924 public: 925 // construction 926 variant() { initialize(); } 927 variant(int v) { initialize(large(v)); } 928 variant(unsigned int v) { initialize(large(v)); } 929 variant(large v) { initialize(v); } 930 variant(bool v) { initialize(v); } 931 variant(double v) { initialize(v); } 932 variant(const char* v) { initialize(v); } 933 variant(const string& v) { initialize(v); } 934 variant(component* v) { initialize(v); } 935 variant(const variant& v) { initialize(v); } 936 ~variant() { finalize(); } 937 938 // assignment 939 variant& operator= (int v) { assign(large(v)); return *this; } 940 variant& operator= (unsigned int v) { assign(large(v)); return *this; } 941 variant& operator= (large v) { assign(v); return *this; } 942 variant& operator= (bool v) { assign(v); return *this; } 943 variant& operator= (double v) { assign(v); return *this; } 944 variant& operator= (const char* v) { assign(v); return *this; } 945 variant& operator= (const string& v) { assign(v); return *this; } 946 variant& operator= (component* v) { assign(v); return *this; } 947 variant& operator= (const variant& v) { assign(v); return *this; } 948 949 // typecast 950 operator int() const; 951 operator unsigned int() const; 952 operator long() const; 953 operator unsigned long() const; 954 operator large() const; 955 operator bool() const; 956 operator double() const; 957 operator string() const; 958 operator component*() const; 959 960 // comparison 961 bool operator== (const variant& v) const { return equal(v); } 962 bool operator!= (const variant& v) const { return !equal(v); } 963 964 // typification 965 ptpublic friend void ptdecl clear(variant&); 966 friend int vartype(const variant& v); 967 friend bool isnull(const variant& v); 968 friend bool isint(const variant& v); 969 friend bool isbool(const variant& v); 970 friend bool isfloat(const variant& v); 971 friend bool isstring(const variant& v); 972 friend bool isarray(const variant& v); 973 friend bool isobject(const variant& v); 974 friend bool iscompound(const variant& v); 975 976 // array manipulation 977 ptpublic friend void ptdecl aclear(variant&); 978 ptpublic friend variant ptdecl aclone(const variant&); 979 ptpublic friend const variant& ptdecl get(const variant&, const string& key); 980 ptpublic friend const variant& ptdecl get(const variant&, large key); 981 ptpublic friend void ptdecl put(variant&, const string& key, const variant& item); 982 ptpublic friend void ptdecl put(variant&, large key, const variant& item); 983 ptpublic friend void ptdecl del(variant&, const string& key); 984 ptpublic friend void ptdecl del(variant&, large key); 985 986 // indexed access to arrays 987 ptpublic friend int ptdecl alength(const variant&); 988 ptpublic friend void ptdecl apack(variant&); 989 ptpublic friend bool ptdecl anext(const variant& a, int&, variant& item); 990 ptpublic friend bool ptdecl anext(const variant& a, int&, variant& item, string& key); 991 ptpublic friend int ptdecl aadd(variant&, const variant& item); 992 ptpublic friend void ptdecl aput(variant&, int index, const variant& item); 993 ptpublic friend void ptdecl ains(variant&, int index, const variant& item); 994 ptpublic friend void ptdecl adel(variant&, int index); 995 ptpublic friend const variant& ptdecl aget(const variant&, int index); 996 ptpublic friend string ptdecl akey(const variant&, int index); 997 998 const variant& operator[](const char* key) const { return get(*this, string(key)); } 999 const variant& operator[](const string& key) const { return get(*this, key); } 1000 const variant& operator[](large key) const { return get(*this, key); } 1001 1002 // 'manual' initialization/finalization, undocumented. use with care! 1003 friend void initialize(variant& v); 1004 friend void initialize(variant& v, large i); 1005 friend void initialize(variant& v, int i); 1006 friend void initialize(variant& v, unsigned int i); 1007 friend void initialize(variant& v, bool i); 1008 friend void initialize(variant& v, double i); 1009 friend void initialize(variant& v, const char* i); 1010 friend void initialize(variant& v, const string& i); 1011 friend void initialize(variant& v, component* i); 1012 friend void initialize(variant& v, const variant& i); 1013 friend void finalize(variant& v); 1014 }; 1015 1016 1017 typedef variant* pvariant; 1018 1019 1020 inline int vartype(const variant& v) { return v.tag; } 1021 inline bool isnull(const variant& v) { return v.tag == VAR_NULL; } 1022 inline bool isint(const variant& v) { return v.tag == VAR_INT; } 1023 inline bool isbool(const variant& v) { return v.tag == VAR_BOOL; } 1024 inline bool isfloat(const variant& v) { return v.tag == VAR_FLOAT; } 1025 inline bool isstring(const variant& v) { return v.tag == VAR_STRING; } 1026 inline bool isarray(const variant& v) { return v.tag == VAR_ARRAY; } 1027 inline bool isobject(const variant& v) { return v.tag == VAR_OBJECT; } 1028 inline bool iscompound(const variant& v) { return v.tag >= VAR_COMPOUND; } 1029 1030 inline void initialize(variant& v) { v.initialize(); } 1031 inline void initialize(variant& v, large i) { v.initialize(i); } 1032 inline void initialize(variant& v, int i) { v.initialize(large(i)); } 1033 inline void initialize(variant& v, unsigned int i) { v.initialize(large(i)); } 1034 inline void initialize(variant& v, bool i) { v.initialize(i); } 1035 inline void initialize(variant& v, double i) { v.initialize(i); } 1036 inline void initialize(variant& v, const char* i) { v.initialize(i); } 1037 inline void initialize(variant& v, const string& i) { v.initialize(i); } 1038 inline void initialize(variant& v, component* i) { v.initialize(i); } 1039 inline void initialize(variant& v, const variant& i) { v.initialize(i); } 1040 inline void finalize(variant& v) { if (v.tag >= VAR_COMPOUND) v.finalize(); } 1041 1042 1043 ptpublic extern const variant nullvar; 1044 1045 1046 // variant exception class; may be thrown when a variant 1047 // is being typecast'ed to 32-bit int and the value is 1048 // out of range 1049 1050 class ptpublic evariant: public exception 1051 { 1052 protected: 1053 public: 1054 evariant(const char* msg): exception(msg) {} 1055 evariant(const string& msg): exception(msg) {} 1056 virtual ~evariant(); 1057 }; 1058 1059 1060 1061 // -------------------------------------------------------------------- // 1062 // --- pre-2.0 compatibility declarations ----------------------------- // 1063 // -------------------------------------------------------------------- // 1064 1065 1066 #ifdef PTYPES19_COMPAT 1067 1068 // ptypes-1.9 objlist and strlist: accept only 'unknown' and 1069 // derivatives as a base type 1070 1071 class ptpublic objlist: public tobjlist<unknown> 1072 { 1073 public: 1074 objlist(bool ownobjects = false); 1075 virtual ~objlist(); 1076 }; 1077 1078 inline int length(const _objlist& s) { return s.get_count(); } 1079 inline void setlength(_objlist& s, int newcount) { s.set_count(newcount); } 1080 inline void pack(_objlist& s) { s.pack(); } 1081 inline void clear(_objlist& s) { s.clear(); } 1082 inline int push(_objlist& s, unknown* obj) { s.add(obj); return length(s) - 1; } 1083 inline unknown* top(const _objlist& s) { return (unknown*)s.top(); } 1084 inline void ins(_objlist& s, int i, unknown* obj) { s.ins(i, obj); } 1085 inline int add(_objlist& s, unknown* obj) { s.add(obj); return length(s) - 1; } 1086 inline void put(_objlist& s, int i, unknown* obj) { s.put(i, obj); } 1087 inline unknown* get(const _objlist& s, int i) { return (unknown*)s[i]; } 1088 inline unknown* pop(_objlist& s) { return (unknown*)s.pop(); } 1089 inline void del(_objlist& s, int i) { s.del(i); } 1090 inline int indexof(const _objlist& s, unknown* obj) { return s.indexof(obj); } 1091 1092 1093 class ptpublic strlist: public tstrlist<unknown> 1094 { 1095 public: 1096 strlist(int flags = 0); 1097 virtual ~strlist(); 1098 }; 1099 1100 inline int length(const _strlist& s) { return s.get_count(); } 1101 inline void clear(_strlist& s) { s.clear(); } 1102 inline void pack(_strlist& s) { s.pack(); } 1103 inline bool search(const _strlist& s, const char* key, int& i) { return s.search(key, i); } 1104 inline void ins(_strlist& s, int i, const string& key, unknown* obj) { s.ins(i, key, obj); } 1105 inline int add(_strlist& s, const string& key, unknown* obj) { return s.add(key, obj); } 1106 inline void put(_strlist& s, int i, const string& key, unknown* obj) { s.put(i, key, obj); } 1107 inline void put(_strlist& s, int i, unknown* obj) { s.put(i, obj); } 1108 inline unknown* get(const _strlist& s, int i) { return (unknown*)s[i]; } 1109 inline const string& getstr(const _strlist& s, int i) { return s.getkey(i); } 1110 inline void del(_strlist& s, int i) { s.del(i); } 1111 inline int find(const _strlist& s, const char* key) { return s.indexof(key); } 1112 inline int indexof(const _strlist& s, unknown* obj) { return s.indexof(obj); } 1113 1114 1115 // ptypes-1.9 strmap: now replaced with _strlist(SL_SORTED) 1116 1117 class ptpublic strmap: public tstrlist<unknown> 1118 { 1119 public: 1120 strmap(int flags = 0); 1121 virtual ~strmap(); 1122 }; 1123 1124 inline void put(strmap& m, const string& key, unknown* obj) { m.put(key, obj); } 1125 inline unknown* get(const strmap& m, const char* key) { return m[key]; } 1126 inline void del(strmap& m, const char* key) { m.del(key); } 1127 1128 template <class X> class tstrmap: public strmap 1129 { 1130 public: 1131 tstrmap(): strmap() {} 1132 tstrmap(int iflags): strmap(iflags) {} 1133 friend inline X* get(const tstrmap& m, const char* str) { return (X*)ptypes::get((const strmap&)m, str); } 1134 friend inline void put(tstrmap& m, const string& str, X* obj) { unknown* t = obj; ptypes::put(m, str, t); } 1135 X* operator[] (const char* str) const { return (X*)ptypes::get(*this, str); } 1136 }; 1137 1138 1139 // ptypes-1.9 textmap interface 1140 1141 inline int length(const textmap& m) { return m.get_count(); } 1142 inline void clear(textmap& m) { m.clear(); } 1143 inline const string& get(const textmap& m, const string& k) { return m.get(k); } 1144 inline void put(textmap& m, const string& k, const string& v) { m.put(k, v); } 1145 inline void del(textmap& m, const string& k) { m.del(k); } 1146 1147 1148 #endif // PTYPES19_COMPAT 1149 1150 1151 #ifdef _MSC_VER 1152 #pragma warning(pop) 1153 #pragma pack(pop) 1154 #endif 1155 1156 1157 } 1158 1159 #endif // __PTYPES_H__