go home Home | Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Globals | Related Pages
TypeList.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright UMC Utrecht and contributors
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18// Denis P. Shamonin remarks:
19// This file was copied from the ITKSimple, located in
20// SimpleITK\src\Code\Common\include\Ancillary\TypeList.h
21// Also missing original Loki classes was restored such as:
22// (Erase, Replace, NoDuplicates, Reverse).
23// Additionally classes VisitDimension and DualVisitDimension was added.
24/*=========================================================================
25 *
26 * Copyright Insight Software Consortium
27 *
28 * Licensed under the Apache License, Version 2.0 (the "License");
29 * you may not use this file except in compliance with the License.
30 * You may obtain a copy of the License at
31 *
32 * http://www.apache.org/licenses/LICENSE-2.0.txt
33 *
34 * Unless required by applicable law or agreed to in writing, software
35 * distributed under the License is distributed on an "AS IS" BASIS,
36 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37 * See the License for the specific language governing permissions and
38 * limitations under the License.
39 *
40 *=========================================================================*/
41// This file is based off of the work done in the Loki library but is
42// substantially modified. It's a good book buy it.
43//
45// The Loki Library
46// Copyright (c) 2001 by Andrei Alexandrescu
47// This code accompanies the book:
48// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
49// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
50// Permission to use, copy, modify, distribute and sell this software for any
51// purpose is hereby granted without fee, provided that the above copyright
52// notice appear in all copies and that both that copyright notice and this
53// permission notice appear in supporting documentation.
54// The author or Addison-Welsey Longman make no representations about the
55// suitability of this software for any purpose. It is provided "as is"
56// without express or implied warranty.
58
59#ifndef TypeList_h
60#define TypeList_h
61
62namespace typelist
63{
64
75template <typename H, typename T>
76struct TypeList
77{
78 using Head = H;
79 using Tail = T;
80};
81
85struct NullType
86{};
87
103template <typename T1 = NullType,
104 typename T2 = NullType,
105 typename T3 = NullType,
106 typename T4 = NullType,
107 typename T5 = NullType,
108 typename T6 = NullType,
109 typename T7 = NullType,
110 typename T8 = NullType,
111 typename T9 = NullType,
112 typename T10 = NullType,
113 typename T11 = NullType,
114 typename T12 = NullType,
115 typename T13 = NullType,
116 typename T14 = NullType,
117 typename T15 = NullType,
118 typename T16 = NullType,
119 typename T17 = NullType,
120 typename T18 = NullType,
121 typename T19 = NullType,
122 typename T20 = NullType,
123 typename T21 = NullType,
124 typename T22 = NullType,
125 typename T23 = NullType,
126 typename T24 = NullType>
127struct MakeTypeList
128{
129private:
130 using TailType = typename MakeTypeList<T2,
131 T3,
132 T4,
133 T5,
134 T6,
135 T7,
136 T8,
137 T9,
138 T10,
139 T11,
140 T12,
141 T13,
142 T14,
143 T15,
144 T16,
145 T17,
146 T18,
147 T19,
148 T20,
149 T21,
150 T22,
151 T23,
152 T24>::Type;
153
154public:
155 using Type = TypeList<T1, TailType>;
156};
157template <>
158struct MakeTypeList<>
159{
160 using Type = NullType;
161};
162
163template <typename TTypeList>
164struct Length;
177template <typename H, typename T>
178struct Length<TypeList<H, T>>
179{
180 enum
181 {
182 Type = 1 + Length<T>::Type
183 };
184};
185
187template <>
188struct Length<NullType>
189{
190 enum
191 {
192 Type = 0
193 };
194};
211template <class TTypeList, unsigned int index>
212struct TypeAt;
213
214template <class Head, class Tail>
215struct TypeAt<TypeList<Head, Tail>, 0>
216{
217 using Type = Head;
218};
219
220template <class Head, class Tail, unsigned int i>
221struct TypeAt<TypeList<Head, Tail>, i>
222{
223 using Type = typename TypeAt<Tail, i - 1>::Type;
224};
225
226template <unsigned int i>
227struct TypeAt<NullType, i>
228{
229 using Type = NullType;
230};
231
232template <class TTypeList1, class TTypeList2>
233struct Append;
255template <class Head, class Tail, class T>
256struct Append<TypeList<Head, Tail>, T>
257{
258 using Type = TypeList<Head, typename Append<Tail, T>::Type>;
259};
260
262template <>
263struct Append<NullType, NullType>
264{
265 using Type = NullType;
266};
267template <class T>
268struct Append<NullType, T>
269{
270 using Type = TypeList<T, NullType>;
271};
272template <class T>
273struct Append<T, NullType>
274{
275 using Type = TypeList<T, NullType>;
276};
277template <class Head, class Tail>
278struct Append<NullType, TypeList<Head, Tail>>
279{
280 using Type = TypeList<Head, Tail>;
281};
282template <class Head, class Tail>
283struct Append<TypeList<Head, Tail>, NullType>
284{
285 using Type = TypeList<Head, Tail>;
286};
287
291template <class TList, class T>
292struct Erase;
293
294template <class T>
295struct Erase<NullType, T>
296{
297 using Type = NullType;
298};
299
300template <class T, class Tail>
301struct Erase<TypeList<T, Tail>, T>
302{
303 using Type = Tail;
304};
305
306template <class Head, class Tail, class T>
307struct Erase<TypeList<Head, Tail>, T>
308{
309 using Type = TypeList<Head, typename Erase<Tail, T>::Type>;
310};
311
315template <class TList, class T>
316struct EraseAll;
317template <class T>
318struct EraseAll<NullType, T>
319{
320 using Type = NullType;
321};
322template <class T, class Tail>
323struct EraseAll<TypeList<T, Tail>, T>
324{
325 using Type = typename EraseAll<Tail, T>::Type;
326};
327template <class Head, class Tail, class T>
328struct EraseAll<TypeList<Head, Tail>, T>
329{
330 using Type = TypeList<Head, typename EraseAll<Tail, T>::Type>;
331};
332
336template <class TList>
337struct NoDuplicates;
338
339template <>
340struct NoDuplicates<NullType>
341{
342 using Type = NullType;
343};
344
345template <class Head, class Tail>
346struct NoDuplicates<TypeList<Head, Tail>>
347{
348private:
349 using L1 = typename NoDuplicates<Tail>::Type;
350 using L2 = typename Erase<L1, Head>::Type;
351
352public:
353 using Type = TypeList<Head, L2>;
354};
355
359template <class TList, class T, class U>
360struct Replace;
361
362template <class T, class U>
363struct Replace<NullType, T, U>
364{
365 using Type = NullType;
366};
367
368template <class T, class Tail, class U>
369struct Replace<TypeList<T, Tail>, T, U>
370{
371 using Type = TypeList<U, Tail>;
372};
373
374template <class Head, class Tail, class T, class U>
375struct Replace<TypeList<Head, Tail>, T, U>
376{
377 using Type = TypeList<Head, typename Replace<Tail, T, U>::Type>;
378};
379
383template <class TList, class T, class U>
384struct ReplaceAll;
385
386template <class T, class U>
387struct ReplaceAll<NullType, T, U>
388{
389 using Type = NullType;
390};
391
392template <class T, class Tail, class U>
393struct ReplaceAll<TypeList<T, Tail>, T, U>
394{
395 using Type = TypeList<U, typename ReplaceAll<Tail, T, U>::Type>;
396};
397
398template <class Head, class Tail, class T, class U>
399struct ReplaceAll<TypeList<Head, Tail>, T, U>
400{
401 using Type = TypeList<Head, typename ReplaceAll<Tail, T, U>::Type>;
402};
403
407template <class TList>
408struct Reverse;
409
410template <>
411struct Reverse<NullType>
412{
413 using Type = NullType;
414};
415
416template <class Head, class Tail>
417struct Reverse<TypeList<Head, Tail>>
418{
419 using Type = typename Append<typename Reverse<Tail>::Type, Head>::Type;
420};
421
436template <class TTypeList, class TType>
437struct IndexOf;
438template <class TType>
439struct IndexOf<NullType, TType>
440{
441 enum
442 {
443 Type = -1
444 };
445};
446template <class TType, class TTail>
447struct IndexOf<TypeList<TType, TTail>, TType>
448{
449 enum
450 {
451 Type = 0
452 };
453};
454template <class Head, class TTail, class TType>
455struct IndexOf<TypeList<Head, TTail>, TType>
456{
457private:
458 enum
459 {
460 temp = IndexOf<TTail, TType>::Type
461 };
462
463public:
464 enum
465 {
466 Type = (temp == -1 ? -1 : 1 + temp)
467 };
468};
469
482template <class TTypeList, class TType>
483struct HasType;
484template <class TType>
485struct HasType<NullType, TType>
486{
487 enum
488 {
489 Type = false
490 };
491};
492template <class TType, class TTail>
493struct HasType<TypeList<TType, TTail>, TType>
494{
495 enum
496 {
497 Type = true
498 };
499};
500template <class Head, class TTail, class TType>
501struct HasType<TypeList<Head, TTail>, TType>
502{
503 enum
504 {
505 Type = HasType<TTail, TType>::Type
506 };
507};
508
527template <class TTypeList>
528struct Visit
529{
530 template <class Predicate>
531 void
532 operator()(Predicate & visitor)
533 {
534 using Head = typename TTypeList::Head;
535 using Tail = typename TTypeList::Tail;
536 visitor.template operator()<Head>();
537 Visit<Tail> next;
538 next.template operator()<Predicate>(visitor);
539 }
540
541
542 template <class Predicate>
543 void
544 operator()(const Predicate & visitor)
545 {
546 using Head = typename TTypeList::Head;
547 using Tail = typename TTypeList::Tail;
548 visitor.template operator()<Head>();
549 Visit<Tail> next;
550 next.template operator()<Predicate>(visitor);
551 }
552};
553
554template <>
555struct Visit<NullType>
556{
557 template <class Predicate>
558 void
559 operator()(const Predicate &)
560 {}
561};
562
579template <class TTypeList, unsigned int Dimension>
580struct VisitDimension
581{
582 template <class Predicate>
583 void
584 operator()(Predicate & visitor)
585 {
586 using Head = typename TTypeList::Head;
587 using Tail = typename TTypeList::Tail;
588 visitor.template operator()<Head, Dimension>();
589 VisitDimension<Tail, Dimension> next;
590 next.template operator()<Predicate>(visitor);
591 }
592
593
594 template <class Predicate>
595 void
596 operator()(const Predicate & visitor)
597 {
598 using Head = typename TTypeList::Head;
599 using Tail = typename TTypeList::Tail;
600 visitor.template operator()<Head, Dimension>();
601 VisitDimension<Tail, Dimension> next;
602 next.template operator()<Predicate>(visitor);
603 }
604};
605
606template <unsigned int Dimension>
607struct VisitDimension<NullType, Dimension>
608{
609 template <class Predicate>
610 void
611 operator()(const Predicate &)
612 {}
613};
614
633template <typename TLeftTypeList, typename TRightTypeList>
634struct DualVisitImpl;
635
636template <typename TLeftTypeList, typename TRightTypeList>
637struct DualVisit
638{
639
640 template <typename Visitor>
641 void
642 operator()(Visitor & visitor) const
643 {
644 DualVisitImpl<TLeftTypeList, TRightTypeList> impl;
645 return impl.template operator()<Visitor>(visitor);
646 }
647
648
649 template <typename Visitor>
650 void
651 operator()(const Visitor & visitor) const
652 {
653 DualVisitImpl<TLeftTypeList, TRightTypeList> impl;
654 return impl.template operator()<Visitor>(visitor);
655 }
656};
657
671template <typename TLeftTypeList, typename TRightTypeList>
672struct DualVisitImpl
673{
674 template <typename Visitor>
675 void
676 operator()(Visitor & visitor) const
677 {
678 using LeftTail = typename TLeftTypeList::Tail;
679
680 DualVisitImpl<TLeftTypeList, TRightTypeList> goRight;
681 goRight.visitRHS<Visitor>(visitor);
682
683 DualVisitImpl<LeftTail, TRightTypeList> goLeft;
684 goLeft.template operator()<Visitor>(visitor);
685 }
686
687
688 template <typename Visitor>
689 void
690 operator()(const Visitor & visitor) const
691 {
692 using LeftTail = typename TLeftTypeList::Tail;
693
694 DualVisitImpl<TLeftTypeList, TRightTypeList> goRight;
695 goRight.visitRHS<Visitor>(visitor);
696
697 DualVisitImpl<LeftTail, TRightTypeList> goLeft;
698 goLeft.template operator()<Visitor>(visitor);
699 }
700
701
702 template <typename Visitor>
703 void
704 visitRHS(Visitor & visitor) const
705 {
706 using LeftHead = typename TLeftTypeList::Head;
707 using RightHead = typename TRightTypeList::Head;
708 using RightTail = typename TRightTypeList::Tail;
709
710 visitor.template operator()<LeftHead, RightHead>();
711
712 DualVisitImpl<TLeftTypeList, RightTail> goRight;
713 goRight.template visitRHS<Visitor>(visitor);
714 }
715
716
717 template <typename Visitor>
718 void
719 visitRHS(const Visitor & visitor) const
720 {
721 using LeftHead = typename TLeftTypeList::Head;
722 using RightHead = typename TRightTypeList::Head;
723 using RightTail = typename TRightTypeList::Tail;
724
725 visitor.template operator()<LeftHead, RightHead>();
726
727 DualVisitImpl<TLeftTypeList, RightTail> goRight;
728 goRight.template visitRHS<Visitor>(visitor);
729 }
730};
731
732template <typename TRightTypeList>
733struct DualVisitImpl<typelist::NullType, TRightTypeList>
734{
735 template <typename Visitor>
736 void
737 operator()(const Visitor &) const
738 {}
739};
740template <typename TLeftTypeList>
741struct DualVisitImpl<TLeftTypeList, typelist::NullType>
742{
743 template <typename Visitor>
744 void
745 operator()(const Visitor &) const
746 {}
747
748 template <typename Visitor>
749 void
750 visitRHS(const Visitor &) const
751 {}
752};
753
754template <>
755struct DualVisitImpl<typelist::NullType, typelist::NullType>
756{
757 template <typename Visitor>
758 void
759 operator()(const Visitor &) const
760 {}
761};
762
783template <typename TLeftTypeList, typename TRightTypeList, unsigned int Dimension>
784struct DualVisitDimensionImpl;
785
786template <typename TLeftTypeList, typename TRightTypeList, unsigned int Dimension>
787struct DualVisitDimension
788{
789
790 template <typename Visitor>
791 void
792 operator()(Visitor & visitor) const
793 {
794 DualVisitDimensionImpl<TLeftTypeList, TRightTypeList, Dimension> impl;
795 return impl.template operator()<Visitor>(visitor);
796 }
797
798
799 template <typename Visitor>
800 void
801 operator()(const Visitor & visitor) const
802 {
803 DualVisitDimensionImpl<TLeftTypeList, TRightTypeList, Dimension> impl;
804 return impl.template operator()<Visitor>(visitor);
805 }
806};
807
821template <typename TLeftTypeList, typename TRightTypeList, unsigned int Dimension>
822struct DualVisitDimensionImpl
823{
824 template <typename Visitor>
825 void
826 operator()(Visitor & visitor) const
827 {
828 using LeftTail = typename TLeftTypeList::Tail;
829
830 DualVisitDimensionImpl<TLeftTypeList, TRightTypeList, Dimension> goRight;
831 goRight.visitRHS<Visitor>(visitor);
832
833 DualVisitDimensionImpl<LeftTail, TRightTypeList, Dimension> goLeft;
834 goLeft.template operator()<Visitor>(visitor);
835 }
836
837
838 template <typename Visitor>
839 void
840 operator()(const Visitor & visitor) const
841 {
842 using LeftTail = typename TLeftTypeList::Tail;
843
844 DualVisitDimensionImpl<TLeftTypeList, TRightTypeList, Dimension> goRight;
845 goRight.visitRHS<Visitor>(visitor);
846
847 DualVisitDimensionImpl<LeftTail, TRightTypeList, Dimension> goLeft;
848 goLeft.template operator()<Visitor>(visitor);
849 }
850
851
852 template <typename Visitor>
853 void
854 visitRHS(Visitor & visitor) const
855 {
856 using LeftHead = typename TLeftTypeList::Head;
857 using RightHead = typename TRightTypeList::Head;
858 using RightTail = typename TRightTypeList::Tail;
859
860 visitor.template operator()<LeftHead, RightHead, Dimension>();
861
862 DualVisitDimensionImpl<TLeftTypeList, RightTail, Dimension> goRight;
863 goRight.template visitRHS<Visitor>(visitor);
864 }
865
866
867 template <typename Visitor>
868 void
869 visitRHS(const Visitor & visitor) const
870 {
871 using LeftHead = typename TLeftTypeList::Head;
872 using RightHead = typename TRightTypeList::Head;
873 using RightTail = typename TRightTypeList::Tail;
874
875 visitor.template operator()<LeftHead, RightHead, Dimension>();
876
877 DualVisitDimensionImpl<TLeftTypeList, RightTail, Dimension> goRight;
878 goRight.template visitRHS<Visitor>(visitor);
879 }
880};
881
882template <typename TRightTypeList, unsigned int Dimension>
883struct DualVisitDimensionImpl<typelist::NullType, TRightTypeList, Dimension>
884{
885 template <typename Visitor>
886 void
887 operator()(const Visitor &) const
888 {}
889};
890template <typename TLeftTypeList, unsigned int Dimension>
891struct DualVisitDimensionImpl<TLeftTypeList, typelist::NullType, Dimension>
892{
893 template <typename Visitor>
894 void
895 operator()(const Visitor &) const
896 {}
897
898 template <typename Visitor>
899 void
900 visitRHS(const Visitor &) const
901 {}
902};
903
904template <unsigned int Dimension>
905struct DualVisitDimensionImpl<typelist::NullType, typelist::NullType, Dimension>
906{
907 template <typename Visitor>
908 void
909 operator()(const Visitor &) const
910 {}
911};
912
915} // namespace typelist
916
917#endif // TypeList_h


Generated on 2023-01-13 for elastix by doxygen 1.9.6 elastix logo