ptypes

ptypes Mercurial Source Tree


Root/doc/include/ptypes.h.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<!--
Syntax highlighting generated by Web C Plus Plus software v0.8.4
Webcpp Copyright (C)2001-2004 Jeffrey Bakker under the GNU GPL
Get webcpp at http://webcpp.sf.net
-->

<html>
<head>
<title>ptypes.h</title>
<style type="text/css">

/*
Webcpp v0.8.1 compatible StyleSheet
http://webcpp.sf.net
Theme: ide-msvcpp
*/

body
{
background-color: #ffffff
}

.webcpp a:link    {color:#000000}
.webcpp a:visited {color:#008000}
.webcpp a:active  {color:#0000ff}
.webcpp a:hover   {color:#0000ff}

.webcpp pre
{
color: #000000
}

.webcpp font
{
font-size:100%
}

.webcpp .symbols
{
color: #000000
}

.webcpp .preproc
{
color: #0000ff
}

.webcpp .integer
{
color: #000000
}

.webcpp .floatpt
{
color: #000000
}

.webcpp .dblquot
{
color: #000000
}

.webcpp .sinquot
{
color: #000000
}

.webcpp .keyword
{
color: #0000ff;

}

.webcpp .keytype
{
color: #0000ff;

}

.webcpp .comment
{
color: #008000;

}

</style>
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40"> <p><a href="../htsrc.html">Index</a><hr noshade></p>

<div class="webcpp">
<pre>


<font CLASS=preproc>#ifndef</font> __PTYPES_H__ 
<font CLASS=preproc>#define</font> __PTYPES_H__ 


<font CLASS=preproc>#ifndef</font> __PPORT_H__ 
<font CLASS=preproc>#include</font> <font CLASS=dblquot>"pport.h"</font> 
<font CLASS=preproc>#endif</font> 

<font CLASS=preproc>#include</font> <string.h> 


PTYPES_BEGIN


<font CLASS=preproc>#ifdef</font> _MSC_VER 
<font CLASS=preproc>#pragma</font> pack(push, <font CLASS=integer>4</font>) 
<font CLASS=comment>// disable "non dll-interface class '...' used as base for dll-interface class '...'" warning</font>
<font CLASS=preproc>#pragma</font> warning(disable : <font CLASS=integer>4275</font>) 
<font CLASS=comment>// disable "conditional expression constant" warning</font>
<font CLASS=preproc>#pragma</font> warning(push) 
<font CLASS=preproc>#pragma</font> warning(disable : <font CLASS=integer>4127</font>) 
<font CLASS=preproc>#endif</font> 


<font CLASS=keytype>int</font>   __PFASTCALL pincrement(<font CLASS=keytype>int</font>* target);
<font CLASS=keytype>int</font>   __PFASTCALL pdecrement(<font CLASS=keytype>int</font>* target);
<font CLASS=keytype>int</font>   __PFASTCALL pexchange(<font CLASS=keytype>int</font>* target, <font CLASS=keytype>int</font> value);
<font CLASS=keytype>void</font>* __PFASTCALL pexchange(<font CLASS=keytype>void</font>** target, <font CLASS=keytype>void</font>* value);

<font CLASS=keyword>template</font> <<font CLASS=keyword>class</font> T> <font CLASS=keyword>inline</font> T* tpexchange(T** target, T* value)
    { <font CLASS=keyword>return</font> (T*)pexchange((<font CLASS=keytype>void</font>**)target, (<font CLASS=keytype>void</font>*)value); }


<font CLASS=preproc>#if</font> ((__GNUC__ <font CLASS=symbols>==</font> <font CLASS=integer>3</font>) && (__GNUC_MINOR__ ><font CLASS=symbols>=</font> <font CLASS=integer>3</font>)) || (__GNUC__ == <font CLASS=integer>4</font>) || defined(__hpux) 
<font CLASS=preproc>#</font>  define VARIANT_TYPECAST_HACK 
<font CLASS=preproc>#endif</font> 


<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- string class --------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>

<font CLASS=comment>// dynamic string class with thread-safe ref-counted buffer</font>

<font CLASS=keyword>struct</font> _strrec 
{
    <font CLASS=keytype>int</font> refcount;
    <font CLASS=keytype>int</font> length;
};
<font CLASS=keyword>typedef</font> _strrec* _pstrrec;


<font CLASS=preproc>#define</font> STR_BASE(x)      (_pstrrec(x)<font CLASS=symbols>-</font><font CLASS=integer>1</font>) 
<font CLASS=preproc>#define</font> STR_REFCOUNT(x)  (STR_BASE(x)<font CLASS=symbols>-</font>>refcount) 
<font CLASS=preproc>#define</font> STR_LENGTH(x)    (STR_BASE(x)<font CLASS=symbols>-</font>>length) 

<font CLASS=preproc>#define</font> PTR_TO_PSTRING(p)   (pstring(&(p))) 
<font CLASS=preproc>#define</font> PTR_TO_STRING(p)    (*PTR_TO_PSTRING(p)) 


<font CLASS=keyword>extern</font> <font CLASS=keytype>char</font>* emptystr;

<font CLASS=keyword>class</font> variant;


<font CLASS=keyword>class</font> string 
{
    <font CLASS=keyword>friend</font> <font CLASS=keyword>class</font> variant;

<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
    <font CLASS=keytype>char</font>* data;

    <font CLASS=keytype>static</font> <font CLASS=keytype>void</font> idxerror();

    <font CLASS=keytype>void</font> _alloc(<font CLASS=keytype>int</font>);
    <font CLASS=keytype>void</font> _realloc(<font CLASS=keytype>int</font>);
    <font CLASS=keytype>void</font> _free();

    <font CLASS=keytype>void</font> initialize()  { data <font CLASS=symbols>=</font> emptystr; }
    <font CLASS=keytype>void</font> initialize(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*, <font CLASS=keytype>int</font>);
    <font CLASS=keytype>void</font> initialize(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*);
    <font CLASS=keytype>void</font> initialize(<font CLASS=keytype>char</font>);
    <font CLASS=keytype>void</font> initialize(<font CLASS=keyword>const</font> string& s);
    <font CLASS=keytype>void</font> initialize(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*, <font CLASS=keytype>int</font>, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*, <font CLASS=keytype>int</font>);
    <font CLASS=keytype>void</font> initialize(<font CLASS=keyword>const</font> variant&);
    <font CLASS=keytype>void</font> finalize();

    <font CLASS=keytype>void</font> assign(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*, <font CLASS=keytype>int</font>);
    <font CLASS=keytype>void</font> assign(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*);
    <font CLASS=keytype>void</font> assign(<font CLASS=keyword>const</font> string&);
    <font CLASS=keytype>void</font> assign(<font CLASS=keytype>char</font>);

<font CLASS=preproc>#ifdef</font> CHECK_BOUNDS 
    <font CLASS=keytype>void</font> idx(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>  { <font CLASS=keyword>if</font> (<font CLASS=keytype>unsigned</font>(index) ><font CLASS=symbols>=</font> <font CLASS=keytype>unsigned</font>(STR_LENGTH(data))) idxerror(); }
<font CLASS=preproc>#else</font> 
    <font CLASS=keytype>void</font> idx(<font CLASS=keytype>int</font>) <font CLASS=keyword>const</font>        { }
<font CLASS=preproc>#endif</font> 

    string(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s1, <font CLASS=keytype>int</font> len1, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s2, <font CLASS=keytype>int</font> len2)  { initialize(s1, len1, s2, len2); }

<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    <font CLASS=keyword>friend</font> <font CLASS=keytype>int</font>    length(<font CLASS=keyword>const</font> string& s);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>int</font>    refcount(<font CLASS=keyword>const</font> string& s);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font>   assign(string& s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> len);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font>   clear(string& s);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font>   isempty(<font CLASS=keyword>const</font> string& s);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>char</font>*  setlength(string&, <font CLASS=keytype>int</font>);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>char</font>*  unique(string&);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font>   concat(string& s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc, <font CLASS=keytype>int</font> catlen);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font>   concat(string& s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s1);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font>   concat(string& s, <font CLASS=keytype>char</font> s1);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font>   concat(string& s, <font CLASS=keyword>const</font> string& s1);
    <font CLASS=keyword>friend</font> string copy(<font CLASS=keyword>const</font> string& s, <font CLASS=keytype>int</font> from, <font CLASS=keytype>int</font> cnt);
    <font CLASS=keyword>friend</font> string copy(<font CLASS=keyword>const</font> string& s, <font CLASS=keytype>int</font> from);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font>   ins(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s1, <font CLASS=keytype>int</font> s1len, string& s, <font CLASS=keytype>int</font> at);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font>   ins(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s1, string& s, <font CLASS=keytype>int</font> at);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font>   ins(<font CLASS=keytype>char</font> s1, string& s, <font CLASS=keytype>int</font> at);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font>   ins(<font CLASS=keyword>const</font> string& s1, string& s, <font CLASS=keytype>int</font> at);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font>   del(string& s, <font CLASS=keytype>int</font> at, <font CLASS=keytype>int</font> cnt);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font>   del(string& s, <font CLASS=keytype>int</font> at);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>int</font>    pos(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s1, <font CLASS=keyword>const</font> string& s);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>int</font>    pos(<font CLASS=keytype>char</font> s1, <font CLASS=keyword>const</font> string& s);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>int</font>    pos(<font CLASS=keyword>const</font> string& s1, <font CLASS=keyword>const</font> string& s);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>int</font>    rpos(<font CLASS=keytype>char</font> s1, <font CLASS=keyword>const</font> string& s);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font>   contains(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s1, <font CLASS=keytype>int</font> len, <font CLASS=keyword>const</font> string& s, <font CLASS=keytype>int</font> at);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font>   contains(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s1, <font CLASS=keyword>const</font> string& s, <font CLASS=keytype>int</font> at);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font>   contains(<font CLASS=keytype>char</font> s1, <font CLASS=keyword>const</font> string& s, <font CLASS=keytype>int</font> at);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font>   contains(<font CLASS=keyword>const</font> string& s1, <font CLASS=keyword>const</font> string& s, <font CLASS=keytype>int</font> at);
    <font CLASS=keyword>friend</font> string dup(<font CLASS=keyword>const</font> string& s);

    string()                                      { initialize(); }
    string(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc, <font CLASS=keytype>int</font> initlen)           { initialize(sc, initlen); }
    string(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc)                        { initialize(sc); }
    string(<font CLASS=keytype>char</font> c)                                { initialize(c); }
    string(<font CLASS=keyword>const</font> string& s)                       { initialize(s); }
    ~string()                                     { finalize(); }

<font CLASS=preproc>#ifdef</font> VARIANT_TYPECAST_HACK 
    string(<font CLASS=keyword>const</font> variant& v)                      { initialize(v); }
<font CLASS=preproc>#endif</font> 

    string& <font CLASS=keyword>operator</font><font CLASS=symbols>=</font>  (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc)           { assign(sc); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    string& <font CLASS=keyword>operator</font><font CLASS=symbols>=</font>  (<font CLASS=keytype>char</font> c)                   { assign(c); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    string& <font CLASS=keyword>operator</font><font CLASS=symbols>=</font>  (<font CLASS=keyword>const</font> string& s)          { assign(s); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    string& <font CLASS=keyword>operator</font><font CLASS=symbols>+=</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc)           { concat(*<font CLASS=keyword>this</font>, sc); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    string& <font CLASS=keyword>operator</font><font CLASS=symbols>+=</font> (<font CLASS=keytype>char</font> c)                   { concat(*<font CLASS=keyword>this</font>, c); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    string& <font CLASS=keyword>operator</font><font CLASS=symbols>+=</font> (<font CLASS=keyword>const</font> string& s)          { concat(*<font CLASS=keyword>this</font>, s); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }

    string  <font CLASS=keyword>operator</font><font CLASS=symbols>+</font>  (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc) <font CLASS=keyword>const</font>;
    string  <font CLASS=keyword>operator</font><font CLASS=symbols>+</font>  (<font CLASS=keytype>char</font> c) <font CLASS=keyword>const</font>;
    string  <font CLASS=keyword>operator</font><font CLASS=symbols>+</font>  (<font CLASS=keyword>const</font> string& s) <font CLASS=keyword>const</font>;

    <font CLASS=keyword>friend</font> string <font CLASS=keyword>operator</font><font CLASS=symbols>+</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc, <font CLASS=keyword>const</font> string& s);
    <font CLASS=keyword>friend</font> string <font CLASS=keyword>operator</font><font CLASS=symbols>+</font> (<font CLASS=keytype>char</font> c, <font CLASS=keyword>const</font> string& s);

    <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>==</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc) <font CLASS=keyword>const</font>        { <font CLASS=keyword>return</font> strcmp(data, sc) <font CLASS=symbols>==</font> <font CLASS=integer>0</font>; }
    <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>==</font> (<font CLASS=keytype>char</font>) <font CLASS=keyword>const</font>;
    <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>==</font> (<font CLASS=keyword>const</font> string&) <font CLASS=keyword>const</font>;
    <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>!=</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc) <font CLASS=keyword>const</font>        { <font CLASS=keyword>return</font> <font CLASS=symbols>!</font>(*<font CLASS=keyword>this</font> == sc); }
    <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>!=</font> (<font CLASS=keytype>char</font> c) <font CLASS=keyword>const</font>                { <font CLASS=keyword>return</font> <font CLASS=symbols>!</font>(*<font CLASS=keyword>this</font> == c); }
    <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>!=</font> (<font CLASS=keyword>const</font> string& s) <font CLASS=keyword>const</font>       { <font CLASS=keyword>return</font> <font CLASS=symbols>!</font>(*<font CLASS=keyword>this</font> == s); }

    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>==</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*, <font CLASS=keyword>const</font> string&);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>==</font> (<font CLASS=keytype>char</font>, <font CLASS=keyword>const</font> string&);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>!=</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*, <font CLASS=keyword>const</font> string&);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>!=</font> (<font CLASS=keytype>char</font>, <font CLASS=keyword>const</font> string&);

    <font CLASS=keyword>operator</font> <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*() <font CLASS=keyword>const</font>                  { <font CLASS=keyword>return</font> data; }
    <font CLASS=keyword>operator</font> <font CLASS=keyword>const</font> uchar*() <font CLASS=keyword>const</font>                 { <font CLASS=keyword>return</font> (uchar*)data; }

    <font CLASS=keytype>char</font>&       <font CLASS=keyword>operator</font>[] (<font CLASS=keytype>int</font> i)                { idx(i); <font CLASS=keyword>return</font> unique(*<font CLASS=keyword>this</font>)[i]; }
    <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>& <font CLASS=keyword>operator</font>[] (<font CLASS=keytype>int</font> i) <font CLASS=keyword>const</font>          { idx(i); <font CLASS=keyword>return</font> data[i]; }

    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(string& s);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(string& s, <font CLASS=keyword>const</font> string& s1);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(string& s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s1);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> finalize(string& s);
};


<font CLASS=keyword>typedef</font> string* pstring;

<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font>  length(<font CLASS=keyword>const</font> string& s)                     { <font CLASS=keyword>return</font> STR_LENGTH(s.data); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font>  refcount(<font CLASS=keyword>const</font> string& s)                   { <font CLASS=keyword>return</font> STR_REFCOUNT(s.data); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> assign(string& s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> len) { s.assign(buf, len); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> clear(string& s)                            { s.finalize(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> isempty(<font CLASS=keyword>const</font> string& s)                    { <font CLASS=keyword>return</font> length(s) <font CLASS=symbols>==</font> <font CLASS=integer>0</font>; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font>  pos(<font CLASS=keyword>const</font> string& s1, <font CLASS=keyword>const</font> string& s)      { <font CLASS=keyword>return</font> pos(s1.data, s); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>==</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc, <font CLASS=keyword>const</font> string& s){ <font CLASS=keyword>return</font> s <font CLASS=symbols>==</font> sc; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>==</font> (<font CLASS=keytype>char</font> c, <font CLASS=keyword>const</font> string& s)        { <font CLASS=keyword>return</font> s <font CLASS=symbols>==</font> c; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>!=</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc, <font CLASS=keyword>const</font> string& s){ <font CLASS=keyword>return</font> s <font CLASS=symbols>!=</font> sc; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>!=</font> (<font CLASS=keytype>char</font> c, <font CLASS=keyword>const</font> string& s)        { <font CLASS=keyword>return</font> s <font CLASS=symbols>!=</font> c; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(string& s)                       { s.initialize(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(string& s, <font CLASS=keyword>const</font> string& s1)     { s.initialize(s1); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(string& s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s1)       { s.initialize(s1); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> finalize(string& s)                         { s.finalize(); }


<font CLASS=keyword>extern</font> <font CLASS=keytype>int</font> stralloc;

<font CLASS=keyword>extern</font> string nullstring;


<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- string utilities ----------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>


string fill(<font CLASS=keytype>int</font> width, <font CLASS=keytype>char</font> pad);
string pad(<font CLASS=keyword>const</font> string& s, <font CLASS=keytype>int</font> width, <font CLASS=keytype>char</font> c, <font CLASS=keytype>bool</font> left <font CLASS=symbols>=</font> <font CLASS=keyword>true</font>);

string itostring(large value, <font CLASS=keytype>int</font> base, <font CLASS=keytype>int</font> width <font CLASS=symbols>=</font> <font CLASS=integer>0</font>, <font CLASS=keytype>char</font> pad <font CLASS=symbols>=</font> <font CLASS=integer>0</font>);
string itostring(ularge value, <font CLASS=keytype>int</font> base, <font CLASS=keytype>int</font> width <font CLASS=symbols>=</font> <font CLASS=integer>0</font>, <font CLASS=keytype>char</font> pad <font CLASS=symbols>=</font> <font CLASS=integer>0</font>);
string itostring(<font CLASS=keytype>int</font> value, <font CLASS=keytype>int</font> base, <font CLASS=keytype>int</font> width <font CLASS=symbols>=</font> <font CLASS=integer>0</font>, <font CLASS=keytype>char</font> pad <font CLASS=symbols>=</font> <font CLASS=integer>0</font>);
string itostring(<font CLASS=keytype>unsigned</font> value, <font CLASS=keytype>int</font> base, <font CLASS=keytype>int</font> width <font CLASS=symbols>=</font> <font CLASS=integer>0</font>, <font CLASS=keytype>char</font> pad <font CLASS=symbols>=</font> <font CLASS=integer>0</font>);
string itostring(large v);
string itostring(ularge v);
string itostring(<font CLASS=keytype>int</font> v);
string itostring(<font CLASS=keytype>unsigned</font> v);

large  stringtoi(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*);
large  stringtoie(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*);
ularge stringtoue(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*, <font CLASS=keytype>int</font> base);

string lowercase(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s);
string lowercase(<font CLASS=keyword>const</font> string& s);

<font CLASS=keytype>char</font> hex4(<font CLASS=keytype>char</font> c);

<font CLASS=keyword>inline</font> <font CLASS=keytype>char</font> locase(<font CLASS=keytype>char</font> c) 
    { <font CLASS=keyword>if</font> (c ><font CLASS=symbols>=</font> <font CLASS=sinquot>'A'</font> && c <<font CLASS=symbols>=</font> <font CLASS=sinquot>'Z'</font>) <font CLASS=keyword>return</font> <font CLASS=keytype>char</font>(c + <font CLASS=integer>32</font>); <font CLASS=keyword>return</font> c; }

<font CLASS=keyword>inline</font> <font CLASS=keytype>char</font> upcase(<font CLASS=keytype>char</font> c) 
    { <font CLASS=keyword>if</font> (c ><font CLASS=symbols>=</font> <font CLASS=sinquot>'a'</font> && c <<font CLASS=symbols>=</font> <font CLASS=sinquot>'z'</font>) <font CLASS=keyword>return</font> <font CLASS=keytype>char</font>(c - <font CLASS=integer>32</font>); <font CLASS=keyword>return</font> c; }

<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> hstrlen(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* p) <font CLASS=comment>// some Unix systems do not accept NULL</font>
    { <font CLASS=keyword>return</font> p <font CLASS=symbols>==</font> nil ? <font CLASS=integer>0</font> : (<font CLASS=keytype>int</font>)strlen(p); }




<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- character set -------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>


<font CLASS=keyword>const</font> <font CLASS=keytype>int</font>  _csetbits <font CLASS=symbols>=</font> <font CLASS=integer>256</font>;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font>  _csetbytes <font CLASS=symbols>=</font> _csetbits / <font CLASS=integer>8</font>;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font>  _csetwords <font CLASS=symbols>=</font> _csetbytes / <font CLASS=keyword>sizeof</font>(<font CLASS=keytype>int</font>);
<font CLASS=keyword>const</font> <font CLASS=keytype>char</font> _csetesc <font CLASS=symbols>=</font> <font CLASS=sinquot>'~'</font>;


<font CLASS=keyword>class</font> cset 
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
    <font CLASS=keytype>char</font> data[_csetbytes];

    <font CLASS=keytype>void</font> assign(<font CLASS=keyword>const</font> cset& s)                  { memcpy(data, s.data, _csetbytes); }
    <font CLASS=keytype>void</font> assign(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* setinit);
    <font CLASS=keytype>void</font> clear()                                { memset(data, <font CLASS=integer>0</font>, _csetbytes); }
    <font CLASS=keytype>void</font> fill()                                 { memset(data, <font CLASS=symbols>-</font><font CLASS=integer>1</font>, _csetbytes); }
    <font CLASS=keytype>void</font> include(<font CLASS=keytype>char</font> b)                        { data[uchar(b) / <font CLASS=integer>8</font>] <font CLASS=symbols>|=</font> uchar(<font CLASS=integer>1</font> << (uchar(b) % <font CLASS=integer>8</font>)); }
    <font CLASS=keytype>void</font> include(<font CLASS=keytype>char</font> min, <font CLASS=keytype>char</font> max);
    <font CLASS=keytype>void</font> exclude(<font CLASS=keytype>char</font> b)                        { data[uchar(b) / <font CLASS=integer>8</font>] &<font CLASS=symbols>=</font> uchar(~(<font CLASS=integer>1</font> << (uchar(b) % <font CLASS=integer>8</font>))); }
    <font CLASS=keytype>void</font> unite(<font CLASS=keyword>const</font> cset& s);
    <font CLASS=keytype>void</font> subtract(<font CLASS=keyword>const</font> cset& s);
    <font CLASS=keytype>void</font> intersect(<font CLASS=keyword>const</font> cset& s);
    <font CLASS=keytype>void</font> invert();
    <font CLASS=keytype>bool</font> contains(<font CLASS=keytype>char</font> b) <font CLASS=keyword>const</font>                 { <font CLASS=keyword>return</font> (data[uchar(b) / <font CLASS=integer>8</font>] & (<font CLASS=integer>1</font> << (uchar(b) % <font CLASS=integer>8</font>))) <font CLASS=symbols>!=</font> <font CLASS=integer>0</font>; }
    <font CLASS=keytype>bool</font> eq(<font CLASS=keyword>const</font> cset& s) <font CLASS=keyword>const</font>                { <font CLASS=keyword>return</font> memcmp(data, s.data, _csetbytes) <font CLASS=symbols>==</font> <font CLASS=integer>0</font>; }
    <font CLASS=keytype>bool</font> le(<font CLASS=keyword>const</font> cset& s) <font CLASS=keyword>const</font>;

<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    cset()                                      { clear(); }
    cset(<font CLASS=keyword>const</font> cset& s)                         { assign(s); }
    cset(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* setinit)                   { assign(setinit); }

    cset& <font CLASS=keyword>operator</font><font CLASS=symbols>=</font>  (<font CLASS=keyword>const</font> cset& s)            { assign(s); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    cset& <font CLASS=keyword>operator</font><font CLASS=symbols>+=</font> (<font CLASS=keyword>const</font> cset& s)            { unite(s); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    cset& <font CLASS=keyword>operator</font><font CLASS=symbols>+=</font> (<font CLASS=keytype>char</font> b)                   { include(b); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    cset  <font CLASS=keyword>operator</font><font CLASS=symbols>+</font>  (<font CLASS=keyword>const</font> cset& s) <font CLASS=keyword>const</font>      { cset t <font CLASS=symbols>=</font> *<font CLASS=keyword>this</font>; <font CLASS=keyword>return</font> t += s; }
    cset  <font CLASS=keyword>operator</font><font CLASS=symbols>+</font>  (<font CLASS=keytype>char</font> b) <font CLASS=keyword>const</font>             { cset t <font CLASS=symbols>=</font> *<font CLASS=keyword>this</font>; <font CLASS=keyword>return</font> t += b; }
    cset& <font CLASS=keyword>operator</font><font CLASS=symbols>-=</font> (<font CLASS=keyword>const</font> cset& s)            { subtract(s); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    cset& <font CLASS=keyword>operator</font><font CLASS=symbols>-=</font> (<font CLASS=keytype>char</font> b)                   { exclude(b); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    cset  <font CLASS=keyword>operator</font><font CLASS=symbols>-</font>  (<font CLASS=keyword>const</font> cset& s) <font CLASS=keyword>const</font>      { cset t <font CLASS=symbols>=</font> *<font CLASS=keyword>this</font>; <font CLASS=keyword>return</font> t -= s; }
    cset  <font CLASS=keyword>operator</font><font CLASS=symbols>-</font>  (<font CLASS=keytype>char</font> b) <font CLASS=keyword>const</font>             { cset t <font CLASS=symbols>=</font> *<font CLASS=keyword>this</font>; <font CLASS=keyword>return</font> t -= b; }
    cset& <font CLASS=keyword>operator</font>*<font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> cset& s)            { intersect(s); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    cset  <font CLASS=keyword>operator</font>*  (<font CLASS=keyword>const</font> cset& s) <font CLASS=keyword>const</font>      { cset t <font CLASS=symbols>=</font> *<font CLASS=keyword>this</font>; <font CLASS=keyword>return</font> t *<font CLASS=symbols>=</font> s; }
    cset  <font CLASS=keyword>operator</font><font CLASS=symbols>!</font>  () <font CLASS=keyword>const</font>                   { cset t <font CLASS=symbols>=</font> *<font CLASS=keyword>this</font>; t.invert(); <font CLASS=keyword>return</font> t; }
    <font CLASS=keytype>bool</font>  <font CLASS=keyword>operator</font><font CLASS=symbols>==</font> (<font CLASS=keyword>const</font> cset& s) <font CLASS=keyword>const</font>      { <font CLASS=keyword>return</font> eq(s); }
    <font CLASS=keytype>bool</font>  <font CLASS=keyword>operator</font><font CLASS=symbols>!=</font> (<font CLASS=keyword>const</font> cset& s) <font CLASS=keyword>const</font>      { <font CLASS=keyword>return</font> !eq(s); }
    <font CLASS=keytype>bool</font>  <font CLASS=keyword>operator</font><<font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> cset& s) <font CLASS=keyword>const</font>      { <font CLASS=keyword>return</font> le(s); }
    <font CLASS=keytype>bool</font>  <font CLASS=keyword>operator</font>><font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> cset& s) <font CLASS=keyword>const</font>      { <font CLASS=keyword>return</font> s.le(*<font CLASS=keyword>this</font>); }

    <font CLASS=keyword>friend</font> cset <font CLASS=keyword>operator</font><font CLASS=symbols>+</font> (<font CLASS=keytype>char</font> b, <font CLASS=keyword>const</font> cset& s);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font>& (<font CLASS=keytype>char</font> b, <font CLASS=keyword>const</font> cset& s);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> assign(cset& s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* setinit);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> clear(cset& s);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> fill(cset& s);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> include(cset& s, <font CLASS=keytype>char</font> b);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> include(cset& s, <font CLASS=keytype>char</font> min, <font CLASS=keytype>char</font> max);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> exclude(cset& s, <font CLASS=keytype>char</font> b);

    <font CLASS=keyword>friend</font> string asstring(<font CLASS=keyword>const</font> cset& s);
};


<font CLASS=keyword>inline</font> cset <font CLASS=keyword>operator</font><font CLASS=symbols>+</font> (<font CLASS=keytype>char</font> b, <font CLASS=keyword>const</font> cset& s)     { <font CLASS=keyword>return</font> s <font CLASS=symbols>+</font> b; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font>& (<font CLASS=keytype>char</font> b, <font CLASS=keyword>const</font> cset& s)     { <font CLASS=keyword>return</font> s.contains(b); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> assign(cset& s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* setinit)  { s.assign(setinit); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> clear(cset& s)                        { s.clear(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> fill(cset& s)                         { s.fill(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> include(cset& s, <font CLASS=keytype>char</font> b)              { s.include(b); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> include(cset& s, <font CLASS=keytype>char</font> min, <font CLASS=keytype>char</font> max)  { s.include(min, max); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> exclude(cset& s, <font CLASS=keytype>char</font> b)              { s.exclude(b); }


<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- basic abstract classes ----------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>

<font CLASS=comment>// basic class with virtual destructor; historically was used as a base</font>
<font CLASS=comment>// for all list items. also helps to count the number of created and</font>
<font CLASS=comment>// destroyed objects in a program (objalloc global) in DEBUG mode, to</font>
<font CLASS=comment>// detect memory leaks. most classes in ptypes are derived from unknown.</font>

<font CLASS=keyword>extern</font> <font CLASS=keytype>int</font> objalloc;

<font CLASS=keyword>class</font> unknown 
{
<font CLASS=preproc><font CLASS=keyword>private</font>:</font>
    // make all classes non-copyable by <font CLASS=keyword>default</font>
    unknown(<font CLASS=keyword>const</font> unknown&);
    <font CLASS=keyword>const</font> unknown& <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> unknown&);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
<font CLASS=preproc>#ifdef</font> COUNT_OBJALLOC 
    unknown()           { pincrement(&objalloc); }
    <font CLASS=keyword>virtual</font> ~unknown()  { pdecrement(&objalloc); }
<font CLASS=preproc>#else</font> 
    unknown()           { }
    <font CLASS=keyword>virtual</font> ~unknown()  { }
<font CLASS=preproc>#endif</font> 
};

<font CLASS=keyword>typedef</font> unknown* punknown;


<font CLASS=comment>// provide non-copyable base for all classes that are</font>
<font CLASS=comment>// not derived from 'unknown'</font>

<font CLASS=keyword>class</font> noncopyable 
{
<font CLASS=preproc><font CLASS=keyword>private</font>:</font>
    noncopyable(<font CLASS=keyword>const</font> noncopyable&);
    <font CLASS=keyword>const</font> noncopyable& <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> noncopyable&);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    noncopyable() {}
    ~noncopyable() {}
};



<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- exception ------------------------------------------------------ //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>

<font CLASS=comment>// the basic exception class. NOTE: the library always throws dynamically</font>
<font CLASS=comment>// allocated exception objects.</font>

<font CLASS=keyword>class</font> exception: public unknown 
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
    string message;
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    exception(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* imsg);
    exception(<font CLASS=keyword>const</font> string& imsg);
    <font CLASS=keyword>virtual</font> ~exception();
    <font CLASS=keyword>virtual</font> string get_message() { <font CLASS=keyword>return</font> message; }
};


<font CLASS=comment>// conversion exception class for stringtoie() and stringtoue()</font>

<font CLASS=keyword>class</font> econv: public exception
{
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    econv(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* msg): exception(msg)  {}
    econv(<font CLASS=keyword>const</font> string& msg): exception(msg)  {}
    <font CLASS=keyword>virtual</font> ~econv();
};


<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- tpodlist ------------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>

<font CLASS=comment>// _podlist implements dynamic array of small POD structures; it serves</font>
<font CLASS=comment>// as a basis for all list types in the library. this class is undocumented.</font>
<font CLASS=comment>// tpodlist template must be used instead.</font>

<font CLASS=keyword>class</font> _podlist: public noncopyable
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
    <font CLASS=keytype>void</font>* list;                   <font CLASS=comment>// pointer to the array</font>
    <font CLASS=keytype>int</font>   count;                  <font CLASS=comment>// number of items in the list</font>
    <font CLASS=keytype>int</font>   capacity;               <font CLASS=comment>// allocated for the list</font>
    <font CLASS=keytype>int</font>   itemsize;               <font CLASS=comment>// list item size</font>

    <font CLASS=keytype>static</font> <font CLASS=keytype>void</font> idxerror();

    _podlist& <font CLASS=keyword>operator</font> <font CLASS=symbols>=</font>(<font CLASS=keyword>const</font> _podlist& t);

    <font CLASS=keytype>void</font>  grow();
    <font CLASS=keytype>void</font>* doins(<font CLASS=keytype>int</font> index);
    <font CLASS=keytype>void</font>  doins(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> _podlist&);
    <font CLASS=keytype>void</font>* doget(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>            { <font CLASS=keyword>return</font> (<font CLASS=keytype>char</font>*)list <font CLASS=symbols>+</font> index * itemsize; }
    <font CLASS=keytype>void</font>  dodel(<font CLASS=keytype>int</font> index);
    <font CLASS=keytype>void</font>  dodel(<font CLASS=keytype>int</font> index, <font CLASS=keytype>int</font> count);
    <font CLASS=keytype>void</font>  dopop();

<font CLASS=preproc>#ifdef</font> CHECK_BOUNDS 
    <font CLASS=keytype>void</font> idx(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>               { <font CLASS=keyword>if</font> (<font CLASS=keytype>unsigned</font>(index) ><font CLASS=symbols>=</font> <font CLASS=keytype>unsigned</font>(count)) idxerror(); }
    <font CLASS=keytype>void</font> idxa(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>              { <font CLASS=keyword>if</font> (<font CLASS=keytype>unsigned</font>(index) > <font CLASS=keytype>unsigned</font>(count)) idxerror(); }
<font CLASS=preproc>#else</font> 
    <font CLASS=keytype>void</font> idx(<font CLASS=keytype>int</font>) <font CLASS=keyword>const</font>                     { }
    <font CLASS=keytype>void</font> idxa(<font CLASS=keytype>int</font>) <font CLASS=keyword>const</font>                    { }
<font CLASS=preproc>#endif</font> 

<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    _podlist(<font CLASS=keytype>int</font> itemsize);
    ~_podlist();

    <font CLASS=keytype>int</font>   get_count() <font CLASS=keyword>const</font>                 { <font CLASS=keyword>return</font> count; }
    <font CLASS=keytype>void</font>  set_count(<font CLASS=keytype>int</font> newcount, <font CLASS=keytype>bool</font> zero <font CLASS=symbols>=</font> <font CLASS=keyword>false</font>);
    <font CLASS=keytype>int</font>   get_capacity() <font CLASS=keyword>const</font>              { <font CLASS=keyword>return</font> capacity; }
    <font CLASS=keytype>void</font>  set_capacity(<font CLASS=keytype>int</font> newcap);
    <font CLASS=keytype>void</font>  clear()                           { set_count(<font CLASS=integer>0</font>); }
    <font CLASS=keytype>void</font>  pack()                            { set_capacity(count); }
    <font CLASS=keytype>void</font>* ins(<font CLASS=keytype>int</font> index)                    { idxa(index); <font CLASS=keyword>return</font> doins(index); }
    <font CLASS=keytype>void</font>  ins(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> _podlist& t) { idxa(index); doins(index, t); }
    <font CLASS=keytype>void</font>* add();
    <font CLASS=keytype>void</font>  add(<font CLASS=keyword>const</font> _podlist& t);
    <font CLASS=keytype>void</font>* <font CLASS=keyword>operator</font> [](<font CLASS=keytype>int</font> index)            { idx(index); <font CLASS=keyword>return</font> doget(index); }
    <font CLASS=keytype>void</font>* top()                             { <font CLASS=keyword>return</font> <font CLASS=keyword>operator</font> [](count <font CLASS=symbols>-</font> <font CLASS=integer>1</font>); }
    <font CLASS=keytype>void</font>  del(<font CLASS=keytype>int</font> index)                    { idx(index); dodel(index); }
    <font CLASS=keytype>void</font>  del(<font CLASS=keytype>int</font> index, <font CLASS=keytype>int</font> count)         { idx(index); dodel(index, count); }
    <font CLASS=keytype>void</font>  pop()                             { idx(<font CLASS=integer>0</font>); dopop(); }
};


<font CLASS=comment>// tpodlist is a fully-inlined template based on _podlist</font>

<font CLASS=keyword>template</font> <<font CLASS=keyword>class</font> X, <font CLASS=keytype>bool</font> initzero <font CLASS=symbols>=</font> <font CLASS=keyword>false</font>> <font CLASS=keyword>class</font> tpodlist: <font CLASS=keyword>public</font> _podlist
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
    X&   dozero(X& t)                       { <font CLASS=keyword>if</font> (initzero) memset(&t, <font CLASS=integer>0</font>, <font CLASS=keyword>sizeof</font>(X)); <font CLASS=keyword>return</font> t; }
    X&   doget(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>             { <font CLASS=keyword>return</font> ((X*)list)[index]; }
    X&   doins(<font CLASS=keytype>int</font> index)                   { X& t <font CLASS=symbols>=</font> *(X*)_podlist::doins(index); <font CLASS=keyword>return</font> dozero(t); }
    <font CLASS=keytype>void</font> doins(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> X& item)    { *(X*)_podlist::doins(index) <font CLASS=symbols>=</font> item; }

<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    tpodlist(): _podlist(<font CLASS=keyword>sizeof</font>(X))         {}
    tpodlist<X, initzero>& <font CLASS=keyword>operator</font> <font CLASS=symbols>=</font>(<font CLASS=keyword>const</font> tpodlist<X, initzero>& t)
                                            { _podlist::<font CLASS=keyword>operator</font> <font CLASS=symbols>=</font>(t); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }

    <font CLASS=keytype>void</font> set_count(<font CLASS=keytype>int</font> newcount)            { _podlist::set_count(newcount, initzero); }
    X&   ins(<font CLASS=keytype>int</font> index)                     { idxa(index); <font CLASS=keyword>return</font> doins(index); }
    <font CLASS=keytype>void</font> ins(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> X& item)      { idxa(index); doins(index, item); }
    <font CLASS=keytype>void</font> ins(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> tpodlist<X, initzero>& t)
                                            { _podlist::ins(index, t); }
    X&   add()                              { grow(); <font CLASS=keyword>return</font> dozero(doget(count<font CLASS=symbols>++</font>)); }
    <font CLASS=keytype>void</font> add(<font CLASS=keyword>const</font> X& item)                 { grow(); doget(count<font CLASS=symbols>++</font>) <font CLASS=symbols>=</font> item; }
    <font CLASS=keytype>void</font> add(<font CLASS=keyword>const</font> tpodlist<X, initzero>& t)
					    { _podlist::add(t); }
    X&   <font CLASS=keyword>operator</font> [](<font CLASS=keytype>int</font> index)             { idx(index); <font CLASS=keyword>return</font> doget(index); }
    <font CLASS=keyword>const</font> X& <font CLASS=keyword>operator</font> [](<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>   { idx(index); <font CLASS=keyword>return</font> doget(index); }
    X&   top()                              { idx(<font CLASS=integer>0</font>); <font CLASS=keyword>return</font> doget(count <font CLASS=symbols>-</font> <font CLASS=integer>1</font>); }
};


<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- tobjlist ------------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>

<font CLASS=comment>// _objlist is a base for the tobjlist template, don't use it directly.</font>
<font CLASS=comment>// also, _objlist is a base for _strlist and derivatives.</font>

<font CLASS=keyword>class</font> _objlist: public unknown, <font CLASS=keyword>protected</font> tpodlist<<font CLASS=keytype>void</font>*, <font CLASS=keyword>true</font>>
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
    <font CLASS=keyword>struct</font>
    {
        <font CLASS=keytype>unsigned</font> ownobjects :<font CLASS=integer>1</font>;   <font CLASS=comment>// list is responsible for destroying the items; used in _objlist</font>
        <font CLASS=keytype>unsigned</font> ownslobjects :<font CLASS=integer>1</font>; <font CLASS=comment>// same but for _strlist items (in _stritem structure)</font>
        <font CLASS=keytype>unsigned</font> sorted :<font CLASS=integer>1</font>;       <font CLASS=comment>// sorted list (_objlist+)</font>
        <font CLASS=keytype>unsigned</font> duplicates :<font CLASS=integer>1</font>;   <font CLASS=comment>// sorted: allows duplicate keys (_objlist+)</font>
        <font CLASS=keytype>unsigned</font> casesens :<font CLASS=integer>1</font>;     <font CLASS=comment>// sorted: string comparison is case sensitive (_strlist+)</font>
        <font CLASS=keytype>unsigned</font> _reserved :<font CLASS=integer>27</font>;
    } config;

    _objlist(bool ownobjects);	  <font CLASS=comment>// we hide this ctor, since _objlist actually can't free objects</font>

    <font CLASS=keytype>void</font>* doget(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>            { <font CLASS=keyword>return</font> ((<font CLASS=keytype>void</font>**)list)[index]; }
    <font CLASS=keytype>void</font>  doput(<font CLASS=keytype>int</font> index, <font CLASS=keytype>void</font>* obj);
    <font CLASS=keytype>void</font>  dodel(<font CLASS=keytype>int</font> index);
    <font CLASS=keytype>void</font>  dodel(<font CLASS=keytype>int</font> index, <font CLASS=keytype>int</font> count);
    <font CLASS=keytype>void</font>* dopop();
    <font CLASS=keytype>void</font>  dofree(<font CLASS=keytype>int</font> index, <font CLASS=keytype>int</font> count);

    <font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> dofree(<font CLASS=keytype>void</font>* obj);        <font CLASS=comment>// pure method; defined in tobjlist instances</font>
    <font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> compare(<font CLASS=keyword>const</font> <font CLASS=keytype>void</font>* key, <font CLASS=keyword>const</font> <font CLASS=keytype>void</font>* obj) <font CLASS=keyword>const</font>;  <font CLASS=comment>// pure method; defined in _strlist</font>

<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    _objlist();
    <font CLASS=keyword>virtual</font> ~_objlist();

    <font CLASS=keytype>int</font>   get_count() <font CLASS=keyword>const</font>                 { <font CLASS=keyword>return</font> count; }
    <font CLASS=keytype>void</font>  set_count(<font CLASS=keytype>int</font> newcount);
    <font CLASS=keytype>int</font>   get_capacity() <font CLASS=keyword>const</font>              { <font CLASS=keyword>return</font> capacity; }
    <font CLASS=keytype>void</font>  set_capacity(<font CLASS=keytype>int</font> newcap)          { tpodlist<<font CLASS=keytype>void</font>*,<font CLASS=keyword>true</font>>::set_capacity(newcap); }
    <font CLASS=keytype>void</font>  clear()                           { set_count(<font CLASS=integer>0</font>); }
    <font CLASS=keytype>void</font>  pack()                            { tpodlist<<font CLASS=keytype>void</font>*,<font CLASS=keyword>true</font>>::pack(); }
    <font CLASS=keytype>void</font>  ins(<font CLASS=keytype>int</font> index, <font CLASS=keytype>void</font>* obj)         { tpodlist<<font CLASS=keytype>void</font>*,<font CLASS=keyword>true</font>>::ins(index, obj); }
    <font CLASS=keytype>void</font>  add(<font CLASS=keytype>void</font>* obj)                    { tpodlist<<font CLASS=keytype>void</font>*,<font CLASS=keyword>true</font>>::add(obj); }
    <font CLASS=keytype>void</font>  put(<font CLASS=keytype>int</font> index, <font CLASS=keytype>void</font>* obj)         { idx(index); doput(index, obj); }
    <font CLASS=keytype>void</font>* <font CLASS=keyword>operator</font> [](<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>      { idx(index); <font CLASS=keyword>return</font> doget(index); }
    <font CLASS=keytype>void</font>* top() <font CLASS=keyword>const</font>                       { idx(<font CLASS=integer>0</font>); <font CLASS=keyword>return</font> doget(count <font CLASS=symbols>-</font> <font CLASS=integer>1</font>); }
    <font CLASS=keytype>void</font>* pop()                             { idx(<font CLASS=integer>0</font>); <font CLASS=keyword>return</font> dopop(); }
    <font CLASS=keytype>void</font>  del(<font CLASS=keytype>int</font> index)                    { idx(index); dodel(index); }
    <font CLASS=keytype>void</font>  del(<font CLASS=keytype>int</font> index, <font CLASS=keytype>int</font> count)         { idx(index); dodel(index, count); }
    <font CLASS=keytype>int</font>   indexof(<font CLASS=keytype>void</font>* obj) <font CLASS=keyword>const</font>;
    <font CLASS=keytype>bool</font>  search(<font CLASS=keyword>const</font> <font CLASS=keytype>void</font>* key, <font CLASS=keytype>int</font>& index) <font CLASS=keyword>const</font>;
};


<font CLASS=comment>// the tobjlist template implements a list of pointers to arbitrary</font>
<font CLASS=comment>// structures. optionally can automatically free objects (ownobjects)</font>
<font CLASS=comment>// when removed from a list. only 2 virtual functions are being</font>
<font CLASS=comment>// instantiated by this template, the rest is static code in _objlist.</font>

<font CLASS=keyword>template</font> <<font CLASS=keyword>class</font> X> <font CLASS=keyword>class</font> tobjlist: <font CLASS=keyword>public</font> _objlist
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
    X* doget(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>               { <font CLASS=keyword>return</font> (X*)_objlist::doget(index); }
    <font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> dofree(<font CLASS=keytype>void</font>* obj);

<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    tobjlist(<font CLASS=keytype>bool</font> ownobjects <font CLASS=symbols>=</font> <font CLASS=keyword>false</font>): _objlist(ownobjects)  {}
    <font CLASS=keyword>virtual</font> ~tobjlist();

    <font CLASS=keytype>bool</font>  get_ownobjects() <font CLASS=keyword>const</font>            { <font CLASS=keyword>return</font> config.ownobjects; }
    <font CLASS=keytype>void</font>  set_ownobjects(<font CLASS=keytype>bool</font> newval)       { config.ownobjects <font CLASS=symbols>=</font> newval; }
    <font CLASS=keytype>void</font>  ins(<font CLASS=keytype>int</font> index, X* obj)            { _objlist::ins(index, obj); }
    <font CLASS=keytype>void</font>  add(X* obj)                       { _objlist::add(obj); }
    <font CLASS=keytype>void</font>  put(<font CLASS=keytype>int</font> index, X* obj)            { _objlist::put(index, obj); }
    X*    <font CLASS=keyword>operator</font> [](<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>      { idx(index); <font CLASS=keyword>return</font> (X*)doget(index); }
    X*    top() <font CLASS=keyword>const</font>                       { <font CLASS=keyword>return</font> (X*)_objlist::top(); }
    X*    pop()                             { <font CLASS=keyword>return</font> (X*)_objlist::pop(); }
    <font CLASS=keytype>int</font>   indexof(X* obj) <font CLASS=keyword>const</font>             { <font CLASS=keyword>return</font> _objlist::indexof(obj); }

<font CLASS=preproc>#ifdef</font> PTYPES19_COMPAT 
    <font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> ins(tobjlist& s, <font CLASS=keytype>int</font> i, X* obj)          { s.ins(i, obj); }
    <font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>int</font>  add(tobjlist& s, X* obj)                 { s.add(obj); <font CLASS=keyword>return</font> s.get_count() <font CLASS=symbols>-</font> <font CLASS=integer>1</font>; }
    <font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> put(tobjlist& s, <font CLASS=keytype>int</font> i, X* obj)          { s.put(i, obj); }
    <font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>int</font>  indexof(<font CLASS=keyword>const</font> tobjlist& s, X* obj)       { <font CLASS=keyword>return</font> s.indexof(obj); }
    <font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>int</font>  push(tobjlist& s, X* obj)                { s.add(obj); <font CLASS=keyword>return</font> s.get_count() <font CLASS=symbols>-</font> <font CLASS=integer>1</font>; }
    <font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> X*   pop(tobjlist& s)                         { <font CLASS=keyword>return</font> (X*)s.pop(); }
    <font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> X*   top(<font CLASS=keyword>const</font> tobjlist& s)                   { <font CLASS=keyword>return</font> (X*)s.top(); }
    <font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> X*   get(<font CLASS=keyword>const</font> tobjlist& s, <font CLASS=keytype>int</font> i)            { <font CLASS=keyword>return</font> (X*)s[i]; }
<font CLASS=preproc>#endif</font> 
};


<font CLASS=keyword>template</font> <<font CLASS=keyword>class</font> X> <font CLASS=keytype>void</font> tobjlist<X>::dofree(<font CLASS=keytype>void</font>* item)
{
    <font CLASS=keyword>delete</font> (X*)item;
}


<font CLASS=keyword>template</font> <<font CLASS=keyword>class</font> X> tobjlist<X>::~tobjlist()
{
    set_count(<font CLASS=integer>0</font>);
}


<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- tstrlist ------------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>

<font CLASS=comment>// _strlist is a base for the tstrlist template</font>


<font CLASS=keyword>typedef</font> <font CLASS=keytype>int</font> slflags; <font CLASS=comment>// left for compatibility</font>

<font CLASS=preproc>#define</font> SL_SORTED      <font CLASS=integer>1</font> 
<font CLASS=preproc>#define</font> SL_DUPLICATES  <font CLASS=integer>2</font> 
<font CLASS=preproc>#define</font> SL_CASESENS    <font CLASS=integer>4</font> 
<font CLASS=preproc>#define</font> SL_OWNOBJECTS  <font CLASS=integer>8</font> 


<font CLASS=keyword>struct</font> _stritem
{
    string key;
    <font CLASS=keytype>void</font>* obj;

    _stritem(<font CLASS=keyword>const</font> string& ikey, <font CLASS=keytype>void</font>* iobj)
        : key(ikey), obj(iobj)  {}
};


<font CLASS=keyword>class</font> _strlist: <font CLASS=keyword>protected</font> tobjlist<_stritem>
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
    <font CLASS=keytype>static</font> <font CLASS=keytype>void</font> sortederror();
    <font CLASS=keytype>static</font> <font CLASS=keytype>void</font> notsortederror();
    <font CLASS=keytype>static</font> <font CLASS=keytype>void</font> duperror();

    <font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> dofree(<font CLASS=keytype>void</font>* item);
    <font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font>  compare(<font CLASS=keyword>const</font> <font CLASS=keytype>void</font>* key, <font CLASS=keyword>const</font> <font CLASS=keytype>void</font>* item) <font CLASS=keyword>const</font>;
    <font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> dofreeobj(<font CLASS=keytype>void</font>* obj);          <font CLASS=comment>// pure; tstrlist overrides it</font>

    <font CLASS=keyword>const</font> string& dogetkey(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>             { <font CLASS=keyword>return</font> doget(index)<font CLASS=symbols>-</font>>key; }
    <font CLASS=keytype>void</font>* dogetobj(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>                     { <font CLASS=keyword>return</font> doget(index)<font CLASS=symbols>-</font>>obj; }
    <font CLASS=keytype>void</font>  doins(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> string& key, <font CLASS=keytype>void</font>* obj);
    <font CLASS=keytype>void</font>  doput(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> string& key, <font CLASS=keytype>void</font>* obj);
    <font CLASS=keytype>void</font>  doput(<font CLASS=keytype>int</font> index, <font CLASS=keytype>void</font>* obj);

<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    _strlist(<font CLASS=keytype>int</font> flags <font CLASS=symbols>=</font> <font CLASS=integer>0</font>);
    <font CLASS=keyword>virtual</font> ~_strlist();

    <font CLASS=keytype>int</font>   get_count() <font CLASS=keyword>const</font>                             { <font CLASS=keyword>return</font> count; }
    <font CLASS=keytype>void</font>  set_count(<font CLASS=keytype>int</font> newcount)                       { tobjlist<_stritem>::set_count(newcount); }
    <font CLASS=keytype>int</font>   get_capacity() <font CLASS=keyword>const</font>                          { <font CLASS=keyword>return</font> capacity; }
    <font CLASS=keytype>void</font>  set_capacity(<font CLASS=keytype>int</font> newcap)                      { tobjlist<_stritem>::set_capacity(newcap); }
    <font CLASS=keytype>void</font>  clear()                                       { tobjlist<_stritem>::clear(); }
    <font CLASS=keytype>void</font>  pack()                                        { tobjlist<_stritem>::pack(); }
    <font CLASS=keytype>bool</font>  get_sorted() <font CLASS=keyword>const</font>                            { <font CLASS=keyword>return</font> config.sorted; }
    <font CLASS=keytype>bool</font>  get_duplicates() <font CLASS=keyword>const</font>                        { <font CLASS=keyword>return</font> config.duplicates; }
    <font CLASS=keytype>bool</font>  get_casesens() <font CLASS=keyword>const</font>                          { <font CLASS=keyword>return</font> config.casesens; }
    <font CLASS=keytype>bool</font>  get_ownobjects() <font CLASS=keyword>const</font>                        { <font CLASS=keyword>return</font> config.ownslobjects; }
    <font CLASS=keytype>void</font>  set_ownobjects(<font CLASS=keytype>bool</font> newval)                   { config.ownslobjects <font CLASS=symbols>=</font> newval; }
    <font CLASS=keytype>void</font>  ins(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> string& key, <font CLASS=keytype>void</font>* obj)  { idxa(index); doins(index, key, obj); }
    <font CLASS=keytype>void</font>  put(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> string& key, <font CLASS=keytype>void</font>* obj)  { idx(index); doput(index, key, obj); }
    <font CLASS=keytype>void</font>  put(<font CLASS=keytype>int</font> index, <font CLASS=keytype>void</font>* obj)                     { idx(index); doput(index, obj); }
    <font CLASS=keytype>int</font>   put(<font CLASS=keyword>const</font> string& key, <font CLASS=keytype>void</font>* obj);
    <font CLASS=keytype>int</font>   add(<font CLASS=keyword>const</font> string& key, <font CLASS=keytype>void</font>* obj);
    <font CLASS=keytype>void</font>* <font CLASS=keyword>operator</font> [](<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>                  { idx(index); <font CLASS=keyword>return</font> dogetobj(index); }
    <font CLASS=keytype>void</font>* <font CLASS=keyword>operator</font> [](<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) <font CLASS=keyword>const</font>;
    <font CLASS=keyword>const</font> string& getkey(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>               { idx(index); <font CLASS=keyword>return</font> dogetkey(index); }
    <font CLASS=keytype>bool</font>  search(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key, <font CLASS=keytype>int</font>& index) <font CLASS=keyword>const</font>     { <font CLASS=keyword>return</font> _objlist::search(key, index); }
    <font CLASS=keytype>void</font>  del(<font CLASS=keytype>int</font> index)                                { idx(index); dodel(index); }
    <font CLASS=keytype>void</font>  del(<font CLASS=keytype>int</font> index, <font CLASS=keytype>int</font> delcount)                  { idx(index); dodel(index, delcount); }
    <font CLASS=keytype>void</font>  del(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key)                          { put(key, nil); }
    <font CLASS=keytype>int</font>   indexof(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) <font CLASS=keyword>const</font>;
    <font CLASS=keytype>int</font>   indexof(<font CLASS=keytype>void</font>* obj) <font CLASS=keyword>const</font>;
};


<font CLASS=comment>// the tstrlist template implements a list of string/object pairs,</font>
<font CLASS=comment>// optionally sorted for fast searching by string key.</font>

<font CLASS=keyword>template</font> <<font CLASS=keyword>class</font> X> <font CLASS=keyword>class</font> tstrlist: <font CLASS=keyword>public</font> _strlist
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
    <font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> dofreeobj(<font CLASS=keytype>void</font>* obj);

<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    tstrlist(<font CLASS=keytype>int</font> flags <font CLASS=symbols>=</font> <font CLASS=integer>0</font>): _strlist(flags)  {}
    <font CLASS=keyword>virtual</font> ~tstrlist();

    <font CLASS=keytype>void</font>  ins(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> string& key, X* obj)     { _strlist::ins(index, key, obj); }
    <font CLASS=keytype>void</font>  put(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> string& key, X* obj)     { _strlist::put(index, key, obj); }
    <font CLASS=keytype>void</font>  put(<font CLASS=keytype>int</font> index, X* obj)                        { _strlist::put(index, obj); }
    <font CLASS=keytype>int</font>   put(<font CLASS=keyword>const</font> string& key, X* obj)                { <font CLASS=keyword>return</font> _strlist::put(key, obj); }
    <font CLASS=keytype>int</font>   add(<font CLASS=keyword>const</font> string& key, X* obj)                { <font CLASS=keyword>return</font> _strlist::add(key, obj); }
    X*    <font CLASS=keyword>operator</font> [](<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>                  { <font CLASS=keyword>return</font> (X*)_strlist::<font CLASS=keyword>operator</font> [](index); }
    X*    <font CLASS=keyword>operator</font> [](<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) <font CLASS=keyword>const</font>            { <font CLASS=keyword>return</font> (X*)_strlist::<font CLASS=keyword>operator</font> [](key); }
    <font CLASS=keytype>int</font>   indexof(X* obj) <font CLASS=keyword>const</font>                         { <font CLASS=keyword>return</font> _strlist::indexof(obj); }
    <font CLASS=keytype>int</font>   indexof(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) <font CLASS=keyword>const</font>                { <font CLASS=keyword>return</font> _strlist::indexof(key); }

<font CLASS=preproc>#ifdef</font> PTYPES19_COMPAT 
    // pre<font CLASS=symbols>-</font><font CLASS=floatpt>2.0</font> interface <font CLASS=keyword>for</font> backwards compatibility
    <font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> ins(tstrlist& s, <font CLASS=keytype>int</font> i, <font CLASS=keyword>const</font> string& str, X* obj)  { s.ins(i, str, obj); }
    <font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>int</font>  add(tstrlist& s, <font CLASS=keyword>const</font> string& str, X* obj)         { <font CLASS=keyword>return</font> s.add(str, obj); }
    <font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> put(tstrlist& s, <font CLASS=keytype>int</font> i, <font CLASS=keyword>const</font> string& str, X* obj)  { s.put(i, str, obj); }
    <font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> put(tstrlist& s, <font CLASS=keytype>int</font> i, X* obj)                     { s.put(i, obj); }
    <font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> indexof(<font CLASS=keyword>const</font> tstrlist& s, X* obj)                   { <font CLASS=keyword>return</font> s.indexof(obj); }
    <font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> X* get(<font CLASS=keyword>const</font> tstrlist& s, <font CLASS=keytype>int</font> i)                         { <font CLASS=keyword>return</font> (X*)s[i]; }
<font CLASS=preproc>#endif</font> 
};


<font CLASS=keyword>template</font> <<font CLASS=keyword>class</font> X> <font CLASS=keytype>void</font> tstrlist<X>::dofreeobj(<font CLASS=keytype>void</font>* obj)
{
    <font CLASS=keyword>delete</font> (X*)obj;
}


<font CLASS=keyword>template</font> <<font CLASS=keyword>class</font> X> tstrlist<X>::~tstrlist()
{
    set_count(<font CLASS=integer>0</font>);
}


<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- textmap -------------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>

<font CLASS=comment>// textmap is a list of string pairs (key/value)</font>

<font CLASS=keyword>struct</font> _textitem
{
    string key;
    string value;

    _textitem(<font CLASS=keyword>const</font> string& ikey, <font CLASS=keyword>const</font> string& ivalue)
        : key(ikey), value(ivalue)  {}
};


<font CLASS=keyword>class</font> textmap: <font CLASS=keyword>protected</font> tobjlist<_textitem>
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
    <font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> compare(<font CLASS=keyword>const</font> <font CLASS=keytype>void</font>* key, <font CLASS=keyword>const</font> <font CLASS=keytype>void</font>* item) <font CLASS=keyword>const</font>;
    <font CLASS=keyword>const</font> string& dogetvalue(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>           { <font CLASS=keyword>return</font> doget(index)<font CLASS=symbols>-</font>>value; }
    <font CLASS=keyword>const</font> string& dogetkey(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>             { <font CLASS=keyword>return</font> doget(index)<font CLASS=symbols>-</font>>key; }

<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    textmap(<font CLASS=keytype>bool</font> casesens <font CLASS=symbols>=</font> <font CLASS=keyword>false</font>);
    <font CLASS=keyword>virtual</font> ~textmap();

    <font CLASS=keytype>int</font>   get_count() <font CLASS=keyword>const</font>                             { <font CLASS=keyword>return</font> tobjlist<_textitem>::get_count(); }
    <font CLASS=keytype>void</font>  pack()                                        { tobjlist<_textitem>::pack(); }
    <font CLASS=keytype>void</font>  clear()                                       { tobjlist<_textitem>::clear(); }
    <font CLASS=keytype>int</font>   put(<font CLASS=keyword>const</font> string& key, <font CLASS=keyword>const</font> string& value);
    <font CLASS=keytype>void</font>  del(<font CLASS=keytype>int</font> index)                                { idx(index); dodel(index); }
    <font CLASS=keytype>void</font>  del(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key)                          { put(key, nullstring); }
    <font CLASS=keyword>const</font> string& get(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>                  { idx(index); <font CLASS=keyword>return</font> dogetvalue(index); }
    <font CLASS=keyword>const</font> string& getkey(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>               { idx(index); <font CLASS=keyword>return</font> dogetkey(index); }
    <font CLASS=keyword>const</font> string& get(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) <font CLASS=keyword>const</font>;
    <font CLASS=keyword>const</font> string& <font CLASS=keyword>operator</font> [](<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font>          { <font CLASS=keyword>return</font> get(index); }
    <font CLASS=keyword>const</font> string& <font CLASS=keyword>operator</font> [](<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) <font CLASS=keyword>const</font>    { <font CLASS=keyword>return</font> get(key); }
    <font CLASS=keytype>int</font>   indexof(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) <font CLASS=keyword>const</font>;
};


<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- component ------------------------------------------------------ //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>

<font CLASS=comment>// the component class is an abstract class that provides reference</font>
<font CLASS=comment>// counting and delete notification mechanisms. all stream classes</font>
<font CLASS=comment>// in ptypes are derived from component.</font>

<font CLASS=comment>// class ID's for all basic types: the first byte (least significant)</font>
<font CLASS=comment>// contains the base ID, the next is for the second level of inheritance,</font>
<font CLASS=comment>// etc. total of 4 levels allowed for basic types. call classid() for an</font>
<font CLASS=comment>// object, mask out first N bytes of interest and compare with a CLASS_XXX</font>
<font CLASS=comment>// value. f.ex. to determine whether an object is of type infile or any</font>
<font CLASS=comment>// derivative: (o->classid() & 0xffff) == CLASS2_INFILE. this scheme is for</font>
<font CLASS=comment>// internal use by PTypes and Objection; partly replaces the costly C++ RTTI</font>
<font CLASS=comment>// system.</font>

<font CLASS=comment>// first level of inheritance</font>
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS_UNDEFINED <font CLASS=symbols>=</font> 0x00000000;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS_INSTM     <font CLASS=symbols>=</font> 0x00000001;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS_OUTSTM    <font CLASS=symbols>=</font> 0x00000002;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS_UNIT      <font CLASS=symbols>=</font> 0x00000003;

<font CLASS=comment>// second level of inheritance</font>
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS2_INFILE    <font CLASS=symbols>=</font> 0x00000100 <font CLASS=symbols>|</font> CLASS_INSTM;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS2_INMEMORY  <font CLASS=symbols>=</font> 0x00000200 <font CLASS=symbols>|</font> CLASS_INSTM;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS2_FDX       <font CLASS=symbols>=</font> 0x00000300 <font CLASS=symbols>|</font> CLASS_INSTM;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS2_OUTFILE   <font CLASS=symbols>=</font> 0x00000100 <font CLASS=symbols>|</font> CLASS_OUTSTM;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS2_OUTMEMORY <font CLASS=symbols>=</font> 0x00000200 <font CLASS=symbols>|</font> CLASS_OUTSTM;

<font CLASS=comment>// third level of inheritance</font>
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS3_LOGFILE   <font CLASS=symbols>=</font> 0x00010000 <font CLASS=symbols>|</font> CLASS2_OUTFILE;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS3_IPSTM     <font CLASS=symbols>=</font> 0x00020000 <font CLASS=symbols>|</font> CLASS2_FDX;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS3_NPIPE     <font CLASS=symbols>=</font> 0x00030000 <font CLASS=symbols>|</font> CLASS2_FDX;


<font CLASS=keyword>class</font> component: public unknown 
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
    <font CLASS=keytype>int</font>                  refcount;     <font CLASS=comment>// reference counting, used by addref() and release()</font>
    tobjlist<component>* freelist;     <font CLASS=comment>// list of components to notify about destruction, safer alternative to ref-counting</font>
    <font CLASS=keytype>void</font>*                typeinfo;     <font CLASS=comment>// reserved for future use</font>

    <font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> freenotify(component* sender);

<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    component();
    <font CLASS=keyword>virtual</font> ~component();
    <font CLASS=keytype>void</font> addnotification(component* obj);
    <font CLASS=keytype>void</font> delnotification(component* obj);
    
    <font CLASS=keyword>friend</font> component* addref(component*);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> release(component*);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>int</font> refcount(component* c);

    <font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> classid();

    <font CLASS=keytype>void</font>  set_typeinfo(<font CLASS=keytype>void</font>* t) { typeinfo <font CLASS=symbols>=</font> t; }
    <font CLASS=keytype>void</font>* get_typeinfo()        { <font CLASS=keyword>return</font> typeinfo; }
};

<font CLASS=keyword>typedef</font> component* pcomponent;


<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> refcount(component* c)  { <font CLASS=keyword>return</font> c<font CLASS=symbols>-</font>>refcount; }


<font CLASS=keyword>template</font> <<font CLASS=keyword>class</font> T> <font CLASS=keyword>inline</font> T* taddref(T* c)
    { <font CLASS=keyword>return</font> (T*)addref((component*)c); }


<font CLASS=keyword>template</font> <<font CLASS=keyword>class</font> T> <font CLASS=keyword>class</font> compref
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
    T* ref;
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    compref()                                   { ref <font CLASS=symbols>=</font> <font CLASS=integer>0</font>; }
    compref(<font CLASS=keyword>const</font> compref<T>& r)                { ref <font CLASS=symbols>=</font> taddref<T>(r.ref); }
    compref(T* c)                               { ref <font CLASS=symbols>=</font> taddref<T>(c); }
    ~compref()                                  { release(ref); }
    compref<T>& <font CLASS=keyword>operator</font> <font CLASS=symbols>=</font>(T* c);
    compref<T>& <font CLASS=keyword>operator</font> <font CLASS=symbols>=</font>(<font CLASS=keyword>const</font> compref<T>& r) { <font CLASS=keyword>return</font> <font CLASS=keyword>operator</font> <font CLASS=symbols>=</font>(r.ref); }
    T&   <font CLASS=keyword>operator</font> *() <font CLASS=keyword>const</font>                     { <font CLASS=keyword>return</font> *ref; }
    T*   <font CLASS=keyword>operator</font> <font CLASS=symbols>-</font>>() <font CLASS=keyword>const</font>                    { <font CLASS=keyword>return</font> ref; }
    <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font> <font CLASS=symbols>==</font>(<font CLASS=keyword>const</font> compref<T>& r) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> ref <font CLASS=symbols>==</font> r.ref; }
    <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font> <font CLASS=symbols>==</font>(T* c) <font CLASS=keyword>const</font>                { <font CLASS=keyword>return</font> ref <font CLASS=symbols>==</font> c; }
    <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font> <font CLASS=symbols>!=</font>(<font CLASS=keyword>const</font> compref<T>& r) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> ref <font CLASS=symbols>!=</font> r.ref; }
    <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font> <font CLASS=symbols>!=</font>(T* c) <font CLASS=keyword>const</font>                { <font CLASS=keyword>return</font> ref <font CLASS=symbols>!=</font> c; }
         <font CLASS=keyword>operator</font> T*() <font CLASS=keyword>const</font>                    { <font CLASS=keyword>return</font> ref; }
};


<font CLASS=keyword>template</font> <<font CLASS=keyword>class</font> T> compref<T>& compref<T>::<font CLASS=keyword>operator</font> <font CLASS=symbols>=</font>(T* c)
{
    release(tpexchange<T>(&ref, taddref<T>(c)));
    <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>;
}


<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- variant -------------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>


<font CLASS=keyword>enum</font> {
    VAR_NULL,
    VAR_INT,
    VAR_BOOL,
    VAR_FLOAT,
    VAR_STRING,
    VAR_ARRAY,
    VAR_OBJECT,

    VAR_COMPOUND <font CLASS=symbols>=</font> VAR_STRING
};


<font CLASS=keyword>class</font> _varray;


<font CLASS=keyword>class</font> variant
{
    <font CLASS=keyword>friend</font> <font CLASS=keyword>class</font> string;
    <font CLASS=keyword>friend</font> <font CLASS=keyword>class</font> _varray;

<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
    <font CLASS=keytype>int</font> tag;            <font CLASS=comment>// VAR_XXX</font>
    <font CLASS=keyword>union</font> {
        large      i;   <font CLASS=comment>// 64-bit int value</font>
        <font CLASS=keytype>bool</font>       b;   <font CLASS=comment>// bool value</font>
        <font CLASS=keytype>double</font>     f;   <font CLASS=comment>// double value</font>
        char*      s;   <font CLASS=comment>// string object; can't declare as string because of the union</font>
        _varray*   a;   <font CLASS=comment>// pointer to a reference-counted _strlist object</font>
        component* o;   <font CLASS=comment>// pointer to a reference-counted component object (or derivative)</font>
    } value;            <font CLASS=comment>// we need this name to be able to copy the entire union in some situations</font>

    <font CLASS=keytype>void</font> initialize()                       { tag <font CLASS=symbols>=</font> VAR_NULL; }
    <font CLASS=keytype>void</font> initialize(large v)                { tag <font CLASS=symbols>=</font> VAR_INT; value.i <font CLASS=symbols>=</font> v; }
    <font CLASS=keytype>void</font> initialize(<font CLASS=keytype>bool</font> v)                 { tag <font CLASS=symbols>=</font> VAR_BOOL; value.b <font CLASS=symbols>=</font> v; }
    <font CLASS=keytype>void</font> initialize(<font CLASS=keytype>double</font> v)               { tag <font CLASS=symbols>=</font> VAR_FLOAT; value.f <font CLASS=symbols>=</font> v; }
    <font CLASS=keytype>void</font> initialize(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* v)          { tag <font CLASS=symbols>=</font> VAR_STRING; PTYPES_NAMESPACE::initialize(PTR_TO_STRING(value.s), v); }
    <font CLASS=keytype>void</font> initialize(<font CLASS=keyword>const</font> string& v)        { tag <font CLASS=symbols>=</font> VAR_STRING; PTYPES_NAMESPACE::initialize(PTR_TO_STRING(value.s), v); }
    <font CLASS=keytype>void</font> initialize(_varray* a);
    <font CLASS=keytype>void</font> initialize(component* o);
    <font CLASS=keytype>void</font> initialize(<font CLASS=keyword>const</font> variant& v);
    <font CLASS=keytype>void</font> finalize();

    <font CLASS=keytype>void</font> assign(large);
    <font CLASS=keytype>void</font> assign(<font CLASS=keytype>bool</font>);
    <font CLASS=keytype>void</font> assign(<font CLASS=keytype>double</font>);
    <font CLASS=keytype>void</font> assign(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*);
    <font CLASS=keytype>void</font> assign(<font CLASS=keyword>const</font> string&);
    <font CLASS=keytype>void</font> assign(_varray*);
    <font CLASS=keytype>void</font> assign(component*);
    <font CLASS=keytype>void</font> assign(<font CLASS=keyword>const</font> variant&);

    <font CLASS=keytype>bool</font> equal(<font CLASS=keyword>const</font> variant& v) <font CLASS=keyword>const</font>;

    variant(_varray* a)                     { initialize(a); }

<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    // construction
    variant()                               { initialize(); }
    variant(<font CLASS=keytype>int</font> v)                          { initialize(large(v)); }
    variant(<font CLASS=keytype>unsigned</font> <font CLASS=keytype>int</font> v)                 { initialize(large(v)); }
    variant(large v)                        { initialize(v); }
    variant(<font CLASS=keytype>bool</font> v)                         { initialize(v); }
    variant(<font CLASS=keytype>double</font> v)                       { initialize(v); }
    variant(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* v)                  { initialize(v); }
    variant(<font CLASS=keyword>const</font> string& v)                { initialize(v); }
    variant(component* v)                   { initialize(v); }
    variant(<font CLASS=keyword>const</font> variant& v)               { initialize(v); }
    ~variant()                              { finalize(); }

    // assignment
    variant& <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keytype>int</font> v)              { assign(large(v)); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    variant& <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keytype>unsigned</font> <font CLASS=keytype>int</font> v)     { assign(large(v)); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    variant& <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (large v)            { assign(v); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    variant& <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keytype>bool</font> v)             { assign(v); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    variant& <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keytype>double</font> v)           { assign(v); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    variant& <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* v)      { assign(v); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    variant& <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> string& v)    { assign(v); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    variant& <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (component* v)       { assign(v); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
    variant& <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> variant& v)   { assign(v); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }

    // typecast
    <font CLASS=keyword>operator</font> <font CLASS=keytype>int</font>() <font CLASS=keyword>const</font>;
    <font CLASS=keyword>operator</font> <font CLASS=keytype>unsigned</font> <font CLASS=keytype>int</font>() <font CLASS=keyword>const</font>;
    <font CLASS=keyword>operator</font> <font CLASS=keytype>long</font>() <font CLASS=keyword>const</font>;
    <font CLASS=keyword>operator</font> <font CLASS=keytype>unsigned</font> <font CLASS=keytype>long</font>() <font CLASS=keyword>const</font>;
    <font CLASS=keyword>operator</font> large() <font CLASS=keyword>const</font>;
    <font CLASS=keyword>operator</font> <font CLASS=keytype>bool</font>() <font CLASS=keyword>const</font>;
    <font CLASS=keyword>operator</font> <font CLASS=keytype>double</font>() <font CLASS=keyword>const</font>;
    <font CLASS=keyword>operator</font> string() <font CLASS=keyword>const</font>;
    <font CLASS=keyword>operator</font> component*() <font CLASS=keyword>const</font>;

    // comparison
    <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>==</font> (<font CLASS=keyword>const</font> variant& v) <font CLASS=keyword>const</font>  { <font CLASS=keyword>return</font> equal(v); }
    <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>!=</font> (<font CLASS=keyword>const</font> variant& v) <font CLASS=keyword>const</font>  { <font CLASS=keyword>return</font> !equal(v); }

    // typification
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> clear(variant&);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>int</font>  vartype(<font CLASS=keyword>const</font> variant& v);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> isnull(<font CLASS=keyword>const</font> variant& v);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> isint(<font CLASS=keyword>const</font> variant& v);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> isbool(<font CLASS=keyword>const</font> variant& v);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> isfloat(<font CLASS=keyword>const</font> variant& v);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> isstring(<font CLASS=keyword>const</font> variant& v);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> isarray(<font CLASS=keyword>const</font> variant& v);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> isobject(<font CLASS=keyword>const</font> variant& v);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> iscompound(<font CLASS=keyword>const</font> variant& v);

    // array manipulation
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> aclear(variant&);
    <font CLASS=keyword>friend</font> variant aclone(<font CLASS=keyword>const</font> variant&);
    <font CLASS=keyword>friend</font> <font CLASS=keyword>const</font> variant& get(<font CLASS=keyword>const</font> variant&, <font CLASS=keyword>const</font> string& key);
    <font CLASS=keyword>friend</font> <font CLASS=keyword>const</font> variant& get(<font CLASS=keyword>const</font> variant&, large key);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> put(variant&, <font CLASS=keyword>const</font> string& key, <font CLASS=keyword>const</font> variant& item);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> put(variant&, large key, <font CLASS=keyword>const</font> variant& item);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> del(variant&, <font CLASS=keyword>const</font> string& key);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> del(variant&, large key);

    // indexed access to arrays
    <font CLASS=keyword>friend</font> <font CLASS=keytype>int</font>  alength(<font CLASS=keyword>const</font> variant&);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> apack(variant&);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> anext(<font CLASS=keyword>const</font> variant& a, <font CLASS=keytype>int</font>&, variant& item);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> anext(<font CLASS=keyword>const</font> variant& a, <font CLASS=keytype>int</font>&, variant& item, string& key);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>int</font>  aadd(variant&, <font CLASS=keyword>const</font> variant& item);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> aput(variant&, <font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> variant& item);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> ains(variant&, <font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> variant& item);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> adel(variant&, <font CLASS=keytype>int</font> index);
    <font CLASS=keyword>friend</font> <font CLASS=keyword>const</font> variant& aget(<font CLASS=keyword>const</font> variant&, <font CLASS=keytype>int</font> index);
    <font CLASS=keyword>friend</font> string akey(<font CLASS=keyword>const</font> variant&, <font CLASS=keytype>int</font> index);

    <font CLASS=keyword>const</font> variant& <font CLASS=keyword>operator</font>[](<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) <font CLASS=keyword>const</font>    { <font CLASS=keyword>return</font> get(*<font CLASS=keyword>this</font>, string(key)); }
    <font CLASS=keyword>const</font> variant& <font CLASS=keyword>operator</font>[](<font CLASS=keyword>const</font> string& key) <font CLASS=keyword>const</font>  { <font CLASS=keyword>return</font> get(*<font CLASS=keyword>this</font>, key); }
    <font CLASS=keyword>const</font> variant& <font CLASS=keyword>operator</font>[](large key) <font CLASS=keyword>const</font>          { <font CLASS=keyword>return</font> get(*<font CLASS=keyword>this</font>, key); }

    // <font CLASS=sinquot>'manual'</font> initialization/finalization, undocumented. use with care<font CLASS=symbols>!</font>
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant& v);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant& v, large i);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant& v, <font CLASS=keytype>int</font> i);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant& v, <font CLASS=keytype>unsigned</font> <font CLASS=keytype>int</font> i);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant& v, <font CLASS=keytype>bool</font> i);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant& v, <font CLASS=keytype>double</font> i);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant& v, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* i);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant& v, <font CLASS=keyword>const</font> string& i);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant& v, component* i);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant& v, <font CLASS=keyword>const</font> variant& i);
    <font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> finalize(variant& v);
};


<font CLASS=keyword>typedef</font> variant* pvariant;


<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font>  vartype(<font CLASS=keyword>const</font> variant& v)       { <font CLASS=keyword>return</font> v.tag; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> isnull(<font CLASS=keyword>const</font> variant& v)        { <font CLASS=keyword>return</font> v.tag <font CLASS=symbols>==</font> VAR_NULL; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> isint(<font CLASS=keyword>const</font> variant& v)         { <font CLASS=keyword>return</font> v.tag <font CLASS=symbols>==</font> VAR_INT; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> isbool(<font CLASS=keyword>const</font> variant& v)        { <font CLASS=keyword>return</font> v.tag <font CLASS=symbols>==</font> VAR_BOOL; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> isfloat(<font CLASS=keyword>const</font> variant& v)       { <font CLASS=keyword>return</font> v.tag <font CLASS=symbols>==</font> VAR_FLOAT; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> isstring(<font CLASS=keyword>const</font> variant& v)      { <font CLASS=keyword>return</font> v.tag <font CLASS=symbols>==</font> VAR_STRING; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> isarray(<font CLASS=keyword>const</font> variant& v)       { <font CLASS=keyword>return</font> v.tag <font CLASS=symbols>==</font> VAR_ARRAY; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> isobject(<font CLASS=keyword>const</font> variant& v)      { <font CLASS=keyword>return</font> v.tag <font CLASS=symbols>==</font> VAR_OBJECT; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> iscompound(<font CLASS=keyword>const</font> variant& v)    { <font CLASS=keyword>return</font> v.tag ><font CLASS=symbols>=</font> VAR_COMPOUND; }

<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant& v)                   { v.initialize(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant& v, large i)          { v.initialize(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant& v, <font CLASS=keytype>int</font> i)            { v.initialize(large(i)); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant& v, <font CLASS=keytype>unsigned</font> <font CLASS=keytype>int</font> i)   { v.initialize(large(i)); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant& v, <font CLASS=keytype>bool</font> i)           { v.initialize(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant& v, <font CLASS=keytype>double</font> i)         { v.initialize(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant& v, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* i)    { v.initialize(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant& v, <font CLASS=keyword>const</font> string& i)  { v.initialize(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant& v, component* i)     { v.initialize(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant& v, <font CLASS=keyword>const</font> variant& i) { v.initialize(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> finalize(variant& v)                     { <font CLASS=keyword>if</font> (v.tag ><font CLASS=symbols>=</font> VAR_COMPOUND) v.finalize(); }


<font CLASS=keyword>extern</font> <font CLASS=keyword>const</font> variant nullvar;


<font CLASS=comment>// variant exception class; may be thrown when a variant</font>
<font CLASS=comment>// is being typecast'ed to 32-bit int and the value is</font>
<font CLASS=comment>// out of range</font>

<font CLASS=keyword>class</font> evariant: public exception
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    evariant(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* msg): exception(msg)  {}
    evariant(<font CLASS=keyword>const</font> string& msg): exception(msg)  {}
    <font CLASS=keyword>virtual</font> ~evariant();
};



<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- pre-2.0 compatibility declarations ----------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>


<font CLASS=preproc>#ifdef</font> PTYPES19_COMPAT 

<font CLASS=comment>// ptypes-1.9 objlist and strlist: accept only 'unknown' and</font>
<font CLASS=comment>// derivatives as a base type</font>

<font CLASS=keyword>class</font> objlist: public tobjlist<unknown>
{
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    objlist(<font CLASS=keytype>bool</font> ownobjects <font CLASS=symbols>=</font> <font CLASS=keyword>false</font>);
    <font CLASS=keyword>virtual</font> ~objlist();
};

<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font>  length(<font CLASS=keyword>const</font> _objlist& s)                { <font CLASS=keyword>return</font> s.get_count(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> setlength(_objlist& s, <font CLASS=keytype>int</font> newcount)     { s.set_count(newcount); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> pack(_objlist& s)                        { s.pack(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> clear(_objlist& s)                       { s.clear(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font>  push(_objlist& s, unknown* obj)          { s.add(obj); <font CLASS=keyword>return</font> length(s) <font CLASS=symbols>-</font> <font CLASS=integer>1</font>; }
<font CLASS=keyword>inline</font> unknown* top(<font CLASS=keyword>const</font> _objlist& s)               { <font CLASS=keyword>return</font> (unknown*)s.top(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> ins(_objlist& s, <font CLASS=keytype>int</font> i, unknown* obj)    { s.ins(i, obj); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font>  add(_objlist& s, unknown* obj)           { s.add(obj); <font CLASS=keyword>return</font> length(s) <font CLASS=symbols>-</font> <font CLASS=integer>1</font>; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> put(_objlist& s, <font CLASS=keytype>int</font> i, unknown* obj)    { s.put(i, obj); }
<font CLASS=keyword>inline</font> unknown* get(<font CLASS=keyword>const</font> _objlist& s, <font CLASS=keytype>int</font> i)        { <font CLASS=keyword>return</font> (unknown*)s[i]; }
<font CLASS=keyword>inline</font> unknown* pop(_objlist& s)                     { <font CLASS=keyword>return</font> (unknown*)s.pop(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> del(_objlist& s, <font CLASS=keytype>int</font> i)                  { s.del(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font>  indexof(<font CLASS=keyword>const</font> _objlist& s, unknown* obj) { <font CLASS=keyword>return</font> s.indexof(obj); }


<font CLASS=keyword>class</font> strlist: public tstrlist<unknown>
{
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    strlist(<font CLASS=keytype>int</font> flags <font CLASS=symbols>=</font> <font CLASS=integer>0</font>);
    <font CLASS=keyword>virtual</font> ~strlist();
};

<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font>  length(<font CLASS=keyword>const</font> _strlist& s)                                { <font CLASS=keyword>return</font> s.get_count(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> clear(_strlist& s)                                       { s.clear(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> pack(_strlist& s)                                        { s.pack(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> search(<font CLASS=keyword>const</font> _strlist& s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key, <font CLASS=keytype>int</font>& i)       { <font CLASS=keyword>return</font> s.search(key, i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> ins(_strlist& s, <font CLASS=keytype>int</font> i, <font CLASS=keyword>const</font> string& key, unknown* obj) { s.ins(i, key, obj); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font>  add(_strlist& s, <font CLASS=keyword>const</font> string& key, unknown* obj)        { <font CLASS=keyword>return</font> s.add(key, obj); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> put(_strlist& s, <font CLASS=keytype>int</font> i, <font CLASS=keyword>const</font> string& key, unknown* obj) { s.put(i, key, obj); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> put(_strlist& s, <font CLASS=keytype>int</font> i, unknown* obj)                    { s.put(i, obj); }
<font CLASS=keyword>inline</font> unknown* get(<font CLASS=keyword>const</font> _strlist& s, <font CLASS=keytype>int</font> i)                        { <font CLASS=keyword>return</font> (unknown*)s[i]; }
<font CLASS=keyword>inline</font> <font CLASS=keyword>const</font> string& getstr(<font CLASS=keyword>const</font> _strlist& s, <font CLASS=keytype>int</font> i)                { <font CLASS=keyword>return</font> s.getkey(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> del(_strlist& s, <font CLASS=keytype>int</font> i)                                  { s.del(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font>  find(<font CLASS=keyword>const</font> _strlist& s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key)                 { <font CLASS=keyword>return</font> s.indexof(key); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font>  indexof(<font CLASS=keyword>const</font> _strlist& s, unknown* obj)                 { <font CLASS=keyword>return</font> s.indexof(obj); }


<font CLASS=comment>// ptypes-1.9 strmap: now replaced with _strlist(SL_SORTED)</font>

<font CLASS=keyword>class</font> strmap: public tstrlist<unknown>
{
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    strmap(<font CLASS=keytype>int</font> flags <font CLASS=symbols>=</font> <font CLASS=integer>0</font>);
    <font CLASS=keyword>virtual</font> ~strmap();
};

<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font>     put(strmap& m, <font CLASS=keyword>const</font> string& key, unknown* obj)     { m.put(key, obj); }
<font CLASS=keyword>inline</font> unknown* get(<font CLASS=keyword>const</font> strmap& m, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key)               { <font CLASS=keyword>return</font> m[key]; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font>     del(strmap& m, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key)                     { m.del(key); }

<font CLASS=keyword>template</font> <<font CLASS=keyword>class</font> X> <font CLASS=keyword>class</font> tstrmap: <font CLASS=keyword>public</font> strmap
{
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
    tstrmap(): strmap()  {}
    tstrmap(<font CLASS=keytype>int</font> iflags): strmap(iflags)  {}
    <font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> X* get(<font CLASS=keyword>const</font> tstrmap& m, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* str)         { <font CLASS=keyword>return</font> (X*)PTYPES_NAMESPACE::get((<font CLASS=keyword>const</font> strmap&)m, str); }
    <font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> put(tstrmap& m, <font CLASS=keyword>const</font> string& str, X* obj)   { unknown* t <font CLASS=symbols>=</font> obj; PTYPES_NAMESPACE::put(m, str, t); }
    X* <font CLASS=keyword>operator</font>[] (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* str) <font CLASS=keyword>const</font>                           { <font CLASS=keyword>return</font> (X*)PTYPES_NAMESPACE::get(*<font CLASS=keyword>this</font>, str); }
};


<font CLASS=comment>// ptypes-1.9 textmap interface</font>

<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font>   length(<font CLASS=keyword>const</font> textmap& m)                           { <font CLASS=keyword>return</font> m.get_count(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font>  clear(textmap& m)                                  { m.clear(); }
<font CLASS=keyword>inline</font> <font CLASS=keyword>const</font> string& get(<font CLASS=keyword>const</font> textmap& m, <font CLASS=keyword>const</font> string& k)     { <font CLASS=keyword>return</font> m.get(k); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font>  put(textmap& m, <font CLASS=keyword>const</font> string& k, <font CLASS=keyword>const</font> string& v)  { m.put(k, v); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font>  del(textmap& m, <font CLASS=keyword>const</font> string& k)                   { m.del(k); }


<font CLASS=preproc>#endif</font> <font CLASS=comment>// PTYPES19_COMPAT </font>


<font CLASS=preproc>#ifdef</font> _MSC_VER 
<font CLASS=preproc>#pragma</font> warning(pop) 
<font CLASS=preproc>#pragma</font> pack(pop) 
<font CLASS=preproc>#endif</font> 


PTYPES_END

<font CLASS=preproc>#endif</font> <font CLASS=comment>// __PTYPES_H__ </font>



</pre>

</div>


<hr noshade></body>
</html>
Source at commit 209d6fa3805c created 11 years 7 months ago.
By Nathan Adams, Updating tparray to use variants as array because tpodlist was causing variant data corruption

Archive Download this file

Branches

Tags

Page rendered in 0.73969s using 11 queries.