00001 #ifndef VFACADE_HPP_
00002 #define VFACADE_HPP_
00003
00004 #include <iostream>
00005 #include <typeinfo>
00006
00007 #include <assert.h>
00008 #include <memory.h>
00009
00015
00016 template<class NonVirtual, class Virtual, class Adaptor>
00017 class vobject_hull : public Virtual {
00018 };
00019
00025
00026 struct vfacade_adaptor_type {
00027 template<class NonVirtual>
00028 class adaptor_type {
00029 private:
00030 NonVirtual* obj_;
00031 public:
00032 explicit inline adaptor_type() :
00033 obj_() {
00034 }
00035 explicit inline adaptor_type(NonVirtual& obj) :
00036 obj_(&obj) {
00037 }
00038 explicit inline adaptor_type(const NonVirtual& obj) :
00039 obj_(&obj) {
00040 }
00041 inline void set(NonVirtual& obj) {
00042 obj_ = &obj;
00043 }
00044 inline NonVirtual* operator->() {
00045 return obj_;
00046 }
00047 inline const NonVirtual* operator->() const {
00048 return obj_;
00049 }
00050 inline const NonVirtual& operator*() const {
00051 return *obj_;
00052 }
00053 inline NonVirtual& operator*() {
00054 return *obj_;
00055 }
00056 };
00057 };
00058
00064
00065 struct vcapsule_adaptor_type {
00066 template<class NonVirtual>
00067 class adaptor_type {
00068 private:
00069 NonVirtual obj_;
00070 public:
00071 inline adaptor_type() :
00072 obj_() {
00073 }
00074 inline adaptor_type(const NonVirtual& obj) :
00075 obj_(obj) {
00076 }
00077 inline void assign(const NonVirtual& obj) {
00078 obj_ = obj;
00079 }
00080 inline NonVirtual* operator->() {
00081 return &obj_;
00082 }
00083 inline const NonVirtual* operator->() const {
00084 return &obj_;
00085 }
00086 inline const NonVirtual& operator*() const {
00087 return obj_;
00088 }
00089 inline NonVirtual& operator*() {
00090 return obj_;
00091 }
00092 };
00093 };
00094
00100
00101 class vfacade_no_class {};
00102
00108
00109 template<class Virtual, class Extension = vfacade_no_class>
00110 class vfacade : public Extension {
00111 public:
00112 typedef vfacade<Virtual> self;
00113
00114 private:
00115 void* vtable;
00116 void* vadaptor;
00117
00118 template<class T>
00119 void assign(T& obj) {
00120 typedef vobject_hull<T, Virtual, vfacade_adaptor_type> adaptor_type;
00121 adaptor_type adaptor(obj);
00122 assert( sizeof(adaptor_type) == sizeof(vfacade) );
00123 memcpy((void*) this, (void*) &adaptor, sizeof(vfacade));
00124 }
00125
00126 template<class T>
00127 void assign(const T& obj) {
00128 T& obj_ = *const_cast<T*>(&obj);
00129 typedef vobject_hull<T, Virtual, vfacade_adaptor_type> adaptor_type;
00130 adaptor_type adaptor(obj_);
00131 assert( sizeof(adaptor_type) == sizeof(vfacade) );
00132 memcpy((void*) this, (void*) &adaptor, sizeof(vfacade));
00133 }
00134
00135 void assign(self& copy) {
00136 this->vtable = copy.vtable;
00137 this->vadaptor = copy.vadaptor;
00138 }
00139
00140 void assign(const self& copy) {
00141 this->vtable = copy.vtable;
00142 this->vadaptor = copy.vadaptor;
00143 }
00144
00145 public:
00147 inline vfacade() {
00148 this->vtable = NULL;
00149 this->vadaptor = NULL;
00150 }
00151
00153 template<class T>
00154 inline vfacade(T& obj) {
00155 assign(*const_cast<T*>(&obj));
00156 }
00157
00159 template<class T>
00160 inline self& operator=(T& obj) {
00161 assign(obj);
00162 return *this;
00163 }
00164
00166 inline bool is_null() const {
00167 return this->vtable == NULL;
00168 }
00169
00170 inline operator Virtual* () {
00171 assert(vtable!=NULL);
00172 return (Virtual*) this;
00173 }
00174
00175 inline operator const Virtual* () const {
00176 assert(vtable!=NULL);
00177 return (const Virtual*) this;
00178 }
00179
00180 inline operator Virtual& () {
00181 assert(vtable!=NULL);
00182 return *(Virtual*) this;
00183 }
00184
00185 inline operator const Virtual& () const {
00186 assert(vtable!=NULL);
00187 return *(const Virtual*) this;
00188 }
00189
00191 inline Virtual* operator->() {
00192 assert(vtable!=NULL);
00193 return (Virtual*) this;
00194 }
00195
00197 inline Virtual& operator*() {
00198 assert(vtable!=NULL);
00199 return *((Virtual*) this);
00200 }
00201
00203 inline const Virtual& operator*() const {
00204 assert(vtable!=NULL);
00205 return *((const Virtual*) this);
00206 }
00207
00209 inline const Virtual* operator->() const {
00210 assert(vtable!=NULL);
00211 return (const Virtual*) this;
00212 }
00213 };
00214
00220
00221 template<class Virtual, class NonVirtual>
00222 Virtual* vcapsule(const NonVirtual& obj) {
00223 return new vobject_hull<NonVirtual, Virtual, vcapsule_adaptor_type> (obj);
00224 }
00225
00231
00232 template<class Virtual, class NonVirtual>
00233 size_t vcapsule_size(const NonVirtual& obj) {
00234 return sizeof(vobject_hull<NonVirtual, Virtual, vcapsule_adaptor_type> (obj));
00235 }
00236
00237 #endif