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