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