Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

Property.hpp

Go to the documentation of this file.
00001 /* 00002 * Copyright (C) 2004 Andrew Sutton 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to: 00016 * 00017 * The Free Software Foundation, Inc. 00018 * 59 Temple Place, Suite 330 00019 * Boston, MA 02111-1307 USA 00020 * 00021 * Contact: 00022 * Andrew Sutton asutton@cs.kent.edu 00023 */ 00024 00025 #ifndef OMF_PROPERTY_HPP 00026 #define OMF_PROPERTY_HPP 00027 00028 // std includes 00029 #include <string> 00030 00031 // OMF includes 00032 #include <OMF/Exception.hpp> 00033 #include <OMF/Primitive.hpp> 00034 00035 namespace OMF 00036 { 00037 // forward declarations 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 // used for type coersion 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

Generated on Fri Sep 10 13:07:33 2004 for OpenModelingFramework by doxygen 1.3.8