@@ -14,37 +14,42 @@ 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>
26- void assignFromTupleElement (Variant& v, T&& elem)
30+ T&& forwardTupleElement( T&& elem)
2731{
2832 static_assert (ArgTraits<T>::isValid,
2933 " wamp::fromTuple - Invalid tuple element type" );
30- v = std::move (elem);
34+ // Normally this should be std::forward, but this function is only called by
35+ // assignFromTuple below, so elem is always actually an rvalue reference, so
36+ // using std::move is sufficient.
37+ return std::move (elem);
3138}
3239
3340template <typename ... Ts>
34- void assignFromTupleElement (Variant& v, std::tuple<Ts...>&& tuple)
41+ Array forwardTupleElement ( std::tuple<Ts...>&& tuple)
3542{
36- v = toArray (std::move (tuple));
43+ return toArray (std::move (tuple));
3744}
3845
39- template <std::size_t N= 0 , typename ... Ts>
40- TupleLastResult< void ,N,Ts...> assignFromTuple (Array&, std::tuple<Ts...>&&) { }
46+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleEnd<N, Ts...> = 0 >
47+ void assignFromTuple (Array&, std::tuple<Ts...>&&) {}
4148
42- template <std::size_t N=0 , typename ... Ts>
43- TupleResult<void ,N,Ts...> assignFromTuple (Array& array,
44- std::tuple<Ts...>&& tuple)
49+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleElement<N, Ts...> = 0 >
50+ void assignFromTuple (Array& array, std::tuple<Ts...>&& tuple)
4551{
46- array.push_back (Variant ());
47- assignFromTupleElement (array.back (), std::get<N>(std::move (tuple)));
52+ array.emplace_back (forwardTupleElement (std::get<N>(std::move (tuple))));
4853 assignFromTuple<N+1 , Ts...>(array, std::move (tuple));
4954}
5055
@@ -70,12 +75,11 @@ void assignToTupleElement(const Variant& v, std::tuple<Ts...>& tuple)
7075 toTuple (v.as <Array>(), tuple);
7176}
7277
73- template <std::size_t N= 0 , typename ... Ts>
74- TupleLastResult< void ,N,Ts...> assignToTuple (const Array&, std::tuple<Ts...>&) {}
78+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleEnd<N, Ts...> = 0 >
79+ void assignToTuple (const Array&, std::tuple<Ts...>&) {}
7580
76- template <std::size_t N=0 , typename ... Ts>
77- TupleResult<void ,N,Ts...> assignToTuple (const Array& array,
78- std::tuple<Ts...>& tuple)
81+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleElement<N, Ts...> = 0 >
82+ void assignToTuple (const Array& array, std::tuple<Ts...>& tuple)
7983{
8084 using ElemType = typename std::tuple_element<N, std::tuple<Ts...>>::type;
8185 static_assert (ArgTraits<ElemType>::isValid,
@@ -97,9 +101,12 @@ TupleResult<void,N,Ts...> assignToTuple(const Array& array,
97101// ------------------------------------------------------------------------------
98102template <typename T> struct TupleTag {};
99103
100- // Foward declaration
101- template <std::size_t N=0 , typename ... Ts>
102- TupleResult<bool ,N,Ts...> isConvertibleToTuple (const Array& array);
104+ // Forward declarations.
105+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleEnd<N, Ts...> = 0 >
106+ bool isConvertibleToTuple (const Array& array);
107+
108+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleElement<N, Ts...> = 0 >
109+ bool isConvertibleToTuple (const Array& array);
103110
104111template <typename T>
105112bool isConvertibleToTupleElement (const Variant& v, TupleTag<T>)
@@ -114,11 +121,12 @@ bool isConvertibleToTupleElement(const Variant& v, TupleTag<std::tuple<Ts...>>)
114121 isConvertibleToTuple<0 ,Ts...>(v.as <Array>());
115122}
116123
117- template <std::size_t N=0 , typename ... Ts>
118- TupleLastResult<bool ,N,Ts...> isConvertibleToTuple (const Array&) {return true ;}
124+ // Template defaults given in forward declaration.
125+ template <std::size_t N, typename ... Ts, EnableIfTupleEnd<N, Ts...>>
126+ bool isConvertibleToTuple (const Array&) {return true ;}
119127
120- template <std::size_t N= 0 , typename ... Ts>
121- TupleResult< bool ,N,Ts...> isConvertibleToTuple (const Array& array)
128+ template <std::size_t N, typename ... Ts, EnableIfTupleElement<N, Ts...> >
129+ bool isConvertibleToTuple (const Array& array)
122130{
123131 using ElemType = typename std::tuple_element<N, std::tuple<Ts...>>::type;
124132 bool result = isConvertibleToTupleElement (array.at (N),
@@ -128,16 +136,14 @@ TupleResult<bool,N,Ts...> isConvertibleToTuple(const Array& array)
128136
129137
130138// ------------------------------------------------------------------------------
131- template <std::size_t N=0 , typename ... Ts>
132- TupleLastResult<bool ,N,Ts...> equalsTuple (const Array&,
133- const std::tuple<Ts...>&)
139+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleEnd<N, Ts...> = 0 >
140+ bool equalsTuple (const Array&, const std::tuple<Ts...>&)
134141{
135142 return true ;
136143}
137144
138- template <std::size_t N=0 , typename ... Ts>
139- TupleResult<bool ,N,Ts...> equalsTuple (const Array& array,
140- const std::tuple<Ts...>& tuple)
145+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleElement<N, Ts...> = 0 >
146+ bool equalsTuple (const Array& array, const std::tuple<Ts...>& tuple)
141147{
142148 using ElemType = typename std::tuple_element<N, std::tuple<Ts...>>::type;
143149 static_assert (ArgTraits<ElemType>::isValid,
@@ -149,16 +155,14 @@ TupleResult<bool,N,Ts...> equalsTuple(const Array& array,
149155}
150156
151157// ------------------------------------------------------------------------------
152- template <std::size_t N=0 , typename ... Ts>
153- TupleLastResult<bool ,N,Ts...> notEqualsTuple (const Array&,
154- const std::tuple<Ts...>&)
158+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleEnd<N, Ts...> = 0 >
159+ bool notEqualsTuple (const Array&, const std::tuple<Ts...>&)
155160{
156161 return false ;
157162}
158163
159- template <std::size_t N=0 , typename ... Ts>
160- TupleResult<bool ,N,Ts...> notEqualsTuple (const Array& array,
161- const std::tuple<Ts...>& tuple)
164+ template <std::size_t N = 0 , typename ... Ts, EnableIfTupleElement<N, Ts...> = 0 >
165+ bool notEqualsTuple (const Array& array, const std::tuple<Ts...>& tuple)
162166{
163167 using ElemType = typename std::tuple_element<N, std::tuple<Ts...>>::type;
164168 static_assert (ArgTraits<ElemType>::isValid,
0 commit comments