00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
#ifndef OMF_PROPERTY_HPP
00026
#define OMF_PROPERTY_HPP
00027
00028
00029
#include <string>
00030
00031
00032
#include <OMF/Exception.hpp>
00033
#include <OMF/Primitive.hpp>
00034
00035
namespace OMF
00036 {
00037
00038
class Object;
00039
class Association;
00040
00047 struct GetMethod
00048 {
00049
virtual Object *
get() = 0;
00050 };
00051
00062 struct SetMethod
00063 {
00064
virtual void set(
Object *value) = 0;
00065 };
00066
00072 struct ClearMethod
00073 {
00074
virtual void clear() = 0;
00075 };
00076
00081
template <
class Self,
class Type>
00082 struct GetByValConst :
public GetMethod
00083 {
00084 typedef const Type &(Self::*
Function)()
const;
00085
00086 GetByValConst(Self *
self,
Function method) :
00087
_self(self),
00088
_method(method)
00089 {}
00090
00091 virtual Object *
get()
00092 {
00093
const Object *ret = &((
_self->*
_method)());
00094
return const_cast<Object *>(ret);
00095 }
00096
00097 Self *
_self;
00098 Function _method;
00099 };
00100
00105
template <
class Self,
class Type>
00106 struct GetByValNonConst :
public GetMethod
00107 {
00108 typedef const Type &(Self::*
Function)();
00109
00110 GetByValNonConst(Self *
self,
Function method) :
00111
_self(self),
00112
_method(method)
00113 {}
00114
00115 virtual Object *
get()
00116 {
00117
const Object *ret = &((
_self->*
_method)());
00118
return const_cast<Object *>(ret);
00119 }
00120
00121 Self *
_self;
00122 Function _method;
00123 };
00124
00129
template <
class Self,
class Type>
00130 struct GetByRef :
public GetMethod
00131 {
00132 typedef Type *(Self::*
Function)();
00133
00134 GetByRef(Self *
self,
Function method) :
00135
_self(self),
00136
_method(method)
00137 {}
00138
00139 virtual Object *
get()
00140 {
00141
return (
_self->*
_method)();
00142 }
00143
00144 Self *
_self;
00145 Function _method;
00146 };
00147
00158
template <
class Self,
class Type>
00159 struct SetByVal :
public SetMethod
00160 {
00161 typedef void (Self::*
Function)(
const Type &);
00162
00163 SetByVal(Self *
self,
Function method) :
00164
_self(self),
00165
_method(method)
00166 {}
00167
00168 virtual void set(
Object *value)
00169 {
00170
00171 Type coerce;
00172
00173 Type *newValue = dynamic_cast<Type *>(value);
00174
if(!newValue) {
00175
Primitive *prim = dynamic_cast<Primitive *>(value);
00176
if(prim) {
00177 coerce = prim->
str();
00178 newValue = &coerce;
00179 }
00180
else {
00181
throw TypeMismatchError();
00182 }
00183 }
00184 (
_self->*
_method)(*newValue);
00185 }
00186
00187 Self *
_self;
00188 Function _method;
00189 };
00190
00196
template <
class Self,
class Type>
00197 struct SetByRef :
public SetMethod
00198 {
00199 typedef void(Self::*
Function)(Type *);
00200
00201 SetByRef(Self *
self,
Function method) :
00202
_self(self),
00203
_method(method)
00204 {}
00205
00206 virtual void set(
Object *value)
00207 {
00208 Type *newValue = dynamic_cast<Type *>(value);
00209
if(!newValue) {
00210
throw TypeMismatchError();
00211 }
00212
else {
00213 (
_self->*
_method)(newValue);
00214 }
00215 }
00216
00217 Self *
_self;
00218 Function _method;
00219 };
00220
00226
template <
class Self>
00227 struct ClearAll :
public ClearMethod
00228 {
00229 typedef void (Self::*
Function)();
00230
00231 ClearAll(Self *
self,
Function method) :
00232
_self(self),
00233
_method(method)
00234 {}
00235
00236 virtual void clear()
00237 {
00238 (
_self->*
_method)();
00239 }
00240
00241 Self *
_self;
00242 Function _method;
00243 };
00244
00245
00253 class Property
00254 {
00255
public:
00264 enum AssocPos {
00265
NoAssoc,
00266
First,
00267
Second
00268 };
00269
00278 enum AssocLevel {
00279
None,
00280
Weak,
00281
Strong
00282 };
00283
00284
Property(
const std::string &name);
00285
virtual ~Property();
00286
00287
template <
class Self,
class Type>
00288 Property &
getMethod(Self *
self,
const Type &(Self::*method)()
const)
00289 {
00290 _get =
new GetByValConst<Self, Type>(
self, method);
00291
return *
this;
00292 }
00293
00294
template<
class Self,
class Type>
00295 Property &
getMethod(Self *
self,
const Type &(Self::*method)())
00296 {
00297 _get =
new GetByValNonConst<Self, Type>(
self, method);
00298
return *
this;
00299 }
00300
00301
template <
class Self,
class Type>
00302 Property &
getMethod(Self *
self, Type *(Self::*method)())
00303 {
00304 _get =
new GetByRef<Self, Type>(
self, method);
00305
return *
this;
00306 }
00307
00308
template <
class Self,
class Type>
00309 Property &
setMethod(Self *
self,
void (Self::*method)(
const Type &))
00310 {
00311 _set =
new SetByVal<Self, Type>(
self, method);
00312
return *
this;
00313 }
00314
00315
template <
class Self,
class Type>
00316 Property &
setMethod(Self *
self,
void (Self::*method)(Type *))
00317 {
00318 _set =
new SetByRef<Self, Type>(
self, method);
00319
return *
this;
00320 }
00321
00322
template <
class Self,
class Type>
00323 Property &
addMethod(Self *
self,
void (Self::*method)(
const Type &))
00324 {
00325 _add =
new SetByVal<Self, Type>(
self, method);
00326
return *
this;
00327 }
00328
00329
template <
class Self,
class Type>
00330 Property &
addMethod(Self *
self,
void (Self::*method)(Type *))
00331 {
00332 _add =
new SetByRef<Self, Type>(
self, method);
00333
return *
this;
00334 }
00335
00336
template <
class Self,
class Type>
00337 Property &
removeMethod(Self *
self,
void (Self::*method)(
const Type &))
00338 {
00339 _remove =
new SetByVal<Self, Type>(
self, method);
00340
return *
this;
00341 }
00342
00343
template <
class Self,
class Type>
00344 Property &
removeMethod(Self *
self,
void (Self::*method)(Type *))
00345 {
00346 _remove =
new SetByRef<Self, Type>(
self, method);
00347
return *
this;
00348 }
00349
00350
template <
class Self>
00351 Property &
clearMethod(Self *
self,
void (Self::*method)())
00352 {
00353 _clear =
new ClearAll<Self>(
self, method);
00354
return *
this;
00355 }
00356
00382 Property &
assoc(
Association *assoc, AssocPos pos, AssocLevel level)
00383 {
00384 _assoc = assoc;
00385 _pos = pos;
00386 _level = level;
00387
return *
this;
00388 }
00389
00393 const std::string &
name()
const
00394
{
return _name; }
00395
00396 virtual bool canGet()
const
00397
{
return _get != 0; }
00398
00399 virtual bool canSet()
const
00400
{
return _set != 0; }
00401
00402 virtual bool canAdd()
const
00403
{
return _add != 0; }
00404
00405 virtual bool canRemove()
const
00406
{
return _remove != 0; }
00407
00408 virtual bool canClear()
const
00409
{
return _clear != 0; }
00410
00411
virtual Object *
get();
00412
virtual void set(
Object *value);
00413
virtual void add(
Object *value);
00414
virtual void remove(
Object *value);
00415
virtual void clear();
00416
00417 Association *
association()
00418 {
return _assoc; }
00419
00420 AssocPos position()
const
00421
{
return _pos; }
00422
00423 AssocLevel level()
const
00424
{
return _level; }
00425
00426
private:
00427 std::string _name;
00428
GetMethod *_get;
00429
SetMethod *_set;
00430
SetMethod *_add;
00431
SetMethod *_remove;
00432
ClearMethod *_clear;
00433
Association *_assoc;
00434 AssocPos _pos;
00435 AssocLevel _level;
00436 };
00437 }
00438
00439
#endif