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 
74 namespace typelist
75 {
76 
87 template< typename H, typename T >
88 struct TypeList
89 {
90  typedef H Head;
91  typedef T Tail;
92 };
93 
97 struct NullType {};
98 
114 template
115 <
116 typename T1 = NullType, typename T2 = NullType, typename T3 = NullType,
117 typename T4 = NullType, typename T5 = NullType, typename T6 = NullType,
118 typename T7 = NullType, typename T8 = NullType, typename T9 = NullType,
119 typename T10 = NullType, typename T11 = NullType, typename T12 = NullType,
120 typename T13 = NullType, typename T14 = NullType, typename T15 = NullType,
121 typename T16 = NullType, typename T17 = NullType, typename T18 = NullType,
122 typename T19 = NullType, typename T20 = NullType, typename T21 = NullType,
123 typename T22 = NullType, typename T23 = NullType, typename T24 = NullType
124 >
125 struct MakeTypeList
126 {
127 private:
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 
141 public:
142 
143  typedef TypeList< T1, TailType > Type;
144 };
145 template< >
146 struct MakeTypeList< >
147 {
148  typedef NullType Type;
149 };
150 
151 template< typename TTypeList >
152 struct Length;
165 template< typename H, typename T >
166 struct Length< TypeList< H, T > >
167 {
168  enum { Type = 1 + Length< T >::Type };
169 };
170 
172 template< >
173 struct Length< NullType >
174 {
175  enum { Type = 0 };
176 };
193 template< class TTypeList, unsigned int index >
194 struct TypeAt;
195 
196 template< class Head, class Tail >
197 struct TypeAt< TypeList< Head, Tail >, 0 >
198 {
199  typedef Head Type;
200 };
201 
202 template< class Head, class Tail, unsigned int i >
203 struct TypeAt< TypeList< Head, Tail >, i >
204 {
205  typedef typename TypeAt< Tail, i - 1 >::Type Type;
206 };
207 
208 template< unsigned int i >
209 struct TypeAt< NullType, i >
210 {
211  typedef NullType Type;
212 };
213 
214 template< class TTypeList1, class TTypeList2 >
215 struct Append;
237 template< class Head, class Tail, class T >
238 struct Append< TypeList< Head, Tail >, T >
239 {
240  typedef TypeList< Head, typename Append< Tail, T >::Type > Type;
241 };
242 
244 template< >
245 struct Append< NullType, NullType >
246 {
247  typedef NullType Type;
248 };
249 template< class T >
250 struct Append< NullType, T >
251 {
252  typedef TypeList< T, NullType > Type;
253 };
254 template< class T >
255 struct Append< T, NullType >
256 {
257  typedef TypeList< T, NullType > Type;
258 };
259 template< class Head, class Tail >
260 struct Append< NullType, TypeList< Head, Tail > >
261 {
262  typedef TypeList< Head, Tail > Type;
263 };
264 template< class Head, class Tail >
265 struct Append< TypeList< Head, Tail >, NullType >
266 {
267  typedef TypeList< Head, Tail > Type;
268 };
269 
273 template< class TList, class T >
274 struct Erase;
275 
276 template< class T >
277 struct Erase< NullType, T >
278 {
279  typedef NullType Type;
280 };
281 
282 template< class T, class Tail >
283 struct Erase< TypeList< T, Tail >, T >
284 {
285  typedef Tail Type;
286 };
287 
288 template< class Head, class Tail, class T >
289 struct Erase< TypeList< Head, Tail >, T >
290 {
291  typedef TypeList< Head, typename Erase< Tail, T >::Type > Type;
292 };
293 
297 template< class TList, class T >
298 struct EraseAll;
299 template< class T >
300 struct EraseAll< NullType, T >
301 {
302  typedef NullType Type;
303 };
304 template< class T, class Tail >
305 struct EraseAll< TypeList< T, Tail >, T >
306 {
307  typedef typename EraseAll< Tail, T >::Type Type;
308 };
309 template< class Head, class Tail, class T >
310 struct EraseAll< TypeList< Head, Tail >, T >
311 {
312  typedef TypeList< Head, typename EraseAll< Tail, T >::Type > Type;
313 };
314 
318 template< class TList >
319 struct NoDuplicates;
320 
321 template< >
322 struct NoDuplicates< NullType >
323 {
324  typedef NullType Type;
325 };
326 
327 template< class Head, class Tail >
328 struct NoDuplicates< TypeList< Head, Tail > >
329 {
330 private:
331 
332  typedef typename NoDuplicates< Tail >::Type L1;
333  typedef typename Erase< L1, Head >::Type L2;
334 
335 public:
336 
337  typedef TypeList< Head, L2 > Type;
338 };
339 
343 template< class TList, class T, class U >
344 struct Replace;
345 
346 template< class T, class U >
347 struct Replace< NullType, T, U >
348 {
349  typedef NullType Type;
350 };
351 
352 template< class T, class Tail, class U >
353 struct Replace< TypeList< T, Tail >, T, U >
354 {
355  typedef TypeList< U, Tail > Type;
356 };
357 
358 template< class Head, class Tail, class T, class U >
359 struct Replace< TypeList< Head, Tail >, T, U >
360 {
361  typedef TypeList< Head, typename Replace< Tail, T, U >::Type > Type;
362 };
363 
367 template< class TList, class T, class U >
368 struct ReplaceAll;
369 
370 template< class T, class U >
371 struct ReplaceAll< NullType, T, U >
372 {
373  typedef NullType Type;
374 };
375 
376 template< class T, class Tail, class U >
377 struct ReplaceAll< TypeList< T, Tail >, T, U >
378 {
379  typedef TypeList< U, typename ReplaceAll< Tail, T, U >::Type > Type;
380 };
381 
382 template< class Head, class Tail, class T, class U >
383 struct ReplaceAll< TypeList< Head, Tail >, T, U >
384 {
385  typedef TypeList< Head, typename ReplaceAll< Tail, T, U >::Type > Type;
386 };
387 
391 template< class TList >
392 struct Reverse;
393 
394 template< >
395 struct Reverse< NullType >
396 {
397  typedef NullType Type;
398 };
399 
400 template< class Head, class Tail >
401 struct Reverse< TypeList< Head, Tail > >
402 {
403  typedef typename Append< typename Reverse< Tail >::Type, Head >::Type Type;
404 };
405 
420 template< class TTypeList, class TType >
421 struct IndexOf;
422 template< class TType >
423 struct IndexOf< NullType, TType >
424 {
425  enum { Type = -1 };
426 };
427 template< class TType, class TTail >
428 struct IndexOf< TypeList< TType, TTail >, TType >
429 {
430  enum { Type = 0 };
431 };
432 template< class Head, class TTail, class TType >
433 struct IndexOf< TypeList< Head, TTail >, TType >
434 {
435 private:
436 
437  enum { temp = IndexOf< TTail, TType >::Type };
438 
439 public:
440 
441  enum { Type = ( temp == -1 ? -1 : 1 + temp ) };
442 };
443 
456 template< class TTypeList, class TType >
457 struct HasType;
458 template< class TType >
459 struct HasType< NullType, TType >
460 {
461  enum { Type = false };
462 };
463 template< class TType, class TTail >
464 struct HasType< TypeList< TType, TTail >, TType >
465 {
466  enum { Type = true };
467 };
468 template< class Head, class TTail, class TType >
469 struct HasType< TypeList< Head, TTail >, TType >
470 {
471  enum { Type = HasType< TTail, TType >::Type };
472 };
473 
492 template< class TTypeList >
493 struct 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 
519 template< >
520 struct Visit< NullType >
521 {
522  template< class Predicate >
523  void operator()( const Predicate & )
524  {}
525 };
526 
543 template< class TTypeList, unsigned int Dimension >
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 >( );
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 >( );
564  next.ELX_TEMPLATE_WORKAROUND operator()< Predicate >( visitor );
565  }
566 
567 
568 };
569 
570 template< unsigned int Dimension >
571 struct VisitDimension< NullType, Dimension >
572 {
573  template< class Predicate >
574  void operator()( const Predicate & )
575  {}
576 };
577 
596 template< typename TLeftTypeList, typename TRightTypeList >
597 struct DualVisitImpl;
598 
599 template< typename TLeftTypeList, typename TRightTypeList >
600 struct 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 
634 template< typename TLeftTypeList, typename TRightTypeList >
635 struct 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 
693 template< typename TRightTypeList >
694 struct DualVisitImpl< typelist::NullType, TRightTypeList >
695 {
696  template< typename Visitor >
697  void operator()( const Visitor & ) const
698  {}
699 };
700 template< typename TLeftTypeList >
701 struct 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 
711 template< >
712 struct DualVisitImpl< typelist::NullType, typelist::NullType >
713 {
714  template< typename Visitor >
715  void operator()( const Visitor & ) const
716  {}
717 };
718 
739 template< typename TLeftTypeList, typename TRightTypeList, unsigned int Dimension >
740 struct DualVisitDimensionImpl;
741 
742 template< typename TLeftTypeList, typename TRightTypeList, unsigned int Dimension >
743 struct 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 
777 template< typename TLeftTypeList, typename TRightTypeList, unsigned int Dimension >
778 struct 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 
836 template< typename TRightTypeList, unsigned int Dimension >
837 struct DualVisitDimensionImpl< typelist::NullType, TRightTypeList, Dimension >
838 {
839  template< typename Visitor >
840  void operator()( const Visitor & ) const
841  {}
842 };
843 template< typename TLeftTypeList, unsigned int Dimension >
844 struct 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 
854 template< unsigned int Dimension >
855 struct 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__
Runs a templated predicate on each type in the list with dimension provided as template parameter.
Definition: TypeList.h:545
void operator()(Predicate &visitor)
Definition: TypeList.h:547
void operator()(const Predicate &visitor)
Definition: TypeList.h:558


Generated on 1652341256 for elastix by doxygen 1.9.1 elastix logo