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