Object traversal utilities for printing, copying, freezing, and serialization. More...
Functions | |
template<typename T > | |
T * | Construct (T *array, size_t elems=1) |
Equivalent to mem::Construct, but exploits properties of shallow types. | |
template<typename T > | |
COMPILER_DEPRECATED void | Copy (const T &src, T *dest) |
Renamed InitCopy. | |
template<typename T > | |
T * | CopyConstruct (T *dest, const T *src, size_t elems=1) |
Equivalent to mem::CopyConstruct, but exploits properties of shallow types and does not require a copy constructor to be defined for traversed types. | |
template<typename T > | |
T * | Destruct (T *array, size_t elems=1) |
Equivalent to mem::Destruct, but exploits properties of shallow types. | |
template<typename T > | |
size_t | Freeze (char *block, const T &src) |
Copy an object's contents into flat buffer for easy transport, normalizing pointers to offsets into the buffer for fast reuse. | |
template<typename T > | |
size_t | FrozenSize (const T &obj) |
Determine the buffer size needed to store a frozen copy of an object. | |
template<typename T > | |
void | InitCopy (T *dest, const T &src) |
Copy an object into a specified destination. | |
template<typename T > | |
size_t | InitDeserialize (T *dest, FILE *stream) |
Read a serialized version of an object from a file stream, reconstructing its transients. | |
template<typename T > | |
void | InitThaw (T *dest, const char *block) |
Copy from a frozen object into a specified destination. | |
template<typename T > | |
COMPILER_DEPRECATED void | PointerFreeze (const T &obj, char *block) |
Renamed Freeze. | |
template<typename T > | |
COMPILER_DEPRECATED size_t | PointerFrozenSize (const T &obj) |
Renamed FrozenSize. | |
template<typename T > | |
COMPILER_DEPRECATED void | PointerRefreeze (const T *src, char *dest) |
Renamed SemiFreeze. | |
template<typename T > | |
COMPILER_DEPRECATED void | PointerRelocate (const char *old_loc, char *new_loc) |
Behavior similar to SemiCopy; beware memory leaks. | |
template<typename T > | |
COMPILER_DEPRECATED T * | PointerThaw (char *block) |
Renamed SemiThaw. | |
template<typename T > | |
void | Print (const T &obj, FILE *stream=stdout) |
template<typename T > | |
const char * | Print (const T &obj, const char *name, FILE *stream=stdout) |
Pretty-print an object using the standard print format. | |
template<typename TPrintFormat , typename T > | |
void | Print (const T &obj, FILE *stream=stdout) |
template<typename TPrintFormat , typename T > | |
const char * | Print (const T &obj, const char *name, FILE *stream=stdout) |
Pretty-print an object using a given print format. | |
template<typename T > | |
T * | RepeatConstruct (T *array, const T &init, size_t elems) |
Equivalent to mem::RepeatConstruct, but does not require a copy constructor to be defined for traversed types. | |
template<typename T > | |
T * | SemiCopy (char *block, const char *orig) |
template<typename T > | |
T * | SemiCopy (char *block, const T *orig) |
Fixes the pointers and reconstructs transients of a semi-object assuming it has already been bit-copied into a new location. | |
template<typename T > | |
void | SemiDestruct (char *block) |
template<typename T > | |
void | SemiDestruct (T *obj) |
Destructs a semi-object's transients and debug-poisons its memory. | |
template<typename T > | |
void | SemiFreeze (char *block, const char *orig) |
template<typename T > | |
void | SemiFreeze (char *block, const T *orig) |
Re-freezes a semi-object assuming it has already been bit-copied into a new location. | |
template<typename T > | |
char * | SemiFreezeDestruct (char *block) |
template<typename T > | |
char * | SemiFreezeDestruct (T *obj) |
Re-freezes a semi-object and destructs its transients. | |
template<typename T > | |
T * | SemiThaw (char *block) |
Thaws a frozen object by fixing pointers and reconstructing transients. | |
template<typename T > | |
size_t | Serialize (const T &obj, FILE *stream) |
Write a serialized version of an object to a file stream. | |
template<typename T > | |
size_t | SerialSize (const T &obj) |
Determine the length in bytes of a serialized version of an object. |
Object traversal utilities for printing, copying, freezing, and serialization.
These tools operate on all classes that invoke the OBJECT_TRAVERSAL macro or an equivalent, which includes all core FASTlib data structures. Specifically, they provide:
You can incorporate many of these functions as methods of your class with the OT_FREEZE_METHODS and OT_SERIALIZE_METHODS macors. Default OBJECT_TRAVERSAL already gives your class Print and InitCopy methods.
T * ot::Construct | ( | T * | array, | |
size_t | elems = 1 | |||
) | [inline] |
Equivalent to mem::Construct, but exploits properties of shallow types.
Definition at line 1918 of file otrav.h.
References mem::DebugPoison().
Referenced by ArrayList< std::pair< index_t, index_t > >::GrowTo(), ArrayList< std::pair< index_t, index_t > >::Init(), ArrayList< std::pair< index_t, index_t > >::Insert(), and ArrayList< std::pair< index_t, index_t > >::PushBack().
COMPILER_DEPRECATED void ot::Copy | ( | const T & | src, | |
T * | dest | |||
) | [inline] |
T * ot::CopyConstruct | ( | T * | dest, | |
const T * | src, | |||
size_t | elems = 1 | |||
) | [inline] |
Equivalent to mem::CopyConstruct, but exploits properties of shallow types and does not require a copy constructor to be defined for traversed types.
Note the absense of DEBUG_INIT_OK. This ensures that this function works on arrays of unconstructed objects.
Definition at line 1948 of file otrav.h.
Referenced by ArrayList< std::pair< index_t, index_t > >::AppendCopy(), ArrayList< std::pair< index_t, index_t > >::InfixCopy(), ArrayList< std::pair< index_t, index_t > >::InitCopy(), ArrayList< std::pair< index_t, index_t > >::InsertCopy(), and ArrayList< std::pair< index_t, index_t > >::PushBackCopy().
T * ot::Destruct | ( | T * | array, | |
size_t | elems = 1 | |||
) | [inline] |
Equivalent to mem::Destruct, but exploits properties of shallow types.
Definition at line 1931 of file otrav.h.
References mem::DebugPoison().
Referenced by ArrayList< std::pair< index_t, index_t > >::Clear(), ArrayList< std::pair< index_t, index_t > >::PopBack(), ArrayList< std::pair< index_t, index_t > >::Remove(), and ArrayList< std::pair< index_t, index_t > >::ShrinkTo().
size_t ot::Freeze | ( | char * | block, | |
const T & | src | |||
) | [inline] |
Copy an object's contents into flat buffer for easy transport, normalizing pointers to offsets into the buffer for fast reuse.
Freezing is the prefered method for transmitting objects from machine to machine, storing them in temporary files, and other situations where speed is favored over efficient use of space. The primary advantage over rote serialization is that ot::SemiThaw permits (formerly) frozen objects to be used in-place. There is no need to allocate memory separately from the buffer holding the semi-thawed copy, and ot::SemiFreeze can quickly repackage the object for subsequent transmittion.
Example (sending an object):
MyClass my_obj; ... // Initialize my_obj char *buf = mem::Alloc<char>(ot::FrozenSize(my_obj)); ot::Freeze(buf, my_obj); ... // Transmit over the network mem::Free(buf);
Example (receiving an object):
char *buf; ... // Fill buf from network MyClass *thawed_obj = ot::SemiThaw(buf); ... // Use thawed_obj ot::SemiDestruct(thawed_obj); mem::Free(buf);
To be more specific, ot::Freeze forms frozen objects by bit-copying the data structure into a flat (e.g. contiguous) buffer. Traversed pointers and arrays are processed depth-first and normalized to the bit-offsets of their represented regions from the beginning of the buffer. It is always safe to bit-copy frozen objects to new locations and their containing buffers may be freed without additional memory maintenance.
Afterward, ot::SemiThaw converts a frozen object into a semi-object by adding the buffer's memory location to all contained pointers and reconstructing transients. These are fully operational up to the ability to allocate or free non-transient fields. It is possible to bit-copy semi-objects to new locations, but after having done so, one must call either ot::Relocate or ot::SemiCopy, the former simply updating pointer positions (semantically invalidating the old location) and the latter reconstructing transients as well (leaving the old location valid). Alternately, you may call ot::SemiFreeze to revert the copy to a frozen state. Semi-objects must be explicitly destructed via ot::SemiDestruct, or may be frozen in-place with ot::SemiFreezeDestruct.
You can form a normal object directly from a frozen object with ot::InitThaw. Keep in mind that ot::InitCopy works when copying from a semi-object.
block | the memory location to receive the frozen copy | |
src | the object to be frozen |
Definition at line 1699 of file otrav.h.
Referenced by PointerFreeze(), and OrthoRangeSearch< T >::SaveTree().
size_t ot::FrozenSize | ( | const T & | obj | ) | [inline] |
Determine the buffer size needed to store a frozen copy of an object.
obj | the object whose frozen size should be computed |
Definition at line 1626 of file otrav.h.
Referenced by PointerFrozenSize(), and OrthoRangeSearch< T >::SaveTree().
void ot::InitCopy | ( | T * | dest, | |
const T & | src | |||
) | [inline] |
Copy an object into a specified destination.
This function works for primitive types and untraversed types with copy constructors by calling their copy construstors. For traversed types, copying behaves identically to the copy constructor if it exists, but no copy constructor is required.
This function does not allocate memory for the top level of the copied object, permitting you to copy objects onto the stack or into your own allocated buffers.
dest | an uninitialized object to receive the copy | |
src | the object to be copied |
Definition at line 1609 of file otrav.h.
Referenced by DBallBound< TMetric, TPoint >::CalculateMidpoint(), and Copy().
size_t ot::InitDeserialize | ( | T * | dest, | |
FILE * | stream | |||
) | [inline] |
Read a serialized version of an object from a file stream, reconstructing its transients.
Example (reading an object from file):
MyClass my_obj; FILE *f_in = fopen("in.dat", "rb"); ot::Deserialize(&my_obj, f_in); fclose(f_in);
dest | an uninitialized object to receive the copy | |
stream | a file stream openned for binary input |
void ot::InitThaw | ( | T * | dest, | |
const char * | block | |||
) | [inline] |
Copy from a frozen object into a specified destination.
Has the same effect as ot::SemiThaw followed by ot::InitCopy.
dest | an uninitialized object to receive the copy | |
block | the frozen object to be copied |
COMPILER_DEPRECATED void ot::PointerFreeze | ( | const T & | obj, | |
char * | block | |||
) | [inline] |
COMPILER_DEPRECATED size_t ot::PointerFrozenSize | ( | const T & | obj | ) | [inline] |
COMPILER_DEPRECATED void ot::PointerRefreeze | ( | const T * | src, | |
char * | dest | |||
) | [inline] |
COMPILER_DEPRECATED void ot::PointerRelocate | ( | const char * | old_loc, | |
char * | new_loc | |||
) | [inline] |
COMPILER_DEPRECATED T * ot::PointerThaw | ( | char * | block | ) | [inline] |
const char * ot::Print | ( | const T & | obj, | |
const char * | name, | |||
FILE * | stream = stdout | |||
) | [inline] |
Pretty-print an object using the standard print format.
Example (debug message):
DEBUG_ASSERT_MSG(node.parent_ != NULL, "NULL parent (see %s).", ot::Print(node, "faulty_node", stderr));
obj | the object to be printed | |
name | the printed name attributed to the object | |
stream | the output stream |
const char * ot::Print | ( | const T & | obj, | |
const char * | name, | |||
FILE * | stream = stdout | |||
) | [inline] |
Pretty-print an object using a given print format.
Print formats are classes used by the traversal printer to emit objects in different ways. At current, two print formats are offered: ot::StandardFormat and ot::XMLFormat.
You can define your own print format; it's interface must include:
Untraversed(const T &obj)
Primitive
(const char *name, index_t index, const char *type, T val) Open
(const char *name, index_t index, const char *type, const T &obj, index_t len = -1) Close(const char *name, const T &obj)
The Untraversed and Primitive functions are responsible for printing their respective types. Open and Close are called before and after traversing the contents of objects, pointers, and arrays. Only allocated arrays will have nonnegative lengths, and unallocated (NULL) arrays and pointers are handled by Primitive. See FOR_ALL_PRIMITIVES_DO to define many Primitive functions with a single macro.
obj | the object to be printed | |
name | the printed name attributed to the object | |
stream | the output stream |
T * ot::RepeatConstruct | ( | T * | array, | |
const T & | init, | |||
size_t | elems | |||
) | [inline] |
Equivalent to mem::RepeatConstruct, but does not require a copy constructor to be defined for traversed types.
Note the absense of DEBUG_INIT_OK. This ensures that this function works on arrays of unconstructed objects.
Definition at line 1961 of file otrav.h.
Referenced by ArrayList< std::pair< index_t, index_t > >::InitRepeat().
T * ot::SemiCopy | ( | char * | block, | |
const T * | orig | |||
) | [inline] |
Fixes the pointers and reconstructs transients of a semi-object assuming it has already been bit-copied into a new location.
It is OK for the original location to have already been freed.
block | the new location of the semi-object to freeze | |
orig | the original location of the semi-object |
Definition at line 1736 of file otrav.h.
Referenced by SemiThaw().
void ot::SemiDestruct | ( | T * | obj | ) | [inline] |
Destructs a semi-object's transients and debug-poisons its memory.
obj | the semi-object to destroy |
void ot::SemiFreeze | ( | char * | block, | |
const T * | orig | |||
) | [inline] |
Re-freezes a semi-object assuming it has already been bit-copied into a new location.
Example (freezing a semi-object):
MyClass *semi_obj; char *freeze_buf; ... // Fill semi_obj with a semi-object of size bytes freeze_buf = mem::AllocCopyBytes<char>(semi_obj, bytes); ot::SemiFreeze(freeze_buf, semi_obj); ... ot::SemiDestruct(semi_obj);
You should not use this freeze semi-objects in place because this precludes properly destructing their transients. Instead, bit-copy the semi-object to a new location and freeze it there, or use ot::SemiFreezeDestruct. It is OK for the original location to have already been freed.
block | the new location of the semi-object to freeze | |
orig | the original location of the semi-object |
Definition at line 1774 of file otrav.h.
Referenced by PointerRefreeze().
char * ot::SemiFreezeDestruct | ( | T * | obj | ) | [inline] |
Re-freezes a semi-object and destructs its transients.
obj | the semi-object to re-freeze |
T * ot::SemiThaw | ( | char * | block | ) | [inline] |
Thaws a frozen object by fixing pointers and reconstructing transients.
Equivalent to ot::SemiCopy with orig equal to NULL.
block | the frozen object to be thawed |
Definition at line 1796 of file otrav.h.
References SemiCopy().
size_t ot::Serialize | ( | const T & | obj, | |
FILE * | stream | |||
) | [inline] |
Write a serialized version of an object to a file stream.
Serialization is more compact than freezing because it emits an object's members without the padding. Further, it emits bools to indicate whether or not a pointer is NULL (or nothing at all if the pointer is not nullable), inferring the position of the pointer's contents by depth-first traversal. This violates the alignment and stride constraints of various platforms, and thus serialization is only available in the form of writing to and reading from a file stream.
Example (saving an object to file):
MyClass my_obj; ... // Initialize my_obj FILE *f_out = fopen("out.dat", "wb"); ot::Serialize(my_obj, f_out); fclose(f_out);
obj | the object to serialize | |
stream | a file stream openned for binary output |
size_t ot::SerialSize | ( | const T & | obj | ) | [inline] |