//////////////////////////////////////////////////////////////////////////////// // The Loki Library // Copyright (c) 2001 by Andrei Alexandrescu // Copyright (c) 2005 by Peter Kuemmel // This code DOES NOT accompany the book: // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design // Patterns Applied". Copyright (c) 2001. Addison-Wesley. // // Code covered by the MIT License // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. //////////////////////////////////////////////////////////////////////////////// #ifndef LOKI_FACTORYPARM_INC_ #define LOKI_FACTORYPARM_INC_ // $Id$ #include #include #include #include #include #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4702) //unreachable code if OnUnknownType throws an exception #endif /** * \defgroup FactoriesGroup Factories * \defgroup FactoryGroup Factory * \ingroup FactoriesGroup * \brief Implements a generic object factory. * * The Factory Method pattern is an object-oriented design pattern. * Like other creational patterns, it deals with the problem of creating objects * (products) without specifying the exact class of object that will be created. * Factory Method, one of the patterns from the Design Patterns book, handles * this problem by defining a separate method for creating the objects, which * subclasses can then override to specify the derived type of product that will * be created. *
* More generally, the term Factory Method is often used to refer to any method * whose main purpose is creation of objects.
* * * Loki proposes a generic version of the Factory. Here is a typical use.
*
* 1. Factory< AbstractProduct, int > aFactory;
* 2. aFactory.Register( 1, createProductNull );
* 3. aFactory.CreateObject( 1 );
*

*
* - 1. The declaration
* You want a Factory that produces AbstractProduct.
* The client will refer to a creation method through an int.
* - 2.The registration
* The code that will contribute to the Factory will now need to declare its * ProductCreator by registering them into the Factory.
* A ProductCreator is a just a function that will return the right object. ie
* * Product* createProductNull()
* {
* return new Product
* }
*

