|
Serialization
|
type_info/typeid()
to perform
the following functions
std::type_info
std::typeid()
is not available in all environments. Support for this function depends upon
runtime typing(RTTI) support from the compiler. This may be non-existent
or not enabled for reasons such as a percieved inefficiency.
std::type_info
includes a string
containing type name. This would seem to satisfy 2) above.
But the format of this string is not consistent accross compilers, libraries,
and operating systems. This makes it unusable for support of portable archives.
extended_type_info
is an implementation
of std::type_info
functionality with the
following features:
extended_type_info
records - one for each type
serialized.
typeid()
to find the external identifier
of a class while another might not.
namespace boost {
namespace serialization {
class extended_type_info
{
protected:
// this class can't be used as is. It's just the
// common functionality for all type_info replacement
// systems. Hence, make these protected
const char * m_key;
extended_type_info(const unsigned int type_info_key);
~extended_type_info();
public:
void key_register(const char *key);
const char * get_key() const {
return m_key;
}
bool operator<(const extended_type_info &rhs) const;
bool operator==(const extended_type_info &rhs) const;
bool operator!=(const extended_type_info &rhs) const {
return !(operator==(rhs));
}
// for plugins
virtual void * construct(unsigned int count = 0, ...) const;
virtual void destroy(void const * const p) const;
static const extended_type_info * find(const char *key);
};
} // namespace serialization
} // namespace boost
Generally, there will be one and only one
extended_type_info
instance created for each type. However, this is enforced only at the executable
module level. That is, if a program includes some shared libraries or DLLS,
there may be more than one instance of this class correponding to a particular type.
For this reason the comparison functions below can't just compare the addresses of
this instance but rather must be programmed to compare the the actual information
the instances contain.
extended_type_info(unsigned int type_info_key);
void key_register(const char *key);
extended_type_info
instance and add it to the corresponding global trable.
This key is used to identify a type accross different instances of the program.
In this way, one instance may know what type to create when necessary.
For this purpose, it must be the same in all program instances which
refer to the same type.
It may sometimes be referred to as a GUID - a Global Unique IDentifier.
const char *get_key() const;
extended_type_info
instance. If no key has been associated with the instance, then a NULL is returned.
bool operator<(const extended_type_info & rhs) const;
bool operator==(const extended_type_info & rhs) const;
bool operator!=(const extended_type_info & rhs) const;
extended_type_info
objects. They a strict total ordering on all instances of this class.
virtual void * construct(unsigned int count = 0, ...) const;
extended_type_info
record corresponds. This function takes variable list of up to 4 arguments
of any type. These arguments are passed to the type's constructor
at runtime. In order to use the facility,
one must declare a type sequence for the constructor arguments.
Arguments for this function must match in number and type
with those specified when the type was exported.
This function permits one to create instances of
any exported type given only the exported GUID assigned
with BOOST_CLASS_EXPORT.
If these types are defined in DLLS or shared libraries. When these modules
are loaded at runtime, these constructor can be called until the module
is unloaded. These modules are referred to as plugin.
virtual void destroy(void const * const p) const;
static const extended_type_info * find(const char *key);
extended_type_info
object.
extended_type_info
,
(referred to as ETI here), must be derived from
extended_type_info
and also implement the following:
template<class ETI>
static extended_type_info &
ETI::get_mutable_instance();
static const extended_type_info &
ETI::get_const:instance();
extended_type_info
which corresponds to type T. Normally these instances are static objects so
this just amounts to returning the address of this static object.
template<class ETI>
const extended_type_info *
ETI::get_derived_extended_type_info(const T & t) const;
extended_type_info
instance that corresponds to
the "true type" of the type T. The "true type" is the lowest type in the
hierarchy of classes. The type T can always be cast to the "true type" with
a static cast. Implemention of this function will vary among type id systems
and sometimes will make presumptions about the type T than can be identified
with a particular extended_type_info
implementation.
bool ETI::less_than(const extended_type_info &rhs) const;
extended_type_info
implementation.
extended_type_info
implementations.
is implemented in terms of the standard typeid(). It presumes that RTTI support is enabled
by the compiler.
extended_type_info_typeid
is implemented in a way that doesn't rely on the existence RTTI.
However, if the export facility is to be used to serialize types
through base class pointers, those types are required to implement
a virtual function with the signature:
extended_type_info_no_rtti
which returns a unique string the most derived object this class.
This function must be virtual in order to implement the functionality required by
virtual const char * get_key();
ETI::get_derived_extended_type_info
as described above.
test_no_rtti
implements this function in terms of the
extended_type_info
API above to return the export key associated with the class.
This requires that non-abstract types be exported. It also demostrates the
inter-operability with between two different implementations of
extended_type_info
.
© Copyright Robert Ramey 2005. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)