@@ -14,12 +14,16 @@ namespace wamp
1414namespace internal
1515{
1616
17- template <typename TResult, std::size_t N, typename ... Ts>
18- using TupleResult = typename std::enable_if<N != sizeof ...(Ts), TResult>::type;
17+ // ------------------------------------------------------------------------------
18+ // This should be possible with return type deduction, but clang doesn't like
19+ // that for some reason: http://stackoverflow.com/q/24454664.
20+ template <std::size_t N, typename ... Ts>
21+ using EnableIfTupleElement =
22+ typename std::enable_if<N != sizeof ...(Ts), int >::type;
1923
20- template < typename TResult, std::size_t N, typename ... Ts>
21- using TupleLastResult =
22- typename std::enable_if<N == sizeof ...(Ts), TResult >::type;
24+ template < std::size_t N, typename ... Ts>
25+ using EnableIfTupleEnd =
26+ typename std::enable_if<N == sizeof ...(Ts), int >::type;
2327
2428// ------------------------------------------------------------------------------
2529template <typename T>
@@ -36,12 +40,11 @@ void assignFromTupleElement(Variant& v, std::tuple<Ts...>&& tuple)
3640 v = toArray (std::move (tuple));
3741}
3842
39- template <std::size_t N= 0 , typename ... Ts>
40- TupleLastResult< void ,N,Ts...> assignFromTuple (Array&, std::tuple<Ts...>&&) { }
43+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleEnd<N, Ts...> = 0 >
44+ void assignFromTuple (Array&, std::tuple<Ts...>&&) {}
4145
42- template <std::size_t N=0 , typename ... Ts>
43- TupleResult<void ,N,Ts...> assignFromTuple (Array& array,
44- std::tuple<Ts...>&& tuple)
46+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleElement<N, Ts...> = 0 >
47+ void assignFromTuple (Array& array, std::tuple<Ts...>&& tuple)
4548{
4649 array.push_back (Variant ());
4750 assignFromTupleElement (array.back (), std::get<N>(std::move (tuple)));
@@ -70,12 +73,11 @@ void assignToTupleElement(const Variant& v, std::tuple<Ts...>& tuple)
7073 toTuple (v.as <Array>(), tuple);
7174}
7275
73- template <std::size_t N= 0 , typename ... Ts>
74- TupleLastResult< void ,N,Ts...> assignToTuple (const Array&, std::tuple<Ts...>&) {}
76+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleEnd<N, Ts...> = 0 >
77+ void assignToTuple (const Array&, std::tuple<Ts...>&) {}
7578
76- template <std::size_t N=0 , typename ... Ts>
77- TupleResult<void ,N,Ts...> assignToTuple (const Array& array,
78- std::tuple<Ts...>& tuple)
79+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleElement<N, Ts...> = 0 >
80+ void assignToTuple (const Array& array, std::tuple<Ts...>& tuple)
7981{
8082 using ElemType = typename std::tuple_element<N, std::tuple<Ts...>>::type;
8183 static_assert (ArgTraits<ElemType>::isValid,
@@ -97,9 +99,12 @@ TupleResult<void,N,Ts...> assignToTuple(const Array& array,
9799// ------------------------------------------------------------------------------
98100template <typename T> struct TupleTag {};
99101
100- // Foward declaration
101- template <std::size_t N=0 , typename ... Ts>
102- TupleResult<bool ,N,Ts...> isConvertibleToTuple (const Array& array);
102+ // Forward declarations.
103+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleEnd<N, Ts...> = 0 >
104+ bool isConvertibleToTuple (const Array& array);
105+
106+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleElement<N, Ts...> = 0 >
107+ bool isConvertibleToTuple (const Array& array);
103108
104109template <typename T>
105110bool isConvertibleToTupleElement (const Variant& v, TupleTag<T>)
@@ -114,11 +119,12 @@ bool isConvertibleToTupleElement(const Variant& v, TupleTag<std::tuple<Ts...>>)
114119 isConvertibleToTuple<0 ,Ts...>(v.as <Array>());
115120}
116121
117- template <std::size_t N=0 , typename ... Ts>
118- TupleLastResult<bool ,N,Ts...> isConvertibleToTuple (const Array&) {return true ;}
122+ // Template defaults given in forward declaration.
123+ template <std::size_t N, typename ... Ts, EnableIfTupleEnd<N, Ts...>>
124+ bool isConvertibleToTuple (const Array&) {return true ;}
119125
120- template <std::size_t N= 0 , typename ... Ts>
121- TupleResult< bool ,N,Ts...> isConvertibleToTuple (const Array& array)
126+ template <std::size_t N, typename ... Ts, EnableIfTupleElement<N, Ts...> >
127+ bool isConvertibleToTuple (const Array& array)
122128{
123129 using ElemType = typename std::tuple_element<N, std::tuple<Ts...>>::type;
124130 bool result = isConvertibleToTupleElement (array.at (N),
@@ -128,16 +134,14 @@ TupleResult<bool,N,Ts...> isConvertibleToTuple(const Array& array)
128134
129135
130136// ------------------------------------------------------------------------------
131- template <std::size_t N=0 , typename ... Ts>
132- TupleLastResult<bool ,N,Ts...> equalsTuple (const Array&,
133- const std::tuple<Ts...>&)
137+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleEnd<N, Ts...> = 0 >
138+ bool equalsTuple (const Array&, const std::tuple<Ts...>&)
134139{
135140 return true ;
136141}
137142
138- template <std::size_t N=0 , typename ... Ts>
139- TupleResult<bool ,N,Ts...> equalsTuple (const Array& array,
140- const std::tuple<Ts...>& tuple)
143+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleElement<N, Ts...> = 0 >
144+ bool equalsTuple (const Array& array, const std::tuple<Ts...>& tuple)
141145{
142146 using ElemType = typename std::tuple_element<N, std::tuple<Ts...>>::type;
143147 static_assert (ArgTraits<ElemType>::isValid,
@@ -149,16 +153,14 @@ TupleResult<bool,N,Ts...> equalsTuple(const Array& array,
149153}
150154
151155// ------------------------------------------------------------------------------
152- template <std::size_t N=0 , typename ... Ts>
153- TupleLastResult<bool ,N,Ts...> notEqualsTuple (const Array&,
154- const std::tuple<Ts...>&)
156+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleEnd<N, Ts...> = 0 >
157+ bool notEqualsTuple (const Array&, const std::tuple<Ts...>&)
155158{
156159 return false ;
157160}
158161
159- template <std::size_t N=0 , typename ... Ts>
160- TupleResult<bool ,N,Ts...> notEqualsTuple (const Array& array,
161- const std::tuple<Ts...>& tuple)
162+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleElement<N, Ts...> = 0 >
163+ bool notEqualsTuple (const Array& array, const std::tuple<Ts...>& tuple)
162164{
163165 using ElemType = typename std::tuple_element<N, std::tuple<Ts...>>::type;
164166 static_assert (ArgTraits<ElemType>::isValid,
0 commit comments