Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

compile time reflection

144 views
Skip to first unread message

Caspin

unread,
Jun 27, 2009, 6:35:57 PM6/27/09
to
It seems like compile time reflection is often talked, but no one ever
seems to do anything about it. I'd like to draft a proposal for the
next c++ standard (not c++0x). I'm looking for feedback.

I've modeled the reflection off of function_traits in the standard
library. Currently the traits classes don't duplicate any
functionality already in type_traits. However I think it may be a
good idea to allow duplication, to fill out the traits and let the
compilers pour as much information into the trait as possible. I had
also considered embedding the traits classes within one another. eg
method traits would be member class of class traits. In the end they
would be implemented the same, just defined differently.

Ideally the traits classes would inherit from compiler specific
classes. e.g.
template< typename T >
struct class_traits : public __gcc_reflect_class(T)
{ };

The following traits classes are pretty straight forward. I hope
someone with compiler experience and verify that these would be easy
to implement. My hope stems from gccxml. For those unfamiliar with
it, it compiles c++ source using gcc's frontend and emits an xml
description of the source file. That description contains all of the
following information, except the symbol mangling.

enum class visibilty_t
{
e_public,
e_protected,
e_private,
e_invisible // for private members of base classes.
};

typedef< typename Type >
struct class_traits
{
typedef Type type;

constexpr char[] name;
constexpr char[] mangled_name; //perhaps unique name would be better
if mangling
// is difficult at
this stage of compilation
constexpr unsigned num_methods;
constexpr unsigned num_classes;
constexpr unsigned num_unions;
constexpr unsigned num_bases;
};

template< typename Type >
struct union_traits
{
typedef Type type;

constexpr char[] name;
constexpr char[] mangled_name;
constexpr unsigned num_types;
typedef some_type memberN_type;
};

template< typename Type, unsigned Number >
struct class_member_traits
{
typedef Type parent_type;
constexpr unsigned number = Number;

constexpr char[] name;
constexpr char[] mangled_name;
constexpr visibility_t visibility;
constexpr bool is_inherited; // true when member is defined in a
base class
typedef some_type type; // type of the member
typedef some_type pointer_type; //member pointer type

constexpr pointer_type pointer = &some_class_member;
};

template< typename Type, unsigned Number >
struct class_method_traits
{
typedef Type parent_type;
constexpr unsigned number = Number;

constexpr char[] name;
constexpr char[] mangled_name;
constexpr char[] signiture;
constexpr visibility_t visibility;
constexpr bool is_inherited;
constexpr bool is_const;
constexpr bool is_virtual;
constexpr bool is_pure;
typedef some_type type;
typedef some_type pointer_type;

constexpr pointer_type pointer = &some_class_method;
};

template< typename Type, unsigned Number >
struct internal_class_traits
{
typedef Type parent_type;
constexpr unsigned number = Number;

constexpr visibility_t visibility;
typedef some_type type;
};

template< typename Type, unsigned Number >
struct internal_union_traits
{
typedef Type parent_type;
constexpr unsigned number = Number;

constexpr visibility_t visibility;
typedef some_type type;
};

template< typename Type, unsigned Number >
struct base_class_traits
{
typedef Type super_type;
constexpr unsigned number = Number;

constexpr visibility_t visibility;
constexpr bool is_virtual;
typedef some_type type;
};

The following are a bit more complicated. namespaces don't have
types. But it would be nice to enumerate all members of a namespace.
My solution is a traits class that takes a member of the namespace.
Types from the most internal namespace would be enumerated. eg
namespace_traits<outer::inner::Foobar> would enumerate the contents of
outer::inner and namespace_traits<outer::Barfoo> would enumerate the
contents of outer. namespace_traits only enumerates complete types
and any functions currently visible. If a module system in integrated
with c++ a module_traits would follow a similar design.

template< typename In_namespace >
struct namespace_traits
{
typedef In_namespace in_namespace_type;

constexpr unsigned num_classes;
typedef some_type classN_type;

constexpr unsigned num_unions;
typedef some_type unionN_type;

constexpr unsigned num_functions;
};

template< typename In_namespace, unsigned Function_number >
struct namespace_function_traits
{
typedef In_namespace in_namespace_type;
constexpr unsigned number = Function_number;

constexpr char[] name;
constexpr char[] signature;
constexpr char[] mangled_name;

typedef some_function_type type;
typedef type* pointer_type;

constexpr pointer_type pointer = &function_name;
};


It would be useful to reflect on the current function or method. I
suggest a special traits class for this.

struct this_function_traits
{
// all members of namespace_funciton_traits
// or class_method_traits depending on where it is instantiated.
// it is a compile time error to instantiate this when not in a
function
// definition
};

it would be used like so:
void Foo::bar()
{
assert( std::string(this_function_traits<>::name), __func__ );
}

void foobar()
{
assert( std::string(this_function_traits<>::name), __func__ );
}

this_function_traits<>; // compiler error


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

0 new messages