Logo  0.95.0-final
Finite Element Embedded Library and Language in C++
Feel++ Feel++ on Github Feel++ community
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
factory.hpp
Go to the documentation of this file.
1 /* -*- mode: c++; coding: utf-8; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; show-trailing-whitespace: t -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
2 
3  This file is part of the Feel library
4 
5  Author(s): Christophe Prud'homme <christophe.prudhomme@feelpp.org>
6  Date: 2004-10-04
7 
8  Copyright (C) 2009 Université de Grenoble 1
9  Copyright (C) 2004 EPFL
10 
11  This library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU Lesser General Public
13  License as published by the Free Software Foundation; either
14  version 3.0 of the License, or (at your option) any later version.
15 
16  This library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  Lesser General Public License for more details.
20 
21  You should have received a copy of the GNU Lesser General Public
22  License along with this library; if not, write to the Free Software
23  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 */
30 #ifndef __factory_H
31 #define __factory_H 1
32 
33 #include <map>
34 #include <stdexcept>
35 #include <string>
36 
37 #include <boost/function.hpp>
38 #include <boost/bind.hpp>
39 
40 #include <feel/feelcore/feel.hpp>
41 #include <feel/feelcore/typeinfo.hpp>
42 
43 namespace Feel
44 {
48 template <
49 typename IdentifierType,
50  class AbstractProduct
51  >
53 {
54  class Exception
55  :
56  public std::exception
57  {
58  public:
59  Exception( IdentifierType id )
60  :
61  std::exception(),
62  M_ex()
63  {
64  M_ex = this->getEx( id );
65 
66  }
67  ~Exception() throw()
68  {}
69  const char* what() const throw ()
70  {
71  return M_ex.c_str();
72  }
73  std::string getEx( std::string const& id )
74  {
75  std::ostringstream __ex_str;
76  __ex_str << "[Factory] Unknown Type : " << id;
77  return __ex_str.str();
78  }
79  template<typename T>
80  std::string getEx( T const& id )
81  {
82  std::ostringstream __ex_str;
83  __ex_str << "[Factory] Unknown Type : ";
84  return __ex_str.str();
85  }
86  private:
87  std::string M_ex;
88  };
89 
90  static AbstractProduct* onUnknownType( IdentifierType id )
91  {
92  throw Exception( id );
93  }
94 };
95 
105 template
106 <
107 class AbstractProduct,
108  typename IdentifierType,
109  typename ProductCreator = boost::function<AbstractProduct*()>,
110  template<typename, class> class FactoryErrorPolicy = FactoryDefaultError
111  >
112 class Factory
113  :
114 public FactoryErrorPolicy<IdentifierType,AbstractProduct>
115 {
116 public:
117 
118 
122  typedef IdentifierType identifier_type;
123  typedef AbstractProduct product_type;
124  typedef ProductCreator creator_type;
125 
126  typedef FactoryErrorPolicy<identifier_type,product_type> super;
127 
129 
130 
134 
148  bool registerProduct( const identifier_type& id, creator_type creator )
149  {
150  DVLOG(2) << "Registered type with id : " << id << "\n";
151  return M_associations.insert( typename id_to_product_type::value_type( id, creator ) ).second;
152  }
153 
161  bool unregisterProduct( const identifier_type& id )
162  {
163  DVLOG(2) << "Unregistered type with id : " << id << "\n";
164  return M_associations.erase( id ) == 1;
165  }
166 
175  product_type* createObject( const identifier_type& id )
176  {
177  typename id_to_product_type::const_iterator i = M_associations.find( id );
178 
179  if ( i != M_associations.end() )
180  {
181  DVLOG(2) << "Creating type with id : " << id << "\n";
182  return ( i->second )();
183  }
184 
185  DVLOG(2) << "Unknown type with id : " << id << "\n";
186  return super::onUnknownType( id );
187  }
188 
189 
190 
192 private:
193  typedef std::map<identifier_type, creator_type> id_to_product_type;
194  id_to_product_type M_associations;
195 
196 };
197 
207 template <
208 class AbstractProduct,
209  class ProductCreator = boost::function<AbstractProduct* ( const AbstractProduct* )>,
210  template<typename, class> class FactoryErrorPolicy = FactoryDefaultError
211  >
213  :
214 public FactoryErrorPolicy<TypeInfo, AbstractProduct>
215 {
216 public:
217 
218 
222 
223  typedef FactoryErrorPolicy<TypeInfo,AbstractProduct> super;
224 
226 
230 
232 
236 
237 
239 
243 
244 
246 
250 
251 
253 
257 
258  bool registerProduct( const TypeInfo& id, ProductCreator creator )
259  {
260  return M_associations.insert( typename id_to_product_type::value_type( id, creator ) ).second;
261  }
262 
263  bool unregisterProduct( const TypeInfo& id )
264  {
265  return M_associations.erase( id ) == 1;
266  }
267 
268  AbstractProduct* createObject( const AbstractProduct* model )
269  {
270  if ( model == 0 ) return 0;
271 
272  typename id_to_product_type::const_iterator i = M_associations.find( typeid( *model ) );
273 
274  if ( i != M_associations.end() )
275  {
276  return ( i->second )( model );
277  }
278 
279  return super::onUnknownType( typeid( *model ) );
280  }
281 
283 
284 private:
285  typedef std::map<TypeInfo, ProductCreator> id_to_product_type;
286  id_to_product_type M_associations;
287 };
288 
289 
290 }
291 #endif /* __Factory_H */

Generated on Fri Oct 25 2013 14:24:09 for Feel++ by doxygen 1.8.4