//////////////////////////////////////////////////////////////////////////////// // The Loki Library // Copyright (c) 2005 by Peter Kuemmel // // Code covered by the MIT License // The authors make no representations about the suitability of this software // for any purpose. It is provided "as is" without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// // $Header$ //#define CLASS_LEVEL_THERADING #define USE_SEQUENCE #include #include #include #include #ifdef LOKI_DISABLE_TYPELIST_MACROS #define USE_WQUENCE #endif #ifdef USE_SEQUENCE #include #endif using namespace Loki; using std::cout; using std::endl; //////////////////////////////////////////// // Object to create: Product // Constructor with 0 and 2 arguments //////////////////////////////////////////// class AbstractProduct{}; class Product : public AbstractProduct { public: Product(){} Product( int, int ){} }; /////////////////////////////////////////////////////////// // Factory for creation a Product object without parameters /////////////////////////////////////////////////////////// typedef SingletonHolder < Factory< AbstractProduct, int >, CreateUsingNew, Loki::LongevityLifetime::DieAsSmallObjectChild > PFactoryNull; ///////////////////////////////////////////////////////////// // Factory for creation a Product object with 2 parameters ///////////////////////////////////////////////////////////// typedef SingletonHolder < #ifndef USE_SEQUENCE Factory< AbstractProduct, std::string, LOKI_TYPELIST_2( int, int ) >, #else Factory< AbstractProduct, std::string, Seq< int, int > >, #endif CreateUsingNew, Loki::LongevityLifetime::DieAsSmallObjectChild > PFactory; //////////////////////////////////////////////////// // Creator functions with different names //////////////////////////////////////////////////// Product* createProductNull() { cout << "createProductNull()" << endl; return new Product; } Product* createProductParm( int a, int b ) { cout << "createProductParm( int a, int b ) " << endl; return new Product( a, b ); } /////////////////////////////////////////////////// // Overloaded creator functions /////////////////////////////////////////////////// Product* createProductOver() { cout << "createProductOver()" << endl; return new Product; } Product* createProductOver( int a, int b ) { cout << "createProductOver( int a, int b )" << endl; return new Product( a, b ); } /////////////////////////////////////////////////// // Creator functions are polymorphic member functions /////////////////////////////////////////////////// class AbstractCreator{ public: virtual ~AbstractCreator() {} virtual AbstractProduct* create() = 0; virtual AbstractProduct* createParm( int, int ) = 0; }; class Creator : public AbstractCreator{ public: Creator(){}; AbstractProduct* create() { cout << "Creator::create()" << endl; return new Product; } AbstractProduct* createParm( int a, int b ) { cout << "Creator::create( int a, int b )" << endl; return new Product( a,b ); } }; /////////////////////////////////////////////////////////////// // Creator functions are member functions of a template class /////////////////////////////////////////////////////////////// template< class T> class CreatorT{ public: CreatorT(){}; T* create() { cout << "CreatorT::create()" << endl; return new T; } T* createParm( int a, int b ) { cout << "CreatorT::create( int a, int b )" << endl; return new T( a,b ); } }; /////////////////////////////////////////////////////////////// // get creator functions on runntime /////////////////////////////////////////////////////////////// #ifndef USE_SEQUENCE typedef Functor CreateFunctor; #else typedef Functor > CreateFunctor; #endif typedef SingletonHolder < #ifndef USE_SEQUENCE Factory< AbstractProduct, int,LOKI_TYPELIST_3(CreateFunctor,int,int) >, #else Factory< AbstractProduct, int,Seq >, #endif CreateUsingNew, Loki::LongevityLifetime::DieAsSmallObjectChild > PFactoryFunctorParm; Product* createProductRuntime(CreateFunctor func, int a, int b) { Product *p = func( a, b ); cout << " called by createProductRuntime(CreateFunctor func, int a, int b) " << endl; return p; } /////////////////////////////////////// // Register creator functions // No additional typdefs are necessary! ////////////////////////////////////// Creator creator; AbstractCreator* c = &creator; CreatorT cT; bool reg() { bool const ok1 = PFactoryNull::Instance().Register( 1, createProductNull ); bool const ok2 = PFactoryNull::Instance().Register( 2, (Product*(*)()) createProductOver ); bool const ok3 = PFactoryNull::Instance().Register( 3, c, &AbstractCreator::create ); bool const ok4 = PFactoryNull::Instance().Register( 4, &cT, &CreatorT::create ); bool const ok5 = PFactory::Instance().Register( "One", createProductParm ); bool const ok6 = PFactory::Instance().Register( "Two", (Product*(*)(int,int))createProductOver ); bool const ok7 = PFactory::Instance().Register( "Three", c, &AbstractCreator::createParm ); bool const ok8 = PFactory::Instance().Register( "Four", &cT, &CreatorT::createParm ); bool const ok9 = PFactoryFunctorParm::Instance().Register( 1, createProductRuntime ); return ok1 && ok2 && ok3 && ok4 && ok5 && ok6 && ok7 && ok8 && ok9; } //////////////////////////////////////////////////////////////////////////////////// // // detect memory leaks on MSVC Ide // //////////////////////////////////////////////////////////////////////////////////// //#define MSVC_DETECT_MEMORY_LEAKS #ifdef MSVC_DETECT_MEMORY_LEAKS #include #include void heap_debug() { int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); // Turn on leak-checking bit tmpFlag |= _CRTDBG_LEAK_CHECK_DF; //tmpFlag |= _CRTDBG_CHECK_MasterLWMasterYS_DF; // Turn off CRT block checking bit tmpFlag &= ~_CRTDBG_CHECK_CRT_DF; // Set flag to the new value _CrtSetDbgFlag( tmpFlag ); } #else void heap_debug() {} #endif int main() { heap_debug(); reg(); AbstractProduct* p; cout << endl << "creator function is a simple function:" << endl; p= PFactoryNull::Instance().CreateObject( 1 ); delete p; p= PFactory::Instance().CreateObject( "One", 64,64 ); delete p; cout << endl << "creator function is a overloaded function:" << endl; p= PFactoryNull::Instance().CreateObject( 2 ); delete p; p= PFactory::Instance().CreateObject( "Two", 64,64 ); delete p; cout << endl << "creator function is a member function:" << endl; p= PFactoryNull::Instance().CreateObject( 3 ); delete p; p= PFactory::Instance().CreateObject( "Three", 64,64 ); delete p; cout << endl << "creator function is a template member function" << endl; p= PFactoryNull::Instance().CreateObject( 4 ); delete p; p= PFactory::Instance().CreateObject( "Four", 64,64 ); delete p; CreateFunctor func1(createProductParm); CreateFunctor func2(&cT, &CreatorT::createParm); cout << endl << "creator function is a functor parameter" << endl; p= PFactoryFunctorParm::Instance().CreateObject( 1, func1, 64,64 ); delete p; p= PFactoryFunctorParm::Instance().CreateObject( 1, func2, 64,64 ); delete p; cout << endl; cout << "Registered ids: \n"; std::vector ids = PFactory::Instance().RegisteredIds(); for(std::vector::iterator it=ids.begin(); it!=ids.end(); ++it) cout << *it << "\n"; cout << endl; cout << endl; #if defined(__BORLANDC__) || defined(_MSC_VER) system("PAUSE"); #endif return EXIT_SUCCESS; } // $Log$ // Revision 1.12 2006/01/05 00:23:43 syntheticpp // always use #include , Thanks to Lukas Fittl // // Revision 1.11 2006/01/04 23:54:28 syntheticpp // remove system(PAUSE) for gcc, Thanks to Lukas Fittl // // Revision 1.10 2006/01/04 23:45:08 syntheticpp // remove gcc 4.0 warnings, Thanks to Lukas Fittl // // Revision 1.9 2005/11/12 16:52:36 syntheticpp // protect private data, add std::vector RegisteredIds() // // Revision 1.8 2005/11/07 12:06:43 syntheticpp // change lifetime policy DieOrder to a msvc7.1 compilable version. Make this the default lifetime for SmallObject // // Revision 1.7 2005/11/05 17:43:55 syntheticpp // disable FollowIntoDeath/DieOrder lifetime policies when using the msvc 7.1 compiler, bug article: 839821 'Microsoft has confirmed that this is a problem..' // // Revision 1.6 2005/11/01 11:38:19 syntheticpp // apply new lifetime policy to avoid crash on exit in test/Factory // // Revision 1.5 2005/10/30 14:03:23 syntheticpp // replace tabs space // // Revision 1.4 2005/10/30 13:49:44 syntheticpp // make disabling the TYPELIST macros possible // // Revision 1.3 2005/10/06 17:50:14 syntheticpp // adding template based list/sequence implementation, should replace LOKI_TYPELIST_, update some files // // Revision 1.2 2005/09/26 07:33:05 syntheticpp // move macros into LOKI_ namespace // // Revision 1.1 2005/09/24 16:10:14 syntheticpp // move Factory example // // Revision 1.1 2005/07/28 14:27:12 syntheticpp // add Factory example //