|
Boost : |
From: Lin Xu (risingdragon3_at_[hidden])
Date: 2003-02-09 23:02:13
I've done some searching on the boost dev list archives, and I've seen some
interest in a reflection system in C++. I've implemented a full reflection
system - not only "properties" but functions as well - in compile time.
There is no storage cost or runtime cost (on MSVC7, the assembly
isntructions are the same - I haven't checked on others). It's also possible
to implement runtime reflection too, but this would bring a runtime cost. I
wish to implement compiletime first, then use that to build runtime.
Mainly, I use templates to implement 'properties'. the syntax I would forsee
is something like this:
struct A {
int z;
int getz() const {return z;}
void setz(int k) {z = k;}
void print() {cout << z << endl;}
};
namespace Prop {
struct val {};
struct print {};
struct val2 {};
}
template <> struct Reflect<A> {
typedef Implements<
Prop::val, GetSetPair<A,int,&A::getz,&A::setz>,
Prop::print, Function<void>::MemberFun<A,&A::print>,
//another way of accessing z, without get/setters:
Prop::val2, Member<A,int,&A::z>,
//read only (even could be write-only!)
Prop::val3, GetSet<Getter<A,int,&A::getz> >
>Info;
};
That's the basic sytnax. This *could* be done using an automated parser, but
there's certain things that the system can do that if you do by hand, you
can do.
For instance, you can have a virtual get/set pair, and have the proeprty
correctly dispatch to the virtual function from a base pointer. You can
inherit properties (...Prop::Inherit, InheritsFrom<BaseClass>...). You can
also have the type of a property be different from the get/set:
...GetSet<Getter<A,const
char*,&A::GetName>,Setter<A,std::string,&A::SetName> >...
Although I'm not sure what use this could be. Similiarly, there is a lot of
flexibility with an function reflection definition.
It enforces access specifier (private/public/protected) distinctions, but in
a previous version I was able to access the internal private data members
(again at compile time). But now I can't because I use member pointers.
There are more interesting things that it can do too, like provide an
"interface" / "implementation" distinction (define a subset of the full
reflection for say serialization - I know there was some discussion about
that). This can be useful, for providing a kind of interface analogy from
java. Functions can act on classes generically, wihtout knowing the true
implementation name, type, or (get/set) vs. (public member). The code is the
same as hand-written though on full optimization. If the types must be
converted, an handwritten bit of codee would similiarly have to do that.
As far as I can tell, there are no 'gotcha's in the implementation, and it's
fairly clean - the only problem is a lot of boost preprocessor code to avoid
PTS. It should work on MSVC6 sp5 (I did not use PTS) and does on MSVC7 and
gcc.
However, if there is more interest I will elaborate further, mainly because
this email is getting far too long already. Any interest? I know the naming
/ coding style is certainly not up to boost standards, but I'm willing to
make it work :)
Thanks.
Lin Xu.
_________________________________________________________________
The new MSN 8: smart spam protection and 2 months FREE*
http://join.msn.com/?page=features/junkmail
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk