Boost Reflect Library 0.1.0
Quick Start
Boost.Reflect

There are two primary uses for the Boost.Reflect library:

Basic Reflection

Basic reflection of a type is achieved using the BOOST_REFLECT(TYPE,INHERITS,MEMBERS) macro to specify base classes and class members. Below is an example of reflecting a struct.

    struct my_struct {
        int         hello;
        std::string world;
    };
    BOOST_REFLECT( my_struct, (hello)(world) )

Now that we have reflected the struct, we can dump it to XML with a simple visitor.

    template<typename T>
    struct xml_printer {
        xml_printer( const T& c ):self(c){}

        template<typename Type> 
        static xml_printer<Type> make( const Type& t ) {
            return xml_printer<Type>(t);
        }

        template<typename Member, typename Class, Member Class::*p>
        void operator()( const char* name )const {
            std::cerr<<"<"<<name<<">"<<(self.*p)<<"</"<<name<<">\n";
        }
        const T& self;
    };

The visitor can then be applied like so:

        my_struct s;
        boost::reflect::reflector<my_struct>::visit( xml_printer<my_struct>(s) );
        boost::reflect::reflector<my_struct>::visit( xml_printer::make(s) );

Type Erasures

Type Erasure is one means to hide implementation details by defining a type that can contain any object that implements the required interface. Examples are boost::any and boost::function. Boost.Reflect enables the rapid generation of new type erasures for arbitrary interfaces via the any_ptr<Interface> type.

boost::reflect::any_ptr can hold a pointer or shared pointer to any type that implements a particular reflected interface.

Here is an example on how to define a new type erasure for two interfaces, Service and Calculator.

    struct Service {
      std::string name()const;
      int         exit();
    };
    struct Calculator : Service {
      double add( double v );           
      double sub( double v );           
      double mult( double v );           
      double div( double v );           
      double result()const;
    };

    BOOST_REFLECT_ANY( Service,(name)(exit) )
    BOOST_REFLECT_ANY_DERIVED( Calculator, (Service), (add)(sub)(mult)(div)(result) )
Note:
When you define an interface, you need not provide implementations of the methods; however, if you want you may also use an interace like any other class without limititations.
    class CalculatorService {
      public:
        CalculatorService():m_result(0){}

        std::string name()const { return "CalculatorService"; }
        int   exit()            { ::exit(0);                  }
        double add( double v )  { return m_result += v;       }
        double sub( double v )  { return m_result -= v;       }
        double mult( double v ) { return m_result *= v;       }
        double div( double v )  { return m_result /= v;       }
        double result()const    { return m_result;            }

      private:
        double m_result;
    };

    void try_it() {
      reflect::any_ptr<Calculator> calc( new CalculatorService() );
      calc->add(5);
      calc->add(6);
      std::string name = calc->name();
      assert( calc->result() == 11 );
    }

Some things to note, CalculatorService did not inherit either Calculator or Service, it simply exposed all of the methods defined by the interface. If it looks like a Duck, quacks like a Duck, then it is a Duck.

The interface of any_ptr<Calculator> is 'identical' to the Calculator defined above.

Pointer semantics were chosen to discourage using reflect::anys as values where assignment and copy construction creates a new instance. Initialization of any_ptr with a new pointer is a relatively expensive operation and value semantics would create objects that are much bigger and more expensive to copy than traditional types as each method is a functor that must be initialized at copy/construction time.

Generally speaking, any_ptr<> should be used to abstract long-lived objects and not for temporaries.


© Daniel Larimer 2010-2011 - Licensed under Boost Software License, Version 1.0 Boost Reflect Library