gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

ptypes.h (47627B)


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