34 #include <boost/function.hpp>
35 #include <boost/format.hpp>
37 #include "../runtime/TypeStringTools.h"
38 #include "../runtime/Properties.h"
67 template<
typename Key>
74 typedef std::map<Key, CreateFunction>
ImplMap;
78 template<
typename K,
typename I>
91 virtual const std::type_info&
99 virtual const ImplMapProxy&
116 createBase(const Key& key, const runtime::Properties& properties_ =
117 runtime::Properties()) = 0;
128 template<typename Key, typename Interface>
136 typedef boost::function1<InterfaceType*, const runtime::Properties&>
139 typedef std::map<Key, CreateFunction>
ImplMap;
159 void register_(
const KeyType& key,
165 void unregister(
const KeyType& key);
181 const std::type_info&
184 const ImplMapBaseProxy&
197 impls() const throw ();
204 createBase(const Key& key, const runtime::Properties& properties_ =
205 runtime::Properties());
221 createInst(const Key& key, const runtime::Properties& properties_ =
222 runtime::Properties());
224 ImplMapBase impl_map_base_;
225 ImplMapBaseProxy impl_map_base_proxy_;
233 virtual
void register_(const Key& key,
239 virtual
void unregister(const Key& key);
245 template<typename Key, typename Interface>
247 public
Factory<Key, Interface> {
255 template<
typename Key,
typename Interface>
258 base_type(owner.impl_map_), owner(owner) {
261 template<
typename Key,
typename Interface>
264 this->owner.register_(key, create_function_);
267 template<
typename Key,
typename Interface>
269 this->owner.unregister(key);
274 template<
typename Key,
typename Interface>
279 template<
typename Key,
typename Interface>
283 template<
typename Key,
typename Interface>
284 const std::type_info&
286 return typeid(Interface);
289 template<
typename Key,
typename Interface>
292 return this->impl_map_base_proxy_;
295 template<
typename Key,
typename Interface>
298 return this->impl_map_proxy_;
301 template<
typename Key,
typename Interface>
304 return this->impl_map_proxy_;
307 template<
typename Key,
typename Interface>
311 if (this->impl_map_.find(key) != this->impl_map_.end()) {
313 "duplicate key", key));
317 this->impl_map_base_[key] = create_function_;
318 this->impl_map_[key] = create_function_;
321 template<
typename Key,
typename Interface>
324 typename ImplMap::iterator it;
325 if ((it = this->impl_map_.find(key)) == this->impl_map_.end()) {
330 "no implementation of interface `%%1%%' found for specified key `%1%'",
331 "no implementation of interface `%%1%%' found for specified key",
332 key)) % runtime::typeName<Interface>()));
336 this->impl_map_base_.erase(key);
337 this->impl_map_.erase(it);
340 template<
typename Key,
typename Interface>
343 Interface* instance = createInst(key, properties_);
348 template<
typename Key,
typename Interface>
353 typename ImplMap::const_iterator it;
354 if ((it = this->impl_map_.find(key)) == this->impl_map_.end()) {
359 "no implementation of interface `%%1%%' found for specified key `%1%'",
360 "no implementation of interface `%%1%%' found for specified key",
361 key)) % runtime::typeName<Interface>()));
365 Interface* instance = 0;
367 instance =
reinterpret_cast<Interface*
> (it->second(properties_));
368 }
catch (
const std::exception& exception_) {
370 + exception_.what());
374 "could not construct implementation instance for key `%1%'",
375 "could not construct implementation instance", key));
384 template<
typename Key,
typename Interface>
390 template<
typename Ch,
typename Tr,
typename Key,
typename Interface>
391 std::basic_ostream<Ch, Tr>&
392 operator<<(std::basic_ostream<Ch, Tr>& stream,
398 stream << (boost::format(
"implementations of interface %1%:\n")
402 const impl_map_proxy_type& impls = factory.impls();
404 for (
typename impl_map_proxy_type::const_iterator it = impls.begin(); it
405 != impls.end(); ++it) {
406 stream << (boost::format(
"* %1%\n") % it->first);
ImplMapProxy(ImplMap &container)
virtual type_and_storage createBase(const Key &key, const runtime::Properties &properties_=runtime::Properties())=0
Create and return an instance of the implementation designated by key.
ImplMapBaseProxy impl_map_base_proxy_
virtual void register_(const Key &key, const CreateFunction &create_function_)
A factory of which at most one instance exists at any time.
Objects of this class manage a family of named implementations of a particular interface.
boost::function1< InterfaceType *, const runtime::Properties & > CreateFunction
container_type & container
std::string typeName(const std::type_info &type)
Returns a (demangled) string representation of type.
pair< _T1, _T2 > make_pair(_T1 __x, _T2 __y)
A convenience wrapper for creating a pair from two objects.
std::map< Key, CreateFunction > ImplMap
Factory< Key, Interface > & owner
virtual void unregister(const Key &key)
boost::function1< void *, const runtime::Properties & > CreateFunction
An interface-independent factory interface, mainly used as a base class for more specific factories...
ImplMapBase impl_map_base_
ImplMapProxy & impls()
Return a container-like object holding all registered implementations.
Interface * createInst(const Key &key, const runtime::Properties &properties_=runtime::Properties())
Create and return an instance of the implementation designated by key.
void register_(const KeyType &key, const CreateFunction &create_function_)
This template class implements the singleton pattern.
base::ImplMap ImplMapBase
virtual const ImplMapProxy & implsBase() const =0
Return a container-like object holding all registered implementations.
ImplMapProxy(Factory< Key, Interface > &owner)
ImplMapProxy impl_map_proxy_
base::ImplMapProxy ImplMapBaseProxy
AssociativeProxy< ImplMap > base_type
virtual const std::type_info & GetInterfaceType() const =0
Return the type information of the interface type of the factory.
std::string typeString(const std::string &known_type_string, const std::string &unknown_type_string, const T &value)
Returns one of two to strings depending on whether type T is known to be able to support stream outpu...
FactoryBase< Key >::type_and_storage createBase(const Key &key, const runtime::Properties &properties_=runtime::Properties())
std::map< Key, CreateFunction > ImplMap
AssociativeProxy< ImplMap > base
Properties objects are basically glorified map<string, boost::any> objects.
std::pair< const std::type_info *, void * > type_and_storage
This object presents the registered implementations in a form very similar to a STL container...
const std::type_info & GetInterfaceType() const
Return the type information of the interface type of the factory.
void unregister(const KeyType &key)
const ImplMapBaseProxy & implsBase() const
Return a container-like object holding all registered implementations.