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