Boost logo

Boost :

From: terekhov (terekhov_at_[hidden])
Date: 2002-02-16 20:04:12


--- In boost_at_y..., Luis Pedro Coelho <deepblack9_at_y...> wrote:
[...]
> The big problem is in calculating offset. This is a compile time
constant. If
> one could get some way of knowing it there would be no need for
properties to
> carry around a pointer to their parents. They could work it out
from there
> own addresses at run time from a compile-time calculated offset.
This is
> basically the reverse operation from the one done by the compiler
to find out
> the address of an subobject given the address of the parent.

#include <string>
#include <iostream>
using namespace std;

template< class Enclosure,class Type,int >
struct property {

  typedef Type type;
  typedef Enclosure enclosure;

  property& operator=( const type& value )
  { set( this,value ); return *this; }

  operator const type&() const
  { return get_const( this ); }

  operator type&()
  { return get( this ); }

};

template< class Enclosure,class Type,int i >
static ostream& operator<<( ostream& os,const property<
Enclosure,Type,i>& p )
{ os << get_const( &p ); return os; }

struct Gadget {

  typedef property< Gadget,int, 1 > A;
  typedef property< Gadget,int, 2 > B;
  typedef property< Gadget,int, 3 > C;
  typedef property< Gadget,string, 4 > D;
  typedef property< Gadget,const char*,5 > E;

//union {
  A a;
  B b;
  C c;
  D d;
  E e;
//};

  static Gadget* memberof( A* p )
  { cout << offsetof(Gadget,a) << endl; return reinterpret_cast<
Gadget* >(
                 reinterpret_cast< char* >(p) - offsetof
(Gadget,a) ); }

  static const Gadget* const_memberof( const A* p )
  { return reinterpret_cast< const Gadget* >(
                 reinterpret_cast< const char* >(p) - offsetof
(Gadget,a) ); }

  static Gadget* memberof( B* p )
  { cout << offsetof(Gadget,b) << endl; return reinterpret_cast<
Gadget* >(
                 reinterpret_cast< char* >(p) - offsetof
(Gadget,b) ); }

  static const Gadget* const_memberof( const B* p )
  { return reinterpret_cast< const Gadget* >(
                 reinterpret_cast< const char* >(p) - offsetof
(Gadget,b) ); }

  static Gadget* memberof( C* p )
  { cout << offsetof(Gadget,c) << endl; return reinterpret_cast<
Gadget* >(
                 reinterpret_cast< char* >(p) - offsetof
(Gadget,c) ); }

  static const Gadget* const_memberof( const C* p )
  { return reinterpret_cast< const Gadget* >(
                 reinterpret_cast< const char* >(p) - offsetof
(Gadget,c) ); }

  static Gadget* memberof( D* p )
  { cout << offsetof(Gadget,d) << endl; return reinterpret_cast<
Gadget* >(
                 reinterpret_cast< char* >(p) - offsetof
(Gadget,d) ); }

  static const Gadget* const_memberof( const D* p )
  { return reinterpret_cast< const Gadget* >(
                 reinterpret_cast< const char* >(p) - offsetof
(Gadget,d) ); }

  static Gadget* memberof( E* p )
  { cout << offsetof(Gadget,e) << endl; return reinterpret_cast<
Gadget* >(
                 reinterpret_cast< char* >(p) - offsetof
(Gadget,e) ); }

  static const Gadget* const_memberof( const E* p )
  { return reinterpret_cast< const Gadget* >(
                 reinterpret_cast< const char* >(p) - offsetof
(Gadget,e) ); }

  int a_value;
  int b_value;
  int c_value;
  string d_value;
  const char* e_value;
};
                  
void set( Gadget::A* p,const Gadget::A::type& value )
{ Gadget::memberof( p )->a_value = value; }

void set( Gadget::B* p,const Gadget::B::type& value )
{ Gadget::memberof( p )->b_value = value; }

void set( Gadget::C* p,const Gadget::C::type& value )
{ Gadget::memberof( p )->c_value = value; }

void set( Gadget::D* p,const Gadget::D::type& value )
{ Gadget::memberof( p )->d_value = value; }

void set( Gadget::E* p,const Gadget::E::type& value )
{ Gadget::memberof( p )->e_value = value; }

Gadget::A::type& get( Gadget::A* p )
{ return Gadget::memberof( p )->a_value; }

Gadget::B::type& get( Gadget::B* p )
{ return Gadget::memberof( p )->b_value; }

Gadget::C::type& get( Gadget::C* p )
{ return Gadget::memberof( p )->c_value; }

Gadget::D::type& get( Gadget::D* p )
{ return Gadget::memberof( p )->d_value; }
         
Gadget::E::type& get( Gadget::E* p )
{ return Gadget::memberof( p )->e_value; }
         
const Gadget::A::type& get_const( const Gadget::A* p )
{ return Gadget::const_memberof( p )->a_value; }

const Gadget::B::type& get_const( const Gadget::B* p )
{ return Gadget::const_memberof( p )->b_value; }

const Gadget::C::type& get_const( const Gadget::C* p )
{ return Gadget::const_memberof( p )->c_value; }

const Gadget::D::type& get_const( const Gadget::D* p )
{ return Gadget::const_memberof( p )->d_value; }

const Gadget::E::type& get_const( const Gadget::E* p )
{ return Gadget::const_memberof( p )->e_value; }

int main()
{
  Gadget g;

  g.a = 100;
  g.b = 200;
  g.c = 300;
  g.d = "HELLO";
  g.e = "WORLD";

  cout << sizeof( g ) << " " << g.a_value << " " << g.b_value << " "
<< g.c_value << " " << g.d_value << " " << g.e_value << endl;
  cout << sizeof( g ) << " " << g.a << " " << g.b << " " << g.c
<< " " << g.d << " " << g.e << endl;

  return 0;
}

regards,
alexander.


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