1 ////////////////////////////////////////////////////////////////////////////////
3 // Copyright (c) 2001 by Andrei Alexandrescu
4 // Copyright (c) 2005 by Peter Kuemmel
5 // This code DOES NOT accompany the book:
6 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
7 // Patterns Applied". Copyright (c) 2001. Addison-Wesley.
9 // Code covered by the MIT License
10 // The authors make no representations about the suitability of this software
11 // for any purpose. It is provided "as is" without express or implied warranty.
12 ////////////////////////////////////////////////////////////////////////////////
13 #ifndef LOKI_FACTORYPARM_INC_
14 #define LOKI_FACTORYPARM_INC_
16 // $Id: Factory.h 788 2006-11-24 22:30:54Z clitte_bbt $
19 #include "LokiTypeInfo.h"
21 #include "AssocVector.h"
27 #pragma warning(disable: 4702)
28 //unreachable code if OnUnknownType throws an exception
32 * \defgroup FactoriesGroup Factories
33 * \defgroup FactoryGroup Factory
34 * \ingroup FactoriesGroup
35 * \brief Implements a generic object factory.
37 * <i>The Factory Method pattern is an object-oriented design pattern.
38 * Like other creational patterns, it deals with the problem of creating objects
39 * (products) without specifying the exact class of object that will be created.
40 * Factory Method, one of the patterns from the Design Patterns book, handles
41 * this problem by defining a separate method for creating the objects, which
42 * subclasses can then override to specify the derived type of product that will
45 * More generally, the term Factory Method is often used to refer to any method
46 * whose main purpose is creation of objects.</i>
47 * <div ALIGN="RIGHT"><a href="http://en.wikipedia.org/wiki/Factory_method_pattern">
50 * Loki proposes a generic version of the Factory. Here is a typical use.<br>
52 * 1. Factory< AbstractProduct, int > aFactory;<br>
53 * 2. aFactory.Register( 1, createProductNull );<br>
54 * 3. aFactory.CreateObject( 1 ); <br>
57 * - 1. The declaration<br>
58 * You want a Factory that produces AbstractProduct.<br>
59 * The client will refer to a creation method through an int.<br>
60 * - 2.The registration<br>
61 * The code that will contribute to the Factory will now need to declare its
62 * ProductCreator by registering them into the Factory.<br>
63 * A ProductCreator is a just a function that will return the right object. ie <br>
65 * Product* createProductNull()<br>
67 * return new Product<br>
71 * Now the client can create object by calling the Factory's CreateObject method
72 * with the right identifier. If the ProductCreator were to have arguments
73 * (<i>ie :Product* createProductParm( int a, int b )</i>)
80 * \defgroup FactoryErrorPoliciesGroup Factory Error Policies
81 * \ingroup FactoryGroup
82 * \brief Manages the "Unknown Type" error in an object factory
84 * \class DefaultFactoryError
85 * \ingroup FactoryErrorPoliciesGroup
86 * \brief Default policy that throws an exception
90 template <typename IdentifierType, class AbstractProduct>
91 struct DefaultFactoryError
93 struct Exception : public std::exception
95 const char *what() const throw()
97 return "Unknown Type";
101 static AbstractProduct *OnUnknownType(IdentifierType)
108 #define LOKI_ENABLE_NEW_FACTORY_CODE
109 #ifdef LOKI_ENABLE_NEW_FACTORY_CODE
112 ////////////////////////////////////////////////////////////////////////////////
113 // class template FunctorImpl
114 ////////////////////////////////////////////////////////////////////////////////
116 struct FactoryImplBase
118 typedef EmptyType Parm1;
119 typedef EmptyType Parm2;
120 typedef EmptyType Parm3;
121 typedef EmptyType Parm4;
122 typedef EmptyType Parm5;
123 typedef EmptyType Parm6;
124 typedef EmptyType Parm7;
125 typedef EmptyType Parm8;
126 typedef EmptyType Parm9;
127 typedef EmptyType Parm10;
128 typedef EmptyType Parm11;
129 typedef EmptyType Parm12;
130 typedef EmptyType Parm13;
131 typedef EmptyType Parm14;
132 typedef EmptyType Parm15;
135 template <typename AP, typename Id, typename TList >
138 template<typename AP, typename Id>
139 struct FactoryImpl<AP, Id, NullType>
140 : public FactoryImplBase
142 virtual ~FactoryImpl() {}
143 virtual AP *CreateObject(const Id &id ) = 0;
145 template <typename AP, typename Id, typename P1 >
146 struct FactoryImpl<AP,Id, Seq<P1> >
147 : public FactoryImplBase
149 typedef typename TypeTraits<P1>::ParameterType Parm1;
150 virtual ~FactoryImpl() {}
151 virtual AP *CreateObject(const Id &id,Parm1 ) = 0;
154 template<typename AP, typename Id, typename P1,typename P2 >
155 struct FactoryImpl<AP, Id, Seq<P1, P2> >
156 : public FactoryImplBase
158 typedef typename TypeTraits<P1>::ParameterType Parm1;
159 typedef typename TypeTraits<P2>::ParameterType Parm2;
160 virtual ~FactoryImpl() {}
161 virtual AP *CreateObject(const Id &id,Parm1, Parm2 ) = 0;
164 template<typename AP, typename Id, typename P1,typename P2,typename P3 >
165 struct FactoryImpl<AP, Id, Seq<P1, P2, P3> >
166 : public FactoryImplBase
168 typedef typename TypeTraits<P1>::ParameterType Parm1;
169 typedef typename TypeTraits<P2>::ParameterType Parm2;
170 typedef typename TypeTraits<P3>::ParameterType Parm3;
171 virtual ~FactoryImpl() {}
172 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3 ) = 0;
175 template<typename AP, typename Id, typename P1,typename P2,typename P3,typename P4 >
176 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4> >
177 : public FactoryImplBase
179 typedef typename TypeTraits<P1>::ParameterType Parm1;
180 typedef typename TypeTraits<P2>::ParameterType Parm2;
181 typedef typename TypeTraits<P3>::ParameterType Parm3;
182 typedef typename TypeTraits<P4>::ParameterType Parm4;
183 virtual ~FactoryImpl() {}
184 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4 ) = 0;
187 template<typename AP, typename Id,
188 typename P1,typename P2,typename P3,typename P4,typename P5 >
189 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5> >
190 : public FactoryImplBase
192 typedef typename TypeTraits<P1>::ParameterType Parm1;
193 typedef typename TypeTraits<P2>::ParameterType Parm2;
194 typedef typename TypeTraits<P3>::ParameterType Parm3;
195 typedef typename TypeTraits<P4>::ParameterType Parm4;
196 typedef typename TypeTraits<P5>::ParameterType Parm5;
197 virtual ~FactoryImpl() {}
198 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5 ) = 0;
201 template<typename AP, typename Id,
202 typename P1,typename P2,typename P3,typename P4,typename P5,
204 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6> >
205 : public FactoryImplBase
207 typedef typename TypeTraits<P1>::ParameterType Parm1;
208 typedef typename TypeTraits<P2>::ParameterType Parm2;
209 typedef typename TypeTraits<P3>::ParameterType Parm3;
210 typedef typename TypeTraits<P4>::ParameterType Parm4;
211 typedef typename TypeTraits<P5>::ParameterType Parm5;
212 typedef typename TypeTraits<P6>::ParameterType Parm6;
213 virtual ~FactoryImpl() {}
214 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
219 template<typename AP, typename Id,
220 typename P1,typename P2,typename P3,typename P4,typename P5,
221 typename P6,typename P7>
222 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7> >
223 : public FactoryImplBase
225 typedef typename TypeTraits<P1>::ParameterType Parm1;
226 typedef typename TypeTraits<P2>::ParameterType Parm2;
227 typedef typename TypeTraits<P3>::ParameterType Parm3;
228 typedef typename TypeTraits<P4>::ParameterType Parm4;
229 typedef typename TypeTraits<P5>::ParameterType Parm5;
230 typedef typename TypeTraits<P6>::ParameterType Parm6;
231 typedef typename TypeTraits<P7>::ParameterType Parm7;
232 virtual ~FactoryImpl() {}
233 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
238 template<typename AP, typename Id,
239 typename P1,typename P2,typename P3,typename P4,typename P5,
240 typename P6,typename P7,typename P8>
241 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8> >
242 : public FactoryImplBase
244 typedef typename TypeTraits<P1>::ParameterType Parm1;
245 typedef typename TypeTraits<P2>::ParameterType Parm2;
246 typedef typename TypeTraits<P3>::ParameterType Parm3;
247 typedef typename TypeTraits<P4>::ParameterType Parm4;
248 typedef typename TypeTraits<P5>::ParameterType Parm5;
249 typedef typename TypeTraits<P6>::ParameterType Parm6;
250 typedef typename TypeTraits<P7>::ParameterType Parm7;
251 typedef typename TypeTraits<P8>::ParameterType Parm8;
252 virtual ~FactoryImpl() {}
253 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
258 template<typename AP, typename Id,
259 typename P1,typename P2,typename P3,typename P4,typename P5,
260 typename P6,typename P7,typename P8,typename P9>
261 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9> >
262 : public FactoryImplBase
264 typedef typename TypeTraits<P1>::ParameterType Parm1;
265 typedef typename TypeTraits<P2>::ParameterType Parm2;
266 typedef typename TypeTraits<P3>::ParameterType Parm3;
267 typedef typename TypeTraits<P4>::ParameterType Parm4;
268 typedef typename TypeTraits<P5>::ParameterType Parm5;
269 typedef typename TypeTraits<P6>::ParameterType Parm6;
270 typedef typename TypeTraits<P7>::ParameterType Parm7;
271 typedef typename TypeTraits<P8>::ParameterType Parm8;
272 typedef typename TypeTraits<P9>::ParameterType Parm9;
273 virtual ~FactoryImpl() {}
274 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
275 Parm6, Parm7, Parm8, Parm9)
279 template<typename AP, typename Id,
280 typename P1,typename P2,typename P3,typename P4,typename P5,
281 typename P6,typename P7,typename P8,typename P9,typename P10>
282 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> >
283 : public FactoryImplBase
285 typedef typename TypeTraits<P1>::ParameterType Parm1;
286 typedef typename TypeTraits<P2>::ParameterType Parm2;
287 typedef typename TypeTraits<P3>::ParameterType Parm3;
288 typedef typename TypeTraits<P4>::ParameterType Parm4;
289 typedef typename TypeTraits<P5>::ParameterType Parm5;
290 typedef typename TypeTraits<P6>::ParameterType Parm6;
291 typedef typename TypeTraits<P7>::ParameterType Parm7;
292 typedef typename TypeTraits<P8>::ParameterType Parm8;
293 typedef typename TypeTraits<P9>::ParameterType Parm9;
294 typedef typename TypeTraits<P10>::ParameterType Parm10;
295 virtual ~FactoryImpl() {}
296 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
297 Parm6, Parm7, Parm8, Parm9,Parm10)
301 template<typename AP, typename Id,
302 typename P1,typename P2,typename P3,typename P4,typename P5,
303 typename P6,typename P7,typename P8,typename P9,typename P10,
305 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11> >
306 : public FactoryImplBase
308 typedef typename TypeTraits<P1>::ParameterType Parm1;
309 typedef typename TypeTraits<P2>::ParameterType Parm2;
310 typedef typename TypeTraits<P3>::ParameterType Parm3;
311 typedef typename TypeTraits<P4>::ParameterType Parm4;
312 typedef typename TypeTraits<P5>::ParameterType Parm5;
313 typedef typename TypeTraits<P6>::ParameterType Parm6;
314 typedef typename TypeTraits<P7>::ParameterType Parm7;
315 typedef typename TypeTraits<P8>::ParameterType Parm8;
316 typedef typename TypeTraits<P9>::ParameterType Parm9;
317 typedef typename TypeTraits<P10>::ParameterType Parm10;
318 typedef typename TypeTraits<P11>::ParameterType Parm11;
319 virtual ~FactoryImpl() {}
320 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
321 Parm6, Parm7, Parm8, Parm9,Parm10,
326 template<typename AP, typename Id,
327 typename P1,typename P2,typename P3,typename P4,typename P5,
328 typename P6,typename P7,typename P8,typename P9,typename P10,
329 typename P11,typename P12>
330 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12> >
331 : public FactoryImplBase
333 typedef typename TypeTraits<P1>::ParameterType Parm1;
334 typedef typename TypeTraits<P2>::ParameterType Parm2;
335 typedef typename TypeTraits<P3>::ParameterType Parm3;
336 typedef typename TypeTraits<P4>::ParameterType Parm4;
337 typedef typename TypeTraits<P5>::ParameterType Parm5;
338 typedef typename TypeTraits<P6>::ParameterType Parm6;
339 typedef typename TypeTraits<P7>::ParameterType Parm7;
340 typedef typename TypeTraits<P8>::ParameterType Parm8;
341 typedef typename TypeTraits<P9>::ParameterType Parm9;
342 typedef typename TypeTraits<P10>::ParameterType Parm10;
343 typedef typename TypeTraits<P11>::ParameterType Parm11;
344 typedef typename TypeTraits<P12>::ParameterType Parm12;
345 virtual ~FactoryImpl() {}
346 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
347 Parm6, Parm7, Parm8, Parm9,Parm10,
352 template<typename AP, typename Id,
353 typename P1,typename P2,typename P3,typename P4,typename P5,
354 typename P6,typename P7,typename P8,typename P9,typename P10,
355 typename P11,typename P12,typename P13>
356 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13> >
357 : public FactoryImplBase
359 typedef typename TypeTraits<P1>::ParameterType Parm1;
360 typedef typename TypeTraits<P2>::ParameterType Parm2;
361 typedef typename TypeTraits<P3>::ParameterType Parm3;
362 typedef typename TypeTraits<P4>::ParameterType Parm4;
363 typedef typename TypeTraits<P5>::ParameterType Parm5;
364 typedef typename TypeTraits<P6>::ParameterType Parm6;
365 typedef typename TypeTraits<P7>::ParameterType Parm7;
366 typedef typename TypeTraits<P8>::ParameterType Parm8;
367 typedef typename TypeTraits<P9>::ParameterType Parm9;
368 typedef typename TypeTraits<P10>::ParameterType Parm10;
369 typedef typename TypeTraits<P11>::ParameterType Parm11;
370 typedef typename TypeTraits<P12>::ParameterType Parm12;
371 typedef typename TypeTraits<P13>::ParameterType Parm13;
372 virtual ~FactoryImpl() {}
373 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
374 Parm6, Parm7, Parm8, Parm9,Parm10,
375 Parm11,Parm12,Parm13)
379 template<typename AP, typename Id,
380 typename P1,typename P2,typename P3,typename P4,typename P5,
381 typename P6,typename P7,typename P8,typename P9,typename P10,
382 typename P11,typename P12,typename P13,typename P14>
383 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14> >
384 : public FactoryImplBase
386 typedef typename TypeTraits<P1>::ParameterType Parm1;
387 typedef typename TypeTraits<P2>::ParameterType Parm2;
388 typedef typename TypeTraits<P3>::ParameterType Parm3;
389 typedef typename TypeTraits<P4>::ParameterType Parm4;
390 typedef typename TypeTraits<P5>::ParameterType Parm5;
391 typedef typename TypeTraits<P6>::ParameterType Parm6;
392 typedef typename TypeTraits<P7>::ParameterType Parm7;
393 typedef typename TypeTraits<P8>::ParameterType Parm8;
394 typedef typename TypeTraits<P9>::ParameterType Parm9;
395 typedef typename TypeTraits<P10>::ParameterType Parm10;
396 typedef typename TypeTraits<P11>::ParameterType Parm11;
397 typedef typename TypeTraits<P12>::ParameterType Parm12;
398 typedef typename TypeTraits<P13>::ParameterType Parm13;
399 typedef typename TypeTraits<P14>::ParameterType Parm14;
400 virtual ~FactoryImpl() {}
401 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
402 Parm6, Parm7, Parm8, Parm8,Parm10,
403 Parm11,Parm12,Parm13,Parm14)
407 template<typename AP, typename Id,
408 typename P1,typename P2,typename P3,typename P4,typename P5,
409 typename P6,typename P7,typename P8,typename P9,typename P10,
410 typename P11,typename P12,typename P13,typename P14,typename P15 >
411 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15> >
412 : public FactoryImplBase
414 typedef typename TypeTraits<P1>::ParameterType Parm1;
415 typedef typename TypeTraits<P2>::ParameterType Parm2;
416 typedef typename TypeTraits<P3>::ParameterType Parm3;
417 typedef typename TypeTraits<P4>::ParameterType Parm4;
418 typedef typename TypeTraits<P5>::ParameterType Parm5;
419 typedef typename TypeTraits<P6>::ParameterType Parm6;
420 typedef typename TypeTraits<P7>::ParameterType Parm7;
421 typedef typename TypeTraits<P8>::ParameterType Parm8;
422 typedef typename TypeTraits<P9>::ParameterType Parm9;
423 typedef typename TypeTraits<P10>::ParameterType Parm10;
424 typedef typename TypeTraits<P11>::ParameterType Parm11;
425 typedef typename TypeTraits<P12>::ParameterType Parm12;
426 typedef typename TypeTraits<P13>::ParameterType Parm13;
427 typedef typename TypeTraits<P14>::ParameterType Parm14;
428 typedef typename TypeTraits<P15>::ParameterType Parm15;
429 virtual ~FactoryImpl() {}
430 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
431 Parm6, Parm7, Parm8, Parm9,Parm10,
432 Parm11,Parm12,Parm13,Parm14,Parm15 )
436 #ifndef LOKI_DISABLE_TYPELIST_MACROS
438 template <typename AP, typename Id, typename P1 >
439 struct FactoryImpl<AP,Id, LOKI_TYPELIST_1( P1 )>
440 : public FactoryImplBase
442 typedef typename TypeTraits<P1>::ParameterType Parm1;
443 virtual ~FactoryImpl() {}
444 virtual AP *CreateObject(const Id &id,Parm1 ) = 0;
447 template<typename AP, typename Id, typename P1,typename P2 >
448 struct FactoryImpl<AP, Id, LOKI_TYPELIST_2( P1, P2 )>
449 : public FactoryImplBase
451 typedef typename TypeTraits<P1>::ParameterType Parm1;
452 typedef typename TypeTraits<P2>::ParameterType Parm2;
453 virtual ~FactoryImpl() {}
454 virtual AP *CreateObject(const Id &id,Parm1, Parm2 ) = 0;
457 template<typename AP, typename Id, typename P1,typename P2,typename P3 >
458 struct FactoryImpl<AP, Id, LOKI_TYPELIST_3( P1, P2, P3 )>
459 : public FactoryImplBase
461 typedef typename TypeTraits<P1>::ParameterType Parm1;
462 typedef typename TypeTraits<P2>::ParameterType Parm2;
463 typedef typename TypeTraits<P3>::ParameterType Parm3;
464 virtual ~FactoryImpl() {}
465 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3 ) = 0;
468 template<typename AP, typename Id, typename P1,typename P2,typename P3,typename P4 >
469 struct FactoryImpl<AP, Id, LOKI_TYPELIST_4( P1, P2, P3, P4 )>
470 : public FactoryImplBase
472 typedef typename TypeTraits<P1>::ParameterType Parm1;
473 typedef typename TypeTraits<P2>::ParameterType Parm2;
474 typedef typename TypeTraits<P3>::ParameterType Parm3;
475 typedef typename TypeTraits<P4>::ParameterType Parm4;
476 virtual ~FactoryImpl() {}
477 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4 ) = 0;
480 template<typename AP, typename Id,
481 typename P1,typename P2,typename P3,typename P4,typename P5 >
482 struct FactoryImpl<AP, Id, LOKI_TYPELIST_5( P1, P2, P3, P4, P5 )>
483 : public FactoryImplBase
485 typedef typename TypeTraits<P1>::ParameterType Parm1;
486 typedef typename TypeTraits<P2>::ParameterType Parm2;
487 typedef typename TypeTraits<P3>::ParameterType Parm3;
488 typedef typename TypeTraits<P4>::ParameterType Parm4;
489 typedef typename TypeTraits<P5>::ParameterType Parm5;
490 virtual ~FactoryImpl() {}
491 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5 ) = 0;
494 template<typename AP, typename Id,
495 typename P1,typename P2,typename P3,typename P4,typename P5,
497 struct FactoryImpl<AP, Id, LOKI_TYPELIST_6( P1, P2, P3, P4, P5, P6 )>
498 : public FactoryImplBase
500 typedef typename TypeTraits<P1>::ParameterType Parm1;
501 typedef typename TypeTraits<P2>::ParameterType Parm2;
502 typedef typename TypeTraits<P3>::ParameterType Parm3;
503 typedef typename TypeTraits<P4>::ParameterType Parm4;
504 typedef typename TypeTraits<P5>::ParameterType Parm5;
505 typedef typename TypeTraits<P6>::ParameterType Parm6;
506 virtual ~FactoryImpl() {}
507 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
512 template<typename AP, typename Id,
513 typename P1,typename P2,typename P3,typename P4,typename P5,
514 typename P6,typename P7>
515 struct FactoryImpl<AP, Id, LOKI_TYPELIST_7( P1, P2, P3, P4, P5, P6, P7 )>
516 : public FactoryImplBase
518 typedef typename TypeTraits<P1>::ParameterType Parm1;
519 typedef typename TypeTraits<P2>::ParameterType Parm2;
520 typedef typename TypeTraits<P3>::ParameterType Parm3;
521 typedef typename TypeTraits<P4>::ParameterType Parm4;
522 typedef typename TypeTraits<P5>::ParameterType Parm5;
523 typedef typename TypeTraits<P6>::ParameterType Parm6;
524 typedef typename TypeTraits<P7>::ParameterType Parm7;
525 virtual ~FactoryImpl() {}
526 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
531 template<typename AP, typename Id,
532 typename P1,typename P2,typename P3,typename P4,typename P5,
533 typename P6,typename P7,typename P8>
534 struct FactoryImpl<AP, Id, LOKI_TYPELIST_8( P1, P2, P3, P4, P5, P6, P7, P8 )>
535 : public FactoryImplBase
537 typedef typename TypeTraits<P1>::ParameterType Parm1;
538 typedef typename TypeTraits<P2>::ParameterType Parm2;
539 typedef typename TypeTraits<P3>::ParameterType Parm3;
540 typedef typename TypeTraits<P4>::ParameterType Parm4;
541 typedef typename TypeTraits<P5>::ParameterType Parm5;
542 typedef typename TypeTraits<P6>::ParameterType Parm6;
543 typedef typename TypeTraits<P7>::ParameterType Parm7;
544 typedef typename TypeTraits<P8>::ParameterType Parm8;
545 virtual ~FactoryImpl() {}
546 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
551 template<typename AP, typename Id,
552 typename P1,typename P2,typename P3,typename P4,typename P5,
553 typename P6,typename P7,typename P8,typename P9>
554 struct FactoryImpl<AP, Id, LOKI_TYPELIST_9( P1, P2, P3, P4, P5, P6, P7, P8, P9 )>
555 : public FactoryImplBase
557 typedef typename TypeTraits<P1>::ParameterType Parm1;
558 typedef typename TypeTraits<P2>::ParameterType Parm2;
559 typedef typename TypeTraits<P3>::ParameterType Parm3;
560 typedef typename TypeTraits<P4>::ParameterType Parm4;
561 typedef typename TypeTraits<P5>::ParameterType Parm5;
562 typedef typename TypeTraits<P6>::ParameterType Parm6;
563 typedef typename TypeTraits<P7>::ParameterType Parm7;
564 typedef typename TypeTraits<P8>::ParameterType Parm8;
565 typedef typename TypeTraits<P9>::ParameterType Parm9;
566 virtual ~FactoryImpl() {}
567 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
568 Parm6, Parm7, Parm8, Parm9)
572 template<typename AP, typename Id,
573 typename P1,typename P2,typename P3,typename P4,typename P5,
574 typename P6,typename P7,typename P8,typename P9,typename P10>
575 struct FactoryImpl<AP, Id, LOKI_TYPELIST_10( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10 )>
576 : public FactoryImplBase
578 typedef typename TypeTraits<P1>::ParameterType Parm1;
579 typedef typename TypeTraits<P2>::ParameterType Parm2;
580 typedef typename TypeTraits<P3>::ParameterType Parm3;
581 typedef typename TypeTraits<P4>::ParameterType Parm4;
582 typedef typename TypeTraits<P5>::ParameterType Parm5;
583 typedef typename TypeTraits<P6>::ParameterType Parm6;
584 typedef typename TypeTraits<P7>::ParameterType Parm7;
585 typedef typename TypeTraits<P8>::ParameterType Parm8;
586 typedef typename TypeTraits<P9>::ParameterType Parm9;
587 typedef typename TypeTraits<P10>::ParameterType Parm10;
588 virtual ~FactoryImpl() {}
589 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
590 Parm6, Parm7, Parm8, Parm9,Parm10)
594 template<typename AP, typename Id,
595 typename P1,typename P2,typename P3,typename P4,typename P5,
596 typename P6,typename P7,typename P8,typename P9,typename P10,
598 struct FactoryImpl<AP, Id, LOKI_TYPELIST_11( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11 )>
599 : public FactoryImplBase
601 typedef typename TypeTraits<P1>::ParameterType Parm1;
602 typedef typename TypeTraits<P2>::ParameterType Parm2;
603 typedef typename TypeTraits<P3>::ParameterType Parm3;
604 typedef typename TypeTraits<P4>::ParameterType Parm4;
605 typedef typename TypeTraits<P5>::ParameterType Parm5;
606 typedef typename TypeTraits<P6>::ParameterType Parm6;
607 typedef typename TypeTraits<P7>::ParameterType Parm7;
608 typedef typename TypeTraits<P8>::ParameterType Parm8;
609 typedef typename TypeTraits<P9>::ParameterType Parm9;
610 typedef typename TypeTraits<P10>::ParameterType Parm10;
611 typedef typename TypeTraits<P11>::ParameterType Parm11;
612 virtual ~FactoryImpl() {}
613 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
614 Parm6, Parm7, Parm8, Parm9,Parm10,
619 template<typename AP, typename Id,
620 typename P1,typename P2,typename P3,typename P4,typename P5,
621 typename P6,typename P7,typename P8,typename P9,typename P10,
622 typename P11,typename P12>
623 struct FactoryImpl<AP, Id, LOKI_TYPELIST_12( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12 )>
624 : public FactoryImplBase
626 typedef typename TypeTraits<P1>::ParameterType Parm1;
627 typedef typename TypeTraits<P2>::ParameterType Parm2;
628 typedef typename TypeTraits<P3>::ParameterType Parm3;
629 typedef typename TypeTraits<P4>::ParameterType Parm4;
630 typedef typename TypeTraits<P5>::ParameterType Parm5;
631 typedef typename TypeTraits<P6>::ParameterType Parm6;
632 typedef typename TypeTraits<P7>::ParameterType Parm7;
633 typedef typename TypeTraits<P8>::ParameterType Parm8;
634 typedef typename TypeTraits<P9>::ParameterType Parm9;
635 typedef typename TypeTraits<P10>::ParameterType Parm10;
636 typedef typename TypeTraits<P11>::ParameterType Parm11;
637 typedef typename TypeTraits<P12>::ParameterType Parm12;
638 virtual ~FactoryImpl() {}
639 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
640 Parm6, Parm7, Parm8, Parm9,Parm10,
645 template<typename AP, typename Id,
646 typename P1,typename P2,typename P3,typename P4,typename P5,
647 typename P6,typename P7,typename P8,typename P9,typename P10,
648 typename P11,typename P12,typename P13>
649 struct FactoryImpl<AP, Id, LOKI_TYPELIST_13( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13 )>
650 : public FactoryImplBase
652 typedef typename TypeTraits<P1>::ParameterType Parm1;
653 typedef typename TypeTraits<P2>::ParameterType Parm2;
654 typedef typename TypeTraits<P3>::ParameterType Parm3;
655 typedef typename TypeTraits<P4>::ParameterType Parm4;
656 typedef typename TypeTraits<P5>::ParameterType Parm5;
657 typedef typename TypeTraits<P6>::ParameterType Parm6;
658 typedef typename TypeTraits<P7>::ParameterType Parm7;
659 typedef typename TypeTraits<P8>::ParameterType Parm8;
660 typedef typename TypeTraits<P9>::ParameterType Parm9;
661 typedef typename TypeTraits<P10>::ParameterType Parm10;
662 typedef typename TypeTraits<P11>::ParameterType Parm11;
663 typedef typename TypeTraits<P12>::ParameterType Parm12;
664 typedef typename TypeTraits<P13>::ParameterType Parm13;
665 virtual ~FactoryImpl() {}
666 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
667 Parm6, Parm7, Parm8, Parm9,Parm10,
668 Parm11,Parm12,Parm13)
672 template<typename AP, typename Id,
673 typename P1,typename P2,typename P3,typename P4,typename P5,
674 typename P6,typename P7,typename P8,typename P9,typename P10,
675 typename P11,typename P12,typename P13,typename P14>
676 struct FactoryImpl<AP, Id, LOKI_TYPELIST_14( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14 )>
677 : public FactoryImplBase
679 typedef typename TypeTraits<P1>::ParameterType Parm1;
680 typedef typename TypeTraits<P2>::ParameterType Parm2;
681 typedef typename TypeTraits<P3>::ParameterType Parm3;
682 typedef typename TypeTraits<P4>::ParameterType Parm4;
683 typedef typename TypeTraits<P5>::ParameterType Parm5;
684 typedef typename TypeTraits<P6>::ParameterType Parm6;
685 typedef typename TypeTraits<P7>::ParameterType Parm7;
686 typedef typename TypeTraits<P8>::ParameterType Parm8;
687 typedef typename TypeTraits<P9>::ParameterType Parm9;
688 typedef typename TypeTraits<P10>::ParameterType Parm10;
689 typedef typename TypeTraits<P11>::ParameterType Parm11;
690 typedef typename TypeTraits<P12>::ParameterType Parm12;
691 typedef typename TypeTraits<P13>::ParameterType Parm13;
692 typedef typename TypeTraits<P14>::ParameterType Parm14;
693 virtual ~FactoryImpl() {}
694 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
695 Parm6, Parm7, Parm8, Parm8,Parm10,
696 Parm11,Parm12,Parm13,Parm14)
700 template<typename AP, typename Id,
701 typename P1,typename P2,typename P3,typename P4,typename P5,
702 typename P6,typename P7,typename P8,typename P9,typename P10,
703 typename P11,typename P12,typename P13,typename P14,typename P15 >
704 struct FactoryImpl<AP, Id, LOKI_TYPELIST_15( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15 )>
705 : public FactoryImplBase
707 typedef typename TypeTraits<P1>::ParameterType Parm1;
708 typedef typename TypeTraits<P2>::ParameterType Parm2;
709 typedef typename TypeTraits<P3>::ParameterType Parm3;
710 typedef typename TypeTraits<P4>::ParameterType Parm4;
711 typedef typename TypeTraits<P5>::ParameterType Parm5;
712 typedef typename TypeTraits<P6>::ParameterType Parm6;
713 typedef typename TypeTraits<P7>::ParameterType Parm7;
714 typedef typename TypeTraits<P8>::ParameterType Parm8;
715 typedef typename TypeTraits<P9>::ParameterType Parm9;
716 typedef typename TypeTraits<P10>::ParameterType Parm10;
717 typedef typename TypeTraits<P11>::ParameterType Parm11;
718 typedef typename TypeTraits<P12>::ParameterType Parm12;
719 typedef typename TypeTraits<P13>::ParameterType Parm13;
720 typedef typename TypeTraits<P14>::ParameterType Parm14;
721 typedef typename TypeTraits<P15>::ParameterType Parm15;
722 virtual ~FactoryImpl() {}
723 virtual AP *CreateObject(const Id &id,Parm1, Parm2, Parm3, Parm4, Parm5,
724 Parm6, Parm7, Parm8, Parm9,Parm10,
725 Parm11,Parm12,Parm13,Parm14,Parm15 )
729 #endif //LOKI_DISABLE_TYPELIST_MACROS
732 ////////////////////////////////////////////////////////////////////////////////
735 /// \ingroup FactoryGroup
736 /// Implements a generic object factory.
738 /// Create functions can have up to 15 parameters.
740 /// \par Singleton lifetime when used with Loki::SingletonHolder
741 /// Because Factory uses internally Functors which inherits from
742 /// SmallObject you must use the singleton lifetime
743 /// \code Loki::LongevityLifetime::DieAsSmallObjectChild \endcode
744 /// Alternatively you could suppress for Functor the inheritance
745 /// from SmallObject by defining the macro:
746 /// \code LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT \endcode
747 ////////////////////////////////////////////////////////////////////////////////
750 class AbstractProduct,
751 typename IdentifierType,
752 typename CreatorParmTList = NullType,
753 template<typename, class> class FactoryErrorPolicy = DefaultFactoryError
755 class Factory : public FactoryErrorPolicy<IdentifierType, AbstractProduct>
757 typedef FactoryImpl< AbstractProduct, IdentifierType, CreatorParmTList > Impl;
759 typedef typename Impl::Parm1 Parm1;
760 typedef typename Impl::Parm2 Parm2;
761 typedef typename Impl::Parm3 Parm3;
762 typedef typename Impl::Parm4 Parm4;
763 typedef typename Impl::Parm5 Parm5;
764 typedef typename Impl::Parm6 Parm6;
765 typedef typename Impl::Parm7 Parm7;
766 typedef typename Impl::Parm8 Parm8;
767 typedef typename Impl::Parm9 Parm9;
768 typedef typename Impl::Parm10 Parm10;
769 typedef typename Impl::Parm11 Parm11;
770 typedef typename Impl::Parm12 Parm12;
771 typedef typename Impl::Parm13 Parm13;
772 typedef typename Impl::Parm14 Parm14;
773 typedef typename Impl::Parm15 Parm15;
775 typedef Functor<AbstractProduct *, CreatorParmTList> ProductCreator;
777 typedef AssocVector<IdentifierType, ProductCreator> IdToProductMap;
779 IdToProductMap associations_;
790 associations_.erase(associations_.begin(), associations_.end());
793 bool Register(const IdentifierType &id, ProductCreator creator)
795 return associations_.insert(
796 typename IdToProductMap::value_type(id, creator)).second != 0;
799 template <class PtrObj, typename CreaFn>
800 bool Register(const IdentifierType &id, const PtrObj &p, CreaFn fn)
802 ProductCreator creator( p, fn );
803 return associations_.insert(
804 typename IdToProductMap::value_type(id, creator)).second != 0;
807 bool Unregister(const IdentifierType &id)
809 return associations_.erase(id) != 0;
812 std::vector<IdentifierType> RegisteredIds()
814 std::vector<IdentifierType> ids;
815 for(typename IdToProductMap::iterator it = associations_.begin();
816 it != associations_.end(); ++it)
818 ids.push_back(it->first);
823 AbstractProduct *CreateObject(const IdentifierType &id)
825 typename IdToProductMap::iterator i = associations_.find(id);
826 if (i != associations_.end())
827 return (i->second)( );
828 return this->OnUnknownType(id);
831 AbstractProduct *CreateObject(const IdentifierType &id,
834 typename IdToProductMap::iterator i = associations_.find(id);
835 if (i != associations_.end())
836 return (i->second)( p1 );
837 return this->OnUnknownType(id);
840 AbstractProduct *CreateObject(const IdentifierType &id,
843 typename IdToProductMap::iterator i = associations_.find(id);
844 if (i != associations_.end())
845 return (i->second)( p1,p2 );
846 return this->OnUnknownType(id);
849 AbstractProduct *CreateObject(const IdentifierType &id,
850 Parm1 p1, Parm2 p2, Parm3 p3)
852 typename IdToProductMap::iterator i = associations_.find(id);
853 if (i != associations_.end())
854 return (i->second)( p1,p2,p3 );
855 return this->OnUnknownType(id);
858 AbstractProduct *CreateObject(const IdentifierType &id,
859 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
861 typename IdToProductMap::iterator i = associations_.find(id);
862 if (i != associations_.end())
863 return (i->second)( p1,p2,p3,p4 );
864 return this->OnUnknownType(id);
867 AbstractProduct *CreateObject(const IdentifierType &id,
868 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
870 typename IdToProductMap::iterator i = associations_.find(id);
871 if (i != associations_.end())
872 return (i->second)( p1,p2,p3,p4,p5 );
873 return this->OnUnknownType(id);
876 AbstractProduct *CreateObject(const IdentifierType &id,
877 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
880 typename IdToProductMap::iterator i = associations_.find(id);
881 if (i != associations_.end())
882 return (i->second)( p1,p2,p3,p4,p5,p6 );
883 return this->OnUnknownType(id);
886 AbstractProduct *CreateObject(const IdentifierType &id,
887 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
890 typename IdToProductMap::iterator i = associations_.find(id);
891 if (i != associations_.end())
892 return (i->second)( p1,p2,p3,p4,p5,p6,p7 );
893 return this->OnUnknownType(id);
896 AbstractProduct *CreateObject(const IdentifierType &id,
897 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
898 Parm6 p6, Parm7 p7, Parm8 p8)
900 typename IdToProductMap::iterator i = associations_.find(id);
901 if (i != associations_.end())
902 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8 );
903 return this->OnUnknownType(id);
906 AbstractProduct *CreateObject(const IdentifierType &id,
907 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
908 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
910 typename IdToProductMap::iterator i = associations_.find(id);
911 if (i != associations_.end())
912 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9 );
913 return this->OnUnknownType(id);
915 AbstractProduct *CreateObject(const IdentifierType &id,
916 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
917 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9,Parm10 p10)
919 typename IdToProductMap::iterator i = associations_.find(id);
920 if (i != associations_.end())
921 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10 );
922 return this->OnUnknownType(id);
925 AbstractProduct *CreateObject(const IdentifierType &id,
926 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
927 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
930 typename IdToProductMap::iterator i = associations_.find(id);
931 if (i != associations_.end())
932 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11 );
933 return this->OnUnknownType(id);
936 AbstractProduct *CreateObject(const IdentifierType &id,
937 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
938 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
939 Parm11 p11, Parm12 p12)
941 typename IdToProductMap::iterator i = associations_.find(id);
942 if (i != associations_.end())
943 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12 );
944 return this->OnUnknownType(id);
947 AbstractProduct *CreateObject(const IdentifierType &id,
948 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
949 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
950 Parm11 p11, Parm12 p12, Parm13 p13)
952 typename IdToProductMap::iterator i = associations_.find(id);
953 if (i != associations_.end())
954 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13 );
955 return this->OnUnknownType(id);
958 AbstractProduct *CreateObject(const IdentifierType &id,
959 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
960 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
961 Parm11 p11, Parm12 p12, Parm13 p13, Parm14 p14)
963 typename IdToProductMap::iterator i = associations_.find(id);
964 if (i != associations_.end())
965 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14 );
966 return this->OnUnknownType(id);
969 AbstractProduct *CreateObject(const IdentifierType &id,
970 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
971 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
972 Parm11 p11, Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
974 typename IdToProductMap::iterator i = associations_.find(id);
975 if (i != associations_.end())
976 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15 );
977 return this->OnUnknownType(id);
986 class AbstractProduct,
987 typename IdentifierType,
988 typename ProductCreator = AbstractProduct *( *)(),
989 template<typename, class>
990 class FactoryErrorPolicy = DefaultFactoryError
993 : public FactoryErrorPolicy<IdentifierType, AbstractProduct>
996 bool Register(const IdentifierType &id, ProductCreator creator)
998 return associations_.insert(
999 typename IdToProductMap::value_type(id, creator)).second != 0;
1002 bool Unregister(const IdentifierType &id)
1004 return associations_.erase(id) != 0;
1007 AbstractProduct *CreateObject(const IdentifierType &id)
1009 typename IdToProductMap::iterator i = associations_.find(id);
1010 if (i != associations_.end())
1012 return (i->second)();
1014 return this->OnUnknownType(id);
1018 typedef AssocVector<IdentifierType, ProductCreator> IdToProductMap;
1019 IdToProductMap associations_;
1022 #endif //#define ENABLE_NEW_FACTORY_CODE
1025 * \defgroup CloneFactoryGroup Clone Factory
1026 * \ingroup FactoriesGroup
1027 * \brief Creates a copy from a polymorphic object.
1029 * \class CloneFactory
1030 * \ingroup CloneFactoryGroup
1031 * \brief Creates a copy from a polymorphic object.
1036 class AbstractProduct,
1037 class ProductCreator =
1038 AbstractProduct *( *)(const AbstractProduct *),
1039 template<typename, class>
1040 class FactoryErrorPolicy = DefaultFactoryError
1043 : public FactoryErrorPolicy<TypeInfo, AbstractProduct>
1046 bool Register(const TypeInfo &ti, ProductCreator creator)
1048 return associations_.insert(
1049 typename IdToProductMap::value_type(ti, creator)).second != 0;
1052 bool Unregister(const TypeInfo &id)
1054 return associations_.erase(id) != 0;
1057 AbstractProduct *CreateObject(const AbstractProduct *model)
1064 typename IdToProductMap::iterator i =
1065 associations_.find(typeid(*model));
1067 if (i != associations_.end())
1069 return (i->second)(model);
1071 return this->OnUnknownType(typeid(*model));
1075 typedef AssocVector<TypeInfo, ProductCreator> IdToProductMap;
1076 IdToProductMap associations_;
1083 #pragma warning( pop )
1086 #endif // end file guardian