1 ////////////////////////////////////////////////////////////////////////////////
2 // The Loki Library
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.
8 //
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_
15 
16 // $Id: Factory.h 788 2006-11-24 22:30:54Z clitte_bbt $
17 
18 
19 #include "LokiTypeInfo.h"
20 #include "Functor.h"
21 #include "AssocVector.h"
22 #include "SmallObj.h"
23 #include "Sequence.h"
24 
25 #ifdef _MSC_VER
26 #pragma warning(push)
27 #pragma warning(disable: 4702)
28 //unreachable code if OnUnknownType throws an exception
29 #endif
30 
31 /**
32  * \defgroup	FactoriesGroup Factories
33  * \defgroup	FactoryGroup Factory
34  * \ingroup		FactoriesGroup
35  * \brief		Implements a generic object factory.
36  *
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
43  * be created.
44  * <br>
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">
48  * Wikipedia</a></div>
49  *
50  * Loki proposes a generic version of the Factory. Here is a typical use.<br>
51  * <code><br>
52  * 1. Factory< AbstractProduct, int > aFactory;<br>
53  * 2. aFactory.Register( 1, createProductNull );<br>
54  * 3. aFactory.CreateObject( 1 ); <br>
55  * </code><br>
56  * <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>
64  * <code>
65  * Product* createProductNull()<br>
66  * {<br>
67  *     return new Product<br>
68  * }<br>
69  * </code><br>
70  * - 3. The use<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>)
74  */
75 
76 namespace Loki
77 {
78 
79 /**
80  * \defgroup	FactoryErrorPoliciesGroup Factory Error Policies
81  * \ingroup		FactoryGroup
82  * \brief		Manages the "Unknown Type" error in an object factory
83  *
84  * \class DefaultFactoryError
85  * \ingroup		FactoryErrorPoliciesGroup
86  * \brief		Default policy that throws an exception
87  *
88  */
89 
90     template <typename IdentifierType, class AbstractProduct>
91     struct DefaultFactoryError
92     {
93         struct Exception : public std::exception
94         {
whatDefaultFactoryError::Exception95             const char* what() const throw() { return "Unknown Type"; }
96         };
97 
OnUnknownTypeDefaultFactoryError98         static AbstractProduct* OnUnknownType(IdentifierType)
99         {
100             throw Exception();
101         }
102     };
103 
104 
105 #define LOKI_ENABLE_NEW_FACTORY_CODE
106 #ifdef LOKI_ENABLE_NEW_FACTORY_CODE
107 
108 
109 ////////////////////////////////////////////////////////////////////////////////
110 // class template FunctorImpl
111 ////////////////////////////////////////////////////////////////////////////////
112 
113     struct FactoryImplBase
114     {
115         typedef EmptyType Parm1;
116         typedef EmptyType Parm2;
117         typedef EmptyType Parm3;
118         typedef EmptyType Parm4;
119         typedef EmptyType Parm5;
120         typedef EmptyType Parm6;
121         typedef EmptyType Parm7;
122         typedef EmptyType Parm8;
123         typedef EmptyType Parm9;
124         typedef EmptyType Parm10;
125         typedef EmptyType Parm11;
126         typedef EmptyType Parm12;
127         typedef EmptyType Parm13;
128         typedef EmptyType Parm14;
129         typedef EmptyType Parm15;
130     };
131 
132     template <typename AP, typename Id, typename TList >
133     struct FactoryImpl;
134 
135     template<typename AP, typename Id>
136     struct FactoryImpl<AP, Id, NullType>
137                 : public FactoryImplBase
138     {
139         virtual ~FactoryImpl() {}
140         virtual AP* CreateObject(const Id & id ) = 0;
141     };
142 template <typename AP, typename Id, typename P1 >
143     struct FactoryImpl<AP,Id, Seq<P1> >
144                 : public FactoryImplBase
145     {
146         typedef typename TypeTraits<P1>::ParameterType Parm1;
147         virtual ~FactoryImpl() {}
148         virtual AP* CreateObject(const Id& id,Parm1 ) = 0;
149     };
150 
151     template<typename AP, typename Id, typename P1,typename P2 >
152     struct FactoryImpl<AP, Id, Seq<P1, P2> >
153                 : public FactoryImplBase
154     {
155         typedef typename TypeTraits<P1>::ParameterType Parm1;
156         typedef typename TypeTraits<P2>::ParameterType Parm2;
157         virtual ~FactoryImpl() {}
158         virtual AP* CreateObject(const Id& id,Parm1, Parm2 ) = 0;
159     };
160 
161     template<typename AP, typename Id, typename P1,typename P2,typename P3 >
162     struct FactoryImpl<AP, Id, Seq<P1, P2, P3> >
163                 : public FactoryImplBase
164     {
165         typedef typename TypeTraits<P1>::ParameterType Parm1;
166         typedef typename TypeTraits<P2>::ParameterType Parm2;
167         typedef typename TypeTraits<P3>::ParameterType Parm3;
168         virtual ~FactoryImpl() {}
169         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3 ) = 0;
170     };
171 
172     template<typename AP, typename Id, typename P1,typename P2,typename P3,typename P4 >
173     struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4> >
174                 : public FactoryImplBase
175     {
176         typedef typename TypeTraits<P1>::ParameterType Parm1;
177         typedef typename TypeTraits<P2>::ParameterType Parm2;
178         typedef typename TypeTraits<P3>::ParameterType Parm3;
179         typedef typename TypeTraits<P4>::ParameterType Parm4;
180         virtual ~FactoryImpl() {}
181         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4 ) = 0;
182     };
183 
184     template<typename AP, typename Id,
185     typename P1,typename P2,typename P3,typename P4,typename P5 >
186     struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5> >
187                 : public FactoryImplBase
188     {
189         typedef typename TypeTraits<P1>::ParameterType Parm1;
190         typedef typename TypeTraits<P2>::ParameterType Parm2;
191         typedef typename TypeTraits<P3>::ParameterType Parm3;
192         typedef typename TypeTraits<P4>::ParameterType Parm4;
193         typedef typename TypeTraits<P5>::ParameterType Parm5;
194         virtual ~FactoryImpl() {}
195         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5 ) = 0;
196     };
197 
198     template<typename AP, typename Id,
199     typename P1,typename P2,typename P3,typename P4,typename P5,
200     typename P6>
201     struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6> >
202                 : public FactoryImplBase
203     {
204         typedef typename TypeTraits<P1>::ParameterType Parm1;
205         typedef typename TypeTraits<P2>::ParameterType Parm2;
206         typedef typename TypeTraits<P3>::ParameterType Parm3;
207         typedef typename TypeTraits<P4>::ParameterType Parm4;
208         typedef typename TypeTraits<P5>::ParameterType Parm5;
209         typedef typename TypeTraits<P6>::ParameterType Parm6;
210         virtual ~FactoryImpl() {}
211         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
212                                 Parm6 )
213         = 0;
214     };
215 
216     template<typename AP, typename Id,
217     typename P1,typename P2,typename P3,typename P4,typename P5,
218     typename P6,typename P7>
219     struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7> >
220                 : public FactoryImplBase
221     {
222         typedef typename TypeTraits<P1>::ParameterType Parm1;
223         typedef typename TypeTraits<P2>::ParameterType Parm2;
224         typedef typename TypeTraits<P3>::ParameterType Parm3;
225         typedef typename TypeTraits<P4>::ParameterType Parm4;
226         typedef typename TypeTraits<P5>::ParameterType Parm5;
227         typedef typename TypeTraits<P6>::ParameterType Parm6;
228         typedef typename TypeTraits<P7>::ParameterType Parm7;
229         virtual ~FactoryImpl() {}
230         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
231                                 Parm6, Parm7 )
232         = 0;
233     };
234 
235     template<typename AP, typename Id,
236     typename P1,typename P2,typename P3,typename P4,typename P5,
237     typename P6,typename P7,typename P8>
238     struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8> >
239                 : public FactoryImplBase
240     {
241         typedef typename TypeTraits<P1>::ParameterType Parm1;
242         typedef typename TypeTraits<P2>::ParameterType Parm2;
243         typedef typename TypeTraits<P3>::ParameterType Parm3;
244         typedef typename TypeTraits<P4>::ParameterType Parm4;
245         typedef typename TypeTraits<P5>::ParameterType Parm5;
246         typedef typename TypeTraits<P6>::ParameterType Parm6;
247         typedef typename TypeTraits<P7>::ParameterType Parm7;
248         typedef typename TypeTraits<P8>::ParameterType Parm8;
249         virtual ~FactoryImpl() {}
250         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
251                                 Parm6, Parm7, Parm8)
252         = 0;
253     };
254 
255     template<typename AP, typename Id,
256     typename P1,typename P2,typename P3,typename P4,typename P5,
257     typename P6,typename P7,typename P8,typename P9>
258     struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9> >
259                 : public FactoryImplBase
260     {
261         typedef typename TypeTraits<P1>::ParameterType Parm1;
262         typedef typename TypeTraits<P2>::ParameterType Parm2;
263         typedef typename TypeTraits<P3>::ParameterType Parm3;
264         typedef typename TypeTraits<P4>::ParameterType Parm4;
265         typedef typename TypeTraits<P5>::ParameterType Parm5;
266         typedef typename TypeTraits<P6>::ParameterType Parm6;
267         typedef typename TypeTraits<P7>::ParameterType Parm7;
268         typedef typename TypeTraits<P8>::ParameterType Parm8;
269         typedef typename TypeTraits<P9>::ParameterType Parm9;
270         virtual ~FactoryImpl() {}
271         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
272                                 Parm6, Parm7, Parm8, Parm9)
273         = 0;
274     };
275 
276     template<typename AP, typename Id,
277     typename P1,typename P2,typename P3,typename P4,typename P5,
278     typename P6,typename P7,typename P8,typename P9,typename P10>
279     struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> >
280                 : public FactoryImplBase
281     {
282         typedef typename TypeTraits<P1>::ParameterType Parm1;
283         typedef typename TypeTraits<P2>::ParameterType Parm2;
284         typedef typename TypeTraits<P3>::ParameterType Parm3;
285         typedef typename TypeTraits<P4>::ParameterType Parm4;
286         typedef typename TypeTraits<P5>::ParameterType Parm5;
287         typedef typename TypeTraits<P6>::ParameterType Parm6;
288         typedef typename TypeTraits<P7>::ParameterType Parm7;
289         typedef typename TypeTraits<P8>::ParameterType Parm8;
290         typedef typename TypeTraits<P9>::ParameterType Parm9;
291         typedef typename TypeTraits<P10>::ParameterType Parm10;
292         virtual ~FactoryImpl() {}
293         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
294                                 Parm6, Parm7, Parm8, Parm9,Parm10)
295         = 0;
296     };
297 
298     template<typename AP, typename Id,
299     typename P1,typename P2,typename P3,typename P4,typename P5,
300     typename P6,typename P7,typename P8,typename P9,typename P10,
301     typename P11>
302     struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11> >
303                 : public FactoryImplBase
304     {
305         typedef typename TypeTraits<P1>::ParameterType Parm1;
306         typedef typename TypeTraits<P2>::ParameterType Parm2;
307         typedef typename TypeTraits<P3>::ParameterType Parm3;
308         typedef typename TypeTraits<P4>::ParameterType Parm4;
309         typedef typename TypeTraits<P5>::ParameterType Parm5;
310         typedef typename TypeTraits<P6>::ParameterType Parm6;
311         typedef typename TypeTraits<P7>::ParameterType Parm7;
312         typedef typename TypeTraits<P8>::ParameterType Parm8;
313         typedef typename TypeTraits<P9>::ParameterType Parm9;
314         typedef typename TypeTraits<P10>::ParameterType Parm10;
315         typedef typename TypeTraits<P11>::ParameterType Parm11;
316         virtual ~FactoryImpl() {}
317         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
318                                 Parm6, Parm7, Parm8, Parm9,Parm10,
319                                 Parm11)
320         = 0;
321     };
322 
323     template<typename AP, typename Id,
324     typename P1,typename P2,typename P3,typename P4,typename P5,
325     typename P6,typename P7,typename P8,typename P9,typename P10,
326     typename P11,typename P12>
327     struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12> >
328                 : public FactoryImplBase
329     {
330         typedef typename TypeTraits<P1>::ParameterType Parm1;
331         typedef typename TypeTraits<P2>::ParameterType Parm2;
332         typedef typename TypeTraits<P3>::ParameterType Parm3;
333         typedef typename TypeTraits<P4>::ParameterType Parm4;
334         typedef typename TypeTraits<P5>::ParameterType Parm5;
335         typedef typename TypeTraits<P6>::ParameterType Parm6;
336         typedef typename TypeTraits<P7>::ParameterType Parm7;
337         typedef typename TypeTraits<P8>::ParameterType Parm8;
338         typedef typename TypeTraits<P9>::ParameterType Parm9;
339         typedef typename TypeTraits<P10>::ParameterType Parm10;
340         typedef typename TypeTraits<P11>::ParameterType Parm11;
341         typedef typename TypeTraits<P12>::ParameterType Parm12;
342         virtual ~FactoryImpl() {}
343         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
344                                 Parm6, Parm7, Parm8, Parm9,Parm10,
345                                 Parm11,Parm12)
346         = 0;
347     };
348 
349     template<typename AP, typename Id,
350     typename P1,typename P2,typename P3,typename P4,typename P5,
351     typename P6,typename P7,typename P8,typename P9,typename P10,
352     typename P11,typename P12,typename P13>
353     struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13> >
354                 : public FactoryImplBase
355     {
356         typedef typename TypeTraits<P1>::ParameterType Parm1;
357         typedef typename TypeTraits<P2>::ParameterType Parm2;
358         typedef typename TypeTraits<P3>::ParameterType Parm3;
359         typedef typename TypeTraits<P4>::ParameterType Parm4;
360         typedef typename TypeTraits<P5>::ParameterType Parm5;
361         typedef typename TypeTraits<P6>::ParameterType Parm6;
362         typedef typename TypeTraits<P7>::ParameterType Parm7;
363         typedef typename TypeTraits<P8>::ParameterType Parm8;
364         typedef typename TypeTraits<P9>::ParameterType Parm9;
365         typedef typename TypeTraits<P10>::ParameterType Parm10;
366         typedef typename TypeTraits<P11>::ParameterType Parm11;
367         typedef typename TypeTraits<P12>::ParameterType Parm12;
368         typedef typename TypeTraits<P13>::ParameterType Parm13;
369         virtual ~FactoryImpl() {}
370         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
371                                 Parm6, Parm7, Parm8, Parm9,Parm10,
372                                 Parm11,Parm12,Parm13)
373         = 0;
374     };
375 
376     template<typename AP, typename Id,
377     typename P1,typename P2,typename P3,typename P4,typename P5,
378     typename P6,typename P7,typename P8,typename P9,typename P10,
379     typename P11,typename P12,typename P13,typename P14>
380     struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14> >
381                 : public FactoryImplBase
382     {
383         typedef typename TypeTraits<P1>::ParameterType Parm1;
384         typedef typename TypeTraits<P2>::ParameterType Parm2;
385         typedef typename TypeTraits<P3>::ParameterType Parm3;
386         typedef typename TypeTraits<P4>::ParameterType Parm4;
387         typedef typename TypeTraits<P5>::ParameterType Parm5;
388         typedef typename TypeTraits<P6>::ParameterType Parm6;
389         typedef typename TypeTraits<P7>::ParameterType Parm7;
390         typedef typename TypeTraits<P8>::ParameterType Parm8;
391         typedef typename TypeTraits<P9>::ParameterType Parm9;
392         typedef typename TypeTraits<P10>::ParameterType Parm10;
393         typedef typename TypeTraits<P11>::ParameterType Parm11;
394         typedef typename TypeTraits<P12>::ParameterType Parm12;
395         typedef typename TypeTraits<P13>::ParameterType Parm13;
396         typedef typename TypeTraits<P14>::ParameterType Parm14;
397         virtual ~FactoryImpl() {}
398         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
399                                 Parm6, Parm7, Parm8, Parm8,Parm10,
400                                 Parm11,Parm12,Parm13,Parm14)
401         = 0;
402     };
403 
404     template<typename AP, typename Id,
405     typename P1,typename P2,typename P3,typename P4,typename P5,
406     typename P6,typename P7,typename P8,typename P9,typename P10,
407     typename P11,typename P12,typename P13,typename P14,typename P15 >
408     struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15> >
409                 : public FactoryImplBase
410     {
411         typedef typename TypeTraits<P1>::ParameterType Parm1;
412         typedef typename TypeTraits<P2>::ParameterType Parm2;
413         typedef typename TypeTraits<P3>::ParameterType Parm3;
414         typedef typename TypeTraits<P4>::ParameterType Parm4;
415         typedef typename TypeTraits<P5>::ParameterType Parm5;
416         typedef typename TypeTraits<P6>::ParameterType Parm6;
417         typedef typename TypeTraits<P7>::ParameterType Parm7;
418         typedef typename TypeTraits<P8>::ParameterType Parm8;
419         typedef typename TypeTraits<P9>::ParameterType Parm9;
420         typedef typename TypeTraits<P10>::ParameterType Parm10;
421         typedef typename TypeTraits<P11>::ParameterType Parm11;
422         typedef typename TypeTraits<P12>::ParameterType Parm12;
423         typedef typename TypeTraits<P13>::ParameterType Parm13;
424         typedef typename TypeTraits<P14>::ParameterType Parm14;
425         typedef typename TypeTraits<P15>::ParameterType Parm15;
426         virtual ~FactoryImpl() {}
427         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
428                                 Parm6, Parm7, Parm8, Parm9,Parm10,
429                                 Parm11,Parm12,Parm13,Parm14,Parm15 )
430         = 0;
431     };
432 
433 #ifndef LOKI_DISABLE_TYPELIST_MACROS
434 
435     template <typename AP, typename Id, typename P1 >
436     struct FactoryImpl<AP,Id, LOKI_TYPELIST_1( P1 )>
437                 : public FactoryImplBase
438     {
439         typedef typename TypeTraits<P1>::ParameterType Parm1;
440         virtual ~FactoryImpl() {}
441         virtual AP* CreateObject(const Id& id,Parm1 ) = 0;
442     };
443 
444     template<typename AP, typename Id, typename P1,typename P2 >
445     struct FactoryImpl<AP, Id, LOKI_TYPELIST_2( P1, P2 )>
446                 : public FactoryImplBase
447     {
448         typedef typename TypeTraits<P1>::ParameterType Parm1;
449         typedef typename TypeTraits<P2>::ParameterType Parm2;
450         virtual ~FactoryImpl() {}
451         virtual AP* CreateObject(const Id& id,Parm1, Parm2 ) = 0;
452     };
453 
454     template<typename AP, typename Id, typename P1,typename P2,typename P3 >
455     struct FactoryImpl<AP, Id, LOKI_TYPELIST_3( P1, P2, P3 )>
456                 : public FactoryImplBase
457     {
458         typedef typename TypeTraits<P1>::ParameterType Parm1;
459         typedef typename TypeTraits<P2>::ParameterType Parm2;
460         typedef typename TypeTraits<P3>::ParameterType Parm3;
461         virtual ~FactoryImpl() {}
462         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3 ) = 0;
463     };
464 
465     template<typename AP, typename Id, typename P1,typename P2,typename P3,typename P4 >
466     struct FactoryImpl<AP, Id, LOKI_TYPELIST_4( P1, P2, P3, P4 )>
467                 : public FactoryImplBase
468     {
469         typedef typename TypeTraits<P1>::ParameterType Parm1;
470         typedef typename TypeTraits<P2>::ParameterType Parm2;
471         typedef typename TypeTraits<P3>::ParameterType Parm3;
472         typedef typename TypeTraits<P4>::ParameterType Parm4;
473         virtual ~FactoryImpl() {}
474         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4 ) = 0;
475     };
476 
477     template<typename AP, typename Id,
478     typename P1,typename P2,typename P3,typename P4,typename P5 >
479     struct FactoryImpl<AP, Id, LOKI_TYPELIST_5( P1, P2, P3, P4, P5 )>
480                 : public FactoryImplBase
481     {
482         typedef typename TypeTraits<P1>::ParameterType Parm1;
483         typedef typename TypeTraits<P2>::ParameterType Parm2;
484         typedef typename TypeTraits<P3>::ParameterType Parm3;
485         typedef typename TypeTraits<P4>::ParameterType Parm4;
486         typedef typename TypeTraits<P5>::ParameterType Parm5;
487         virtual ~FactoryImpl() {}
488         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5 ) = 0;
489     };
490 
491     template<typename AP, typename Id,
492     typename P1,typename P2,typename P3,typename P4,typename P5,
493     typename P6>
494     struct FactoryImpl<AP, Id, LOKI_TYPELIST_6( P1, P2, P3, P4, P5, P6 )>
495                 : public FactoryImplBase
496     {
497         typedef typename TypeTraits<P1>::ParameterType Parm1;
498         typedef typename TypeTraits<P2>::ParameterType Parm2;
499         typedef typename TypeTraits<P3>::ParameterType Parm3;
500         typedef typename TypeTraits<P4>::ParameterType Parm4;
501         typedef typename TypeTraits<P5>::ParameterType Parm5;
502         typedef typename TypeTraits<P6>::ParameterType Parm6;
503         virtual ~FactoryImpl() {}
504         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
505                                 Parm6 )
506         = 0;
507     };
508 
509     template<typename AP, typename Id,
510     typename P1,typename P2,typename P3,typename P4,typename P5,
511     typename P6,typename P7>
512     struct FactoryImpl<AP, Id, LOKI_TYPELIST_7( P1, P2, P3, P4, P5, P6, P7 )>
513                 : public FactoryImplBase
514     {
515         typedef typename TypeTraits<P1>::ParameterType Parm1;
516         typedef typename TypeTraits<P2>::ParameterType Parm2;
517         typedef typename TypeTraits<P3>::ParameterType Parm3;
518         typedef typename TypeTraits<P4>::ParameterType Parm4;
519         typedef typename TypeTraits<P5>::ParameterType Parm5;
520         typedef typename TypeTraits<P6>::ParameterType Parm6;
521         typedef typename TypeTraits<P7>::ParameterType Parm7;
522         virtual ~FactoryImpl() {}
523         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
524                                 Parm6, Parm7 )
525         = 0;
526     };
527 
528     template<typename AP, typename Id,
529     typename P1,typename P2,typename P3,typename P4,typename P5,
530     typename P6,typename P7,typename P8>
531     struct FactoryImpl<AP, Id, LOKI_TYPELIST_8( P1, P2, P3, P4, P5, P6, P7, P8 )>
532                 : public FactoryImplBase
533     {
534         typedef typename TypeTraits<P1>::ParameterType Parm1;
535         typedef typename TypeTraits<P2>::ParameterType Parm2;
536         typedef typename TypeTraits<P3>::ParameterType Parm3;
537         typedef typename TypeTraits<P4>::ParameterType Parm4;
538         typedef typename TypeTraits<P5>::ParameterType Parm5;
539         typedef typename TypeTraits<P6>::ParameterType Parm6;
540         typedef typename TypeTraits<P7>::ParameterType Parm7;
541         typedef typename TypeTraits<P8>::ParameterType Parm8;
542         virtual ~FactoryImpl() {}
543         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
544                                 Parm6, Parm7, Parm8)
545         = 0;
546     };
547 
548     template<typename AP, typename Id,
549     typename P1,typename P2,typename P3,typename P4,typename P5,
550     typename P6,typename P7,typename P8,typename P9>
551     struct FactoryImpl<AP, Id, LOKI_TYPELIST_9( P1, P2, P3, P4, P5, P6, P7, P8, P9 )>
552                 : public FactoryImplBase
553     {
554         typedef typename TypeTraits<P1>::ParameterType Parm1;
555         typedef typename TypeTraits<P2>::ParameterType Parm2;
556         typedef typename TypeTraits<P3>::ParameterType Parm3;
557         typedef typename TypeTraits<P4>::ParameterType Parm4;
558         typedef typename TypeTraits<P5>::ParameterType Parm5;
559         typedef typename TypeTraits<P6>::ParameterType Parm6;
560         typedef typename TypeTraits<P7>::ParameterType Parm7;
561         typedef typename TypeTraits<P8>::ParameterType Parm8;
562         typedef typename TypeTraits<P9>::ParameterType Parm9;
563         virtual ~FactoryImpl() {}
564         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
565                                 Parm6, Parm7, Parm8, Parm9)
566         = 0;
567     };
568 
569     template<typename AP, typename Id,
570     typename P1,typename P2,typename P3,typename P4,typename P5,
571     typename P6,typename P7,typename P8,typename P9,typename P10>
572     struct FactoryImpl<AP, Id, LOKI_TYPELIST_10( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10 )>
573                 : public FactoryImplBase
574     {
575         typedef typename TypeTraits<P1>::ParameterType Parm1;
576         typedef typename TypeTraits<P2>::ParameterType Parm2;
577         typedef typename TypeTraits<P3>::ParameterType Parm3;
578         typedef typename TypeTraits<P4>::ParameterType Parm4;
579         typedef typename TypeTraits<P5>::ParameterType Parm5;
580         typedef typename TypeTraits<P6>::ParameterType Parm6;
581         typedef typename TypeTraits<P7>::ParameterType Parm7;
582         typedef typename TypeTraits<P8>::ParameterType Parm8;
583         typedef typename TypeTraits<P9>::ParameterType Parm9;
584         typedef typename TypeTraits<P10>::ParameterType Parm10;
585         virtual ~FactoryImpl() {}
586         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
587                                 Parm6, Parm7, Parm8, Parm9,Parm10)
588         = 0;
589     };
590 
591     template<typename AP, typename Id,
592     typename P1,typename P2,typename P3,typename P4,typename P5,
593     typename P6,typename P7,typename P8,typename P9,typename P10,
594     typename P11>
595     struct FactoryImpl<AP, Id, LOKI_TYPELIST_11( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11 )>
596                 : public FactoryImplBase
597     {
598         typedef typename TypeTraits<P1>::ParameterType Parm1;
599         typedef typename TypeTraits<P2>::ParameterType Parm2;
600         typedef typename TypeTraits<P3>::ParameterType Parm3;
601         typedef typename TypeTraits<P4>::ParameterType Parm4;
602         typedef typename TypeTraits<P5>::ParameterType Parm5;
603         typedef typename TypeTraits<P6>::ParameterType Parm6;
604         typedef typename TypeTraits<P7>::ParameterType Parm7;
605         typedef typename TypeTraits<P8>::ParameterType Parm8;
606         typedef typename TypeTraits<P9>::ParameterType Parm9;
607         typedef typename TypeTraits<P10>::ParameterType Parm10;
608         typedef typename TypeTraits<P11>::ParameterType Parm11;
609         virtual ~FactoryImpl() {}
610         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
611                                 Parm6, Parm7, Parm8, Parm9,Parm10,
612                                 Parm11)
613         = 0;
614     };
615 
616     template<typename AP, typename Id,
617     typename P1,typename P2,typename P3,typename P4,typename P5,
618     typename P6,typename P7,typename P8,typename P9,typename P10,
619     typename P11,typename P12>
620     struct FactoryImpl<AP, Id, LOKI_TYPELIST_12( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12 )>
621                 : public FactoryImplBase
622     {
623         typedef typename TypeTraits<P1>::ParameterType Parm1;
624         typedef typename TypeTraits<P2>::ParameterType Parm2;
625         typedef typename TypeTraits<P3>::ParameterType Parm3;
626         typedef typename TypeTraits<P4>::ParameterType Parm4;
627         typedef typename TypeTraits<P5>::ParameterType Parm5;
628         typedef typename TypeTraits<P6>::ParameterType Parm6;
629         typedef typename TypeTraits<P7>::ParameterType Parm7;
630         typedef typename TypeTraits<P8>::ParameterType Parm8;
631         typedef typename TypeTraits<P9>::ParameterType Parm9;
632         typedef typename TypeTraits<P10>::ParameterType Parm10;
633         typedef typename TypeTraits<P11>::ParameterType Parm11;
634         typedef typename TypeTraits<P12>::ParameterType Parm12;
635         virtual ~FactoryImpl() {}
636         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
637                                 Parm6, Parm7, Parm8, Parm9,Parm10,
638                                 Parm11,Parm12)
639         = 0;
640     };
641 
642     template<typename AP, typename Id,
643     typename P1,typename P2,typename P3,typename P4,typename P5,
644     typename P6,typename P7,typename P8,typename P9,typename P10,
645     typename P11,typename P12,typename P13>
646     struct FactoryImpl<AP, Id, LOKI_TYPELIST_13( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13 )>
647                 : public FactoryImplBase
648     {
649         typedef typename TypeTraits<P1>::ParameterType Parm1;
650         typedef typename TypeTraits<P2>::ParameterType Parm2;
651         typedef typename TypeTraits<P3>::ParameterType Parm3;
652         typedef typename TypeTraits<P4>::ParameterType Parm4;
653         typedef typename TypeTraits<P5>::ParameterType Parm5;
654         typedef typename TypeTraits<P6>::ParameterType Parm6;
655         typedef typename TypeTraits<P7>::ParameterType Parm7;
656         typedef typename TypeTraits<P8>::ParameterType Parm8;
657         typedef typename TypeTraits<P9>::ParameterType Parm9;
658         typedef typename TypeTraits<P10>::ParameterType Parm10;
659         typedef typename TypeTraits<P11>::ParameterType Parm11;
660         typedef typename TypeTraits<P12>::ParameterType Parm12;
661         typedef typename TypeTraits<P13>::ParameterType Parm13;
662         virtual ~FactoryImpl() {}
663         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
664                                 Parm6, Parm7, Parm8, Parm9,Parm10,
665                                 Parm11,Parm12,Parm13)
666         = 0;
667     };
668 
669     template<typename AP, typename Id,
670     typename P1,typename P2,typename P3,typename P4,typename P5,
671     typename P6,typename P7,typename P8,typename P9,typename P10,
672     typename P11,typename P12,typename P13,typename P14>
673     struct FactoryImpl<AP, Id, LOKI_TYPELIST_14( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14 )>
674                 : public FactoryImplBase
675     {
676         typedef typename TypeTraits<P1>::ParameterType Parm1;
677         typedef typename TypeTraits<P2>::ParameterType Parm2;
678         typedef typename TypeTraits<P3>::ParameterType Parm3;
679         typedef typename TypeTraits<P4>::ParameterType Parm4;
680         typedef typename TypeTraits<P5>::ParameterType Parm5;
681         typedef typename TypeTraits<P6>::ParameterType Parm6;
682         typedef typename TypeTraits<P7>::ParameterType Parm7;
683         typedef typename TypeTraits<P8>::ParameterType Parm8;
684         typedef typename TypeTraits<P9>::ParameterType Parm9;
685         typedef typename TypeTraits<P10>::ParameterType Parm10;
686         typedef typename TypeTraits<P11>::ParameterType Parm11;
687         typedef typename TypeTraits<P12>::ParameterType Parm12;
688         typedef typename TypeTraits<P13>::ParameterType Parm13;
689         typedef typename TypeTraits<P14>::ParameterType Parm14;
690         virtual ~FactoryImpl() {}
691         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
692                                 Parm6, Parm7, Parm8, Parm8,Parm10,
693                                 Parm11,Parm12,Parm13,Parm14)
694         = 0;
695     };
696 
697     template<typename AP, typename Id,
698     typename P1,typename P2,typename P3,typename P4,typename P5,
699     typename P6,typename P7,typename P8,typename P9,typename P10,
700     typename P11,typename P12,typename P13,typename P14,typename P15 >
701     struct FactoryImpl<AP, Id, LOKI_TYPELIST_15( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15 )>
702                 : public FactoryImplBase
703     {
704         typedef typename TypeTraits<P1>::ParameterType Parm1;
705         typedef typename TypeTraits<P2>::ParameterType Parm2;
706         typedef typename TypeTraits<P3>::ParameterType Parm3;
707         typedef typename TypeTraits<P4>::ParameterType Parm4;
708         typedef typename TypeTraits<P5>::ParameterType Parm5;
709         typedef typename TypeTraits<P6>::ParameterType Parm6;
710         typedef typename TypeTraits<P7>::ParameterType Parm7;
711         typedef typename TypeTraits<P8>::ParameterType Parm8;
712         typedef typename TypeTraits<P9>::ParameterType Parm9;
713         typedef typename TypeTraits<P10>::ParameterType Parm10;
714         typedef typename TypeTraits<P11>::ParameterType Parm11;
715         typedef typename TypeTraits<P12>::ParameterType Parm12;
716         typedef typename TypeTraits<P13>::ParameterType Parm13;
717         typedef typename TypeTraits<P14>::ParameterType Parm14;
718         typedef typename TypeTraits<P15>::ParameterType Parm15;
719         virtual ~FactoryImpl() {}
720         virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
721                                 Parm6, Parm7, Parm8, Parm9,Parm10,
722                                 Parm11,Parm12,Parm13,Parm14,Parm15 )
723         = 0;
724     };
725 
726 #endif //LOKI_DISABLE_TYPELIST_MACROS
727 
728 
729 ////////////////////////////////////////////////////////////////////////////////
730 ///  \class Factory
731 ///
732 ///  \ingroup FactoryGroup
733 ///  Implements a generic object factory.
734 ///
735 ///  Create functions can have up to 15 parameters.
736 ///
737 ///  \par Singleton lifetime when used with Loki::SingletonHolder
738 ///  Because Factory uses internally Functors which inherits from
739 ///  SmallObject you must use the singleton lifetime
740 ///  \code Loki::LongevityLifetime::DieAsSmallObjectChild \endcode
741 ///  Alternatively you could suppress for Functor the inheritance
742 ///  from SmallObject by defining the macro:
743 /// \code LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT \endcode
744 ////////////////////////////////////////////////////////////////////////////////
745     template
746     <
747         class AbstractProduct,
748         typename IdentifierType,
749         typename CreatorParmTList = NullType,
750         template<typename, class> class FactoryErrorPolicy = DefaultFactoryError
751     >
752     class Factory : public FactoryErrorPolicy<IdentifierType, AbstractProduct>
753     {
754         typedef FactoryImpl< AbstractProduct, IdentifierType, CreatorParmTList > Impl;
755 
756         typedef typename Impl::Parm1 Parm1;
757         typedef typename Impl::Parm2 Parm2;
758         typedef typename Impl::Parm3 Parm3;
759         typedef typename Impl::Parm4 Parm4;
760         typedef typename Impl::Parm5 Parm5;
761         typedef typename Impl::Parm6 Parm6;
762         typedef typename Impl::Parm7 Parm7;
763         typedef typename Impl::Parm8 Parm8;
764         typedef typename Impl::Parm9 Parm9;
765         typedef typename Impl::Parm10 Parm10;
766         typedef typename Impl::Parm11 Parm11;
767         typedef typename Impl::Parm12 Parm12;
768         typedef typename Impl::Parm13 Parm13;
769         typedef typename Impl::Parm14 Parm14;
770         typedef typename Impl::Parm15 Parm15;
771 
772         typedef Functor<AbstractProduct*, CreatorParmTList> ProductCreator;
773 
774         typedef AssocVector<IdentifierType, ProductCreator> IdToProductMap;
775 
776         IdToProductMap associations_;
777 
778     public:
779 
780         Factory()
781             : associations_()
782         {
783         }
784 
785         ~Factory()
786         {
787             associations_.erase(associations_.begin(), associations_.end());
788         }
789 
790         bool Register(const IdentifierType& id, ProductCreator creator)
791         {
792             return associations_.insert(
793                          typename IdToProductMap::value_type(id, creator)).second != 0;
794         }
795 
796         template <class PtrObj, typename CreaFn>
797         bool Register(const IdentifierType& id, const PtrObj& p, CreaFn fn)
798         {
799             ProductCreator creator( p, fn );
800             return associations_.insert(
801                 typename IdToProductMap::value_type(id, creator)).second != 0;
802         }
803 
804         bool Unregister(const IdentifierType& id)
805         {
806             return associations_.erase(id) != 0;
807         }
808 
809         std::vector<IdentifierType> RegisteredIds()
810         {
811             std::vector<IdentifierType> ids;
812             for(typename IdToProductMap::iterator it = associations_.begin();
813                 it != associations_.end(); ++it)
814             {
815                 ids.push_back(it->first);
816             }
817             return ids;
818         }
819 
820         AbstractProduct* CreateObject(const IdentifierType& id)
821         {
822             typename IdToProductMap::iterator i = associations_.find(id);
823             if (i != associations_.end())
824                 return (i->second)( );
825             return this->OnUnknownType(id);
826         }
827 
828         AbstractProduct* CreateObject(const IdentifierType& id,
829                                             Parm1 p1)
830         {
831             typename IdToProductMap::iterator i = associations_.find(id);
832             if (i != associations_.end())
833                 return (i->second)( p1 );
834             return this->OnUnknownType(id);
835         }
836 
837         AbstractProduct* CreateObject(const IdentifierType& id,
838                                             Parm1 p1, Parm2 p2)
839         {
840             typename IdToProductMap::iterator i = associations_.find(id);
841             if (i != associations_.end())
842                 return (i->second)( p1,p2 );
843             return this->OnUnknownType(id);
844         }
845 
846         AbstractProduct* CreateObject(const IdentifierType& id,
847                                             Parm1 p1, Parm2 p2, Parm3 p3)
848         {
849             typename IdToProductMap::iterator i = associations_.find(id);
850             if (i != associations_.end())
851                 return (i->second)( p1,p2,p3 );
852             return this->OnUnknownType(id);
853         }
854 
855         AbstractProduct* CreateObject(const IdentifierType& id,
856                                             Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
857         {
858             typename IdToProductMap::iterator i = associations_.find(id);
859             if (i != associations_.end())
860                 return (i->second)( p1,p2,p3,p4 );
861             return this->OnUnknownType(id);
862         }
863 
864         AbstractProduct* CreateObject(const IdentifierType& id,
865                                             Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
866         {
867             typename IdToProductMap::iterator i = associations_.find(id);
868             if (i != associations_.end())
869                 return (i->second)( p1,p2,p3,p4,p5 );
870             return this->OnUnknownType(id);
871         }
872 
873         AbstractProduct* CreateObject(const IdentifierType& id,
874                                             Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
875                                             Parm6 p6)
876         {
877             typename IdToProductMap::iterator i = associations_.find(id);
878             if (i != associations_.end())
879                 return (i->second)( p1,p2,p3,p4,p5,p6 );
880             return this->OnUnknownType(id);
881         }
882 
883         AbstractProduct* CreateObject(const IdentifierType& id,
884                                             Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
885                                             Parm6 p6, Parm7 p7 )
886         {
887             typename IdToProductMap::iterator i = associations_.find(id);
888             if (i != associations_.end())
889                 return (i->second)( p1,p2,p3,p4,p5,p6,p7 );
890             return this->OnUnknownType(id);
891         }
892 
893         AbstractProduct* CreateObject(const IdentifierType& id,
894                                             Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
895                                             Parm6 p6, Parm7 p7, Parm8 p8)
896         {
897             typename IdToProductMap::iterator i = associations_.find(id);
898             if (i != associations_.end())
899                 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8 );
900             return this->OnUnknownType(id);
901         }
902 
903         AbstractProduct* CreateObject(const IdentifierType& id,
904                                             Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
905                                             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
906         {
907             typename IdToProductMap::iterator i = associations_.find(id);
908             if (i != associations_.end())
909                 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9 );
910             return this->OnUnknownType(id);
911         }
912         AbstractProduct* CreateObject(const IdentifierType& id,
913                                             Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
914                                             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9,Parm10 p10)
915         {
916             typename IdToProductMap::iterator i = associations_.find(id);
917             if (i != associations_.end())
918                 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10 );
919             return this->OnUnknownType(id);
920         }
921 
922         AbstractProduct* CreateObject(const IdentifierType& id,
923                                             Parm1  p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5  p5,
924                                             Parm6  p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
925                                             Parm11 p11)
926         {
927             typename IdToProductMap::iterator i = associations_.find(id);
928             if (i != associations_.end())
929                 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11 );
930             return this->OnUnknownType(id);
931         }
932 
933         AbstractProduct* CreateObject(const IdentifierType& id,
934                                             Parm1  p1,  Parm2  p2, Parm3 p3, Parm4 p4, Parm5  p5,
935                                             Parm6  p6,  Parm7  p7, Parm8 p8, Parm9 p9, Parm10 p10,
936                                             Parm11 p11, Parm12 p12)
937         {
938             typename IdToProductMap::iterator i = associations_.find(id);
939             if (i != associations_.end())
940                 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12 );
941             return this->OnUnknownType(id);
942         }
943 
944         AbstractProduct* CreateObject(const IdentifierType& id,
945                                             Parm1  p1,  Parm2  p2,  Parm3  p3, Parm4 p4, Parm5  p5,
946                                             Parm6  p6,  Parm7  p7,  Parm8  p8, Parm9 p9, Parm10 p10,
947                                             Parm11 p11, Parm12 p12, Parm13 p13)
948         {
949             typename IdToProductMap::iterator i = associations_.find(id);
950             if (i != associations_.end())
951                 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13 );
952             return this->OnUnknownType(id);
953         }
954 
955         AbstractProduct* CreateObject(const IdentifierType& id,
956                                             Parm1  p1,  Parm2  p2,  Parm3  p3,  Parm4  p4, Parm5  p5,
957                                             Parm6  p6,  Parm7  p7,  Parm8  p8,  Parm9  p9, Parm10 p10,
958                                             Parm11 p11, Parm12 p12, Parm13 p13, Parm14 p14)
959         {
960             typename IdToProductMap::iterator i = associations_.find(id);
961             if (i != associations_.end())
962                 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14 );
963             return this->OnUnknownType(id);
964         }
965 
966         AbstractProduct* CreateObject(const IdentifierType& id,
967                                             Parm1  p1,  Parm2  p2,  Parm3  p3,  Parm4  p4,  Parm5  p5,
968                                             Parm6  p6,  Parm7  p7,  Parm8  p8,  Parm9  p9,  Parm10 p10,
969                                             Parm11 p11, Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
970         {
971             typename IdToProductMap::iterator i = associations_.find(id);
972             if (i != associations_.end())
973                 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15 );
974             return this->OnUnknownType(id);
975         }
976 
977     };
978 
979 #else
980 
981     template
982     <
983         class AbstractProduct,
984         typename IdentifierType,
985         typename ProductCreator = AbstractProduct* (*)(),
986         template<typename, class>
987             class FactoryErrorPolicy = DefaultFactoryError
988     >
989     class Factory
990         : public FactoryErrorPolicy<IdentifierType, AbstractProduct>
991     {
992     public:
993         bool Register(const IdentifierType& id, ProductCreator creator)
994         {
995             return associations_.insert(
996                 typename IdToProductMap::value_type(id, creator)).second != 0;
997         }
998 
999         bool Unregister(const IdentifierType& id)
1000         {
1001             return associations_.erase(id) != 0;
1002         }
1003 
1004         AbstractProduct* CreateObject(const IdentifierType& id)
1005         {
1006             typename IdToProductMap::iterator i = associations_.find(id);
1007             if (i != associations_.end())
1008             {
1009                 return (i->second)();
1010             }
1011             return this->OnUnknownType(id);
1012         }
1013 
1014     private:
1015         typedef AssocVector<IdentifierType, ProductCreator> IdToProductMap;
1016         IdToProductMap associations_;
1017     };
1018 
1019 #endif //#define ENABLE_NEW_FACTORY_CODE
1020 
1021 /**
1022  *   \defgroup	CloneFactoryGroup Clone Factory
1023  *   \ingroup	FactoriesGroup
1024  *   \brief		Creates a copy from a polymorphic object.
1025  *
1026  *   \class		CloneFactory
1027  *   \ingroup	CloneFactoryGroup
1028  *   \brief		Creates a copy from a polymorphic object.
1029  */
1030 
1031     template
1032     <
1033         class AbstractProduct,
1034         class ProductCreator =
1035             AbstractProduct* (*)(const AbstractProduct*),
1036         template<typename, class>
1037             class FactoryErrorPolicy = DefaultFactoryError
1038     >
1039     class CloneFactory
1040         : public FactoryErrorPolicy<TypeInfo, AbstractProduct>
1041     {
1042     public:
1043         bool Register(const TypeInfo& ti, ProductCreator creator)
1044         {
1045             return associations_.insert(
1046                 typename IdToProductMap::value_type(ti, creator)).second != 0;
1047         }
1048 
1049         bool Unregister(const TypeInfo& id)
1050         {
1051             return associations_.erase(id) != 0;
1052         }
1053 
1054         AbstractProduct* CreateObject(const AbstractProduct* model)
1055         {
1056             if (model == NULL)
1057             {
1058             	return NULL;
1059             }
1060 
1061             typename IdToProductMap::iterator i =
1062             	associations_.find(typeid(*model));
1063 
1064             if (i != associations_.end())
1065             {
1066                 return (i->second)(model);
1067             }
1068             return this->OnUnknownType(typeid(*model));
1069         }
1070 
1071     private:
1072         typedef AssocVector<TypeInfo, ProductCreator> IdToProductMap;
1073         IdToProductMap associations_;
1074     };
1075 
1076 } // namespace Loki
1077 
1078 
1079 #ifdef _MSC_VER
1080 #pragma warning( pop )
1081 #endif
1082 
1083 #endif // end file guardian
1084 
1085