1 // PR c++/62134 2 // { dg-do compile { target c++11 } } 3 4 template<typename... T> struct tuple; 5 template<__SIZE_TYPE__, typename U> struct tuple_element; 6 7 template<bool, typename T = void> struct enable_if { }; 8 template<typename T> struct enable_if<true, T> { typedef T type; }; 9 10 template <int V> struct int_t { static constexpr int value = V; }; 11 template <int V> int constexpr int_t<V>::value; 12 13 template <class A, class Val, int i=0> 14 struct Index 15 { 16 static int const value = -1; 17 }; 18 19 template <class ... A, class Val, int i> 20 struct Index<tuple<Val, A ...>, Val, i> 21 { 22 static int const value = i; 23 }; 24 25 template <class A0, class ... A, class Val, int i> 26 struct Index<tuple<A0, A ...>, Val, i> 27 { 28 static int const value = Index<tuple<A ...>, Val, i+1>::value; 29 }; 30 31 template <class C, class R> struct PermutationSign; 32 33 template <int w, class C, class R> 34 struct PermutationSignIfFound 35 { 36 static int const value = 0; 37 }; 38 39 template <class C, class R> 40 struct PermutationSignIfFound<-1, C, R> 41 { 42 static int const value = 0; 43 }; 44 45 template <> 46 struct PermutationSign<tuple<>, tuple<>> 47 { 48 static int const value = 1; 49 }; 50 51 template <class C> 52 struct PermutationSign<C, tuple<>> 53 { 54 static int const value = 0; 55 }; 56 57 template <class R> 58 struct PermutationSign<tuple<>, R> 59 { 60 static int const value = 0; 61 }; 62 63 template <class C, class Org> 64 struct PermutationSign 65 { 66 static int const value 67 = PermutationSignIfFound 68 <Index<C, typename tuple_element<0, Org>::type>::value, 69 C, Org>::value; 70 }; 71 72 template <class A, template <class> class Pred, int i=0, class Enable=void> 73 struct IndexIf 74 { 75 static int const value = -1; 76 using type = tuple<>; 77 }; 78 79 template <class A0, class ... A, template <class> class Pred, int i> 80 struct IndexIf<tuple<A0, A ...>, Pred, i, 81 typename enable_if<Pred<A0>::value>::type> 82 { 83 using type = A0; 84 static int const value = i; 85 }; 86 87 template <class A0, class ... A, template <class> class Pred, int i> 88 struct IndexIf<tuple<A0, A ...>, Pred, i, 89 typename enable_if<!Pred<A0>::value>::type> 90 { 91 using next = IndexIf<tuple<A ...>, Pred, i+1>; 92 using type = typename next::type; 93 static int const value = next::value; 94 }; 95 96 template <class P> 97 struct MatchPermutationP 98 { 99 template <class A> using type = PermutationSign<P, A>; 100 }; 101 102 template <class P, class Plist> struct FindCombination 103 { 104 using type = IndexIf<Plist, MatchPermutationP<P>::template type>; 105 static int const where = type::value; 106 static int const sign 107 = (where>=0) ? PermutationSign<P, typename type::type>::value : 0; 108 }; 109 110 int main() 111 { 112 using finder = FindCombination<tuple<>, tuple<tuple<>>>; 113 static_assert(finder::where==0 && finder::sign==+1, "bad"); 114 } 115