1 /* { dg-do link } */
2 /* { dg-timeout-factor 2.0 } */
3 /* { dg-skip-if "Program too big" { "avr-*-*" } { "*" } { "" } } */
4 
5 namespace 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 =
22 NullType,
23                 typename T4 = NullType, typename T5 = NullType, typename T6 =
24 NullType,
25                 typename T7 = NullType, typename T8 = NullType, typename T9 =
26 NullType,
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 }
82 template <class Key>
83 class Factory;
84 
85 template <class Key, bool iW>
86 struct Context
87 {
88     typedef Key KeyType;
89     enum
90     {
91         isWrite = iW
92     };
93 };
94 
95 namespace detail
96 {
97 
98 template <class Key, bool isWrite>
99 class CreatorUnitBaseImpl
100 {
101 public:
102     typedef Context<Key, isWrite> Context_;
103 private:
104     typedef void*(CreatorUnitBaseImpl::*CreateFun)(Context_&, unsigned&, const
105 Key&);
106     CreateFun createFun_;
107 
108 protected:
109     virtual void* createUninitialized () = 0;
110     template <class Value>
111     void* createImpl (Context_& ctx, unsigned& ver, const Key& k)
112     {
113         return createUninitialized();
114     }
115 private:
116     CreatorUnitBaseImpl();
117 public:
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 
142 template <class Key>
143 class Creator : protected CreatorUnitBaseImpl<Key, true>, protected
144 CreatorUnitBaseImpl<Key, false>
145 {
146 public:
147     typedef void* (*CreatorFun) ();
148 
149 private:
150     CreatorFun fun_;
151 protected:
152     virtual void* createUninitialized ()
153     {
154         if (fun_)
155             return (*fun_)();
156         return 0;
157     }
158 private:
159     Creator ();
160 public:
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,
193 k);
194         return r;
195     }
196 };
197 
198 }
199 
200 template <class Key>
201 class Factory
202 {
203 public:
204     typedef Key KeyType;
205     typedef void* (*CreatorFun) ();
206     typedef detail::Creator<Key> Creator;
207 public:
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 
223 template <class Key, class Base, Key key>
224 struct ClassSpec
225 {
226     typedef Key KeyType;
227     typedef Base BaseType;
228     enum {KeyValue = key};
229 };
230 
231 template <class Key, class T>
232 class Serializer;
233 
234 template <class Key, class Base, Key key>
235 class 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     }
248 public:
249     Serializer()
250     {
251         Inherited::template registerCreator<BaseType>(
252                 KeyValue,
253                 &SelfType::create);
254     }
255 };
256 
257 template <class Key, class Head>
258 class Serializer<Key, Loki::Typelist<Head, Loki::NullType> >:
259     public Serializer<Key, Head>
260 {
261 };
262 
263 template <class Key, class Head, class Tail>
264 class Serializer<Key, Loki::Typelist<Head, Tail> >:
265     public virtual Serializer<Key, Head>,
266     public virtual Serializer<Key, Tail>
267 {
268 };
269 
270 template <class Key>
271 class Serializer<Key, Loki::NullType> : public virtual Factory<Key>
272 {
273 };
274 
275 
276 
277 
278 typedef unsigned KeyType;
279 
280 
281 
282 typedef Factory<KeyType> FactoryType;
283 
284 typedef KeyType Key;
285 
286 struct 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 
297 struct 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 
308 struct 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 
319 struct 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 
330 struct 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 
341 struct 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 
352 struct 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 
363 struct 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 
374 struct 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 
385 struct 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 
396 struct 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 
407 struct 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 
418 struct 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 
429 struct 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 
440 struct 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 
451 struct 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 
462 struct 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 
473 struct 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 
484 struct 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 
495 struct 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 
506 struct 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 
517 struct 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 
528 struct 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 
539 struct 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 
550 struct 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 
561 struct 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 
572 struct 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 
583 struct 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 
594 struct 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 
605 struct 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 
616 struct 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 
627 struct 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 
638 struct 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 
649 struct 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 
660 struct 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 
671 struct 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 
682 struct 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 
693 struct 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 
704 struct 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 
715 struct 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 
726 Factory<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 
775 int main ()
776 {
777     return 0;
778 }
779