Factory.h

  1 ////////////////////////////////////////////////////////////////////////////////
  2 // The Loki Library
  3 // Copyright (c) 2001 by Andrei Alexandrescu
  4 // This code accompanies the book:
  5 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 
  6 //     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
  7 // Permission to use, copy, modify, distribute and sell this software for any 
  8 //     purpose is hereby granted without fee, provided that the above copyright 
  9 //     notice appear in all copies and that both that copyright notice and this 
 10 //     permission notice appear in supporting documentation.
 11 // The author or Addison-Welsey Longman make no representations about the 
 12 //     suitability of this software for any purpose. It is provided "as is" 
 13 //     without express or implied warranty.
 14 ////////////////////////////////////////////////////////////////////////////////
 15 
 16 // Last update: June 20, 2001
 17 
 18 #ifndef FACTORY_INC_
 19 #define FACTORY_INC_
 20 
 21 #include "TypeInfo.h"
 22 #include "AssocVector.h"
 23 #include <exception>
 24 
 25 namespace Loki
 26 {
 27 
 28 ////////////////////////////////////////////////////////////////////////////////
 29 // class template DefaultFactoryError
 30 // Manages the "Unknown Type" error in an object factory
 31 ////////////////////////////////////////////////////////////////////////////////
 32 
 33     template <typename IdentifierType, class AbstractProduct>
 34     struct DefaultFactoryError
 35     {
 36         struct Exception : public std::exception
 37         {
 38             const char* what() const { return "Unknown Type"; }
 39         };
 40         
 41         static AbstractProduct* OnUnknownType(IdentifierType)
 42         {
 43             throw Exception();
 44         }
 45     };
 46 
 47 ////////////////////////////////////////////////////////////////////////////////
 48 // class template Factory
 49 // Implements a generic object factory
 50 ////////////////////////////////////////////////////////////////////////////////
 51 
 52     template
 53     <
 54         class AbstractProduct, 
 55         typename IdentifierType,
 56         typename ProductCreator = AbstractProduct* (*)(),
 57         template<typename, class>
 58             class FactoryErrorPolicy = DefaultFactoryError
 59     >
 60     class Factory 
 61         : public FactoryErrorPolicy<IdentifierType, AbstractProduct>
 62     {
 63     public:
 64         bool Register(const IdentifierType& id, ProductCreator creator)
 65         {
 66             return associations_.insert(
 67                 IdToProductMap::value_type(id, creator)).second;
 68         }
 69         
 70         bool Unregister(const IdentifierType& id)
 71         {
 72             return associations_.erase(id) == 1;
 73         }
 74         
 75         AbstractProduct* CreateObject(const IdentifierType& id)
 76         {
 77             typename IdToProductMap::const_iterator i = associations_.find(id);
 78             if (i != associations_.end())
 79             {
 80                 return (i->second)();
 81             }
 82             return OnUnknownType(id);
 83         }
 84         
 85     private:
 86         typedef AssocVector<IdentifierType, ProductCreator> IdToProductMap;
 87         IdToProductMap associations_;
 88     };
 89 
 90 ////////////////////////////////////////////////////////////////////////////////
 91 // class template CloneFactory
 92 // Implements a generic cloning factory
 93 ////////////////////////////////////////////////////////////////////////////////
 94 
 95     template
 96     <
 97         class AbstractProduct, 
 98         class ProductCreator = 
 99             AbstractProduct* (*)(const AbstractProduct*),
100         template<typename, class>
101             class FactoryErrorPolicy = DefaultFactoryError
102     >
103     class CloneFactory
104         : public FactoryErrorPolicy<TypeInfo, AbstractProduct>
105     {
106     public:
107         bool Register(const TypeInfo& ti, ProductCreator creator)
108         {
109             return associations_.insert(
110                 IdToProductMap::value_type(ti, creator)).second;
111         }
112         
113         bool Unregister(const TypeInfo& id)
114         {
115             return associations_.erase(id) == 1;
116         }
117         
118         AbstractProduct* CreateObject(const AbstractProduct* model)
119         {
120             if (model == 0) return 0;
121             
122             typename IdToProductMap::const_iterator i = 
123                 associations_.find(typeid(*model));
124             if (i != associations_.end())
125             {
126                 return (i->second)(model);
127             }
128             return OnUnknownType(typeid(*model));
129         }
130         
131     private:
132         typedef AssocVector<TypeInfo, ProductCreator> IdToProductMap;
133         IdToProductMap associations_;
134     };
135 } // namespace Loki
136 
137 ////////////////////////////////////////////////////////////////////////////////
138 // Change log:
139 // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
140 ////////////////////////////////////////////////////////////////////////////////
141 
142 #endif // FACTORY_INC_
posted @ 2012-10-31 15:13  crazylhf  阅读(198)  评论(0)    收藏  举报