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
62#ifndef ELX_TEMPLATE_WORKAROUND
63# ifdef _MSC_VER
64# if _MSC_VER < 1910 // Before MSVC++ 14.1 (Visual Studio 2017 version 15.0)
65# define ELX_TEMPLATE_WORKAROUND
66# else
67# define ELX_TEMPLATE_WORKAROUND template
68# endif
69# else
70# define ELX_TEMPLATE_WORKAROUND template
71# endif
72#endif
73
74namespace typelist
75{
76
87template< typename H, typename T >
88struct TypeList
89{
90 typedef H Head;
91 typedef T Tail;
92};
93
97struct NullType {};
98
114template
115<
116typename T1 = NullType, typename T2 = NullType, typename T3 = NullType,
117typename T4 = NullType, typename T5 = NullType, typename T6 = NullType,
118typename T7 = NullType, typename T8 = NullType, typename T9 = NullType,
119typename T10 = NullType, typename T11 = NullType, typename T12 = NullType,
120typename T13 = NullType, typename T14 = NullType, typename T15 = NullType,
121typename T16 = NullType, typename T17 = NullType, typename T18 = NullType,
122typename T19 = NullType, typename T20 = NullType, typename T21 = NullType,
123typename T22 = NullType, typename T23 = NullType, typename T24 = NullType
124>
125struct MakeTypeList
126{
127private:
128
129 typedef typename MakeTypeList
130 <
131 T2, T3, T4,
132 T5, T6, T7,
133 T8, T9, T10,
134 T11, T12, T13,
135 T14, T15, T16,
136 T17, T18, T19,
137 T20, T21, T22,
138 T23, T24
139 >::Type TailType;
140
141public:
142
143 typedef TypeList< T1, TailType > Type;
144};
145template< >
146struct MakeTypeList< >
147{
148 typedef NullType Type;
149};
150
151template< typename TTypeList >
152struct Length;
165template< typename H, typename T >
166struct Length< TypeList< H, T > >
167{
168 enum { Type = 1 + Length< T >::Type };
169};
170
172template< >
173struct Length< NullType >
174{
175 enum { Type = 0 };
176};
193template< class TTypeList, unsigned int index >
194struct TypeAt;
195
196template< class Head, class Tail >
197struct TypeAt< TypeList< Head, Tail >, 0 >
198{
199 typedef Head Type;
200};
201
202template< class Head, class Tail, unsigned int i >
203struct TypeAt< TypeList< Head, Tail >, i >
204{
205 typedef typename TypeAt< Tail, i - 1 >::Type Type;
206};
207
208template< unsigned int i >
209struct TypeAt< NullType, i >
210{
211 typedef NullType Type;
212};
213
214template< class TTypeList1, class TTypeList2 >
215struct Append;
237template< class Head, class Tail, class T >
238struct Append< TypeList< Head, Tail >, T >
239{
240 typedef TypeList< Head, typename Append< Tail, T >::Type > Type;
241};
242
244template< >
245struct Append< NullType, NullType >
246{
247 typedef NullType Type;
248};
249template< class T >
250struct Append< NullType, T >
251{
252 typedef TypeList< T, NullType > Type;
253};
254template< class T >
255struct Append< T, NullType >
256{
257 typedef TypeList< T, NullType > Type;
258};
259template< class Head, class Tail >
260struct Append< NullType, TypeList< Head, Tail > >
261{
262 typedef TypeList< Head, Tail > Type;
263};
264template< class Head, class Tail >
265struct Append< TypeList< Head, Tail >, NullType >
266{
267 typedef TypeList< Head, Tail > Type;
268};
269
273template< class TList, class T >
274struct Erase;
275
276template< class T >
277struct Erase< NullType, T >
278{
279 typedef NullType Type;
280};
281
282template< class T, class Tail >
283struct Erase< TypeList< T, Tail >, T >
284{
285 typedef Tail Type;
286};
287
288template< class Head, class Tail, class T >
289struct Erase< TypeList< Head, Tail >, T >
290{
291 typedef TypeList< Head, typename Erase< Tail, T >::Type > Type;
292};
293
297template< class TList, class T >
298struct EraseAll;
299template< class T >
300struct EraseAll< NullType, T >
301{
302 typedef NullType Type;
303};
304template< class T, class Tail >
305struct EraseAll< TypeList< T, Tail >, T >
306{
307 typedef typename EraseAll< Tail, T >::Type Type;
308};
309template< class Head, class Tail, class T >
310struct EraseAll< TypeList< Head, Tail >, T >
311{
312 typedef TypeList< Head, typename EraseAll< Tail, T >::Type > Type;
313};
314
318template< class TList >
319struct NoDuplicates;
320
321template< >
322struct NoDuplicates< NullType >
323{
324 typedef NullType Type;
325};
326
327template< class Head, class Tail >
328struct NoDuplicates< TypeList< Head, Tail > >
329{
330private:
331
332 typedef typename NoDuplicates< Tail >::Type L1;
333 typedef typename Erase< L1, Head >::Type L2;
334
335public:
336
337 typedef TypeList< Head, L2 > Type;
338};
339
343template< class TList, class T, class U >
344struct Replace;
345
346template< class T, class U >
347struct Replace< NullType, T, U >
348{
349 typedef NullType Type;
350};
351
352template< class T, class Tail, class U >
353struct Replace< TypeList< T, Tail >, T, U >
354{
355 typedef TypeList< U, Tail > Type;
356};
357
358template< class Head, class Tail, class T, class U >
359struct Replace< TypeList< Head, Tail >, T, U >
360{
361 typedef TypeList< Head, typename Replace< Tail, T, U >::Type > Type;
362};
363
367template< class TList, class T, class U >
368struct ReplaceAll;
369
370template< class T, class U >
371struct ReplaceAll< NullType, T, U >
372{
373 typedef NullType Type;
374};
375
376template< class T, class Tail, class U >
377struct ReplaceAll< TypeList< T, Tail >, T, U >
378{
379 typedef TypeList< U, typename ReplaceAll< Tail, T, U >::Type > Type;
380};
381
382template< class Head, class Tail, class T, class U >
383struct ReplaceAll< TypeList< Head, Tail >, T, U >
384{
385 typedef TypeList< Head, typename ReplaceAll< Tail, T, U >::Type > Type;
386};
387
391template< class TList >
392struct Reverse;
393
394template< >
395struct Reverse< NullType >
396{
397 typedef NullType Type;
398};
399
400template< class Head, class Tail >
401struct Reverse< TypeList< Head, Tail > >
402{
403 typedef typename Append< typename Reverse< Tail >::Type, Head >::Type Type;
404};
405
420template< class TTypeList, class TType >
421struct IndexOf;
422template< class TType >
423struct IndexOf< NullType, TType >
424{
425 enum { Type = -1 };
426};
427template< class TType, class TTail >
428struct IndexOf< TypeList< TType, TTail >, TType >
429{
430 enum { Type = 0 };
431};
432template< class Head, class TTail, class TType >
433struct IndexOf< TypeList< Head, TTail >, TType >
434{
435private:
436
437 enum { temp = IndexOf< TTail, TType >::Type };
438
439public:
440
441 enum { Type = ( temp == -1 ? -1 : 1 + temp ) };
442};
443
456template< class TTypeList, class TType >
457struct HasType;
458template< class TType >
459struct HasType< NullType, TType >
460{
461 enum { Type = false };
462};
463template< class TType, class TTail >
464struct HasType< TypeList< TType, TTail >, TType >
465{
466 enum { Type = true };
467};
468template< class Head, class TTail, class TType >
469struct HasType< TypeList< Head, TTail >, TType >
470{
471 enum { Type = HasType< TTail, TType >::Type };
472};
473
492template< class TTypeList >
493struct Visit
494{
495 template< class Predicate >
496 void operator()( Predicate & visitor )
497 {
498 typedef typename TTypeList::Head Head;
499 typedef typename TTypeList::Tail Tail;
500 visitor.ELX_TEMPLATE_WORKAROUND operator()< Head >( );
501 Visit< Tail > next;
502 next.ELX_TEMPLATE_WORKAROUND operator()< Predicate >( visitor );
503 }
504
505
506 template< class Predicate >
507 void operator()( const Predicate & visitor )
508 {
509 typedef typename TTypeList::Head Head;
510 typedef typename TTypeList::Tail Tail;
511 visitor.ELX_TEMPLATE_WORKAROUND operator()< Head >( );
512 Visit< Tail > next;
513 next.ELX_TEMPLATE_WORKAROUND operator()< Predicate >( visitor );
514 }
515
516
517};
518
519template< >
520struct Visit< NullType >
521{
522 template< class Predicate >
523 void operator()( const Predicate & )
524 {}
525};
526
543template< class TTypeList, unsigned int Dimension >
544struct VisitDimension
545{
546 template< class Predicate >
547 void operator()( Predicate & visitor )
548 {
549 typedef typename TTypeList::Head Head;
550 typedef typename TTypeList::Tail Tail;
551 visitor.ELX_TEMPLATE_WORKAROUND operator()< Head, Dimension >( );
552 VisitDimension< Tail, Dimension > next;
553 next.ELX_TEMPLATE_WORKAROUND operator()< Predicate >( visitor );
554 }
555
556
557 template< class Predicate >
558 void operator()( const Predicate & visitor )
559 {
560 typedef typename TTypeList::Head Head;
561 typedef typename TTypeList::Tail Tail;
562 visitor.ELX_TEMPLATE_WORKAROUND operator()< Head, Dimension >( );
563 VisitDimension< Tail, Dimension > next;
564 next.ELX_TEMPLATE_WORKAROUND operator()< Predicate >( visitor );
565 }
566
567
568};
569
570template< unsigned int Dimension >
571struct VisitDimension< NullType, Dimension >
572{
573 template< class Predicate >
574 void operator()( const Predicate & )
575 {}
576};
577
596template< typename TLeftTypeList, typename TRightTypeList >
597struct DualVisitImpl;
598
599template< typename TLeftTypeList, typename TRightTypeList >
600struct DualVisit
601{
602
603 template< typename Visitor >
604 void operator()( Visitor & visitor ) const
605 {
606 DualVisitImpl< TLeftTypeList, TRightTypeList > impl;
607 return impl.ELX_TEMPLATE_WORKAROUND operator()< Visitor >( visitor );
608 }
609
610
611 template< typename Visitor >
612 void operator()( const Visitor & visitor ) const
613 {
614 DualVisitImpl< TLeftTypeList, TRightTypeList > impl;
615 return impl.ELX_TEMPLATE_WORKAROUND operator()< Visitor >( visitor );
616 }
617
618
619};
620
634template< typename TLeftTypeList, typename TRightTypeList >
635struct DualVisitImpl
636{
637 template< typename Visitor >
638 void operator()( Visitor & visitor ) const
639 {
640 typedef typename TLeftTypeList::Tail LeftTail;
641
642 DualVisitImpl< TLeftTypeList, TRightTypeList > goRight;
643 goRight.visitRHS< Visitor >( visitor );
644
645 DualVisitImpl< LeftTail, TRightTypeList > goLeft;
646 goLeft.ELX_TEMPLATE_WORKAROUND operator()< Visitor >( visitor );
647 }
648
649
650 template< typename Visitor >
651 void operator()( const Visitor & visitor ) const
652 {
653 typedef typename TLeftTypeList::Tail LeftTail;
654
655 DualVisitImpl< TLeftTypeList, TRightTypeList > goRight;
656 goRight.visitRHS< Visitor >( visitor );
657
658 DualVisitImpl< LeftTail, TRightTypeList > goLeft;
659 goLeft.ELX_TEMPLATE_WORKAROUND operator()< Visitor >( visitor );
660 }
661
662
663 template< typename Visitor >
664 void visitRHS( Visitor & visitor ) const
665 {
666 typedef typename TLeftTypeList::Head LeftHead;
667 typedef typename TRightTypeList::Head RightHead;
668 typedef typename TRightTypeList::Tail RightTail;
669
670 visitor.ELX_TEMPLATE_WORKAROUND operator()< LeftHead, RightHead >( );
671
672 DualVisitImpl< TLeftTypeList, RightTail > goRight;
673 goRight.ELX_TEMPLATE_WORKAROUND visitRHS< Visitor >( visitor );
674 }
675
676
677 template< typename Visitor >
678 void visitRHS( const Visitor & visitor ) const
679 {
680 typedef typename TLeftTypeList::Head LeftHead;
681 typedef typename TRightTypeList::Head RightHead;
682 typedef typename TRightTypeList::Tail RightTail;
683
684 visitor.ELX_TEMPLATE_WORKAROUND operator()< LeftHead, RightHead >( );
685
686 DualVisitImpl< TLeftTypeList, RightTail > goRight;
687 goRight.ELX_TEMPLATE_WORKAROUND visitRHS< Visitor >( visitor );
688 }
689
690
691};
692
693template< typename TRightTypeList >
694struct DualVisitImpl< typelist::NullType, TRightTypeList >
695{
696 template< typename Visitor >
697 void operator()( const Visitor & ) const
698 {}
699};
700template< typename TLeftTypeList >
701struct DualVisitImpl< TLeftTypeList, typelist::NullType >
702{
703 template< typename Visitor >
704 void operator()( const Visitor & ) const
705 {}
706
707 template< typename Visitor >
708 void visitRHS( const Visitor & ) const {}
709};
710
711template< >
712struct DualVisitImpl< typelist::NullType, typelist::NullType >
713{
714 template< typename Visitor >
715 void operator()( const Visitor & ) const
716 {}
717};
718
739template< typename TLeftTypeList, typename TRightTypeList, unsigned int Dimension >
740struct DualVisitDimensionImpl;
741
742template< typename TLeftTypeList, typename TRightTypeList, unsigned int Dimension >
743struct DualVisitDimension
744{
745
746 template< typename Visitor >
747 void operator()( Visitor & visitor ) const
748 {
749 DualVisitDimensionImpl< TLeftTypeList, TRightTypeList, Dimension > impl;
750 return impl.ELX_TEMPLATE_WORKAROUND operator()< Visitor >( visitor );
751 }
752
753
754 template< typename Visitor >
755 void operator()( const Visitor & visitor ) const
756 {
757 DualVisitDimensionImpl< TLeftTypeList, TRightTypeList, Dimension > impl;
758 return impl.ELX_TEMPLATE_WORKAROUND operator()< Visitor >( visitor );
759 }
760
761
762};
763
777template< typename TLeftTypeList, typename TRightTypeList, unsigned int Dimension >
778struct DualVisitDimensionImpl
779{
780 template< typename Visitor >
781 void operator()( Visitor & visitor ) const
782 {
783 typedef typename TLeftTypeList::Tail LeftTail;
784
785 DualVisitDimensionImpl< TLeftTypeList, TRightTypeList, Dimension > goRight;
786 goRight.visitRHS< Visitor >( visitor );
787
788 DualVisitDimensionImpl< LeftTail, TRightTypeList, Dimension > goLeft;
789 goLeft.ELX_TEMPLATE_WORKAROUND operator()< Visitor >( visitor );
790 }
791
792
793 template< typename Visitor >
794 void operator()( const Visitor & visitor ) const
795 {
796 typedef typename TLeftTypeList::Tail LeftTail;
797
798 DualVisitDimensionImpl< TLeftTypeList, TRightTypeList, Dimension > goRight;
799 goRight.visitRHS< Visitor >( visitor );
800
801 DualVisitDimensionImpl< LeftTail, TRightTypeList, Dimension > goLeft;
802 goLeft.ELX_TEMPLATE_WORKAROUND operator()< Visitor >( visitor );
803 }
804
805
806 template< typename Visitor >
807 void visitRHS( Visitor & visitor ) const
808 {
809 typedef typename TLeftTypeList::Head LeftHead;
810 typedef typename TRightTypeList::Head RightHead;
811 typedef typename TRightTypeList::Tail RightTail;
812
813 visitor.ELX_TEMPLATE_WORKAROUND operator()< LeftHead, RightHead, Dimension >( );
814
815 DualVisitDimensionImpl< TLeftTypeList, RightTail, Dimension > goRight;
816 goRight.ELX_TEMPLATE_WORKAROUND visitRHS< Visitor >( visitor );
817 }
818
819
820 template< typename Visitor >
821 void visitRHS( const Visitor & visitor ) const
822 {
823 typedef typename TLeftTypeList::Head LeftHead;
824 typedef typename TRightTypeList::Head RightHead;
825 typedef typename TRightTypeList::Tail RightTail;
826
827 visitor.ELX_TEMPLATE_WORKAROUND operator()< LeftHead, RightHead, Dimension >( );
828
829 DualVisitDimensionImpl< TLeftTypeList, RightTail, Dimension > goRight;
830 goRight.ELX_TEMPLATE_WORKAROUND visitRHS< Visitor >( visitor );
831 }
832
833
834};
835
836template< typename TRightTypeList, unsigned int Dimension >
837struct DualVisitDimensionImpl< typelist::NullType, TRightTypeList, Dimension >
838{
839 template< typename Visitor >
840 void operator()( const Visitor & ) const
841 {}
842};
843template< typename TLeftTypeList, unsigned int Dimension >
844struct DualVisitDimensionImpl< TLeftTypeList, typelist::NullType, Dimension >
845{
846 template< typename Visitor >
847 void operator()( const Visitor & ) const
848 {}
849
850 template< typename Visitor >
851 void visitRHS( const Visitor & ) const {}
852};
853
854template< unsigned int Dimension >
855struct DualVisitDimensionImpl< typelist::NullType, typelist::NullType, Dimension >
856{
857 template< typename Visitor >
858 void operator()( const Visitor & ) const
859 {}
860};
861
864}
865
866#endif // __TypeList_H__


Generated on 1667476801 for elastix by doxygen 1.9.4 elastix logo