00001 // 00002 // MetaObject.h 00003 // 00004 // $Id: //poco/1.3/Foundation/include/Poco/MetaObject.h#1 $ 00005 // 00006 // Library: Foundation 00007 // Package: SharedLibrary 00008 // Module: ClassLoader 00009 // 00010 // Definition of the MetaObject class. 00011 // 00012 // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. 00013 // and Contributors. 00014 // 00015 // Permission is hereby granted, free of charge, to any person or organization 00016 // obtaining a copy of the software and accompanying documentation covered by 00017 // this license (the "Software") to use, reproduce, display, distribute, 00018 // execute, and transmit the Software, and to prepare derivative works of the 00019 // Software, and to permit third-parties to whom the Software is furnished to 00020 // do so, all subject to the following: 00021 // 00022 // The copyright notices in the Software and this entire statement, including 00023 // the above license grant, this restriction and the following disclaimer, 00024 // must be included in all copies of the Software, in whole or in part, and 00025 // all derivative works of the Software, unless such copies or derivative 00026 // works are solely in the form of machine-executable object code generated by 00027 // a source language processor. 00028 // 00029 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00030 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00031 // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 00032 // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 00033 // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 00034 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00035 // DEALINGS IN THE SOFTWARE. 00036 // 00037 00038 00039 #ifndef Foundation_MetaObject_INCLUDED 00040 #define Foundation_MetaObject_INCLUDED 00041 00042 00043 #include "Poco/Foundation.h" 00044 #include "Poco/Exception.h" 00045 #include "Poco/SingletonHolder.h" 00046 #include <set> 00047 00048 00049 namespace Poco { 00050 00051 00052 template <class B> 00053 class AbstractMetaObject 00061 { 00062 public: 00063 AbstractMetaObject(const char* name): _name(name) 00064 { 00065 } 00066 00067 virtual ~AbstractMetaObject() 00068 { 00069 for (typename ObjectSet::iterator it = _deleteSet.begin(); it != _deleteSet.end(); ++it) 00070 { 00071 delete *it; 00072 } 00073 } 00074 00075 const char* name() const 00076 { 00077 return _name; 00078 } 00079 00080 virtual B* create() const = 0; 00083 00084 virtual B& instance() const = 0; 00087 00088 virtual bool canCreate() const = 0; 00092 00093 virtual void destroy(B* pObject) const 00097 { 00098 typename ObjectSet::iterator it = _deleteSet.find(pObject); 00099 00100 if (it != _deleteSet.end()) 00101 { 00102 _deleteSet.erase(pObject); 00103 delete pObject; 00104 } 00105 } 00106 00107 B* autoDelete(B* pObject) const 00113 { 00114 if (this->canCreate()) // guard against singleton 00115 { 00116 poco_check_ptr (pObject); 00117 _deleteSet.insert(pObject); 00118 } 00119 else throw InvalidAccessException("Cannot take ownership of", this->name()); 00120 00121 return pObject; 00122 } 00123 00124 virtual bool isAutoDelete(B* pObject) const 00130 { 00131 return _deleteSet.find(pObject) != _deleteSet.end(); 00132 } 00133 00134 private: 00135 AbstractMetaObject(); 00136 AbstractMetaObject(const AbstractMetaObject&); 00137 AbstractMetaObject& operator = (const AbstractMetaObject&); 00138 00139 typedef std::set<B*> ObjectSet; 00140 00141 const char* _name; 00142 mutable ObjectSet _deleteSet; 00143 }; 00144 00145 00146 template <class C, class B> 00147 class MetaObject: public AbstractMetaObject<B> 00153 { 00154 public: 00155 MetaObject(const char* name): AbstractMetaObject<B>(name) 00156 { 00157 } 00158 00159 ~MetaObject() 00160 { 00161 } 00162 00163 B* create() const 00164 { 00165 return new C; 00166 } 00167 00168 B& instance() const 00169 { 00170 throw InvalidAccessException("Not a singleton. Use create() to create instances of", this->name()); 00171 } 00172 00173 bool canCreate() const 00174 { 00175 return true; 00176 } 00177 }; 00178 00179 00180 template <class C, class B> 00181 class MetaSingleton: public AbstractMetaObject<B> 00185 { 00186 public: 00187 MetaSingleton(const char* name): AbstractMetaObject<B>(name) 00188 { 00189 } 00190 00191 ~MetaSingleton() 00192 { 00193 } 00194 00195 B* create() const 00196 { 00197 throw InvalidAccessException("Cannot create instances of a singleton class. Use instance() to obtain a", this->name()); 00198 } 00199 00200 bool canCreate() const 00201 { 00202 return false; 00203 } 00204 00205 B& instance() const 00206 { 00207 return *_object.get(); 00208 } 00209 00210 bool isAutoDelete(B* pObject) const 00211 { 00212 return true; 00213 } 00214 00215 private: 00216 mutable SingletonHolder<C> _object; 00217 }; 00218 00219 00220 } // namespace Poco 00221 00222 00223 #endif // Foundation_MetaObject_INCLUDED