Factory.hpp
Go to the documentation of this file.
1 //===========================================================================
2 //
3 // File: Factory.hpp
4 //
5 // Created: Mon Nov 6 10:00:43 2000
6 //
7 // Author(s): Atgeirr F Rasmussen <atgeirr@sintef.no>
8 //
9 // $Date$
10 //
11 // $Revision$
12 //
13 //===========================================================================
14 
15 /*
16  Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
17  Copyright 2009, 2010 Statoil ASA.
18 
19  This file is part of the Open Porous Media project (OPM).
20 
21  OPM is free software: you can redistribute it and/or modify
22  it under the terms of the GNU General Public License as published by
23  the Free Software Foundation, either version 3 of the License, or
24  (at your option) any later version.
25 
26  OPM is distributed in the hope that it will be useful,
27  but WITHOUT ANY WARRANTY; without even the implied warranty of
28  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29  GNU General Public License for more details.
30 
31  You should have received a copy of the GNU General Public License
32  along with OPM. If not, see <http://www.gnu.org/licenses/>.
33 */
34 
35 #ifndef OPM_FACTORY_HEADER
36 #define OPM_FACTORY_HEADER
37 
38 #include <opm/common/ErrorMacros.hpp>
39 
40 #include <map>
41 #include <memory>
42 
43 namespace Opm
44 {
45 
52  template<class Base>
53  class Factory
54  {
55  public:
57  typedef std::shared_ptr<Base> ProductPtr;
58 
64  static ProductPtr createObject(const std::string& type)
65  {
66  return instance().doCreateObject(type);
67  }
68 
75  static ProductPtr cloneObject(const std::string& type,
76  const ProductPtr original)
77  {
78  return instance().doCloneObject(type, original);
79  }
80 
88  template<class Derived>
89  static void addCreator(const std::string& type)
90  {
91  instance().template doAddCreator<Derived>(type);
92  }
93 
94  private:
95  // The method that implements the singleton pattern,
96  // using the Meyers singleton technique.
97  static Factory& instance()
98  {
99  static Factory singleton;
100  return singleton;
101  }
102 
103  // Private constructor, to keep users from creating a Factory.
104  Factory()
105  {
106  }
107 
108  // Abstract base class for Creators.
109  class Creator
110  {
111  public:
112  virtual ProductPtr create() = 0;
113  virtual ProductPtr clone(ProductPtr original) = 0;
114  virtual ~Creator() {}
115  };
116 
118  template<class Derived>
119  class ConcreteCreator: public Creator
120  {
121  public:
122  virtual ProductPtr create()
123  {
124  return ProductPtr(new Derived);
125  }
126  virtual ProductPtr clone(const ProductPtr original)
127  {
128  const Derived& orig = dynamic_cast<const Derived&>(*original);
129  return ProductPtr(new Derived(orig));
130  }
131  };
132 
133  typedef std::shared_ptr<Creator> CreatorPtr;
134  typedef std::map<std::string, CreatorPtr> CreatorMap;
135  // This map contains the whole factory, i.e. all the Creators.
136  CreatorMap string_to_creator_;
137 
138  // Actually creates the product object.
139  ProductPtr doCreateObject(const std::string& type)
140  {
141  typename CreatorMap::iterator it;
142  it = string_to_creator_.find(type);
143  if (it == string_to_creator_.end()) {
144  OPM_THROW(std::runtime_error, "Creator type " << type
145  << " is not registered in the factory.");
146  }
147  return it->second->create();
148  }
149 
150  // Actually clones the product object.
151  ProductPtr doCloneObject(const std::string& type,
152  const ProductPtr original)
153  {
154  typename CreatorMap::iterator it;
155  it = string_to_creator_.find(type);
156  if (it == string_to_creator_.end()) {
157  OPM_THROW(std::runtime_error, "Creator type " << type
158  << " is not registered in the factory.");
159  }
160  return it->second->clone(original);
161  }
162 
163  // Actually adds the creator.
164  template<class Derived>
165  void doAddCreator(const std::string& type)
166  {
167  CreatorPtr c(new ConcreteCreator<Derived>);
168  string_to_creator_[type] = c;
169  }
170  };
171 
172 } // namespace Opm
173 
174 #endif // OPM_FACTORY_HEADER
static ProductPtr cloneObject(const std::string &type, const ProductPtr original)
Definition: Factory.hpp:75
Definition: AnisotropicEikonal.hpp:43
static void addCreator(const std::string &type)
Definition: Factory.hpp:89
Definition: Factory.hpp:53
std::shared_ptr< Base > ProductPtr
The type of pointer returned by createObject().
Definition: Factory.hpp:57
static ProductPtr createObject(const std::string &type)
Definition: Factory.hpp:64