#include using std::cout; namespace test { /* === Layer-1: a singleton factory based on a templated static variable === */ template class Fac ///< Policy: actual factory to create the instance > struct Holder { static I* instance; I& get() { if (!instance) { cout << "Singleton Factory: invoke Fabrication ---> address of static instance variable: "<<&instance<<"...\n"; instance = Fac::create(); } return *instance; } }; /** * allocate storage for the per-type shared * (static) variable to hold the singleton instance */ template class F > I* Holder::instance; template struct Factory { static C* create() { return new C(); } }; /* === Layer-2: configurable product type === */ template struct Adapter { typedef I* FactoryFunction (void); static FactoryFunction* factoryFunction; template static I* concreteFactoryFunction() { return static_cast (Factory::create()); } template struct AdaptedConfigurableFactory { static X* create() { return (*factoryFunction)(); } }; }; /** storage for the per-type shared function pointer to the concrete factory */ template typename Adapter::FactoryFunction* Adapter::factoryFunction; template struct TypeInfo { }; /** * Singleton factory with the ability to configure the actual product type C * only at the \em definition site. Users get to see only the interface type T */ template struct ConfigurableHolder : Holder::template AdaptedConfigurableFactory> { /** define the actual product type */ template ConfigurableHolder (TypeInfo) { Adapter::factoryFunction = &Adapter::template concreteFactoryFunction; } }; /* === Actual usage: Test case fabricating Subject instances === */ struct Subject { static int creationCount; Subject(); }; typedef ConfigurableHolder AccessPoint; extern AccessPoint fab; Subject& fabricate(); } // namespace test