Mirror reflection library 0.5.13

Reflection with Mirror

Examples of reflection

This section shows how to use Mirror to obtain meta-data describing various language constructs like namespaces, types, typedefs, classes, templates, member variables, member functions, constructors, etc.

This section however shows only the basics which may not seem very useful at the first glance. For more elaborate examples showing the real power of reflective programming and meta-programming with Mirror see the example section of this documentation and the examples included with the sources.

Generally reflection is performed by using the reflection macros, which are expanded into types conforming to various concepts. This means that they can be given a symbolic name by using typedef or be used as the type of a variable, for example:

  // reflect the 'std' namespace                                       //
  typedef MIRRORED_NAMESPACE(std) meta_std_t;                          // typedef
  MIRRORED_NAMESPACE(std) meta_std;                                    // variable
                                                                       //
  meta_std_t::base_name();                                             // use the typedef
  meta_std.full_name();                                                // use the variable
                                                                       //
  // reflect the 'mstring' typedef                                     //
  typedef MIRRORED_TYPEDEF(mirror,mstring) meta_mstring_t;             // typedef
  MIRRORED_TYPEDEF(mirror,mstring) meta_mstring;                       // variable
                                                                       //
  meta_mstring.base_name();                                            // use the variable
  meta_mstring_t::full_name();                                         // use the typedef

The meta-objects (types) are stateless and have only static member functions and thus constructing instances of these types is cheap. On the other hand it is probably better to use the meta-objects as types since one cannot access the member typedefs of a variable nor use them directly in the template metafunctions, like members, parameters, base_classes, etc. Therefore the meta-objects are used as types in most of the following examples.

Namespace reflection

Namespaces are reflected with the MIRRORED_NAMESPACE() macro. This macro expands into a type conforming to the MetaNamespace concept. For starters, let us reflect the std namespace.

  // reflect the 'std' namespace                                       //
  typedef MIRRORED_NAMESPACE(std) meta_std;                            //

The first thing we can do is to examine the base and the full name of the reflected entity.

  // get the base name of the namespace                                //
  meta_std::base_name();                                               // string: "std"
  // get the full name of the namespace                                //
  meta_std::full_name();                                               // string: "std"

This is not very spectacular since the base and the full names are the same because the namespace is not nested. Let us do the same thing with the mirror namespace:

  // reflect the 'mirror' namespace                                    //
  typedef MIRRORED_NAMESPACE(mirror) meta_mirror;                      //
  // get the base name of the namespace                                //
  meta_mirror::base_name();                                            // string: "mirror"
  // get the full name of the namespace                                //
  meta_mirror::full_name();                                            // string: "mirror"

The base_name member function is defined by the MetaNamedObject concept and allows to get the base name of the reflected entity without the nested name specifier. The full_name member function is defined by the MetaNamedScopedObject concept and returns the full name including the nested name specifier.

There is one another name getting function in the MetaNamedScopedObject concept called local_name , which allows to strip certain prefixes of the full nested name specifier, based on the use of the MIRROR_USING_NAMESPACE() macro, as shown for example here and on the following code sample:

  // reflect the 'mirror' namespace                                    //
  typedef MIRRORED_NAMESPACE(mirror) meta_mirror;                      //
  // get the local name of the namespace                               //
  meta_mirror::local_name();                                           // string: "mirror"
  // now 'use' the boost namespace                                     //
  MIRROR_USING_NAMESPACE(boost)                                        //
  // get the local name of the namespace again                         //
  meta_mirror::local_name();                                           // string: "mirror"

Of course namespaces are not the only named constructs; meta-objects reflecting for example types, typedefs, classes, member functions and many other things are also models of the MetaNamedObject or the MetaNamedScopedObject concept and have the get_name, base_name, full_name and local_name member functions.

Global scope reflection

There is one special namespace - the global scope, which is anonymous and must be reflected with the MIRRORED_GLOBAL_SCOPE macro:

  // reflect the global scope                                //
  typedef MIRRORED_GLOBAL_SCOPE() meta_gs;                   //
                                                             //
  meta_gs::base_name();                                      // string: ""
  meta_gs::full_name();                                      // string: ""

Type reflection

Types are reflected with the MIRRORED_TYPE() macro, which expands into a type conforming to the MetaType concept.

  // reflect the 'int' type                                            //
  typedef MIRRORED_TYPE(int) meta_int;                                 //
  // reflect the standard string type                                  //
  typedef MIRRORED_TYPE(std::string) meta_str;                         //
                                                                       //
  meta_int::base_name();                                               // string: "int"
  meta_str::base_name();                                               // string: "string"
  meta_int::full_name();                                               // string: "int"
  meta_str::full_name();                                               // string: "std::string"
  meta_int::scope;                                                     // type: MetaNamespace
  meta_str::scope;                                                     // type: MetaNamespace
  meta_int::scope::full_name();                                        // string: ""
  meta_str::scope::full_name();                                        // string: "std"
  meta_int::original_type;                                             // type: int
  meta_str::original_type;                                             // type: std::string

Class reflection

Elaborated types (classes) are reflected with the MIRRORED_CLASS() macro, which expands into a type conforming to the MetaClass concept.

                                                                       //

Copyright © 2006-2011 Matus Chochlik, University of Zilina, Zilina, Slovakia.
<matus.chochlik -at- fri.uniza.sk>
<chochlik -at -gmail.com>
Documentation generated on Fri Dec 16 2011 by Doxygen (version 1.7.3).
Important note: Although the 'boostified' version of Mirror uses the Boost C++ libraries Coding Guidelines and is implemented inside of the boost namespace, it IS NOT an officially reviewed and accepted Boost library. Mirror is being developed with the intention to be submitted for review for inclusion to the Boost C++ libraries.