Changeset 241 in Sophya for trunk/SophyaLib/BaseTools/ppersist.h


Ignore:
Timestamp:
Apr 21, 1999, 3:12:11 PM (26 years ago)
Author:
ansari
Message:

ppersist + pexc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/SophyaLib/BaseTools/ppersist.h

    r219 r241  
     1// This may look like C code, but it is really -*- C++ -*-
     2
    13#ifndef PPERSIST_H_SEEN
    24#define PPERSIST_H_SEEN
    35
    4 // Classe mixin pour implementer une persistance pas trop bete.
    5 
    6 #include "defs.h"
    7 #include "machine.h"
    8 #include "perrors.h"
    9 #include "pclassids.h"
     6// Flat file persistance, similar to Java serialization
     7//
     8// E. Aubourg     CEA DAPNIA/SPP  1999
     9
     10
     11#include "machdefs.h"
     12#include "pexceptions.h"
     13#include "md5.h"
    1014
    1115#include <string>
    12 #include <list>
    1316#include <map>
    14 #include <functional>
     17#include <vector>
     18#include <typeinfo>
    1519
    1620#if defined(__KCC__)
     
    2125#endif
    2226
    23 #ifdef RFIO
    24 #include "erostream.h"
    25 #else
    26 #include <iostream.h>
    27 #endif
    28 
    29 
    30 class PPersistMgr;
    31 class PPersist;
    32 class PShPersist;
    33 class PInPersist;
    34 class POutPersist;
    35 
    36 typedef less<int_4> Int4Compare;
    37 
    38 class PPersistMgr {
    39 public:
    40   typedef PPersist*           (*ClassCreatorFunc)();
    41  
    42   static void                  RegisterClass(int_4 classId, ClassCreatorFunc f,
    43                                              bool shared=false);
    44   static PPersist*             ReadObject(PInPersist&);
    45  
    46   static ClassCreatorFunc      FindCreatorFunc(int_4 classId);
    47   static ClassCreatorFunc      FindCreatorFunc(int_4 classId, bool& isShared);
    48  
    49   static void                  Reset();  // Nouveau fichier, on oublie les objets partages.
    50 
    51 #ifndef __DECCXX
    52 private:
    53 #endif
    54   struct  ClassListEntry {
    55     bool             shared;
    56     ClassCreatorFunc f;
     27namespace PlanckDPC {
     28 
     29  class PIOPersist;
     30  class PInPersist;
     31  class POutPersist;
     32  class PPersist;
     33
     34  /* Persistant (delegate or mixin) object */
     35
     36  class PPersist  {
     37  public:
     38    virtual           ~PPersist() {}
     39
     40    void               Write(string const& fn) const;
     41    void               Read(string const& fn);
     42
     43    virtual void       Write(POutPersist&) const;
     44    void               Read(PInPersist& s);               // Reads the type tag and the object
     45    void               Write(POutPersist&, string const& tag) const;
     46    void               ReadAtTag(PInPersist& s, string const& tag);
     47  protected: 
     48    virtual void       ReadSelf(PInPersist&)=0;           
     49    virtual void       WriteSelf(POutPersist&) const=0; 
     50
     51    friend class       PInPersist;
     52    friend class       POutPersist;
    5753  };
    58 #ifdef __DECCXX
    59 private:
    60 #endif
    61 
    62   typedef map<int_4, ClassListEntry, Int4Compare> ClassList;
    63 
    64 
    65   static ClassList*            classList;
    66   friend class                 PeidaInitiator;
    67 };
    68 
    69 
    70 
    71 class PPersist EXC_AWARE {
    72 public:
    73   enum {PPS_NATIVE = -1, PPS_LITTLE_ENDIAN = 0, PPS_BIG_ENDIAN = 1};
    74   virtual                   ~PPersist() {}
    75   virtual int_4              ClassId() const=0;
    76 
    77           void               Write(string const& fn) const;
    78           void               Read(string const& fn);
    79 
    80   virtual void               Write(POutPersist&) const;
    81           void               Read(PInPersist& s);  // Se lit, y compris le tag de type.
    82           int_4              Write(POutPersist&, int_4 key) const;
    83           int_4              Write(POutPersist&, int_4 key, string& nom) const;
    84           void               ReadAtTag(PInPersist& s, int_4 tagid);
    85           void               ReadAtKey(PInPersist& s, int_4 key);
    86 protected: 
    87   virtual void               ReadSelf(PInPersist&)=0;        // A redefinir...
    88   virtual void               WriteSelf(POutPersist&) const=0; // A redefinir...
    89 
    90   friend class               PPersistMgr;
    91 };
    92 
    93 class PShPersist : public PPersist{
    94 public:
    95                              PShPersist() :mObjectID(0) {}
    96   virtual                   ~PShPersist();
    97   virtual void               Write(POutPersist&) const;
    98   static PShPersist*         FindObject(int_4 objId);
    99  
    100 private:
    101   typedef map<int_4, PShPersist*, Int4Compare> ObjList;
    102 
    103   static ObjList*            objList;
    104   /*mutable*/ int_4          mObjectID;
    105   friend class               PPersistMgr;
    106   friend class               PeidaInitiator;
    107 };
    108 
    109 
    110 
    111 class PInPersist {
    112 public:
    113   PInPersist(string const& flnm, bool scan=true);
    114   ~PInPersist();
    115 
    116   bool   GotoTag(int_4 num);
    117   bool   GotoKey(int_4 key, int rang=0);
    118   int    NbKey(int_4 key);
    119   void   ListTags();
    120   inline int_4   NbTags() { return(mNTags); }
    121   int_4  TagKey(int_4 num, int_4& cid, int_4& ln);
    122   string TagName(int_4 num);
    123 
    124   void   GetByte (char& c);
    125   void   GetBytes(void* ptr, size_t bytes);
    126   void   GetR4   (r_4&);
    127   void   GetR4s  (r_4*, size_t);
    128   void   GetR8   (r_8&);
    129   void   GetR8s  (r_8*, size_t);
    130   void   GetI2   (int_2&);
    131   void   GetI2s  (int_2*, size_t);
    132   void   GetU2   (uint_2&);
    133   void   GetU2s  (uint_2*, size_t);
    134   void   GetI4   (int_4&);
    135   void   GetI4s  (int_4*, size_t);
    136   void   GetU4   (uint_4&);
    137   void   GetU4s  (uint_4*, size_t);
    138   void   GetI8   (int_8&);
    139   void   GetI8s  (int_8*, size_t);
    140   void   GetU8   (uint_8&);
    141   void   GetU8s  (uint_8*, size_t);
    142   void   GetLine (char* ptr, size_t len);
    143 
    144   void   Get(char&   c) {GetByte(c);}
    145   void   Get(r_4&    x) {GetR4(x);}
    146   void   Get(r_8&    x) {GetR8(x);}
    147   void   Get(uint_2& x) {GetU2(x);}
    148   void   Get(int_2&  x) {GetI2(x);}
    149   void   Get(uint_4& x) {GetU4(x);}
    150   void   Get(int_4&  x) {GetI4(x);}
    151   void   Get(uint_8& x) {GetU8(x);}
    152   void   Get(int_8&  x) {GetI8(x);}
    153   void   Get(r_4*    x, size_t n) {GetR4s(x,n);}
    154   void   Get(r_8*    x, size_t n) {GetR8s(x,n);}
    155   void   Get(uint_2* x, size_t n) {GetU2s(x,n);}
    156   void   Get(int_2*  x, size_t n) {GetI2s(x,n);}
    157   void   Get(uint_4* x, size_t n) {GetU4s(x,n);}
    158   void   Get(int_4*  x, size_t n) {GetI4s(x,n);}
    159   void   Get(uint_8* x, size_t n) {GetU8s(x,n);}
    160   void   Get(int_8*  x, size_t n) {GetI8s(x,n);}
    161 
    162   int    Version() {return version;}
    163   string CreationDate() { return creationdate; }
    164 
    165 protected:
    166   void      Scan();
    167   char*     GetCStr(uint_2 l);
    168 #ifdef RFIO
    169   erosifstream *s;
    170 #else
    171   istream* s;
    172 #endif
    173   int bigEndian;
    174   int version;
    175 
    176   string fName;
    177   string creationdate;
    178 
    179   struct PPFTag {
    180     int_8 popos;
    181     int_4 cid;
    182     int_4 key;
    183     uint_2 lnom;
    184     char* nom;
    185   };   
    186   PPFTag* mTags;
    187   int_4 mNTags;
    188   list<char*> mSbuffs;
    189   char* mSbuf;
    190   int mSbsz;
    191 };
    192 
    193 class POutPersist {
    194 public:
    195   POutPersist(string const& flnm, int endianness = PPersist::PPS_NATIVE);
    196   ~POutPersist();
    197 
    198   int_4 WriteTag(int_4 key, char const * name=NULL);
    199   void PutByte (char c);
    200   void PutBytes(void const* ptr, size_t bytes);
    201   void PutR4   (r_4);
    202   void PutR4s  (r_4 const*, size_t);
    203   void PutR8   (r_8);
    204   void PutR8s  (r_8 const*, size_t);
    205   void PutI2   (int_2);
    206   void PutI2s  (int_2 const*, size_t);
    207   void PutU2   (uint_2);
    208   void PutU2s  (uint_2 const*, size_t);
    209   void PutI4   (int_4);
    210   void PutI4s  (int_4 const*, size_t);
    211   void PutU4   (uint_4);
    212   void PutU4s  (uint_4 const*, size_t);
    213   void PutI8   (int_8);
    214   void PutI8s  (int_8 const*, size_t);
    215   void PutU8   (uint_8);
    216   void PutU8s  (uint_8 const*, size_t);
    217   void PutLine (char const* ptr, size_t len=0);
    218 
    219   void   Put(char   c) {PutByte(c);}
    220   void   Put(r_4    x) {PutR4(x);}
    221   void   Put(r_8    x) {PutR8(x);}
    222   void   Put(uint_2 x) {PutU2(x);}
    223   void   Put(int_2  x) {PutI2(x);}
    224   void   Put(uint_4 x) {PutU4(x);}
    225   void   Put(int_4  x) {PutI4(x);}
    226   void   Put(uint_8 x) {PutU8(x);}
    227   void   Put(int_8  x) {PutI8(x);}
    228   void   Put(r_4 const*    x, size_t n) {PutR4s(x,n);}
    229   void   Put(r_8 const*    x, size_t n) {PutR8s(x,n);}
    230   void   Put(uint_2 const* x, size_t n) {PutU2s(x,n);}
    231   void   Put(int_2 const*  x, size_t n) {PutI2s(x,n);}
    232   void   Put(uint_4 const* x, size_t n) {PutU4s(x,n);}
    233   void   Put(int_4 const*  x, size_t n) {PutI4s(x,n);}
    234   void   Put(uint_8 const* x, size_t n) {PutU8s(x,n);}
    235   void   Put(int_8 const*  x, size_t n) {PutI8s(x,n);}
    236 
    237 
    238 protected:
    239 #ifdef RFIO
    240   erosofstream *s;
    241 #else
    242   ostream* s;
    243 #endif
    244   int bigEndian;
    245   int_4 numTag;
    246   int_8 previous;
    247 };
    248 
    249 /*
    250 // Ceci est dangereux car un template a priorite sur un changement de type, meme trivial...
    251 
    252 template <class T>
    253 POutPersist& operator << (POutPersist& c, T const& data)
    254 {
    255   c.PutBytes(&data, sizeof(T));
    256   return c;
    257 }
    258 
    259 template <class T>
    260 PInPersist& operator >> (PInPersist& c, T& data)
    261 {
    262   c.GetBytes(&data, sizeof(T));
    263   return c;
    264 }
    265 */
    266 
     54
     55
     56
     57  // Ancestor for PInPersist and POutPersist
     58  // Handles (statically) the registration of classes.
     59
     60  class PIOPersist {
     61  public:
     62    enum                         {PPS_NATIVE = -1, PPS_LITTLE_ENDIAN = 0, PPS_BIG_ENDIAN = 1};
     63    typedef PPersist*            (*ClassCreatorFunc)();
     64 
     65    static void                  RegisterClass(uint_8 classId, ClassCreatorFunc f);
     66    static ClassCreatorFunc      FindCreatorFunc(uint_8 classId);
     67    static uint_8 Hash(string const& typname) {
     68        MD5Init(&ctx);
     69        MD5Update(&ctx, (unsigned char*) typname.c_str(), typname.size());
     70        MD5Final(&ctx);
     71        return ( *((uint_8*) ctx.digest) + *((uint_8*) (ctx.digest+8)));
     72    }
     73    static MD5_CTX ctx;
     74 
     75  private:
     76
     77    typedef map<uint_8, ClassCreatorFunc, less<uint_8> > ClassList; 
     78    static ClassList             classList;
     79
     80  protected:
     81    enum {PPS_NULL = 0,             // this is a null object
     82          PPS_STRING = 1,           // string, length (2b) + data
     83          PPS_OBJECT = 2,           // classId, data...
     84          PPS_REFERENCE = 3,        // objectId
     85          PPS_TAG = 4,              // tag entries
     86          PPS_EOF = 5,              // Just before tag infomation, offset to PPS_TAG
     87          PPS_LINE = 6,             // '\n'-terminated, deprecated ?
     88          PPS_SIMPLE = 16,          // 16 + number of bytes, up to 8 bytes
     89          PPS_SIMPLE_ARRAY = 32,    // 32 + number of bytes, up to 8 bytes, then 2 bytes of length
     90          PPS_SIMPLE_ARRAY4 = 64,   // 64 + number of bytes, up to 8 bytes, then 4 bytes of length
     91          PPS_SIMPLE_ARRAY8 = 128   // 64 + number of bytes, up to 8 bytes, then 8 bytes of length
     92   };
     93
     94    map<string, int_8> tags;
     95  };
     96
     97
     98  // TBD : use hash tables instead of maps. Check hashtbl status in STL.
     99
     100  class PInPersist : public PIOPersist {
     101  public:
     102    PInPersist(string const& flnm, bool scan=true);
     103    ~PInPersist();
     104
     105    bool   GotoTag(string const& name);
     106
     107    void   GetByte (char& c);
     108    void   GetBytes(void* ptr, size_t bytes);
     109    void   GetR4   (r_4&);
     110    void   GetR4s  (r_4*, size_t);
     111    void   GetR8   (r_8&);
     112    void   GetR8s  (r_8*, size_t);
     113    void   GetI2   (int_2&);
     114    void   GetI2s  (int_2*, size_t);
     115    void   GetU2   (uint_2&);
     116    void   GetU2s  (uint_2*, size_t);
     117    void   GetI4   (int_4&);
     118    void   GetI4s  (int_4*, size_t);
     119    void   GetU4   (uint_4&);
     120    void   GetU4s  (uint_4*, size_t);
     121    void   GetI8   (int_8&);
     122    void   GetI8s  (int_8*, size_t);
     123    void   GetU8   (uint_8&);
     124    void   GetU8s  (uint_8*, size_t);
     125    void   GetLine (char* ptr, size_t len);
     126    void   GetStr  (string&);
     127
     128    void   Get(char&   c) {GetByte(c);}
     129    void   Get(r_4&    x) {GetR4(x);}
     130    void   Get(r_8&    x) {GetR8(x);}
     131    void   Get(uint_2& x) {GetU2(x);}
     132    void   Get(int_2&  x) {GetI2(x);}
     133    void   Get(uint_4& x) {GetU4(x);}
     134    void   Get(int_4&  x) {GetI4(x);}
     135    void   Get(uint_8& x) {GetU8(x);}
     136    void   Get(int_8&  x) {GetI8(x);}
     137    void   Get(r_4*    x, size_t n) {GetR4s(x,n);}
     138    void   Get(r_8*    x, size_t n) {GetR8s(x,n);}
     139    void   Get(uint_2* x, size_t n) {GetU2s(x,n);}
     140    void   Get(int_2*  x, size_t n) {GetI2s(x,n);}
     141    void   Get(uint_4* x, size_t n) {GetU4s(x,n);}
     142    void   Get(int_4*  x, size_t n) {GetI4s(x,n);}
     143    void   Get(uint_8* x, size_t n) {GetU8s(x,n);}
     144    void   Get(int_8*  x, size_t n) {GetI8s(x,n);}
     145    void   Get(string& x) {GetStr(x);}
     146 
     147    PPersist*  ReadObject();
     148
     149
     150    int    Version() {return version;}
     151    time_t CreationDate() { return creationdate; }
     152
     153  protected:
     154    void   CheckTag   (short datasz);
     155    void   CheckArrayTag(short datasz, size_t sz);
     156    void   GetRawByte (char& c);
     157    void   GetRawBytes(void* ptr, size_t bytes);
     158    void   GetRawI2   (int_2&);
     159    void   GetRawI4   (int_4&);
     160    void   GetRawI8   (int_8&);
     161    void   GetRawU8   (uint_8&);
     162    void   GetObject(PPersist*);               // Object has been allocated with correct type
     163    int_4  assignObjectId(PPersist* x);
     164    void   Scan();
     165    char*  GetCStr(uint_2 l);
     166
     167    istream* s;
     168
     169    bool bigEndian;
     170    int version;
     171
     172    time_t creationdate;
     173
     174    // already read objects, id = order in array
     175    typedef vector<PPersist*> ObjList;
     176    ObjList objList;
     177
     178    friend class PPersist;
     179  };
     180
     181  class POutPersist : public PIOPersist {
     182  public:
     183    POutPersist(string const& flnm, int endianness = PPS_NATIVE);
     184    ~POutPersist();
     185
     186    void WriteTag(string const& name);
     187 
     188    void PutByte (char c);
     189    void PutBytes(void const* ptr, size_t bytes);
     190    void PutR4   (r_4);
     191    void PutR4s  (r_4 const*, size_t);
     192    void PutR8   (r_8);
     193    void PutR8s  (r_8 const*, size_t);
     194    void PutI2   (int_2);
     195    void PutI2s  (int_2 const*, size_t);
     196    void PutU2   (uint_2);
     197    void PutU2s  (uint_2 const*, size_t);
     198    void PutI4   (int_4);
     199    void PutI4s  (int_4 const*, size_t);
     200    void PutU4   (uint_4);
     201    void PutU4s  (uint_4 const*, size_t);
     202    void PutI8   (int_8);
     203    void PutI8s  (int_8 const*, size_t);
     204    void PutU8   (uint_8);
     205    void PutU8s  (uint_8 const*, size_t);
     206    void PutLine (char const* ptr, size_t len=0); // deprecated ?
     207    void PutStr  (string const&);
     208    void PutObject (PPersist const*); // Like doing Write(stream) on object
     209
     210    void   Put(char   c) {PutByte(c);}
     211    void   Put(r_4    x) {PutR4(x);}
     212    void   Put(r_8    x) {PutR8(x);}
     213    void   Put(uint_2 x) {PutU2(x);}
     214    void   Put(int_2  x) {PutI2(x);}
     215    void   Put(uint_4 x) {PutU4(x);}
     216    void   Put(int_4  x) {PutI4(x);}
     217    void   Put(uint_8 x) {PutU8(x);}
     218    void   Put(int_8  x) {PutI8(x);}
     219    void   Put(r_4 const*    x, size_t n) {PutR4s(x,n);}
     220    void   Put(r_8 const*    x, size_t n) {PutR8s(x,n);}
     221    void   Put(uint_2 const* x, size_t n) {PutU2s(x,n);}
     222    void   Put(int_2 const*  x, size_t n) {PutI2s(x,n);}
     223    void   Put(uint_4 const* x, size_t n) {PutU4s(x,n);}
     224    void   Put(int_4 const*  x, size_t n) {PutI4s(x,n);}
     225    void   Put(uint_8 const* x, size_t n) {PutU8s(x,n);}
     226    void   Put(int_8 const*  x, size_t n) {PutI8s(x,n);}
     227    void   Put(string const& s) {PutStr(s);}
     228    void   Put(PPersist const* x) {PutObject(x);}
     229
     230
     231  protected:
     232    ostream* s;
     233    bool bigEndian;
     234
     235    void     PutArrayTag(short datasz, size_t sz);
     236    void     PutRawByte (char);
     237    void     PutRawI2   (int_2);
     238    void     PutRawI4   (int_4);
     239    void     PutRawI8   (int_8);
     240    void     PutRawU8   (uint_8);
     241    void     PutRawBytes(void const* ptr, size_t bytes);
     242    bool     serializeNullAndRepeat(PPersist const* x);
     243    int_4    findObjectId(PPersist const* x);
     244    int_4    assignObjectId(PPersist const* x);
     245
     246    // already serialized objects
     247    typedef map<PPersist const*, int_4, less<PPersist const*> >  ObjList;
     248    ObjList objList;
     249  };
     250 
     251 
    267252#define RAWPERSISTIO(_Type_,_xtyp_)                                             \
    268 inline POutPersist& operator << (POutPersist& c, _Type_ const& data)            \
    269 {                                                                               \
    270   c.Put##_xtyp_(data);                                                        \
    271   return c;                                                                     \
    272 }                                                                               \
     253  inline POutPersist& operator << (POutPersist& c, _Type_ const& data)            \
     254  {                                                                               \
     255    c.Put##_xtyp_(data);                                                          \
     256    return c;                                                                     \
     257  }                                                                               \
    273258                                                                                \
    274 inline PInPersist& operator >> (PInPersist& c, _Type_& data)                    \
    275 {                                                                               \
    276   c.Get##_xtyp_(data);                                                        \
    277   return c;                                                                     \
    278 }                                                                               
    279 
    280 RAWPERSISTIO(int_4,I4)
    281 RAWPERSISTIO(uint_4,U4)
    282 RAWPERSISTIO(int_2,I2)
    283 RAWPERSISTIO(uint_2,U2)
    284 RAWPERSISTIO(char,Byte)
    285 RAWPERSISTIO(r_4,R4)
    286 RAWPERSISTIO(r_8,R8)
    287 
     259  inline PInPersist& operator >> (PInPersist& c, _Type_& data)                    \
     260  {                                                                               \
     261    c.Get##_xtyp_(data);                                                          \
     262    return c;                                                                     \
     263  }                                                                               
     264
     265  RAWPERSISTIO(int_4,I4);
     266  RAWPERSISTIO(uint_4,U4);
     267  RAWPERSISTIO(int_2,I2);
     268  RAWPERSISTIO(uint_2,U2);
     269  RAWPERSISTIO(char,Byte);
     270  RAWPERSISTIO(r_4,R4);
     271  RAWPERSISTIO(r_8,R8);
     272 
    288273#if 0
    289274#define STRUCTPERSISTIO(_Type_, _field_, _size_)                                \
    290 inline POutPersist& operator << (POutPersist& c, _Type_ const& data)            \
    291 {                                                                               \
    292   c.PutBytes(&data._field_, _size_);                                            \
    293   return c;                                                                     \
    294 }                                                                               \
     275  inline POutPersist& operator << (POutPersist& c, _Type_ const& data)            \
     276  {                                                                               \
     277    c.PutBytes(&data._field_, _size_);                                            \
     278    return c;                                                                     \
     279  }                                                                               \
    295280                                                                                \
    296 inline PInPersist& operator >> (PInPersist& c, _Type_& data)                    \
    297 {                                                                               \
    298   c.GetBytes(&data._field_, _size_);                                            \
    299   return c;                                                                     \
    300 }                                                                               
     281  inline PInPersist& operator >> (PInPersist& c, _Type_& data)                    \
     282  {                                                                               \
     283    c.GetBytes(&data._field_, _size_);                                            \
     284    return c;                                                                     \
     285  }                                                                               
    301286
    302287#endif
    303 
    304 inline POutPersist& operator << (POutPersist& c, PPersist const& obj)
    305 {
    306   obj.Write(c);
    307   return c;
    308 }
    309 
    310 inline PInPersist& operator >> (PInPersist& c, PPersist& obj)
    311 {
    312   obj.Read(c);
    313   return c;
    314 }
    315 
    316 // Fabrication de fonction Create automatique, et enregistrement...
    317 template <class T>
    318 class PPersistRegistrar {
    319 public:
    320   static PPersist* Create() {return new T();}
    321   static void Register() {PPersistMgr::RegisterClass(T::classId,Create);}
    322 };
    323 
     288 
     289  inline POutPersist& operator << (POutPersist& c, PPersist const& obj)
     290    {
     291      obj.Write(c);
     292      return c;
     293    }
     294 
     295  inline PInPersist& operator >> (PInPersist& c, PPersist& obj)
     296    {
     297      obj.Read(c);
     298      return c;
     299    }
     300 
     301  // Utility class to
     302  //   - compute the class ID from a MD5 hash of the class name
     303  //   - register classes with PIOPersist, through PPRegister macro
     304 
     305  template <class T>
     306    class PPersistRegistrar {
     307    public:
     308      static PPersist* Create() {return new T();}
     309      static void Register() {PIOPersist::RegisterClass(Hash(),Create);}
     310      static uint_8 Hash() {
     311        return PIOPersist::Hash(typeid(T).name());
     312      }
     313    };
     314 
    324315#define PPRegister(className) PPersistRegistrar<className>::Register();
     316 
     317} // namespace
    325318
    326319#endif
Note: See TracChangeset for help on using the changeset viewer.