LifeV
Factory.hpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 *******************************************************************************
4 
5  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
7 
8  This file is part of LifeV.
9 
10  LifeV is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  LifeV is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  @file
29  @brief Factory class
30 
31  @date 4-10-2004
32  @author Christophe Prud'homme <christophe.prudhomme@epfl.ch>
33 
34  @maintainer Radu Popescu <radu.popescu@epfl.ch>
35 */
36 
37 #ifndef FACTORY_H
38 #define FACTORY_H 1
39 
40 
41 #include <stdexcept>
42 
43 #include <boost/bind.hpp>
44 
45 
46 #include <lifev/core/LifeV.hpp>
47 
48 #include <lifev/core/util/LifeDebug.hpp>
49 #include <lifev/core/util/FactoryTypeInfo.hpp>
50 
51 namespace LifeV
52 {
53 
54 //! @struct FactoryDefaultError
55 /*!
56  Manages the "Unknown Type" error in an object factory.
57 */
58 template <class AbstractProduct>
60 {
61  class Exception : public std::exception
62  {
63  public:
64  //! @name Constructor and destructor
65  //@{
66 
67  Exception ( const std::string& id ) : std::exception(), M_exception()
68  {
69  std::ostringstream ex_str;
70  ex_str << "[factory] Unknown Type : " + id;
71  M_exception = ex_str.str();
72  }
73 
74  ~Exception() throw() {}
75 
76  //@}
77 
78 
79  //! @name Methods
80  //@{
81 
82  const char* what() const throw ()
83  {
84  return M_exception.c_str();
85  }
86 
87  //@}
88 
89  private:
90  std::string M_exception;
91  };
92 
93  static AbstractProduct* onUnknownType (const std::string& id )
94  {
95  throw Exception ( id );
96  }
97 };
98 
99 
100 
101 
102 
103 /*!
104  @class factory
105  @brief Implements a generic object factory
106 
107  @sa factoryDefaultError, factoryClone, FactoryTypeInfo
108 */
109 template < class AbstractProduct, typename IdentifierType,
110  typename ProductCreator = std::function<AbstractProduct*() >,
111  template<class> class FactoryErrorPolicy = FactoryDefaultError >
112 class Factory : public FactoryErrorPolicy<AbstractProduct>
113 {
114 public:
115  //! @name Public Typedefs
116  //@{
117 
118  typedef IdentifierType identifier_Type;
119  typedef AbstractProduct product_Type;
120  typedef ProductCreator creator_Type;
121  typedef FactoryErrorPolicy<product_Type> super;
122 
123  //@}
124 
125 
126  //! @name Constructor and destructor
127  //@{
128 
129  Factory() {}
130 
131  virtual ~Factory() {}
132 
133  //@}
134 
135 
136  //! @name Methods
137  //@{
138 
139  /**
140  * Register a product.
141  *
142  * A product is composed of an identifier (typically a
143  * std::string) and a functor that will create the associated
144  * object.
145  *
146  * @param id identifier for the object to be registered
147  * @param creator the functor that will create the registered
148  * object
149  *
150  * @return true if registration went fine, false otherwise
151  */
152  bool registerProduct ( const identifier_Type& id, creator_Type creator )
153  {
154 #ifdef HAVE_LIFEV_DEBUG
155  debugStream ( 2200 ) << "Registered type with id : " << id << "\n";
156 #endif
157  return M_associations.insert ( typename productId_Type::value_type ( id, creator ) ).second;
158  }
159 
160  /**
161  * Unregister a product
162  *
163  * @param id
164  * @sa registerProduct
165  * @return true if unregistration went fine, false otherwise
166  */
168  {
169 #ifdef HAVE_LIFEV_DEBUG
170  debugStream ( 2200 ) << "Unregistered type with id : " << id << "\n";
171 #endif
172  return M_associations.erase ( id ) == 1;
173  }
174 
175  /**
176  * Create an object from a product registered in the factory using
177  * identifier \c id
178  *
179  * @param id identifier of the product to instantiate
180  *
181  * @return the object associate with \c id
182  */
184  {
185  typename productId_Type::const_iterator i = M_associations.find ( id );
186  if (i != M_associations.end() )
187  {
188 #ifdef HAVE_LIFEV_DEBUG
189  debugStream ( 2200 ) << "Creating type with id : " << id << "\n";
190 #endif
191  return (i->second) ();
192  }
193 #ifdef HAVE_LIFEV_DEBUG
194  debugStream ( 2200 ) << "Unknown type with id : " << id << "\n";
195 #endif
196  return super::onUnknownType ( id );
197  }
198 
199  /**
200  * Create an object from a product registered in the factory using
201  * identifier \c id (of type enum) and a map to catch the exception.
202  *
203  * @param id identifier of the product to instantiate
204  *
205  * @return the object associate with \c id
206  */
207  template< typename map_Type >
208  product_Type* createObject ( const identifier_Type& id, const map_Type& map )
209  {
210  typename productId_Type::const_iterator i = M_associations.find ( id );
211  if ( i != M_associations.end() )
212  {
213 #ifdef HAVE_LIFEV_DEBUG
214  debugStream ( 2200 ) << "Creating type with id : " << enum2String ( id, map ) << "\n";
215 #endif
216  return (i->second) ();
217  }
218 #ifdef HAVE_LIFEV_DEBUG
219  debugStream ( 2200 ) << "Unknown type with id : " << enum2String ( id, map ) << "\n";
220 #endif
221  return super::onUnknownType ( enum2String ( id, map ) );
222  }
223 
224  //@}
225 
226 private:
227 
228  //! @name Private typedefs
229  //@{
230 
232 
233  //@}
234 
236 };
237 
238 
239 }
240 #endif // FACTORY_H
AbstractProduct product_Type
Definition: Factory.hpp:119
product_Type * createObject(const identifier_Type &id)
Create an object from a product registered in the factory using identifier id.
Definition: Factory.hpp:183
virtual ~Factory()
Definition: Factory.hpp:131
product_Type * createObject(const identifier_Type &id, const map_Type &map)
Create an object from a product registered in the factory using identifier id (of type enum) and a ma...
Definition: Factory.hpp:208
ProductCreator creator_Type
Definition: Factory.hpp:120
void updateInverseJacobian(const UInt &iQuadPt)
productId_Type M_associations
Definition: Factory.hpp:235
static AbstractProduct * onUnknownType(const std::string &id)
Definition: Factory.hpp:93
FactoryErrorPolicy< product_Type > super
Definition: Factory.hpp:121
bool unregisterProduct(const identifier_Type &id)
Unregister a product.
Definition: Factory.hpp:167
std::map< identifier_Type, creator_Type > productId_Type
Definition: Factory.hpp:231
Exception(const std::string &id)
Definition: Factory.hpp:67
bool registerProduct(const identifier_Type &id, creator_Type creator)
Register a product.
Definition: Factory.hpp:152
IdentifierType identifier_Type
Definition: Factory.hpp:118