CHROMA
objfactory.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /*! @file
3  * @brief Factory class for objects from XML input
4  */
5 
6 #ifndef __objfact_h__
7 #define __objfact_h__
8 
9 #include "chromabase.h"
10 
11 #include "typeinfo.h"
12 #include "typelist.h"
13 #include <map>
14 #include <exception>
15 
16 
17 namespace Chroma
18 {
19 
20 ////////////////////////////////////////////////////////////////////////////////
21 // class template DefaultFactoryError
22 // Manages the "Unknown Type" error in an object factory
23 ////////////////////////////////////////////////////////////////////////////////
24 
25  template <typename IdentifierType, class AbstractProduct>
27  {
28  struct Exception : public std::exception
29  {
30  const char* what() const throw() { return "Unknown Type"; }
31  };
32 
33  static AbstractProduct* OnUnknownType(const IdentifierType& id)
34  {
35  throw Exception();
36  }
37  };
38 
39 ////////////////////////////////////////////////////////////////////////////////
40 // class template StringFactoryError
41 // Manages the "Unknown Type" error in an object factory
42 ////////////////////////////////////////////////////////////////////////////////
43 
44  template <typename IdentifierType, class AbstractProduct>
46  {
47  static AbstractProduct* OnUnknownType(const IdentifierType& id)
48  {
49  std::ostringstream os;
50  os << "Factory error: unknown identifier: id = " << id << std::endl;
51  throw os.str();
52  }
53  };
54 
55 ////////////////////////////////////////////////////////////////////////////////
56 // class template NullFactoryError
57 // Manages the "Unknown Type" error in an object factory
58 ////////////////////////////////////////////////////////////////////////////////
59 
60  template <typename IdentifierType, class AbstractProduct>
62  {
63  static AbstractProduct* OnUnknownType(const IdentifierType&)
64  {
65  return 0;
66  }
67  };
68 
69 
70 //! Object factory class
71 /*! @ingroup actions
72  *
73  * Supports abstract creation of objects
74  */
75  template<class AbstractProduct,
76  typename IdentifierType,
77  class TList = NullType,
78  typename ProductCreator = AbstractProduct* (*)(),
79  template<typename, class>
80  class FactoryErrorPolicy = DefaultFactoryError>
81  class ObjectFactory : public FactoryErrorPolicy<IdentifierType, AbstractProduct>
82  {
83  public:
84  // Handy type definitions for the body type
85  typedef TList ParmList;
95 
96  // Member functions
97  //! Register the object
98  /*!
99  * \param id object id
100  * \param creator the callback function to create the object
101  * \return returns true if registration successful
102  */
103  bool registerObject(const IdentifierType& id, ProductCreator creator)
104  {
105  return associations_.insert(
106  typename IdToProductMap::value_type(id, creator)).second;
107  }
108 
109  //! Unregister the object
110  /*!
111  * \param id object id
112  * \return returns true if object name was registered before
113  */
114  bool unregisterObject(const IdentifierType& id)
115  {
116  return associations_.erase(id) == 1;
117  }
118 
119  //! Create the object
120  /*!
121  * \param id object id
122  * \return returns pointer to the object
123  */
124  AbstractProduct* createObject(const IdentifierType& id)
125  {
126  typename IdToProductMap::const_iterator i = associations_.find(id);
127  if (i == associations_.end()) {
128 
129  typedef typename IdToProductMap::const_iterator CI;
130  QDPIO::cerr << "Couldnt find key " << id << " in the std::map: " << std::endl;
131  QDPIO::cerr << "Available Keys are : " << std::endl;
132  for( CI j = associations_.begin();
133  j != associations_.end(); j++) {
134  QDPIO::cerr << j->first << std::endl << std::flush;
135  }
136 
137  return this->OnUnknownType(id);
138  }
139  else {
140  return (i->second)();
141  }
142  }
143 
144  //! Create the object
145  /*!
146  * \param id object id
147  * \param p1 first parameter arg to callback
148  * \return returns pointer to the object
149  */
150  AbstractProduct* createObject(const IdentifierType& id, Parm1 p1)
151  {
152  typename IdToProductMap::const_iterator i = associations_.find(id);
153  if (i == associations_.end()) {
154 
155  typedef typename IdToProductMap::const_iterator CI;
156  QDPIO::cerr << "Couldnt find key " << id << " in the std::map: " << std::endl;
157  QDPIO::cerr << "Available Keys are : " << std::endl;
158  for( CI j = associations_.begin();
159  j != associations_.end(); j++) {
160  QDPIO::cerr << j->first << std::endl << std::flush;
161  }
162 
163  return this->OnUnknownType(id);
164  }
165  else {
166  return (i->second)(p1);
167  }
168  }
169 
170  AbstractProduct* createObject(const IdentifierType& id, Parm1 p1, Parm2 p2)
171  {
172  typename IdToProductMap::const_iterator i = associations_.find(id);
173  if (i == associations_.end()) {
174 
175  typedef typename IdToProductMap::const_iterator CI;
176  QDPIO::cerr << "Couldnt find key " << id << " in the std::map: " << std::endl;
177  QDPIO::cerr << "Available Keys are : " << std::endl;
178  for( CI j = associations_.begin();
179  j != associations_.end(); j++) {
180  QDPIO::cerr << j->first << std::endl << std::flush;
181  }
182 
183  return this->OnUnknownType(id);
184  }
185  else {
186  return (i->second)(p1, p2);
187  }
188  }
189 
190  AbstractProduct* createObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3)
191  {
192  typename IdToProductMap::const_iterator i = associations_.find(id);
193  if (i == associations_.end()) {
194 
195  typedef typename IdToProductMap::const_iterator CI;
196  QDPIO::cerr << "Couldnt find key " << id << " in the std::map: " << std::endl;
197  QDPIO::cerr << "Available Keys are : " << std::endl;
198  for( CI j = associations_.begin();
199  j != associations_.end(); j++) {
200  QDPIO::cerr << j->first << std::endl << std::flush;
201  }
202 
203  return this->OnUnknownType(id);
204  }
205  else {
206  return (i->second)(p1, p2, p3);
207  }
208  }
209 
210  AbstractProduct* createObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3,
211  Parm4 p4)
212  {
213  typename IdToProductMap::const_iterator i = associations_.find(id);
214  if (i == associations_.end()) {
215 
216  typedef typename IdToProductMap::const_iterator CI;
217  QDPIO::cerr << "Couldnt find key " << id << " in the std::map: " << std::endl;
218  QDPIO::cerr << "Available Keys are : " << std::endl;
219  for( CI j = associations_.begin();
220  j != associations_.end(); j++) {
221  QDPIO::cerr << j->first << std::endl << std::flush;
222  }
223 
224  return this->OnUnknownType(id);
225  }
226  else {
227  return (i->second)(p1, p2, p3, p4);
228  }
229  }
230 
231  AbstractProduct* createObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3,
232  Parm4 p4, Parm5 p5)
233  {
234  typename IdToProductMap::const_iterator i = associations_.find(id);
235  if (i == associations_.end()) {
236 
237  typedef typename IdToProductMap::const_iterator CI;
238  QDPIO::cerr << "Couldnt find key " << id << " in the std::map: " << std::endl;
239  QDPIO::cerr << "Available Keys are : " << std::endl;
240  for( CI j = associations_.begin();
241  j != associations_.end(); j++) {
242  QDPIO::cerr << j->first << std::endl << std::flush;
243  }
244 
245  return this->OnUnknownType(id);
246  }
247  else {
248  return (i->second)(p1, p2, p3, p4, p5);
249  }
250  }
251 
252  AbstractProduct* createObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3,
253  Parm4 p4, Parm5 p5, Parm6 p6)
254  {
255  typename IdToProductMap::const_iterator i = associations_.find(id);
256  if (i == associations_.end()) {
257 
258  typedef typename IdToProductMap::const_iterator CI;
259  QDPIO::cerr << "Couldnt find key " << id << " in the std::map: " << std::endl;
260  QDPIO::cerr << "Available Keys are : " << std::endl;
261  for( CI j = associations_.begin();
262  j != associations_.end(); j++) {
263  QDPIO::cerr << j->first << std::endl << std::flush;
264  }
265 
266  return this->OnUnknownType(id);
267  }
268  else {
269  return (i->second)(p1, p2, p3, p4, p5, p6);
270  }
271  }
272 
273  AbstractProduct* createObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3,
274  Parm4 p4, Parm5 p5, Parm6 p6, Parm7 p7)
275  {
276  typename IdToProductMap::const_iterator i = associations_.find(id);
277  if (i == associations_.end()) {
278 
279  typedef typename IdToProductMap::const_iterator CI;
280  QDPIO::cerr << "Couldnt find key " << id << " in the std::map: " << std::endl;
281  QDPIO::cerr << "Available Keys are : " << std::endl;
282  for( CI j = associations_.begin();
283  j != associations_.end(); j++) {
284  QDPIO::cerr << j->first << std::endl << std::flush;
285  }
286 
287  return this->OnUnknownType(id);
288  }
289  else {
290  return (i->second)(p1, p2, p3, p4, p5, p6, p7);
291  }
292  }
293 
294  AbstractProduct* createObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3,
295  Parm4 p4, Parm5 p5, Parm6 p6, Parm7 p7, Parm8 p8)
296  {
297  typename IdToProductMap::const_iterator i = associations_.find(id);
298  if (i == associations_.end()) {
299 
300  typedef typename IdToProductMap::const_iterator CI;
301  QDPIO::cerr << "Couldnt find key " << id << " in the std::map: " << std::endl;
302  QDPIO::cerr << "Available Keys are : " << std::endl;
303  for( CI j = associations_.begin();
304  j != associations_.end(); j++) {
305  QDPIO::cerr << j->first << std::endl << std::flush;
306  }
307 
308  return this->OnUnknownType(id);
309  }
310  else {
311  return (i->second)(p1, p2, p3, p4, p5, p6, p7, p8);
312  }
313  }
314 
315 
316  private:
317  typedef std::map<IdentifierType, ProductCreator> IdToProductMap;
319  };
320 
321 } // namespace Chroma
322 
323 #endif
Primary include file for CHROMA library code.
Object factory class.
Definition: objfactory.h:82
TL::TypeAtNonStrict< ParmList, 5, NullType >::Result Parm6
Definition: objfactory.h:91
TL::TypeAtNonStrict< ParmList, 7, NullType >::Result Parm8
Definition: objfactory.h:93
bool registerObject(const IdentifierType &id, ProductCreator creator)
Register the object.
Definition: objfactory.h:103
TL::TypeAtNonStrict< ParmList, 0, NullType >::Result Parm1
Definition: objfactory.h:86
AbstractProduct * createObject(const IdentifierType &id, Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, Parm6 p6)
Definition: objfactory.h:252
AbstractProduct * createObject(const IdentifierType &id, Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, Parm6 p6, Parm7 p7)
Definition: objfactory.h:273
AbstractProduct * createObject(const IdentifierType &id, Parm1 p1, Parm2 p2)
Definition: objfactory.h:170
std::map< IdentifierType, ProductCreator > IdToProductMap
Definition: objfactory.h:317
TL::TypeAtNonStrict< ParmList, 3, NullType >::Result Parm4
Definition: objfactory.h:89
AbstractProduct * createObject(const IdentifierType &id, Parm1 p1)
Create the object.
Definition: objfactory.h:150
AbstractProduct * createObject(const IdentifierType &id, Parm1 p1, Parm2 p2, Parm3 p3)
Definition: objfactory.h:190
TL::TypeAtNonStrict< ParmList, 1, NullType >::Result Parm2
Definition: objfactory.h:87
TL::TypeAtNonStrict< ParmList, 2, NullType >::Result Parm3
Definition: objfactory.h:88
AbstractProduct * createObject(const IdentifierType &id)
Create the object.
Definition: objfactory.h:124
TL::TypeAtNonStrict< ParmList, 8, NullType >::Result Parm9
Definition: objfactory.h:94
TL::TypeAtNonStrict< ParmList, 6, NullType >::Result Parm7
Definition: objfactory.h:92
IdToProductMap associations_
Definition: objfactory.h:318
bool unregisterObject(const IdentifierType &id)
Unregister the object.
Definition: objfactory.h:114
AbstractProduct * createObject(const IdentifierType &id, Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
Definition: objfactory.h:231
AbstractProduct * createObject(const IdentifierType &id, Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, Parm6 p6, Parm7 p7, Parm8 p8)
Definition: objfactory.h:294
AbstractProduct * createObject(const IdentifierType &id, Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
Definition: objfactory.h:210
TL::TypeAtNonStrict< ParmList, 4, NullType >::Result Parm5
Definition: objfactory.h:90
unsigned j
Definition: ldumul_w.cc:35
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
int i
Definition: pbg5p_w.cc:55
static AbstractProduct * OnUnknownType(const IdentifierType &id)
Definition: objfactory.h:33
static AbstractProduct * OnUnknownType(const IdentifierType &)
Definition: objfactory.h:63
static AbstractProduct * OnUnknownType(const IdentifierType &id)
Definition: objfactory.h:47
Type info support.
Typelist support.