59 #ifndef __TypeList_H__
60 #define __TypeList_H__
62 #if defined( __clang__ )
63 #define CLANG_TEMPLATE template
65 #define CLANG_TEMPLATE
81 template<
typename H,
typename T >
145 template<
typename TTypeList >
159 template<
typename H,
typename T >
167 struct Length< NullType >
187 template<
class TTypeList,
unsigned int index >
190 template<
class Head,
class Tail >
196 template<
class Head,
class Tail,
unsigned int i >
202 template<
unsigned int i >
208 template<
class TTypeList1,
class TTypeList2 >
231 template<
class Head,
class Tail,
class T >
244 struct Append< NullType, T >
246 typedef TypeList< T, NullType > Type;
249 struct Append< T, NullType >
251 typedef TypeList< T, NullType > Type;
253 template<
class Head,
class Tail >
254 struct Append< NullType, TypeList< Head, Tail > >
256 typedef TypeList< Head, Tail > Type;
258 template<
class Head,
class Tail >
259 struct Append< TypeList< Head, Tail >, NullType >
261 typedef TypeList< Head, Tail > Type;
267 template<
class TList,
class T >
271 struct Erase< NullType, T >
273 typedef NullType Type;
276 template<
class T,
class Tail >
277 struct Erase< TypeList< T, Tail >, T >
282 template<
class Head,
class Tail,
class T >
283 struct Erase< TypeList< Head, Tail >, T >
285 typedef TypeList< Head, typename Erase< Tail, T >::Type > Type;
291 template<
class TList,
class T >
294 struct EraseAll< NullType, T >
296 typedef NullType Type;
298 template<
class T,
class Tail >
299 struct EraseAll< TypeList< T, Tail >, T >
301 typedef typename EraseAll< Tail, T >::Type Type;
303 template<
class Head,
class Tail,
class T >
304 struct EraseAll< TypeList< Head, Tail >, T >
306 typedef TypeList< Head, typename EraseAll< Tail, T >::Type > Type;
312 template<
class TList >
316 struct NoDuplicates< NullType >
318 typedef NullType Type;
321 template<
class Head,
class Tail >
322 struct NoDuplicates< TypeList< Head, Tail > >
326 typedef typename NoDuplicates< Tail >::Type L1;
327 typedef typename Erase< L1, Head >::Type L2;
331 typedef TypeList< Head, L2 > Type;
337 template<
class TList,
class T,
class U >
340 template<
class T,
class U >
341 struct Replace< NullType, T, U >
343 typedef NullType Type;
346 template<
class T,
class Tail,
class U >
347 struct Replace< TypeList< T, Tail >, T, U >
349 typedef TypeList< U, Tail > Type;
352 template<
class Head,
class Tail,
class T,
class U >
353 struct Replace< TypeList< Head, Tail >, T, U >
355 typedef TypeList< Head, typename Replace< Tail, T, U >::Type > Type;
361 template<
class TList,
class T,
class U >
364 template<
class T,
class U >
365 struct ReplaceAll< NullType, T, U >
367 typedef NullType Type;
370 template<
class T,
class Tail,
class U >
371 struct ReplaceAll< TypeList< T, Tail >, T, U >
373 typedef TypeList< U, typename ReplaceAll< Tail, T, U >::Type > Type;
376 template<
class Head,
class Tail,
class T,
class U >
377 struct ReplaceAll< TypeList< Head, Tail >, T, U >
379 typedef TypeList< Head, typename ReplaceAll< Tail, T, U >::Type > Type;
385 template<
class TList >
389 struct Reverse< NullType >
391 typedef NullType Type;
394 template<
class Head,
class Tail >
395 struct Reverse< TypeList< Head, Tail > >
397 typedef typename Append< typename Reverse< Tail >::Type, Head >::Type Type;
414 template<
class TTypeList,
class TType >
416 template<
class TType >
421 template<
class TType,
class TTail >
426 template<
class Head,
class TTail,
class TType >
435 enum { Type = ( temp == -1 ? -1 : 1 + temp ) };
450 template<
class TTypeList,
class TType >
452 template<
class TType >
455 enum { Type =
false };
457 template<
class TType,
class TTail >
460 enum { Type =
true };
462 template<
class Head,
class TTail,
class TType >
486 template<
class TTypeList >
489 template<
class Predicate >
492 typedef typename TTypeList::Head Head;
493 typedef typename TTypeList::Tail Tail;
494 visitor.CLANG_TEMPLATE operator()< Head >( );
496 next.CLANG_TEMPLATE operator()< Predicate >( visitor );
500 template<
class Predicate >
503 typedef typename TTypeList::Head Head;
504 typedef typename TTypeList::Tail Tail;
505 visitor.CLANG_TEMPLATE operator()< Head >( );
507 next.CLANG_TEMPLATE operator()< Predicate >( visitor );
516 template<
class Predicate >
537 template<
class TTypeList,
unsigned int Dimension >
540 template<
class Predicate >
543 typedef typename TTypeList::Head Head;
544 typedef typename TTypeList::Tail Tail;
545 visitor.CLANG_TEMPLATE operator()< Head, Dimension >( );
547 next.CLANG_TEMPLATE operator()< Predicate >( visitor );
551 template<
class Predicate >
554 typedef typename TTypeList::Head Head;
555 typedef typename TTypeList::Tail Tail;
556 visitor.CLANG_TEMPLATE operator()< Head, Dimension >( );
558 next.CLANG_TEMPLATE operator()< Predicate >( visitor );
564 template<
unsigned int Dimension >
567 template<
class Predicate >
590 template<
typename TLeftTypeList,
typename TRightTypeList >
593 template<
typename TLeftTypeList,
typename TRightTypeList >
597 template<
typename Visitor >
601 return impl.CLANG_TEMPLATE operator()< Visitor >( visitor );
605 template<
typename Visitor >
609 return impl.CLANG_TEMPLATE operator()< Visitor >( visitor );
628 template<
typename TLeftTypeList,
typename TRightTypeList >
631 template<
typename Visitor >
632 void operator()( Visitor & visitor )
const
634 typedef typename TLeftTypeList::Tail LeftTail;
636 DualVisitImpl< TLeftTypeList, TRightTypeList > goRight;
637 goRight.visitRHS< Visitor >( visitor );
639 DualVisitImpl< LeftTail, TRightTypeList > goLeft;
640 goLeft.CLANG_TEMPLATE operator()< Visitor >( visitor );
644 template<
typename Visitor >
645 void operator()(
const Visitor & visitor )
const
647 typedef typename TLeftTypeList::Tail LeftTail;
649 DualVisitImpl< TLeftTypeList, TRightTypeList > goRight;
650 goRight.visitRHS< Visitor >( visitor );
652 DualVisitImpl< LeftTail, TRightTypeList > goLeft;
653 goLeft.CLANG_TEMPLATE operator()< Visitor >( visitor );
657 template<
typename Visitor >
658 void visitRHS( Visitor & visitor )
const
660 typedef typename TLeftTypeList::Head LeftHead;
661 typedef typename TRightTypeList::Head RightHead;
662 typedef typename TRightTypeList::Tail RightTail;
664 visitor.CLANG_TEMPLATE operator()< LeftHead, RightHead >( );
666 DualVisitImpl< TLeftTypeList, RightTail > goRight;
667 goRight.CLANG_TEMPLATE visitRHS< Visitor >( visitor );
671 template<
typename Visitor >
672 void visitRHS(
const Visitor & visitor )
const
674 typedef typename TLeftTypeList::Head LeftHead;
675 typedef typename TRightTypeList::Head RightHead;
676 typedef typename TRightTypeList::Tail RightTail;
678 visitor.CLANG_TEMPLATE operator()< LeftHead, RightHead >( );
680 DualVisitImpl< TLeftTypeList, RightTail > goRight;
681 goRight.CLANG_TEMPLATE visitRHS< Visitor >( visitor );
687 template<
typename TRightTypeList >
688 struct DualVisitImpl<
typelist::NullType, TRightTypeList >
690 template<
typename Visitor >
691 void operator()(
const Visitor & )
const
694 template<
typename TLeftTypeList >
695 struct DualVisitImpl< TLeftTypeList,
typelist::NullType >
697 template<
typename Visitor >
698 void operator()(
const Visitor & )
const
701 template<
typename Visitor >
702 void visitRHS(
const Visitor & )
const {}
708 template<
typename Visitor >
709 void operator()(
const Visitor & )
const
733 template<
typename TLeftTypeList,
typename TRightTypeList,
unsigned int Dimension >
734 struct DualVisitDimensionImpl;
736 template<
typename TLeftTypeList,
typename TRightTypeList,
unsigned int Dimension >
737 struct DualVisitDimension
740 template<
typename Visitor >
741 void operator()( Visitor & visitor )
const
743 DualVisitDimensionImpl< TLeftTypeList, TRightTypeList, Dimension > impl;
744 return impl.CLANG_TEMPLATE operator()< Visitor >( visitor );
748 template<
typename Visitor >
749 void operator()(
const Visitor & visitor )
const
751 DualVisitDimensionImpl< TLeftTypeList, TRightTypeList, Dimension > impl;
752 return impl.CLANG_TEMPLATE operator()< Visitor >( visitor );
771 template<
typename TLeftTypeList,
typename TRightTypeList,
unsigned int Dimension >
772 struct DualVisitDimensionImpl
774 template<
typename Visitor >
775 void operator()( Visitor & visitor )
const
777 typedef typename TLeftTypeList::Tail LeftTail;
779 DualVisitDimensionImpl< TLeftTypeList, TRightTypeList, Dimension > goRight;
780 goRight.visitRHS< Visitor >( visitor );
782 DualVisitDimensionImpl< LeftTail, TRightTypeList, Dimension > goLeft;
783 goLeft.CLANG_TEMPLATE operator()< Visitor >( visitor );
787 template<
typename Visitor >
788 void operator()(
const Visitor & visitor )
const
790 typedef typename TLeftTypeList::Tail LeftTail;
792 DualVisitDimensionImpl< TLeftTypeList, TRightTypeList, Dimension > goRight;
793 goRight.visitRHS< Visitor >( visitor );
795 DualVisitDimensionImpl< LeftTail, TRightTypeList, Dimension > goLeft;
796 goLeft.CLANG_TEMPLATE operator()< Visitor >( visitor );
800 template<
typename Visitor >
801 void visitRHS( Visitor & visitor )
const
803 typedef typename TLeftTypeList::Head LeftHead;
804 typedef typename TRightTypeList::Head RightHead;
805 typedef typename TRightTypeList::Tail RightTail;
807 visitor.CLANG_TEMPLATE operator()< LeftHead, RightHead, Dimension >( );
809 DualVisitDimensionImpl< TLeftTypeList, RightTail, Dimension > goRight;
810 goRight.CLANG_TEMPLATE visitRHS< Visitor >( visitor );
814 template<
typename Visitor >
815 void visitRHS(
const Visitor & visitor )
const
817 typedef typename TLeftTypeList::Head LeftHead;
818 typedef typename TRightTypeList::Head RightHead;
819 typedef typename TRightTypeList::Tail RightTail;
821 visitor.CLANG_TEMPLATE operator()< LeftHead, RightHead, Dimension >( );
823 DualVisitDimensionImpl< TLeftTypeList, RightTail, Dimension > goRight;
824 goRight.CLANG_TEMPLATE visitRHS< Visitor >( visitor );
830 template<
typename TRightTypeList,
unsigned int Dimension >
831 struct DualVisitDimensionImpl<
typelist::NullType, TRightTypeList, Dimension >
833 template<
typename Visitor >
834 void operator()(
const Visitor & )
const
837 template<
typename TLeftTypeList,
unsigned int Dimension >
838 struct DualVisitDimensionImpl< TLeftTypeList,
typelist::NullType, Dimension >
840 template<
typename Visitor >
841 void operator()(
const Visitor & )
const
844 template<
typename Visitor >
845 void visitRHS(
const Visitor & )
const {}
848 template<
unsigned int Dimension >
851 template<
typename Visitor >
852 void operator()(
const Visitor & )
const
860 #endif // __TypeList_H__