1/* { dg-do link } */
2/* { dg-timeout-factor 2.0 } */
3
4namespace Loki
5{
6    class NullType {};
7    template <class T, class U>
8    struct Typelist
9    {
10       typedef T Head;
11       typedef U Tail;
12    };
13
14
15
16    namespace TL
17    {
18        template
19        <
20                typename T1 = NullType, typename T2 = NullType, typename T3 =
21NullType,
22                typename T4 = NullType, typename T5 = NullType, typename T6 =
23NullType,
24                typename T7 = NullType, typename T8 = NullType, typename T9 =
25NullType,
26                typename T10 = NullType, typename T11 = NullType, typename T12
27= NullType,
28                typename T13 = NullType, typename T14 = NullType, typename T15
29= NullType,
30                typename T16 = NullType, typename T17 = NullType, typename T18
31= NullType,
32                typename T19 = NullType, typename T20 = NullType, typename T21
33= NullType,
34                typename T22 = NullType, typename T23 = NullType, typename T24
35= NullType,
36                typename T25 = NullType, typename T26 = NullType, typename T27
37= NullType,
38                typename T28 = NullType, typename T29 = NullType, typename T30
39= NullType,
40                typename T31 = NullType, typename T32 = NullType, typename T33
41= NullType,
42                typename T34 = NullType, typename T35 = NullType, typename T36
43= NullType,
44                typename T37 = NullType, typename T38 = NullType, typename T39
45= NullType,
46                typename T40 = NullType
47        >
48        struct MakeTypelist
49        {
50        private:
51            typedef typename MakeTypelist
52            <
53                T2 , T3 , T4 ,
54                T5 , T6 , T7 ,
55                T8 , T9 , T10,
56                T11, T12, T13,
57                T14, T15, T16,
58                T17, T18, T19,
59                T20, T21, T22,
60                T23, T24, T25,
61                T26, T27, T28,
62                T29, T30, T31,
63                T32, T33, T34,
64                T35, T36, T37,
65                T38, T39, T40
66            >
67            ::Result TailResult;
68
69        public:
70            typedef Typelist<T1, TailResult> Result;
71        };
72
73        template<>
74        struct MakeTypelist<>
75        {
76            typedef NullType Result;
77        };
78
79    }
80}
81template <class Key>
82class Factory;
83
84template <class Key, bool iW>
85struct Context
86{
87    typedef Key KeyType;
88    enum
89    {
90        isWrite = iW
91    };
92};
93
94namespace detail
95{
96
97template <class Key, bool isWrite>
98class CreatorUnitBaseImpl
99{
100public:
101    typedef Context<Key, isWrite> Context_;
102private:
103    typedef void*(CreatorUnitBaseImpl::*CreateFun)(Context_&, unsigned&, const
104Key&);
105    CreateFun createFun_;
106
107protected:
108    virtual void* createUninitialized () = 0;
109    template <class Value>
110    void* createImpl (Context_& ctx, unsigned& ver, const Key& k)
111    {
112        return createUninitialized();
113    }
114private:
115    CreatorUnitBaseImpl();
116public:
117    template <class Value>
118    CreatorUnitBaseImpl (Value*) :
119        createFun_( &CreatorUnitBaseImpl::template createImpl<Value> )
120    {
121    }
122
123    virtual ~CreatorUnitBaseImpl () {}
124
125    CreatorUnitBaseImpl(const CreatorUnitBaseImpl& s)
126        : createFun_(s.createFun_)
127    {
128    }
129
130    CreatorUnitBaseImpl& operator=(const CreatorUnitBaseImpl& s)
131    {
132        createFun_ = s.createFun_;
133        return *this;
134    }
135    void* create (Context_& ctx, unsigned& ver, const Key& k)
136    {
137        return (this->*createFun_)(ctx, ver, k);
138    }
139};
140
141template <class Key>
142class Creator : protected CreatorUnitBaseImpl<Key, true>, protected
143CreatorUnitBaseImpl<Key, false>
144{
145public:
146    typedef void* (*CreatorFun) ();
147
148private:
149    CreatorFun fun_;
150protected:
151    virtual void* createUninitialized ()
152    {
153        if (fun_)
154            return (*fun_)();
155        return 0;
156    }
157private:
158    Creator ();
159public:
160    template <class Value>
161    Creator (CreatorFun f, Value*) :
162        CreatorUnitBaseImpl<Key, true>((Value*)0),
163        CreatorUnitBaseImpl<Key, false>((Value*)0),
164        fun_(f)
165    {
166    }
167
168    Creator(const Creator& s) :
169        CreatorUnitBaseImpl<Key, true>(s),
170        CreatorUnitBaseImpl<Key, false>(s),
171        fun_(s.fun_)
172    {
173
174    }
175
176    Creator& operator=(const Creator& s)
177    {
178        CreatorUnitBaseImpl<Key, true>::operator=(s);
179        CreatorUnitBaseImpl<Key, false>::operator=(s);
180        fun_ = s.fun_;
181        return *this;
182    }
183
184    virtual ~Creator ()
185    {
186    }
187
188    template <class Context>
189    void* createObject (Context& ctx, unsigned& ver, const Key& k)
190    {
191        void* r = CreatorUnitBaseImpl<Key, Context::isWrite>::create(ctx, ver,
192k);
193        return r;
194    }
195};
196
197}
198
199template <class Key>
200class Factory
201{
202public:
203    typedef Key KeyType;
204    typedef void* (*CreatorFun) ();
205    typedef detail::Creator<Key> Creator;
206public:
207    Factory () {}
208    ~Factory () {}
209
210    template <class Value>
211    bool registerCreator (const Key& k, CreatorFun fun)
212    {
213        return true;
214    }
215    template <class Context>
216    void* createObject (const Key& k, Context& ctx, unsigned& ver)
217    {
218        return 0;
219    }
220};
221
222template <class Key, class Base, Key key>
223struct ClassSpec
224{
225    typedef Key KeyType;
226    typedef Base BaseType;
227    enum {KeyValue = key};
228};
229
230template <class Key, class T>
231class Serializer;
232
233template <class Key, class Base, Key key>
234class Serializer<Key, ClassSpec <Key, Base, key> >
235    : public virtual Factory<Key>
236{
237    typedef Key KeyType;
238    typedef Base BaseType;
239    enum {KeyValue = key};
240    typedef Factory<Key> Inherited;
241    typedef Serializer<Key, ClassSpec< Key, Base, key > > SelfType;
242
243    static void* create ()
244    {
245        return (void*) (new BaseType);
246    }
247public:
248    Serializer()
249    {
250        Inherited::template registerCreator<BaseType>(
251                KeyValue,
252                &SelfType::create);
253    }
254};
255
256template <class Key, class Head>
257class Serializer<Key, Loki::Typelist<Head, Loki::NullType> >:
258    public Serializer<Key, Head>
259{
260};
261
262template <class Key, class Head, class Tail>
263class Serializer<Key, Loki::Typelist<Head, Tail> >:
264    public virtual Serializer<Key, Head>,
265    public virtual Serializer<Key, Tail>
266{
267};
268
269template <class Key>
270class Serializer<Key, Loki::NullType> : public virtual Factory<Key>
271{
272};
273
274
275
276
277typedef unsigned KeyType;
278
279
280
281typedef Factory<KeyType> FactoryType;
282
283typedef KeyType Key;
284
285struct A001
286{
287    template <class Context>
288    bool serialize(Context& ctx, unsigned& ver)
289    {
290        return true;
291    }
292    static Key classId() { return 1; }
293    static const char* className () {return "A001";}
294};
295
296struct A002
297{
298    template <class Context>
299    bool serialize(Context& ctx, unsigned& ver)
300    {
301        return true;
302    }
303    static Key classId() { return 2; }
304    static const char* className () {return "A002";}
305};
306
307struct A003
308{
309    template <class Context>
310    bool serialize(Context& ctx, unsigned& ver)
311    {
312        return true;
313    }
314    static Key classId() { return 3; }
315    static const char* className () {return "A003";}
316};
317
318struct A004
319{
320    template <class Context>
321    bool serialize(Context& ctx, unsigned& ver)
322    {
323        return true;
324    }
325    static Key classId() { return 4; }
326    static const char* className () {return "A004";}
327};
328
329struct A005
330{
331    template <class Context>
332    bool serialize(Context& ctx, unsigned& ver)
333    {
334        return true;
335    }
336    static Key classId() { return 5; }
337    static const char* className () {return "A005";}
338};
339
340struct A006
341{
342    template <class Context>
343    bool serialize(Context& ctx, unsigned& ver)
344    {
345        return true;
346    }
347    static Key classId() { return 6; }
348    static const char* className () {return "A006";}
349};
350
351struct A007
352{
353    template <class Context>
354    bool serialize(Context& ctx, unsigned& ver)
355    {
356        return true;
357    }
358    static Key classId() { return 7; }
359    static const char* className () {return "A007";}
360};
361
362struct A008
363{
364    template <class Context>
365    bool serialize(Context& ctx, unsigned& ver)
366    {
367        return true;
368    }
369    static Key classId() { return 8; }
370    static const char* className () {return "A008";}
371};
372
373struct A009
374{
375    template <class Context>
376    bool serialize(Context& ctx, unsigned& ver)
377    {
378        return true;
379    }
380    static Key classId() { return 9; }
381    static const char* className () {return "A009";}
382};
383
384struct A010
385{
386    template <class Context>
387    bool serialize(Context& ctx, unsigned& ver)
388    {
389        return true;
390    }
391    static Key classId() { return 10; }
392    static const char* className () {return "A010";}
393};
394
395struct A011
396{
397    template <class Context>
398    bool serialize(Context& ctx, unsigned& ver)
399    {
400        return true;
401    }
402    static Key classId() { return 11; }
403    static const char* className () {return "A011";}
404};
405
406struct A012
407{
408    template <class Context>
409    bool serialize(Context& ctx, unsigned& ver)
410    {
411        return true;
412    }
413    static Key classId() { return 12; }
414    static const char* className () {return "A012";}
415};
416
417struct A013
418{
419    template <class Context>
420    bool serialize(Context& ctx, unsigned& ver)
421    {
422        return true;
423    }
424    static Key classId() { return 13; }
425    static const char* className () {return "A013";}
426};
427
428struct A014
429{
430    template <class Context>
431    bool serialize(Context& ctx, unsigned& ver)
432    {
433        return true;
434    }
435    static Key classId() { return 14; }
436    static const char* className () {return "A014";}
437};
438
439struct A015
440{
441    template <class Context>
442    bool serialize(Context& ctx, unsigned& ver)
443    {
444        return true;
445    }
446    static Key classId() { return 15; }
447    static const char* className () {return "A015";}
448};
449
450struct A016
451{
452    template <class Context>
453    bool serialize(Context& ctx, unsigned& ver)
454    {
455        return true;
456    }
457    static Key classId() { return 16; }
458    static const char* className () {return "A016";}
459};
460
461struct A017
462{
463    template <class Context>
464    bool serialize(Context& ctx, unsigned& ver)
465    {
466        return true;
467    }
468    static Key classId() { return 17; }
469    static const char* className () {return "A017";}
470};
471
472struct A018
473{
474    template <class Context>
475    bool serialize(Context& ctx, unsigned& ver)
476    {
477        return true;
478    }
479    static Key classId() { return 18; }
480    static const char* className () {return "A018";}
481};
482
483struct A019
484{
485    template <class Context>
486    bool serialize(Context& ctx, unsigned& ver)
487    {
488        return true;
489    }
490    static Key classId() { return 19; }
491    static const char* className () {return "A019";}
492};
493
494struct A020
495{
496    template <class Context>
497    bool serialize(Context& ctx, unsigned& ver)
498    {
499        return true;
500    }
501    static Key classId() { return 20; }
502    static const char* className () {return "A020";}
503};
504
505struct A021
506{
507    template <class Context>
508    bool serialize(Context& ctx, unsigned& ver)
509    {
510        return true;
511    }
512    static Key classId() { return 21; }
513    static const char* className () {return "A021";}
514};
515
516struct A022
517{
518    template <class Context>
519    bool serialize(Context& ctx, unsigned& ver)
520    {
521        return true;
522    }
523    static Key classId() { return 22; }
524    static const char* className () {return "A022";}
525};
526
527struct A023
528{
529    template <class Context>
530    bool serialize(Context& ctx, unsigned& ver)
531    {
532        return true;
533    }
534    static Key classId() { return 23; }
535    static const char* className () {return "A023";}
536};
537
538struct A024
539{
540    template <class Context>
541    bool serialize(Context& ctx, unsigned& ver)
542    {
543        return true;
544    }
545    static Key classId() { return 24; }
546    static const char* className () {return "A024";}
547};
548
549struct A025
550{
551    template <class Context>
552    bool serialize(Context& ctx, unsigned& ver)
553    {
554        return true;
555    }
556    static Key classId() { return 25; }
557    static const char* className () {return "A025";}
558};
559
560struct A026
561{
562    template <class Context>
563    bool serialize(Context& ctx, unsigned& ver)
564    {
565        return true;
566    }
567    static Key classId() { return 26; }
568    static const char* className () {return "A026";}
569};
570
571struct A027
572{
573    template <class Context>
574    bool serialize(Context& ctx, unsigned& ver)
575    {
576        return true;
577    }
578    static Key classId() { return 27; }
579    static const char* className () {return "A027";}
580};
581
582struct A028
583{
584    template <class Context>
585    bool serialize(Context& ctx, unsigned& ver)
586    {
587        return true;
588    }
589    static Key classId() { return 28; }
590    static const char* className () {return "A028";}
591};
592
593struct A029
594{
595    template <class Context>
596    bool serialize(Context& ctx, unsigned& ver)
597    {
598        return true;
599    }
600    static Key classId() { return 29; }
601    static const char* className () {return "A029";}
602};
603
604struct A030
605{
606    template <class Context>
607    bool serialize(Context& ctx, unsigned& ver)
608    {
609        return true;
610    }
611    static Key classId() { return 30; }
612    static const char* className () {return "A030";}
613};
614
615struct A031
616{
617    template <class Context>
618    bool serialize(Context& ctx, unsigned& ver)
619    {
620        return true;
621    }
622    static Key classId() { return 31; }
623    static const char* className () {return "A031";}
624};
625
626struct A032
627{
628    template <class Context>
629    bool serialize(Context& ctx, unsigned& ver)
630    {
631        return true;
632    }
633    static Key classId() { return 32; }
634    static const char* className () {return "A032";}
635};
636
637struct A033
638{
639    template <class Context>
640    bool serialize(Context& ctx, unsigned& ver)
641    {
642        return true;
643    }
644    static Key classId() { return 33; }
645    static const char* className () {return "A033";}
646};
647
648struct A034
649{
650    template <class Context>
651    bool serialize(Context& ctx, unsigned& ver)
652    {
653        return true;
654    }
655    static Key classId() { return 34; }
656    static const char* className () {return "A034";}
657};
658
659struct A035
660{
661    template <class Context>
662    bool serialize(Context& ctx, unsigned& ver)
663    {
664        return true;
665    }
666    static Key classId() { return 35; }
667    static const char* className () {return "A035";}
668};
669
670struct A036
671{
672    template <class Context>
673    bool serialize(Context& ctx, unsigned& ver)
674    {
675        return true;
676    }
677    static Key classId() { return 36; }
678    static const char* className () {return "A036";}
679};
680
681struct A037
682{
683    template <class Context>
684    bool serialize(Context& ctx, unsigned& ver)
685    {
686        return true;
687    }
688    static Key classId() { return 37; }
689    static const char* className () {return "A037";}
690};
691
692struct A038
693{
694    template <class Context>
695    bool serialize(Context& ctx, unsigned& ver)
696    {
697        return true;
698    }
699    static Key classId() { return 38; }
700    static const char* className () {return "A038";}
701};
702
703struct A039
704{
705    template <class Context>
706    bool serialize(Context& ctx, unsigned& ver)
707    {
708        return true;
709    }
710    static Key classId() { return 39; }
711    static const char* className () {return "A039";}
712};
713
714struct A040
715{
716    template <class Context>
717    bool serialize(Context& ctx, unsigned& ver)
718    {
719        return true;
720    }
721    static Key classId() { return 40; }
722    static const char* className () {return "A040";}
723};
724
725Factory<Key>& getInstance()
726{
727    static Serializer<Key,
728        Loki::TL::MakeTypelist<
729            ClassSpec<Key, A001, 1>,
730            ClassSpec<Key, A002, 2>,
731            ClassSpec<Key, A003, 3>,
732            ClassSpec<Key, A004, 4>,
733            ClassSpec<Key, A005, 5>,
734            ClassSpec<Key, A006, 6>,
735            ClassSpec<Key, A007, 7>,
736            ClassSpec<Key, A008, 8>,
737            ClassSpec<Key, A009, 9>,
738            ClassSpec<Key, A010, 10>,
739            ClassSpec<Key, A011, 11>,
740            ClassSpec<Key, A012, 12>,
741            ClassSpec<Key, A013, 13>,
742            ClassSpec<Key, A014, 14>,
743            ClassSpec<Key, A015, 15>,
744            ClassSpec<Key, A016, 16>,
745            ClassSpec<Key, A017, 17>,
746            ClassSpec<Key, A018, 18>,
747            ClassSpec<Key, A019, 19>,
748            ClassSpec<Key, A020, 20>,
749            ClassSpec<Key, A021, 21>,
750            ClassSpec<Key, A022, 22>,
751            ClassSpec<Key, A023, 23>,
752            ClassSpec<Key, A024, 24>,
753            ClassSpec<Key, A025, 25>,
754            ClassSpec<Key, A026, 26>,
755            ClassSpec<Key, A027, 27>,
756            ClassSpec<Key, A028, 28>,
757            ClassSpec<Key, A029, 29>,
758            ClassSpec<Key, A030, 30>,
759            ClassSpec<Key, A031, 31>,
760            ClassSpec<Key, A032, 32>,
761            ClassSpec<Key, A033, 33>,
762            ClassSpec<Key, A034, 34>,
763            ClassSpec<Key, A035, 35>,
764            ClassSpec<Key, A036, 36>,
765            ClassSpec<Key, A037, 37>,
766            ClassSpec<Key, A038, 38>,
767            ClassSpec<Key, A039, 39>,
768            ClassSpec<Key, A040, 40>
769        >::Result
770    > instance;
771    return instance;
772}
773
774int main ()
775{
776    return 0;
777}
778