]> git.cworth.org Git - vogl/blob - src/extlib/loki/include/loki/Factory.h
Initial vogl checkin
[vogl] / src / extlib / loki / include / loki / Factory.h
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         {
95                 const char *what() const throw()
96                 {
97                         return "Unknown Type";
98                 }
99         };
100
101         static AbstractProduct *OnUnknownType(IdentifierType)
102         {
103                 throw Exception();
104         }
105 };
106
107
108 #define LOKI_ENABLE_NEW_FACTORY_CODE
109 #ifdef LOKI_ENABLE_NEW_FACTORY_CODE
110
111
112 ////////////////////////////////////////////////////////////////////////////////
113 // class template FunctorImpl
114 ////////////////////////////////////////////////////////////////////////////////
115
116 struct FactoryImplBase
117 {
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;
133 };
134
135 template <typename AP, typename Id, typename TList >
136 struct FactoryImpl;
137
138 template<typename AP, typename Id>
139 struct FactoryImpl<AP, Id, NullType>
140                 : public FactoryImplBase
141 {
142         virtual ~FactoryImpl() {}
143         virtual AP *CreateObject(const Id &id ) = 0;
144 };
145 template <typename AP, typename Id, typename P1 >
146 struct FactoryImpl<AP,Id, Seq<P1> >
147                 : public FactoryImplBase
148 {
149         typedef typename TypeTraits<P1>::ParameterType Parm1;
150         virtual ~FactoryImpl() {}
151         virtual AP *CreateObject(const Id &id,Parm1 ) = 0;
152 };
153
154 template<typename AP, typename Id, typename P1,typename P2 >
155 struct FactoryImpl<AP, Id, Seq<P1, P2> >
156                 : public FactoryImplBase
157 {
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;
162 };
163
164 template<typename AP, typename Id, typename P1,typename P2,typename P3 >
165 struct FactoryImpl<AP, Id, Seq<P1, P2, P3> >
166                 : public FactoryImplBase
167 {
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;
173 };
174
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
178 {
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;
185 };
186
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
191 {
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;
199 };
200
201 template<typename AP, typename Id,
202          typename P1,typename P2,typename P3,typename P4,typename P5,
203          typename P6>
204 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6> >
205                 : public FactoryImplBase
206 {
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,
215                                  Parm6 )
216         = 0;
217 };
218
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
224 {
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,
234                                  Parm6, Parm7 )
235         = 0;
236 };
237
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
243 {
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,
254                                  Parm6, Parm7, Parm8)
255         = 0;
256 };
257
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
263 {
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)
276         = 0;
277 };
278
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
284 {
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)
298         = 0;
299 };
300
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,
304          typename P11>
305 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11> >
306                 : public FactoryImplBase
307 {
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,
322                                  Parm11)
323         = 0;
324 };
325
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
332 {
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,
348                                  Parm11,Parm12)
349         = 0;
350 };
351
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
358 {
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)
376         = 0;
377 };
378
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
385 {
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)
404         = 0;
405 };
406
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
413 {
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 )
433         = 0;
434 };
435
436 #ifndef LOKI_DISABLE_TYPELIST_MACROS
437
438 template <typename AP, typename Id, typename P1 >
439 struct FactoryImpl<AP,Id, LOKI_TYPELIST_1( P1 )>
440 : public FactoryImplBase
441 {
442     typedef typename TypeTraits<P1>::ParameterType Parm1;
443 virtual ~FactoryImpl() {}
444 virtual AP *CreateObject(const Id &id,Parm1 ) = 0;
445 };
446
447 template<typename AP, typename Id, typename P1,typename P2 >
448 struct FactoryImpl<AP, Id, LOKI_TYPELIST_2( P1, P2 )>
449 : public FactoryImplBase
450 {
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;
455 };
456
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
460 {
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;
466 };
467
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
471 {
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;
478 };
479
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
484 {
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;
492 };
493
494 template<typename AP, typename Id,
495          typename P1,typename P2,typename P3,typename P4,typename P5,
496          typename P6>
497 struct FactoryImpl<AP, Id, LOKI_TYPELIST_6( P1, P2, P3, P4, P5, P6 )>
498 : public FactoryImplBase
499 {
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,
508                          Parm6 )
509 = 0;
510 };
511
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
517 {
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,
527                          Parm6, Parm7 )
528 = 0;
529 };
530
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
536 {
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,
547                          Parm6, Parm7, Parm8)
548 = 0;
549 };
550
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
556 {
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)
569 = 0;
570 };
571
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
577 {
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)
591 = 0;
592 };
593
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,
597          typename P11>
598 struct FactoryImpl<AP, Id, LOKI_TYPELIST_11( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11 )>
599 : public FactoryImplBase
600 {
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,
615                          Parm11)
616 = 0;
617 };
618
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
625 {
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,
641                          Parm11,Parm12)
642 = 0;
643 };
644
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
651 {
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)
669 = 0;
670 };
671
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
678 {
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)
697 = 0;
698 };
699
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
706 {
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 )
726 = 0;
727 };
728
729 #endif //LOKI_DISABLE_TYPELIST_MACROS
730
731
732 ////////////////////////////////////////////////////////////////////////////////
733 ///  \class Factory
734 ///
735 ///  \ingroup FactoryGroup
736 ///  Implements a generic object factory.
737 ///
738 ///  Create functions can have up to 15 parameters.
739 ///
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 ////////////////////////////////////////////////////////////////////////////////
748 template
749 <
750 class AbstractProduct,
751       typename IdentifierType,
752       typename CreatorParmTList = NullType,
753       template<typename, class> class FactoryErrorPolicy = DefaultFactoryError
754       >
755 class Factory : public FactoryErrorPolicy<IdentifierType, AbstractProduct>
756 {
757         typedef FactoryImpl< AbstractProduct, IdentifierType, CreatorParmTList > Impl;
758
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;
774
775         typedef Functor<AbstractProduct *, CreatorParmTList> ProductCreator;
776
777         typedef AssocVector<IdentifierType, ProductCreator> IdToProductMap;
778
779         IdToProductMap associations_;
780
781 public:
782
783         Factory()
784                 : associations_()
785         {
786         }
787
788         ~Factory()
789         {
790                 associations_.erase(associations_.begin(), associations_.end());
791         }
792
793         bool Register(const IdentifierType &id, ProductCreator creator)
794         {
795                 return associations_.insert(
796                            typename IdToProductMap::value_type(id, creator)).second != 0;
797         }
798
799         template <class PtrObj, typename CreaFn>
800         bool Register(const IdentifierType &id, const PtrObj &p, CreaFn fn)
801         {
802                 ProductCreator creator( p, fn );
803                 return associations_.insert(
804                            typename IdToProductMap::value_type(id, creator)).second != 0;
805         }
806
807         bool Unregister(const IdentifierType &id)
808         {
809                 return associations_.erase(id) != 0;
810         }
811
812         std::vector<IdentifierType> RegisteredIds()
813         {
814                 std::vector<IdentifierType> ids;
815                 for(typename IdToProductMap::iterator it = associations_.begin();
816                         it != associations_.end(); ++it)
817                 {
818                         ids.push_back(it->first);
819                 }
820                 return ids;
821         }
822
823         AbstractProduct *CreateObject(const IdentifierType &id)
824         {
825                 typename IdToProductMap::iterator i = associations_.find(id);
826                 if (i != associations_.end())
827                         return (i->second)( );
828                 return this->OnUnknownType(id);
829         }
830
831         AbstractProduct *CreateObject(const IdentifierType &id,
832                                       Parm1 p1)
833         {
834                 typename IdToProductMap::iterator i = associations_.find(id);
835                 if (i != associations_.end())
836                         return (i->second)( p1 );
837                 return this->OnUnknownType(id);
838         }
839
840         AbstractProduct *CreateObject(const IdentifierType &id,
841                                       Parm1 p1, Parm2 p2)
842         {
843                 typename IdToProductMap::iterator i = associations_.find(id);
844                 if (i != associations_.end())
845                         return (i->second)( p1,p2 );
846                 return this->OnUnknownType(id);
847         }
848
849         AbstractProduct *CreateObject(const IdentifierType &id,
850                                       Parm1 p1, Parm2 p2, Parm3 p3)
851         {
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);
856         }
857
858         AbstractProduct *CreateObject(const IdentifierType &id,
859                                       Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
860         {
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);
865         }
866
867         AbstractProduct *CreateObject(const IdentifierType &id,
868                                       Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
869         {
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);
874         }
875
876         AbstractProduct *CreateObject(const IdentifierType &id,
877                                       Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
878                                       Parm6 p6)
879         {
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);
884         }
885
886         AbstractProduct *CreateObject(const IdentifierType &id,
887                                       Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
888                                       Parm6 p6, Parm7 p7 )
889         {
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);
894         }
895
896         AbstractProduct *CreateObject(const IdentifierType &id,
897                                       Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
898                                       Parm6 p6, Parm7 p7, Parm8 p8)
899         {
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);
904         }
905
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)
909         {
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);
914         }
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)
918         {
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);
923         }
924
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,
928                                       Parm11 p11)
929         {
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);
934         }
935
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)
940         {
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);
945         }
946
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)
951         {
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);
956         }
957
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)
962         {
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);
967         }
968
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)
973         {
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);
978         }
979
980 };
981
982 #else
983
984 template
985 <
986 class AbstractProduct,
987       typename IdentifierType,
988       typename ProductCreator = AbstractProduct *( *)(),
989       template<typename, class>
990       class FactoryErrorPolicy = DefaultFactoryError
991       >
992 class Factory
993         : public FactoryErrorPolicy<IdentifierType, AbstractProduct>
994 {
995 public:
996         bool Register(const IdentifierType &id, ProductCreator creator)
997         {
998                 return associations_.insert(
999                            typename IdToProductMap::value_type(id, creator)).second != 0;
1000         }
1001
1002         bool Unregister(const IdentifierType &id)
1003         {
1004                 return associations_.erase(id) != 0;
1005         }
1006
1007         AbstractProduct *CreateObject(const IdentifierType &id)
1008         {
1009                 typename IdToProductMap::iterator i = associations_.find(id);
1010                 if (i != associations_.end())
1011                 {
1012                         return (i->second)();
1013                 }
1014                 return this->OnUnknownType(id);
1015         }
1016
1017 private:
1018         typedef AssocVector<IdentifierType, ProductCreator> IdToProductMap;
1019         IdToProductMap associations_;
1020 };
1021
1022 #endif //#define ENABLE_NEW_FACTORY_CODE
1023
1024 /**
1025  *   \defgroup  CloneFactoryGroup Clone Factory
1026  *   \ingroup   FactoriesGroup
1027  *   \brief             Creates a copy from a polymorphic object.
1028  *
1029  *   \class             CloneFactory
1030  *   \ingroup   CloneFactoryGroup
1031  *   \brief             Creates a copy from a polymorphic object.
1032  */
1033
1034 template
1035 <
1036 class AbstractProduct,
1037       class ProductCreator =
1038       AbstractProduct *( *)(const AbstractProduct *),
1039       template<typename, class>
1040       class FactoryErrorPolicy = DefaultFactoryError
1041       >
1042 class CloneFactory
1043         : public FactoryErrorPolicy<TypeInfo, AbstractProduct>
1044 {
1045 public:
1046         bool Register(const TypeInfo &ti, ProductCreator creator)
1047         {
1048                 return associations_.insert(
1049                            typename IdToProductMap::value_type(ti, creator)).second != 0;
1050         }
1051
1052         bool Unregister(const TypeInfo &id)
1053         {
1054                 return associations_.erase(id) != 0;
1055         }
1056
1057         AbstractProduct *CreateObject(const AbstractProduct *model)
1058         {
1059                 if (model == NULL)
1060                 {
1061                         return NULL;
1062                 }
1063
1064                 typename IdToProductMap::iterator i =
1065                     associations_.find(typeid(*model));
1066
1067                 if (i != associations_.end())
1068                 {
1069                         return (i->second)(model);
1070                 }
1071                 return this->OnUnknownType(typeid(*model));
1072         }
1073
1074 private:
1075         typedef AssocVector<TypeInfo, ProductCreator> IdToProductMap;
1076         IdToProductMap associations_;
1077 };
1078
1079 } // namespace Loki
1080
1081
1082 #ifdef _MSC_VER
1083 #pragma warning( pop )
1084 #endif
1085
1086 #endif // end file guardian
1087