00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00041 #ifndef BASE_OTRAV_H
00042 #define BASE_OTRAV_H
00043 
00044 #include "fastlib/base/common.h"
00045 #include "fastlib/base/debug.h"
00046 #include "fastlib/base/cc.h"
00047 #include "fastlib/base/ccmem.h"
00048 
00049 #include <typeinfo>
00050 
00086 #define OT_CUSTOM_PRINT_OBJ(x, name) \
00087     if (true) { \
00088       ot__visitor->Name(name, x); \
00089       ot__visitor->Obj(x); \
00090     } else NOP // require semicolon
00091 
00124 #define OT_OBJ(x) \
00125     OT_CUSTOM_PRINT_OBJ(x, #x)
00126 
00135 #define OT_ENUM_VAL(val) \
00136    case val: \
00137     if (ot__visitor->IS_PRINTER) { \
00138       const char *ot__temp = #val; \
00139       ot__visitor->Obj(ot__temp); \
00140       break; \
00141     } // fall-through to default inside OT_ENUM_EXPERT
00142 
00143 
00144 
00145 
00146 
00147 
00197 #define OT_ENUM_EXPERT(x, T, print_code) \
00198     if (true) { \
00199       ot__visitor->Name(#x, x); \
00200       switch (x) { \
00201         print_code \
00202        default: \
00203         ot__visitor->Enum(x); \
00204       } \
00205     } else NOP // require semicolon
00206 
00220 #define OT_ENUM(x) \
00221     OT_ENUM_EXPERT(x, int, )
00222 
00241 #define OT_ARRAY_IMPL(x, len, iter_var, loop_code, func, args...) \
00242     if (true) { \
00243       ot__visitor->Name(#x, x); \
00244       index_t ot__len = len; \
00245       if (ot__visitor->Pre##func(x, ot__len, ## args)) { \
00246         for (index_t iter_var = 0; iter_var < ot__len; ++iter_var) { \
00247           ot__visitor->ElemOf(x); \
00248           loop_code; \
00249         } \
00250         ot__visitor->Name(#x, x); \
00251         ot__visitor->Post##func(x, ot__len, ## args); \
00252       } \
00253     } else NOP // require semicolon
00254 
00279 #define OT_STATIC_ARRAY_EXPERT(x, iter_var, elem_code) \
00280     OT_ARRAY_IMPL(x, sizeof(x) / sizeof(*x), \
00281         iter_var, elem_code, StaticArray)
00282 
00294 #define OT_STATIC_ARRAY(x) \
00295     OT_STATIC_ARRAY_EXPERT(x, ot__iter, OT_OBJ((x)[ot__iter]))
00296 
00325 #define OT_PTR_EXPERT(x, nullable, deref_code) \
00326     OT_ARRAY_IMPL(x, 1, ot__iter, deref_code, \
00327         Array, nullable, false, true)
00328 
00343 #define OT_PTR(x) \
00344     OT_PTR_EXPERT(x, true, OT_OBJ(*(x)))
00345 
00390 #define OT_ARRAY_EXPERT(x, len, nullable, iter_var, elem_code) \
00391     OT_ARRAY_IMPL(x, len, iter_var, elem_code, \
00392         Array, nullable, false, false)
00393 
00412 #define OT_ARRAY(x, len) \
00413     OT_ARRAY_EXPERT(x, len, true, ot__iter, OT_OBJ((x)[ot__iter]))
00414 
00447 #define OT_ALLOC_EXPERT(x, len, nullable, iter_var, elem_code) \
00448     OT_ARRAY_IMPL(x, len, iter_var, elem_code, \
00449         Array, nullable, true, false)
00450 
00466 #define OT_ALLOC(x, len) \
00467     OT_ALLOC_EXPERT(x, len, true, ot__iter, OT_OBJ((x)[ot__iter]))
00468 
00500 #define OT_STR_EXPERT(x, nullable, alloc) \
00501     if (true) { \
00502       ot__visitor->Name(#x, x); \
00503       ot__visitor->Str(x, nullable, alloc); \
00504     } else NOP // require semicolon
00505 
00516 #define OT_STR(x) \
00517     OT_STR_EXPERT(x, true, true)
00518 
00519 
00520 
00532 #define OT_CONSTRUCTOR(C) \
00533    public: \
00534     C() { \
00535       ot__private::Unstructor ot__unstructor(this); \
00536       OT__DefaultConstruct(this); \
00537     } \
00538    private:
00539 
00550 #define OT_DESTRUCTOR(C) \
00551    public: \
00552     ~C() { \
00553       DEBUG_DESTRUCT_OK(this); \
00554       ot__private::Destructor<false> ot__destructor(this); \
00555     } \
00556    private:
00557 
00571 #define OT_COPY_CONSTRUCTOR(C) \
00572    public: \
00573     C(const C &src) { \
00574       ot__private::Copier<false> ot__copier(this, &src); \
00575     } \
00576     ASSIGN_VIA_RECURSION_SAFE_COPY_CONSTRUCTION(C) \
00577    private:
00578 
00592 #define OT_DEPRECATED_COPY_CONSTRUCTOR(C) \
00593    public: \
00594     COMPILER_DEPRECATED \
00595     C(const C &src) { \
00596       ot__private::Copier<false> ot__copier(this, &src); \
00597     } \
00598     ASSIGN_VIA_RECURSION_SAFE_COPY_CONSTRUCTION(C) \
00599    private:
00600 
00601 
00602 
00615 #define OT_RENEW_METHOD(C) \
00616    public: \
00617     void Renew() { \
00618       this->~C(); \
00619       new(this) C(); \
00620     } \
00621    private:
00622 
00635 #define OT_COPY_METHOD(C) \
00636    public: \
00637     void InitCopy(const C &src) { \
00638       ot::InitCopy(this, src); \
00639     } \
00640     COMPILER_DEPRECATED \
00641     void Copy(const C &src) { \
00642       ot::InitCopy(this, src); \
00643     } \
00644    private:
00645 
00658 #define OT_PRINT_METHOD(C) \
00659    public: \
00660     template<typename TPrintFormat> \
00661     const char *Print(const char *name, FILE *stream = stdout) { \
00662       return ot::Print<TPrintFormat>(*this, name, stream); \
00663     } \
00664     const char *Print(const char *name, FILE *stream = stdout) { \
00665       return Print<ot::StandardFormat>(name, stream); \
00666     } \
00667    private:
00668 
00669 
00670 
00680 #define OT_FREEZE_METHODS(C) \
00681    public: \
00682     size_t FrozenSize() { \
00683       return ot::FrozenSize(*this); \
00684     } \
00685     size_t Freeze(char *block) { \
00686       return ot::Freeze(block, *this); \
00687     } \
00688     void InitThaw(char *block) { \
00689       ot::InitThaw(this, block); \
00690     } \
00691    private:
00692 
00704 #define OT_SERIALIZE_METHODS(C) \
00705    public: \
00706     size_t SerialSize() { \
00707       return ot::SerialSize(*this); \
00708     } \
00709     size_t Serialize(FILE *stream) { \
00710       return ot::Serialize(*this, stream); \
00711     } \
00712     size_t InitDeserialize(FILE *stream) { \
00713       return ot::InitDeserialize(this, stream); \
00714     } \
00715    private:
00716 
00717 
00718 
00739 #define OT_BECOME_NON_ALIAS(C) \
00740    public: \
00741     friend void OT__BecomeNonAlias(C *ot__obj) { \
00742       ot__obj->OT__BecomeNonAlias_(); \
00743       DEBUG_ASSERT_MSG(!OT__IsAlias(ot__obj), \
00744           "OT_BECOME_NON_ALIAS left OT_IS_ALIAS true for %s.", \
00745           typeid(C).name()); \
00746     } \
00747    private: \
00748     void OT__BecomeNonAlias_()
00749 
00765 #define OT_BECOME_ALIAS(C) \
00766    public: \
00767     friend bool OT__Aliasable(const C *ot__obj) { \
00768       return true; \
00769     } \
00770     friend void OT__BecomeAlias(C *ot__obj) { \
00771       ot__obj->OT__BecomeAlias_(); \
00772       DEBUG_ASSERT_MSG(OT__IsAlias(ot__obj), \
00773           "OT_BECOME_ALIAS left OT_IS_ALIAS false for %s.", \
00774           typeid(C).name()); \
00775     } \
00776    private: \
00777     void OT__BecomeAlias_()
00778 
00795 #define OT_IS_ALIAS(C) \
00796    public: \
00797     friend bool OT__IsAlias(C *ot__obj) { \
00798       return ot__obj->OT__IsAlias_(); \
00799     } \
00800    private: \
00801     bool OT__IsAlias_()
00802 
00852 #define OT_ALIAS_METHODS(C) \
00853    public: \
00854     void InitAlias(const C &src) { \
00855       DEBUG_INIT_OK(this); \
00856       mem::Copy(this, &src); \
00857       ot__private::Aliaser ot__aliaser(this); \
00858     } \
00859     void InitSteal(C *src) { \
00860       DEBUG_INIT_OK(this); \
00861       DEBUG_WARN_MSG_IF(OT__IsAlias(src), \
00862           "Stealing from an alias %s.", typeid(C).name()); \
00863       mem::Copy(this, src); \
00864       ot__private::Aliaser ot__aliaser(src); \
00865     } \
00866     bool IsAlias() { \
00867       return OT__IsAlias(this); \
00868     } \
00869    private:
00870 
00871 
00872 
00909 #define OT_DEFAULT_CONSTRUCT(C) \
00910    public: \
00911     friend void OT__DefaultConstruct(C *ot__obj) { \
00912       ot__obj->OT__DefaultConstruct_(); \
00913     } \
00914    private: \
00915     void OT__DefaultConstruct_()
00916 
00957 #define OT_DEBUG_INIT_OK(C) \
00958    public: \
00959     friend bool OT__DebugInitOK(C *ot__obj) { \
00960       return ot__obj->OT__DebugInitOK_(); \
00961     } \
00962    private: \
00963     bool OT__DebugInitOK_()
00964 
00977 #define DEBUG_INIT_OK(x) \
00978     DEBUG_ASSERT_MSG(OT__DebugInitOK(x), \
00979         "Reinitialization of %s; missing Renew()?", \
00980         typeid(*x).name());
00981 
01015 #define OT_DEBUG_MODIFY_OK(C) \
01016    public: \
01017     friend bool OT__DebugModifyOK(C *ot__obj) { \
01018       return ot__obj->OT__DebugModifyOK_(); \
01019     } \
01020    private: \
01021     bool OT__DebugModifyOK_()
01022 
01036 #define DEBUG_MODIFY_OK(x) \
01037     DEBUG_ASSERT_MSG(OT__DebugModifyOK(x), \
01038         "Modification of alias/locked %s; missing Init?", \
01039         typeid(*x).name());
01040 
01071 #define OT_DEBUG_DESTRUCT_OK(x) \
01072    public: \
01073     friend bool OT__DebugDestructOK(C *ot__obj) { \
01074       return ot__obj->OT__DebugDestructOK_(); \
01075     } \
01076    private: \
01077     bool OT__DebugDestructOK_()
01078 
01089 #define DEBUG_DESTRUCT_OK(x) \
01090     DEBUG_ASSERT_MSG(OT__DebugDestructOK(x), \
01091         "Premature destruction of %s; missing Init?", \
01092         typeid(*x).name());
01093 
01094 
01095 
01135 #define OT_REFILL_TRANSIENTS(C) \
01136    public: \
01137     friend void OT__RefillTransients(C *ot__obj) { \
01138       OT__BecomeNonAlias(ot__obj); \
01139       ot__obj->OT__RefillTransients_(); \
01140     } \
01141    private: \
01142     void OT__RefillTransients_()
01143 
01184 #define OT_TRANSIENTS(C) \
01185    public: \
01186     template<typename TVisitor> \
01187     friend void OT__TraverseTransients(C *ot__obj, TVisitor *ot__visitor) { \
01188       ot__obj->OT__TraverseTransients_(ot__visitor); \
01189     } \
01190    private: \
01191     template<typename TVisitor> \
01192     void OT__TraverseTransients_(TVisitor *ot__visitor)
01193 
01194 
01195 
01209 #define OBJECT_TRAVERSAL_ONLY(C) \
01210    public: \
01211     template<typename TVisitor> \
01212     friend bool OT__PreTraverse(C *ot__dest, const C *ot__src, \
01213                                 index_t ot__len, TVisitor *ot__visitor) { \
01214       return ot__visitor->PreTraverse(ot__dest, ot__src, ot__len); \
01215     } \
01216     template<typename TVisitor> \
01217     friend void OT__TraverseObject(C *ot__obj, TVisitor *ot__visitor) { \
01218       ot__obj->OT__TraverseObject_(ot__visitor); \
01219     } \
01220    private: \
01221     template<typename TVisitor> \
01222     void OT__TraverseObject_(TVisitor *ot__visitor)
01223 
01239 #define OBJECT_TRAVERSAL_CORE(C) \
01240     OT_RENEW_METHOD(C) \
01241     OT_COPY_METHOD(C) \
01242     OT_PRINT_METHOD(C) \
01243     OBJECT_TRAVERSAL_ONLY(C)
01244 
01311 #define OBJECT_TRAVERSAL(C) \
01312     OT_CONSTRUCTOR(C) \
01313     OT_DESTRUCTOR(C) \
01314     OT_COPY_CONSTRUCTOR(C) \
01315     OBJECT_TRAVERSAL_CORE(C)
01316 
01329 #define OBJECT_TRAVERSAL_NO_COPIES(C) \
01330     OT_CONSTRUCTOR(C) \
01331     OT_DESTRUCTOR(C) \
01332     FORBID_ACCIDENTAL_COPIES(C) \
01333     OBJECT_TRAVERSAL_CORE(C)
01334 
01349 #define OBJECT_TRAVERSAL_DEPRECATED_COPIES(C) \
01350     OT_CONSTRUCTOR(C) \
01351     OT_DESTRUCTOR(C) \
01352     OT_DEPRECATED_COPY_CONSTRUCTOR(C) \
01353     OBJECT_TRAVERSAL_CORE(C)
01354 
01380 #define OBJECT_TRAVERSAL_SHALLOW(C) \
01381    public: \
01382     C() { \
01383       mem::DebugPoison(this); \
01384     } \
01385     ~C() { \
01386       DEBUG_DESTRUCT_OK(this); \
01387       mem::DebugPoison(this); \
01388     } \
01389     friend bool OT__Shallow(const C *ot__obj) { \
01390       return true; \
01391     } \
01392    private: \
01393     OT_IS_ALIAS(C) { return false; } \
01394     OT_DEFAULT_CONSTRUCT(C) {} \
01395     OT_REFILL_TRANSIENTS(C) {} \
01396     OT_TRANSIENTS(C) {} \
01397     OBJECT_TRAVERSAL_CORE(C)
01398 
01399 
01400 
01430 #define OT_CUSTOM_PRINT(C) \
01431    private: \
01432     template<typename TPrintFormat> \
01433     void OT__TraverseObject_(ot__private::Printer<TPrintFormat> *ot__visitor)
01434 
01481 #define OT_CUSTOM_DESTRUCT(C) \
01482    private: \
01483     template<bool t_semi> \
01484     void OT__TraverseObject_(ot__private::Destructor<t_semi> *ot__visitor)
01485 
01486 
01487 
01488 #define NEED_OTRAV_IMPL
01489 #include "fastlib/base/otrav_impl.h"
01490 #undef NEED_OTRAV_IMPL
01491 
01492 
01493 
01516 namespace ot {
01554   template<typename TPrintFormat, typename T>
01555   const char *Print(const T &obj, const char *name, FILE *stream = stdout) {
01556     ot__private::Printer<TPrintFormat> ot__printer(obj, name, stream);
01557     return name;
01558   }
01559   template<typename TPrintFormat, typename T>
01560   void Print(const T &obj, FILE *stream = stdout) {
01561     ot__private::Printer<TPrintFormat> ot__printer(obj, "_", stream);
01562   }
01563 
01580   template<typename T>
01581   const char *Print(const T &obj, const char *name, FILE *stream = stdout) {
01582     return Print<ot::StandardFormat>(obj, name, stream);
01583   }
01584   template<typename T>
01585   void Print(const T &obj, FILE *stream = stdout) {
01586     Print<ot::StandardFormat>(obj, stream);
01587   }
01588 
01589 
01590 
01608   template<typename T>
01609   inline void InitCopy(T *dest, const T &src) {
01610     DEBUG_INIT_OK(dest);
01611     ot__private::Copier<false> ot__copier(dest, &src);
01612   }
01613 
01614 
01615 
01625   template<typename T>
01626   inline size_t FrozenSize(const T &obj) {
01627     ot__private::Freezer<true> ot__freezer(NULL, obj);
01628     return ot__freezer.size();
01629   }
01630 
01698   template<typename T>
01699   inline size_t Freeze(char *block, const T &src) {
01700     ot__private::Freezer<false> ot__freezer(block, src);
01701     return ot__freezer.size();
01702   }
01703 
01714   template<typename T>
01715   inline void InitThaw(T *dest, const char *block) {
01716     DEBUG_INIT_OK(dest);
01717     ot__private::Copier<true> 
01718         ot__copier(dest, reinterpret_cast<const T *>(block));
01719   }
01720 
01721 
01722 
01735   template<typename T>
01736   inline T *SemiCopy(char *block, const T *orig) {
01737     DEBUG_WARN_MSG_IF(block == reinterpret_cast<const char *>(orig),
01738         "In-place SemiCopy may leak memory; probably incorrect.");
01739     ot__private::Relocator<false, true> ot__relocator(block, orig);
01740     return reinterpret_cast<T *>(block);
01741   }
01742   template<typename T>
01743   inline T *SemiCopy(char *block, const char *orig) {
01744     return SemiCopy(block, reinterpret_cast<const T *>(orig));
01745   }
01746 
01773   template<typename T>
01774   inline void SemiFreeze(char *block, const T *orig) {
01775     DEBUG_WARN_MSG_IF(block == reinterpret_cast<const char *>(orig),
01776         "In-place SemiFreeze may leak memory; use SemiFreezeDestruct.");
01777     ot__private::Relocator<true, false> ot__relocator(block, orig);
01778   }
01779   template<typename T>
01780   void SemiFreeze(char *block, const char *orig) {
01781     SemiFreeze(block, reinterpret_cast<const T *>(orig));
01782   }
01783 
01795   template<typename T>
01796   inline T *SemiThaw(char *block) {
01797     return SemiCopy(block, reinterpret_cast<const T *>(NULL));
01798   }
01799 
01808   template<typename T>
01809   inline void SemiDestruct(T *obj) {
01810     ot__private::Destructor<true> ot__destructor(obj);
01811   }
01812   template<typename T>
01813   inline void SemiDestruct(char *block) {
01814     SemiDestruct(reinterpret_cast<T *>(block));
01815   }
01816 
01825   template<typename T>
01826   inline char *SemiFreezeDestruct(T *obj) {
01827     ot__private::Relocator<true, true>
01828         ot__relocator(reinterpret_cast<char *>(obj), obj);
01829     return reinterpret_cast<char *>(obj);
01830   }
01831   template<typename T>
01832   inline char *SemiFreezeDestruct(char *block) {
01833     return SemiFreezeDestruct(reinterpret_cast<T *>(block));
01834   }
01835 
01836 
01837 
01847   template<typename T>
01848   inline size_t SerialSize(const T &obj) {
01849     ot__private::Serializer<true> ot__serializer(obj, NULL);
01850     return ot__serializer.size();
01851   }
01852 
01880   template<typename T>
01881   inline size_t Serialize(const T &obj, FILE *stream) {
01882     ot__private::Serializer<false> ot__serializer(obj, stream);
01883     return ot__serializer.size();
01884   }
01885 
01904   template<typename T>
01905   inline size_t InitDeserialize(T *dest, FILE *stream) {
01906     DEBUG_INIT_OK(dest);
01907     ot__private::Deserializer ot__deserializer(dest, stream);
01908     return ot__deserializer.size();
01909   }
01910 
01911 
01912 
01917   template<typename T>
01918   inline T *Construct(T *array, size_t elems = 1) {
01919     if (OT__ShallowOrPtr(array)) {
01920       return mem::DebugPoison(array, elems);
01921     } else {
01922       return mem::Construct(array, elems);
01923     }
01924   }
01925 
01930   template<typename T>
01931   inline T *Destruct(T *array, size_t elems = 1) {
01932     if (OT__ShallowOrPtr(array)) {
01933       return mem::DebugPoison(array, elems);
01934     } else {
01935       return mem::Destruct(array, elems);
01936     }
01937   }
01938 
01947   template<typename T>
01948   inline T *CopyConstruct(T *dest, const T *src, size_t elems = 1) {
01949     ot__private::Copier<false> ot__copier(dest, src, elems);
01950     return dest;
01951   }
01952 
01960   template<typename T>
01961   inline T *RepeatConstruct(T *array, const T &init, size_t elems) {
01962     for (size_t i = 0; i < elems; ++i) {
01963       ot__private::Copier<false> ot__copier(array + i, &init);
01964     }
01965     return array;
01966   }
01967 
01969 
01971   template<typename T>
01972   COMPILER_DEPRECATED
01973   void Copy(const T &src, T *dest) {
01974     InitCopy(dest, src);
01975   }
01976 
01978   template<typename T>
01979   COMPILER_DEPRECATED
01980   size_t PointerFrozenSize(const T &obj) {
01981     return FrozenSize(obj);
01982   }
01983 
01985   template<typename T>
01986   COMPILER_DEPRECATED
01987   void PointerFreeze(const T &obj, char *block) {
01988     Freeze(block, obj);
01989   }
01990 
01992   template<typename T>
01993   COMPILER_DEPRECATED
01994   void PointerRefreeze(const T *src, char *dest) {
01995     SemiFreeze(dest, src);
01996   }
01997 
01999   template<typename T>
02000   COMPILER_DEPRECATED
02001   T *PointerThaw(char *block) {
02002     return SemiThaw<T>(block);
02003   }
02004 
02006   template<typename T>
02007   COMPILER_DEPRECATED
02008   void PointerRelocate(const char *old_loc, char *new_loc) {
02009     
02010 
02011 
02012 
02013 
02014 
02015     
02016     SemiCopy<T>(new_loc, old_loc);
02017   }
02018 };
02019 
02021 
02022 #define OT_MY_OBJECT OT_OBJ
02023 #define OT_MY_ARRAY OT_STATIC_ARRAY
02024 #define OT_MALLOC_ARRAY OT_ALLOC
02025 #define OT_PTR_NULLABLE OT_PTR
02026 
02027 #define OT_FIX OT_REFILL_TRANSIENTS
02028 
02029 #define OT_DEF OBJECT_TRAVERSAL
02030 #define OT_DEF_BASIC OBJECT_TRAVERSAL
02031 
02032 #endif