C++ Boost

Serialization

extended_type_info


Motivation
Runtime Interface
Requirements
Models
Example

Motivation

The serialization library needs a system like type_info/typeid() to perform the following functions
  1. given a pointer to a type T discover the true type pointed to.
  2. given an "external" key - determine what type of object to create.

The problem with std::type_info

Features

extended_type_info is an implementation of std::type_info functionality with the following features: The serialization system maintains two global tables. This library includes two different type id systems:

Runtime Interface


namespace boost { 
namespace serialization {

class BOOST_SERIALIZATION_DECL extended_type_info : 
    private boost::noncopyable 
{
protected:
    extended_type_info(const char * type_info_key);
public:
    void self_register();
    void key_register(const char *key);
    const char * get_key() const;

    bool operator<(const extended_type_info &rhs) const;
    bool operator==(const extended_type_info &rhs) const;
    bool operator!=(const extended_type_info &rhs) const;

    static const extended_type_info * find(const char *key);
    static const extended_type_info * find(const extended_type_info * t);
};

} // namespace serialization 
} // namespace boost
There must be one and only one extended_type_info instance created for each type. For this reason, this class is marked is derived from boost::noncopyable.


extended_type_info(const char * type_info_key);

This constructor should be called by all derived classes. It should be passed a pointer to a const string which identifies the type id system being used. This type id is used to distinguish among the various type id system that might be used and allow them to interoperate.


void self_register();

This function adds entry for an entry to the global type table. It would usually be called from the constructor of the derived class which implements the extended_type_info functionality.


void key_register(const char *key);

Assign a unique character string identifier to this 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;

Retrieves the key for 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;

These functions are used to compare two extended_type_info objects. Among other things, these are used for lookup in the tables.


static const extended_type_info * find(const char *key);

Given a character string key or GUID, return the address of the unique corresponding extended_type_info object.


static const extended_type_info * find(const extended_type_info * t);

Given a pointer to an extended_type_info, return the address of the instance of the same type in the main table. That is the argument t is used as a search argment to find the main table entry for a given type. It would be used like this:
// return the global type entry for our type T
return find(some_extended_type_info_implementation<T>())

Requirements

In order to be used by the serialization library, an implementation of extended_type_info, (referred to as ETI here), must implement the following:

template<class ETI>
virtual bool
ETI::less_than(const extended_type_info &rhs) const;

Impose a strict total ordering on all instances of the class ETI.

template<class ETI>
static const extended_type_info *
ETI::get_derived_extended_type_info(const T & t);

Return a pointer to the 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.

template<class ETI>
static extended_type_info *
ETI::get_instance();

Return a pointer to the instance of 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.

static void
template<class ETI>
ETI::export_register(const char * key);

The main function is to invoke key_register to add the GUID to the global table. Depending on the type id system being used, it might perform other initializaition functions as well.
It must define the following Itegral Constant of type bool:

ETI::is_polymorphic

Models

The serialization library includes two distinct extended_type_info implementations.

extended_type_info_typeid

is implemented in terms of the standard typeid(). It presumes that RTTI support is enabled by the compiler.

extended_type_info_no_rtti

is implemented in a way that doesn't rely on the existence RTTI. However, it does require that all classes for which type id is to be used implement a virtual function of the signiture:
virtual const char * get_key();
which returns a unique string the most derived object this class. This function must be virtual in order to implement the functionality required by ETI::get_derived_extended_type_info as described above.

Example

The test program 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.

© 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)