* - 3. The use
* Now the client can create object by calling the Factory's CreateObject method * with the right identifier. If the ProductCreator were to have arguments * (ie :Product* createProductParm( int a, int b )) */ namespace Loki { /** * \defgroup FactoryErrorPoliciesGroup Factory Error Policies * \ingroup FactoryGroup * \brief Manages the "Unknown Type" error in an object factory * * \class DefaultFactoryError * \ingroup FactoryErrorPoliciesGroup * \brief Default policy that throws an exception * */ template struct DefaultFactoryError { struct Exception : public std::exception { const char* what() const throw() { return "Unknown Type"; } }; static AbstractProduct* OnUnknownType(IdentifierType) { throw Exception(); } }; #define LOKI_ENABLE_NEW_FACTORY_CODE #ifdef LOKI_ENABLE_NEW_FACTORY_CODE //////////////////////////////////////////////////////////////////////////////// // class template FunctorImpl //////////////////////////////////////////////////////////////////////////////// struct FactoryImplBase { typedef EmptyType Parm1; typedef EmptyType Parm2; typedef EmptyType Parm3; typedef EmptyType Parm4; typedef EmptyType Parm5; typedef EmptyType Parm6; typedef EmptyType Parm7; typedef EmptyType Parm8; typedef EmptyType Parm9; typedef EmptyType Parm10; typedef EmptyType Parm11; typedef EmptyType Parm12; typedef EmptyType Parm13; typedef EmptyType Parm14; typedef EmptyType Parm15; }; template struct FactoryImpl; template struct FactoryImpl : public FactoryImplBase { virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id & id ) = 0; }; template struct FactoryImpl > : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1 ) = 0; }; template struct FactoryImpl > : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2 ) = 0; }; template struct FactoryImpl > : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3 ) = 0; }; template struct FactoryImpl > : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4 ) = 0; }; template struct FactoryImpl > : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5 ) = 0; }; template struct FactoryImpl > : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6 ) = 0; }; template struct FactoryImpl > : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; typedef typename TypeTraits::ParameterType Parm7; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7 ) = 0; }; template struct FactoryImpl > : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; typedef typename TypeTraits::ParameterType Parm7; typedef typename TypeTraits::ParameterType Parm8; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8) = 0; }; template struct FactoryImpl > : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; typedef typename TypeTraits::ParameterType Parm7; typedef typename TypeTraits::ParameterType Parm8; typedef typename TypeTraits::ParameterType Parm9; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9) = 0; }; template struct FactoryImpl > : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; typedef typename TypeTraits::ParameterType Parm7; typedef typename TypeTraits::ParameterType Parm8; typedef typename TypeTraits::ParameterType Parm9; typedef typename TypeTraits::ParameterType Parm10; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9,Parm10) = 0; }; template struct FactoryImpl > : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; typedef typename TypeTraits::ParameterType Parm7; typedef typename TypeTraits::ParameterType Parm8; typedef typename TypeTraits::ParameterType Parm9; typedef typename TypeTraits::ParameterType Parm10; typedef typename TypeTraits::ParameterType Parm11; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9,Parm10, Parm11) = 0; }; template struct FactoryImpl > : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; typedef typename TypeTraits::ParameterType Parm7; typedef typename TypeTraits::ParameterType Parm8; typedef typename TypeTraits::ParameterType Parm9; typedef typename TypeTraits::ParameterType Parm10; typedef typename TypeTraits::ParameterType Parm11; typedef typename TypeTraits::ParameterType Parm12; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9,Parm10, Parm11,Parm12) = 0; }; template struct FactoryImpl > : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; typedef typename TypeTraits::ParameterType Parm7; typedef typename TypeTraits::ParameterType Parm8; typedef typename TypeTraits::ParameterType Parm9; typedef typename TypeTraits::ParameterType Parm10; typedef typename TypeTraits::ParameterType Parm11; typedef typename TypeTraits::ParameterType Parm12; typedef typename TypeTraits::ParameterType Parm13; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9,Parm10, Parm11,Parm12,Parm13) = 0; }; template struct FactoryImpl > : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; typedef typename TypeTraits::ParameterType Parm7; typedef typename TypeTraits::ParameterType Parm8; typedef typename TypeTraits::ParameterType Parm9; typedef typename TypeTraits::ParameterType Parm10; typedef typename TypeTraits::ParameterType Parm11; typedef typename TypeTraits::ParameterType Parm12; typedef typename TypeTraits::ParameterType Parm13; typedef typename TypeTraits::ParameterType Parm14; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm8,Parm10, Parm11,Parm12,Parm13,Parm14) = 0; }; template struct FactoryImpl > : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; typedef typename TypeTraits::ParameterType Parm7; typedef typename TypeTraits::ParameterType Parm8; typedef typename TypeTraits::ParameterType Parm9; typedef typename TypeTraits::ParameterType Parm10; typedef typename TypeTraits::ParameterType Parm11; typedef typename TypeTraits::ParameterType Parm12; typedef typename TypeTraits::ParameterType Parm13; typedef typename TypeTraits::ParameterType Parm14; typedef typename TypeTraits::ParameterType Parm15; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9,Parm10, Parm11,Parm12,Parm13,Parm14,Parm15 ) = 0; }; #ifndef LOKI_DISABLE_TYPELIST_MACROS template struct FactoryImpl : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1 ) = 0; }; template struct FactoryImpl : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2 ) = 0; }; template struct FactoryImpl : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3 ) = 0; }; template struct FactoryImpl : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4 ) = 0; }; template struct FactoryImpl : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5 ) = 0; }; template struct FactoryImpl : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6 ) = 0; }; template struct FactoryImpl : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; typedef typename TypeTraits::ParameterType Parm7; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7 ) = 0; }; template struct FactoryImpl : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; typedef typename TypeTraits::ParameterType Parm7; typedef typename TypeTraits::ParameterType Parm8; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8) = 0; }; template struct FactoryImpl : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; typedef typename TypeTraits::ParameterType Parm7; typedef typename TypeTraits::ParameterType Parm8; typedef typename TypeTraits::ParameterType Parm9; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9) = 0; }; template struct FactoryImpl : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; typedef typename TypeTraits::ParameterType Parm7; typedef typename TypeTraits::ParameterType Parm8; typedef typename TypeTraits::ParameterType Parm9; typedef typename TypeTraits::ParameterType Parm10; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9,Parm10) = 0; }; template struct FactoryImpl : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; typedef typename TypeTraits::ParameterType Parm7; typedef typename TypeTraits::ParameterType Parm8; typedef typename TypeTraits::ParameterType Parm9; typedef typename TypeTraits::ParameterType Parm10; typedef typename TypeTraits::ParameterType Parm11; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9,Parm10, Parm11) = 0; }; template struct FactoryImpl : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; typedef typename TypeTraits::ParameterType Parm7; typedef typename TypeTraits::ParameterType Parm8; typedef typename TypeTraits::ParameterType Parm9; typedef typename TypeTraits::ParameterType Parm10; typedef typename TypeTraits::ParameterType Parm11; typedef typename TypeTraits::ParameterType Parm12; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9,Parm10, Parm11,Parm12) = 0; }; template struct FactoryImpl : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; typedef typename TypeTraits::ParameterType Parm7; typedef typename TypeTraits::ParameterType Parm8; typedef typename TypeTraits::ParameterType Parm9; typedef typename TypeTraits::ParameterType Parm10; typedef typename TypeTraits::ParameterType Parm11; typedef typename TypeTraits::ParameterType Parm12; typedef typename TypeTraits::ParameterType Parm13; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9,Parm10, Parm11,Parm12,Parm13) = 0; }; template struct FactoryImpl : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; typedef typename TypeTraits::ParameterType Parm7; typedef typename TypeTraits::ParameterType Parm8; typedef typename TypeTraits::ParameterType Parm9; typedef typename TypeTraits::ParameterType Parm10; typedef typename TypeTraits::ParameterType Parm11; typedef typename TypeTraits::ParameterType Parm12; typedef typename TypeTraits::ParameterType Parm13; typedef typename TypeTraits::ParameterType Parm14; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm8,Parm10, Parm11,Parm12,Parm13,Parm14) = 0; }; template struct FactoryImpl : public FactoryImplBase { typedef typename TypeTraits::ParameterType Parm1; typedef typename TypeTraits::ParameterType Parm2; typedef typename TypeTraits::ParameterType Parm3; typedef typename TypeTraits::ParameterType Parm4; typedef typename TypeTraits::ParameterType Parm5; typedef typename TypeTraits::ParameterType Parm6; typedef typename TypeTraits::ParameterType Parm7; typedef typename TypeTraits::ParameterType Parm8; typedef typename TypeTraits::ParameterType Parm9; typedef typename TypeTraits::ParameterType Parm10; typedef typename TypeTraits::ParameterType Parm11; typedef typename TypeTraits::ParameterType Parm12; typedef typename TypeTraits::ParameterType Parm13; typedef typename TypeTraits::ParameterType Parm14; typedef typename TypeTraits::ParameterType Parm15; virtual ~FactoryImpl() {} virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9,Parm10, Parm11,Parm12,Parm13,Parm14,Parm15 ) = 0; }; #endif //LOKI_DISABLE_TYPELIST_MACROS //////////////////////////////////////////////////////////////////////////////// /// \class Factory /// /// \ingroup FactoryGroup /// Implements a generic object factory. /// /// Create functions can have up to 15 parameters. /// /// \par Singleton lifetime when used with Loki::SingletonHolder /// Because Factory uses internally Functors which inherits from /// SmallObject you must use the singleton lifetime /// \code Loki::LongevityLifetime::DieAsSmallObjectChild \endcode /// Alternatively you could suppress for Functor the inheritance /// from SmallObject by defining the macro: /// \code LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT \endcode //////////////////////////////////////////////////////////////////////////////// template < class AbstractProduct, typename IdentifierType, typename CreatorParmTList = NullType, template class FactoryErrorPolicy = DefaultFactoryError > class Factory : public FactoryErrorPolicy { protected: typedef FactoryImpl< AbstractProduct, IdentifierType, CreatorParmTList > Impl; typedef typename Impl::Parm1 Parm1; typedef typename Impl::Parm2 Parm2; typedef typename Impl::Parm3 Parm3; typedef typename Impl::Parm4 Parm4; typedef typename Impl::Parm5 Parm5; typedef typename Impl::Parm6 Parm6; typedef typename Impl::Parm7 Parm7; typedef typename Impl::Parm8 Parm8; typedef typename Impl::Parm9 Parm9; typedef typename Impl::Parm10 Parm10; typedef typename Impl::Parm11 Parm11; typedef typename Impl::Parm12 Parm12; typedef typename Impl::Parm13 Parm13; typedef typename Impl::Parm14 Parm14; typedef typename Impl::Parm15 Parm15; typedef Functor ProductCreator; private: typedef AssocVector IdToProductMap; IdToProductMap associations_; public: Factory() : associations_() { } ~Factory() { associations_.erase(associations_.begin(), associations_.end()); } bool Register(const IdentifierType& id, ProductCreator creator) { return associations_.insert( typename IdToProductMap::value_type(id, creator)).second != 0; } template bool Register(const IdentifierType& id, const PtrObj& p, CreaFn fn) { ProductCreator creator( p, fn ); return associations_.insert( typename IdToProductMap::value_type(id, creator)).second != 0; } bool Unregister(const IdentifierType& id) { return associations_.erase(id) != 0; } bool IsRegistered(const IdentifierType& id) { return associations_.find(id) != associations_.end(); } std::vector RegisteredIds() { std::vector ids; for(typename IdToProductMap::iterator it = associations_.begin(); it != associations_.end(); ++it) { ids.push_back(it->first); } return ids; } AbstractProduct* CreateObject(const IdentifierType& id) { typename IdToProductMap::iterator i = associations_.find(id); if (i != associations_.end()) return (i->second)( ); return this->OnUnknownType(id); } AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1) { typename IdToProductMap::iterator i = associations_.find(id); if (i != associations_.end()) return (i->second)( p1 ); return this->OnUnknownType(id); } AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1, Parm2 p2) { typename IdToProductMap::iterator i = associations_.find(id); if (i != associations_.end()) return (i->second)( p1,p2 ); return this->OnUnknownType(id); } AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3) { typename IdToProductMap::iterator i = associations_.find(id); if (i != associations_.end()) return (i->second)( p1,p2,p3 ); return this->OnUnknownType(id); } AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4) { typename IdToProductMap::iterator i = associations_.find(id); if (i != associations_.end()) return (i->second)( p1,p2,p3,p4 ); return this->OnUnknownType(id); } AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5) { typename IdToProductMap::iterator i = associations_.find(id); if (i != associations_.end()) return (i->second)( p1,p2,p3,p4,p5 ); return this->OnUnknownType(id); } AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, Parm6 p6) { typename IdToProductMap::iterator i = associations_.find(id); if (i != associations_.end()) return (i->second)( p1,p2,p3,p4,p5,p6 ); return this->OnUnknownType(id); } AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, Parm6 p6, Parm7 p7 ) { typename IdToProductMap::iterator i = associations_.find(id); if (i != associations_.end()) return (i->second)( p1,p2,p3,p4,p5,p6,p7 ); return this->OnUnknownType(id); } AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, Parm6 p6, Parm7 p7, Parm8 p8) { typename IdToProductMap::iterator i = associations_.find(id); if (i != associations_.end()) return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8 ); return this->OnUnknownType(id); } AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9) { typename IdToProductMap::iterator i = associations_.find(id); if (i != associations_.end()) return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9 ); return this->OnUnknownType(id); } AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9,Parm10 p10) { typename IdToProductMap::iterator i = associations_.find(id); if (i != associations_.end()) return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10 ); return this->OnUnknownType(id); } AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11) { typename IdToProductMap::iterator i = associations_.find(id); if (i != associations_.end()) return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11 ); return this->OnUnknownType(id); } AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, Parm12 p12) { typename IdToProductMap::iterator i = associations_.find(id); if (i != associations_.end()) return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12 ); return this->OnUnknownType(id); } AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, Parm12 p12, Parm13 p13) { typename IdToProductMap::iterator i = associations_.find(id); if (i != associations_.end()) return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13 ); return this->OnUnknownType(id); } AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, Parm12 p12, Parm13 p13, Parm14 p14) { typename IdToProductMap::iterator i = associations_.find(id); if (i != associations_.end()) return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14 ); return this->OnUnknownType(id); } AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15) { typename IdToProductMap::iterator i = associations_.find(id); if (i != associations_.end()) return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15 ); return this->OnUnknownType(id); } }; #else template < class AbstractProduct, typename IdentifierType, typename ProductCreator = AbstractProduct* (*)(), template class FactoryErrorPolicy = DefaultFactoryError > class Factory : public FactoryErrorPolicy { public: bool Register(const IdentifierType& id, ProductCreator creator) { return associations_.insert( typename IdToProductMap::value_type(id, creator)).second != 0; } bool Unregister(const IdentifierType& id) { return associations_.erase(id) != 0; } AbstractProduct* CreateObject(const IdentifierType& id) { typename IdToProductMap::iterator i = associations_.find(id); if (i != associations_.end()) { return (i->second)(); } return this->OnUnknownType(id); } private: typedef AssocVector IdToProductMap; IdToProductMap associations_; }; #endif //#define ENABLE_NEW_FACTORY_CODE /** * \defgroup CloneFactoryGroup Clone Factory * \ingroup FactoriesGroup * \brief Creates a copy from a polymorphic object. * * \class CloneFactory * \ingroup CloneFactoryGroup * \brief Creates a copy from a polymorphic object. */ template < class AbstractProduct, class ProductCreator = AbstractProduct* (*)(const AbstractProduct*), template class FactoryErrorPolicy = DefaultFactoryError > class CloneFactory : public FactoryErrorPolicy { public: bool Register(const TypeInfo& ti, ProductCreator creator) { return associations_.insert( typename IdToProductMap::value_type(ti, creator)).second != 0; } bool Unregister(const TypeInfo& id) { return associations_.erase(id) != 0; } AbstractProduct* CreateObject(const AbstractProduct* model) { if (model == NULL) { return NULL; } typename IdToProductMap::iterator i = associations_.find(typeid(*model)); if (i != associations_.end()) { return (i->second)(model); } return this->OnUnknownType(typeid(*model)); } private: typedef AssocVector IdToProductMap; IdToProductMap associations_; }; } // namespace Loki #ifdef _MSC_VER #pragma warning( pop ) #endif #endif // end file guardian