Boost logo

Boost :

From: Luis Pedro Coelho (deepblack9_at_[hidden])
Date: 2002-02-13 17:12:50


Em Quarta, 13 de Fevereiro de 2002 16:01, escreveste:
> When you do
>    A.value = 100 ;
> how does the property 'value' receives &A?
>
> My point is that there is NO WAY to store &A inside 'value' at compile
> time. You can store &A::foo, but without &A this still requires runtime
> support.

Off the top of my head:

value doesn't know where A is, but it knows where it is and it knows that it
lies inside A. In typical implementations (the begginning of) A will lie in a
fixed offset from where value is.

So

void value::operator = (const int x) {
        A* a = reinterpret_cast<A*>(reinterpret_cast<unsigned char*>(this) - offset);
        a->set_value(x);
}

All we got to do is find a way to calculate OFFSET at compile time. I think
that something like:

T A::*ptr = &A::value;
A* A = reinterpret_cast<A*>(&ptr);
        // <- I just use ptr, could be anything!
T* t = A->*ptr;
long offset = reinterpret_cast<unsigned char*>(t) - reinterpret_cast<unsigned
char*>(A);

Of course, we can do this in one constant expression inside the template
class definition:

        enum { offset = (reinterpret_cast<unsigned char*>
                (reinterpret_cast<unsigned char*>(&whatever)->*Ptr_to_member)
                 -
                reinterpret_cast<unsigned char*>(&whatever)));
                }

Where Ptr_to_member is passed as a template parameter.

Note that we have to write:

        boost::property<A, &A::value, read<&A::get_x>, write<&A::set_x> > value;

This approach has at least one advantage: No need to store an extra pointer
to the parent in every property object. Also there is now no need to pass to
this as a constructor argument.

HTH,

-- 
Luis Pedro Coelho.

Check out my game of Hearts, a card game, for KDE at:
http://hearts.sourceforge.net/


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