Boost logo

Boost :

Subject: Re: [boost] Reflection?
From: Jean-Louis Leroy (jl_at_[hidden])
Date: 2008-11-04 15:47:35


> I've merged several of Your posts so I can reply in one message,
> lazy me, sorry ;-P
>
Excellent idea :-)

I have renamed my library 'introspection' (to avoid clashing with
Jeremy's work) and committed it to the sandbox.

Today I wet my feet with Boost.Mirror. Using the doc (and the source
code ;-)) I was able to make the code at the bottom of this message
work. After a couple of hours 1/ I was very impressed 2/ I had a
headache 3/ I was convinced that building runtime reflection on top of
your work will be easy and 4/ I had found a bug ;-)

> But I was thinking (suprisingly enough) about gcc2xml being used
> as an optional support for automated registering of things into mirror,
> on those platforms where it is available.
>
Sure, we must write the backend in such a way that it is useable
stand-alone then write generators. My experience is that generators are
fine as long as you have only one of them in a project but two won't
coexist well, usually.

I'm running out of time, I have to work on serious things, namely
preparing my trip to ... Slovakia !

Here's my Mirror hello-world, with the bug report:

#include <iostream>

#include <boost/mirror/meta_class.hpp>
#include <boost/mirror/meta_inheritance.hpp>
#include <boost/mirror/algorithm/for_each.hpp>

using namespace std;
using namespace boost;
using namespace boost::mirror;

struct animal {
  int age;
};

struct mammal : virtual animal {
};

struct carnivore : virtual animal {
};

struct dog : mammal, carnivore {
};

namespace boost { namespace mirror {

BOOST_MIRROR_REG_TYPE_GLOBAL_SCOPE(animal)
BOOST_MIRROR_REG_CLASS_ATTRIBS_BEGIN(animal)
BOOST_MIRROR_REG_SIMPLE_CLASS_ATTRIB(_, int, age)
BOOST_MIRROR_REG_CLASS_ATTRIBS_END

BOOST_MIRROR_REG_TYPE_GLOBAL_SCOPE(mammal)
BOOST_MIRROR_REG_BASE_CLASSES_BEGIN(mammal)
BOOST_MIRROR_REG_VIRTUAL_BASE_CLASS(0, public, animal)
BOOST_MIRROR_REG_BASE_CLASSES_END

// watch out: BOOST_MIRROR_REG_SINGLE_BASE_CLASS_VIRTUAL(mammal, public,
animal)
// doesn't work because it calls BOOST_MIRROR_REG_BASE_CLASS_VIRTUAL
// instead of BOOST_MIRROR_REG_VIRTUAL_BASE_CLASS

BOOST_MIRROR_REG_TYPE_GLOBAL_SCOPE(carnivore)
BOOST_MIRROR_REG_BASE_CLASSES_BEGIN(carnivore)
BOOST_MIRROR_REG_VIRTUAL_BASE_CLASS(0, public, animal)
BOOST_MIRROR_REG_BASE_CLASSES_END

BOOST_MIRROR_REG_TYPE_GLOBAL_SCOPE(dog)
BOOST_MIRROR_REG_BASE_CLASSES_BEGIN(dog)
BOOST_MIRROR_REG_BASE_CLASS(0, public, mammal)
BOOST_MIRROR_REG_BASE_CLASS(1, public, carnivore)
BOOST_MIRROR_REG_BASE_CLASSES_END

} }

struct print_attribute {
  template<typename ATTRIBUTE> void operator()(ATTRIBUTE) {
    cout << ATTRIBUTE::get_name(mpl::false_(), std::char_traits<char>())
<< endl;
  }
};

struct print_base {
  template<typename CLASS> void display(CLASS, virtual_base_) {
    cout << "virtual " <<
CLASS::meta_base_class::get_name(mpl::false_(),
std::char_traits<char>()) << endl;
  }
  template<typename CLASS> void display(CLASS, nonvirtual_base_) {
    cout << CLASS::meta_base_class::get_name(mpl::false_(),
std::char_traits<char>()) << endl;
  }
  template<typename CLASS> void operator()(CLASS c) {
    display(c, CLASS::inheritance_specifier());
  }
};

int main() {
  mirror::for_each< meta_class<animal>::attributes >(print_attribute());
  mirror::for_each< meta_class<mammal>::base_classes >(print_base());
  mirror::for_each< meta_class<dog>::base_classes >(print_base());
  return 0;
}

Cordially,
Jean-Louis


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk