1//
2// MetaObject.h
3//
4// Library: Foundation
5// Package: SharedLibrary
6// Module: ClassLoader
7//
8// Definition of the MetaObject class.
9//
10// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// SPDX-License-Identifier: BSL-1.0
14//
15
16
17#ifndef Foundation_MetaObject_INCLUDED
18#define Foundation_MetaObject_INCLUDED
19
20
21#include "Poco/Foundation.h"
22#include "Poco/Exception.h"
23#include "Poco/SingletonHolder.h"
24#include <set>
25
26
27namespace Poco {
28
29
30template <class B>
31class AbstractMetaObject
32 /// A MetaObject stores some information
33 /// about a C++ class. The MetaObject class
34 /// is used by the Manifest class.
35 /// AbstractMetaObject is a common base class
36 /// for all MetaObject in a rooted class hierarchy.
37 /// A MetaObject can also be used as an object
38 /// factory for its class.
39{
40public:
41 AbstractMetaObject(const char* pName): _name(pName)
42 {
43 }
44
45 virtual ~AbstractMetaObject()
46 {
47 for (typename ObjectSet::iterator it = _deleteSet.begin(); it != _deleteSet.end(); ++it)
48 {
49 delete *it;
50 }
51 }
52
53 const char* name() const
54 {
55 return _name;
56 }
57
58 virtual B* create() const = 0;
59 /// Create a new instance of a class.
60 /// Cannot be used for singletons.
61
62 virtual B& instance() const = 0;
63 /// Returns a reference to the only instance
64 /// of the class. Used for singletons only.
65
66 virtual bool canCreate() const = 0;
67 /// Returns true iff the create method can be used
68 /// to create instances of the class.
69 /// Returns false if the class is a singleton.
70
71 virtual void destroy(B* pObject) const
72 /// If pObject was owned by meta object, the
73 /// ownership of the deleted object is removed
74 /// and the object is deleted.
75 {
76 typename ObjectSet::iterator it = _deleteSet.find(pObject);
77
78 if (it != _deleteSet.end())
79 {
80 _deleteSet.erase(pObject);
81 delete pObject;
82 }
83 }
84
85 B* autoDelete(B* pObject) const
86 /// Give ownership of pObject to the meta object.
87 /// The meta object will delete all objects it owns
88 /// when it is destroyed.
89 ///
90 /// Returns pObject.
91 {
92 if (this->canCreate()) // guard against singleton
93 {
94 poco_check_ptr (pObject);
95 _deleteSet.insert(pObject);
96 }
97 else throw InvalidAccessException("Cannot take ownership of", this->name());
98
99 return pObject;
100 }
101
102 virtual bool isAutoDelete(B* pObject) const
103 /// Returns true if the object is owned
104 /// by meta object.
105 ///
106 /// Overloaded in MetaSingleton - returns true
107 /// if the class is a singleton.
108 {
109 return _deleteSet.find(pObject) != _deleteSet.end();
110 }
111
112private:
113 AbstractMetaObject();
114 AbstractMetaObject(const AbstractMetaObject&);
115 AbstractMetaObject& operator = (const AbstractMetaObject&);
116
117 typedef std::set<B*> ObjectSet;
118
119 const char* _name;
120 mutable ObjectSet _deleteSet;
121};
122
123
124template <class C, class B>
125class MetaObject: public AbstractMetaObject<B>
126 /// A MetaObject stores some information
127 /// about a C++ class. The MetaObject class
128 /// is used by the Manifest class.
129 /// A MetaObject can also be used as an object
130 /// factory for its class.
131{
132public:
133 MetaObject(const char* name): AbstractMetaObject<B>(name)
134 {
135 }
136
137 ~MetaObject()
138 {
139 }
140
141 B* create() const
142 {
143 return new C;
144 }
145
146 B& instance() const
147 {
148 throw InvalidAccessException("Not a singleton. Use create() to create instances of", this->name());
149 }
150
151 bool canCreate() const
152 {
153 return true;
154 }
155};
156
157
158template <class C, class B>
159class MetaSingleton: public AbstractMetaObject<B>
160 /// A SingletonMetaObject disables the create() method
161 /// and instead offers an instance() method to access
162 /// the single instance of its class.
163{
164public:
165 MetaSingleton(const char* name): AbstractMetaObject<B>(name)
166 {
167 }
168
169 ~MetaSingleton()
170 {
171 }
172
173 B* create() const
174 {
175 throw InvalidAccessException("Cannot create instances of a singleton class. Use instance() to obtain a", this->name());
176 }
177
178 bool canCreate() const
179 {
180 return false;
181 }
182
183 B& instance() const
184 {
185 return *_object.get();
186 }
187
188 bool isAutoDelete(B* /*pObject*/) const
189 {
190 return true;
191 }
192
193private:
194 mutable SingletonHolder<C> _object;
195};
196
197
198} // namespace Poco
199
200
201#endif // Foundation_MetaObject_INCLUDED
202