diff options
Diffstat (limited to 'shared/loki/AbstractFactory.h')
-rw-r--r-- | shared/loki/AbstractFactory.h | 216 |
1 files changed, 108 insertions, 108 deletions
diff --git a/shared/loki/AbstractFactory.h b/shared/loki/AbstractFactory.h index 8ff518dc..9a30583b 100644 --- a/shared/loki/AbstractFactory.h +++ b/shared/loki/AbstractFactory.h @@ -2,14 +2,14 @@ // The Loki Library // Copyright (c) 2001 by Andrei Alexandrescu // This code accompanies the book: -// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design +// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design // Patterns Applied". Copyright (c) 2001. Addison-Wesley. -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this +// Permission to use, copy, modify, distribute and sell this software for any +// purpose is hereby granted without fee, provided that the above copyright +// notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. -// The author or Addison-Wesley Longman make no representations about the -// suitability of this software for any purpose. It is provided "as is" +// The author or Addison-Wesley Longman make no representations about the +// suitability of this software for any purpose. It is provided "as is" // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// #ifndef LOKI_ABSTRACTFACTORY_INC_ @@ -31,7 +31,7 @@ * \ingroup FactoriesGroup * \brief Implements an abstract object factory. */ - + /** * \class AbstractFactory * \ingroup AbstractFactoryGroup @@ -46,137 +46,137 @@ namespace Loki // The building block of an Abstract Factory //////////////////////////////////////////////////////////////////////////////// - template <class T> - class AbstractFactoryUnit - { - public: - virtual T* DoCreate(Type2Type<T>) = 0; - virtual ~AbstractFactoryUnit() {} - }; +template <class T> +class AbstractFactoryUnit +{ +public: + virtual T* DoCreate(Type2Type<T>) = 0; + virtual ~AbstractFactoryUnit() {} +}; //////////////////////////////////////////////////////////////////////////////// // class template AbstractFactory // Defines an Abstract Factory interface starting from a typelist //////////////////////////////////////////////////////////////////////////////// - template - < - class TList, - template <class> class Unit = AbstractFactoryUnit - > - class AbstractFactory : public GenScatterHierarchy<TList, Unit> +template +< +class TList, + template <class> class Unit = AbstractFactoryUnit + > +class AbstractFactory : public GenScatterHierarchy<TList, Unit> +{ +public: + typedef TList ProductList; + + template <class T> T* Create() { - public: - typedef TList ProductList; - - template <class T> T* Create() - { - Unit<T>& unit = *this; - return unit.DoCreate(Type2Type<T>()); - } - }; - + Unit<T>& unit = *this; + return unit.DoCreate(Type2Type<T>()); + } +}; + //////////////////////////////////////////////////////////////////////////////// // class template OpNewFactoryUnit // Creates an object by invoking the new operator //////////////////////////////////////////////////////////////////////////////// - template <class ConcreteProduct, class Base> - class OpNewFactoryUnit : public Base +template <class ConcreteProduct, class Base> +class OpNewFactoryUnit : public Base +{ + typedef typename Base::ProductList BaseProductList; + +protected: + typedef typename BaseProductList::Tail ProductList; + +public: + typedef typename BaseProductList::Head AbstractProduct; + ConcreteProduct* DoCreate(Type2Type<AbstractProduct>) { - typedef typename Base::ProductList BaseProductList; - - protected: - typedef typename BaseProductList::Tail ProductList; - - public: - typedef typename BaseProductList::Head AbstractProduct; - ConcreteProduct* DoCreate(Type2Type<AbstractProduct>) - { - return new ConcreteProduct; - } - }; + return new ConcreteProduct; + } +}; //////////////////////////////////////////////////////////////////////////////// // class template PrototypeFactoryUnit // Creates an object by cloning a prototype // There is a difference between the implementation herein and the one described -// in the book: GetPrototype and SetPrototype use the helper friend +// in the book: GetPrototype and SetPrototype use the helper friend // functions DoGetPrototype and DoSetPrototype. The friend functions avoid // name hiding issues. Plus, GetPrototype takes a reference to pointer // instead of returning the pointer by value. //////////////////////////////////////////////////////////////////////////////// - template <class ConcreteProduct, class Base> - class PrototypeFactoryUnit : public Base +template <class ConcreteProduct, class Base> +class PrototypeFactoryUnit : public Base +{ + typedef typename Base::ProductList BaseProductList; + +protected: + typedef typename BaseProductList::Tail ProductList; + +public: + typedef typename BaseProductList::Head AbstractProduct; + + PrototypeFactoryUnit(AbstractProduct* p = 0) + : pPrototype_(p) + {} + + template <class CP, class Base1> + friend void DoGetPrototype(const PrototypeFactoryUnit<CP, Base1>& me, + typename Base1::ProductList::Head*& pPrototype); + + template <class CP, class Base1> + friend void DoSetPrototype(PrototypeFactoryUnit<CP, Base1>& me, + typename Base1::ProductList::Head* pObj); + + template <class U> + void GetPrototype(U*& p) + { return DoGetPrototype(*this, p); } + + template <class U> + void SetPrototype(U* pObj) + { DoSetPrototype(*this, pObj); } + + AbstractProduct* DoCreate(Type2Type<AbstractProduct>) { - typedef typename Base::ProductList BaseProductList; - - protected: - typedef typename BaseProductList::Tail ProductList; - - public: - typedef typename BaseProductList::Head AbstractProduct; - - PrototypeFactoryUnit(AbstractProduct* p = 0) - : pPrototype_(p) - {} - - template <class CP, class Base1> - friend void DoGetPrototype(const PrototypeFactoryUnit<CP, Base1>& me, - typename Base1::ProductList::Head*& pPrototype); - - template <class CP, class Base1> - friend void DoSetPrototype(PrototypeFactoryUnit<CP, Base1>& me, - typename Base1::ProductList::Head* pObj); - - template <class U> - void GetPrototype(U*& p) - { return DoGetPrototype(*this, p); } - - template <class U> - void SetPrototype(U* pObj) - { DoSetPrototype(*this, pObj); } - - AbstractProduct* DoCreate(Type2Type<AbstractProduct>) - { - assert(pPrototype_); - return pPrototype_->Clone(); - } - - private: - AbstractProduct* pPrototype_; - }; - - template <class CP, class Base> - inline void DoGetPrototype(const PrototypeFactoryUnit<CP, Base>& me, - typename Base::ProductList::Head*& pPrototype) - { pPrototype = me.pPrototype_; } - - template <class CP, class Base> - inline void DoSetPrototype(PrototypeFactoryUnit<CP, Base>& me, - typename Base::ProductList::Head* pObj) - { me.pPrototype_ = pObj; } + assert(pPrototype_); + return pPrototype_->Clone(); + } + +private: + AbstractProduct* pPrototype_; +}; + +template <class CP, class Base> +inline void DoGetPrototype(const PrototypeFactoryUnit<CP, Base>& me, + typename Base::ProductList::Head*& pPrototype) +{ pPrototype = me.pPrototype_; } + +template <class CP, class Base> +inline void DoSetPrototype(PrototypeFactoryUnit<CP, Base>& me, + typename Base::ProductList::Head* pObj) +{ me.pPrototype_ = pObj; } //////////////////////////////////////////////////////////////////////////////// // class template ConcreteFactory // Implements an AbstractFactory interface //////////////////////////////////////////////////////////////////////////////// - template - < - class AbstractFact, - template <class, class> class Creator = OpNewFactoryUnit, - class TList = typename AbstractFact::ProductList - > - class ConcreteFactory - : public GenLinearHierarchy< - typename TL::Reverse<TList>::Result, Creator, AbstractFact> - { - public: - typedef typename AbstractFact::ProductList ProductList; - typedef TList ConcreteProductList; - }; +template +< +class AbstractFact, + template <class, class> class Creator = OpNewFactoryUnit, + class TList = typename AbstractFact::ProductList + > +class ConcreteFactory + : public GenLinearHierarchy< + typename TL::Reverse<TList>::Result, Creator, AbstractFact> +{ +public: + typedef typename AbstractFact::ProductList ProductList; + typedef TList ConcreteProductList; +}; } // namespace Loki |