7 #ifndef CPPWAMP_TYPES_TUPLE_HPP
8 #define CPPWAMP_TYPES_TUPLE_HPP
17 #include <type_traits>
19 #include "../variant.hpp"
20 #include "../internal/integersequence.hpp"
32 template <
typename... Ts>
34 std::tuple<Ts...>& tuple);
41 template <
typename... Ts>
48 template <
typename... Ts>
49 CPPWAMP_API
void convert(FromVariantConverter& conv, std::tuple<Ts...>& tuple);
55 template <
typename... Ts>
56 CPPWAMP_API
void convert(ToVariantConverter& conv, std::tuple<Ts...>& tuple);
61 template <
typename... Ts>
62 CPPWAMP_API
bool operator==(
const Array& array,
const std::tuple<Ts...>& tuple);
67 template <
typename... Ts>
68 CPPWAMP_API
bool operator==(
const std::tuple<Ts...>& tuple,
const Array& array);
73 template <
typename... Ts>
74 CPPWAMP_API
bool operator!=(
const Array& array,
const std::tuple<Ts...>& tuple);
79 template <
typename... Ts>
80 CPPWAMP_API
bool operator!=(
const std::tuple<Ts...>& tuple,
const Array& array);
85 template <
typename... Ts>
86 CPPWAMP_API
bool operator==(
const Variant& variant,
87 const std::tuple<Ts...>& tuple);
92 template <
typename... Ts>
93 CPPWAMP_API
bool operator==(
const std::tuple<Ts...>& tuple,
94 const Variant& variant);
99 template <
typename... Ts>
100 CPPWAMP_API
bool operator!=(
const Variant& variant,
101 const std::tuple<Ts...>& tuple);
106 template <
typename... Ts>
107 CPPWAMP_API
bool operator!=(
const std::tuple<Ts...>& tuple,
108 const Variant& variant);
119 template <
int N,
typename...Ts>
120 int toTupleElement(
const Array& array, std::tuple<Ts...>& tuple)
122 auto& elem = std::get<N>(tuple);
125 array.at(N).to(elem);
127 catch (
const error::Conversion& e)
129 std::ostringstream oss;
130 oss << e.what() <<
" (for tuple element #" << N <<
")";
131 throw error::Conversion(oss.str());
136 template <
int N,
typename...Ts>
137 int fromTupleElement(
Array& array,
const std::tuple<Ts...>& tuple)
139 const auto& elem = std::get<N>(tuple);
144 template <
typename... Ts,
int ...Seq>
145 void convertToTuple(
const Array& array, std::tuple<Ts...>& tuple,
146 internal::IntegerSequence<Seq...>)
148 if (
array.size() !=
sizeof...(Ts))
149 throw error::Conversion(
"Cannot convert variant array to tuple; "
150 "sizes do not match");
151 using swallow =
int[];
152 (void)swallow{0, toTupleElement<Seq>(array, tuple)...};
155 template <
typename... Ts,
int ...Seq>
156 void convertFromTuple(
Array& array,
const std::tuple<Ts...>& tuple,
157 internal::IntegerSequence<Seq...>)
159 array.reserve(
sizeof...(Ts));
160 using swallow =
int[];
161 (void)swallow{0, fromTupleElement<Seq>(array, tuple)...};
165 template <std::size_t N,
typename... Ts>
166 using EnableIfTupleElement =
EnableIf<N !=
sizeof...(Ts)>;
168 template <std::size_t N,
typename... Ts>
169 using EnableIfTupleEnd =
EnableIf<N ==
sizeof...(Ts)>;
171 template <std::size_t N = 0,
typename... Ts, EnableIfTupleEnd<N, Ts...> = 0>
172 bool equalsTuple(
const Array&,
const std::tuple<Ts...>&)
177 template <std::size_t N = 0,
typename... Ts, EnableIfTupleElement<N, Ts...> = 0>
178 bool equalsTuple(
const Array& array,
const std::tuple<Ts...>& tuple)
180 const auto& arrayElem =
array.at(N);
181 const auto& tupleElem = std::get<N>(tuple);
182 bool result = (arrayElem == tupleElem);
183 return result && equalsTuple<N+1, Ts...>(
array, tuple);
187 template <std::size_t N = 0,
typename... Ts, EnableIfTupleEnd<N, Ts...> = 0>
188 bool notEqualsTuple(
const Array&,
const std::tuple<Ts...>&)
193 template <std::size_t N = 0,
typename... Ts, EnableIfTupleElement<N, Ts...> = 0>
194 bool notEqualsTuple(
const Array& array,
const std::tuple<Ts...>& tuple)
196 const auto& arrayElem =
array.at(N);
197 const auto& tupleElem = std::get<N>(tuple);
198 bool result = (arrayElem != tupleElem);
199 return result || notEqualsTuple<N+1, Ts...>(
array, tuple);
210 template <
typename... Ts>
213 using Seq =
typename internal::GenIntegerSequence<
sizeof...(Ts)>::type;
214 convertToTuple(
array, tuple, Seq());
218 template <
typename... Ts>
221 using Seq =
typename internal::GenIntegerSequence<
sizeof...(Ts)>::type;
223 convertFromTuple(
array, tuple, Seq());
228 template <
typename... Ts>
231 auto& variant = conv.
variant();
232 if (!variant.is<
Array>())
235 "the variant is not an array");
241 template <
typename... Ts>
248 template <
typename... Ts>
249 bool operator==(
const Array& array,
const std::tuple<Ts...>& tuple)
251 auto N = std::tuple_size<std::tuple<Ts...>>::value;
252 return array.size() == N ? internal::equalsTuple(
array, tuple) :
false;
256 template <
typename... Ts>
257 bool operator==(
const std::tuple<Ts...>& tuple,
const Array& array)
259 return array == tuple;
263 template <
typename... Ts>
264 bool operator!=(
const Array& array,
const std::tuple<Ts...>& tuple)
266 auto N = std::tuple_size<std::tuple<Ts...>>::value;
267 return array.size() == N ? internal::notEqualsTuple(
array, tuple) :
true;
271 template <
typename... Ts>
272 bool operator!=(
const std::tuple<Ts...>& tuple,
const Array& array)
274 return array != tuple;
278 template <
typename... Ts>
279 bool operator==(
const Variant& variant,
const std::tuple<Ts...>& tuple)
285 template <
typename... Ts>
286 bool operator==(
const std::tuple<Ts...>& tuple,
const Variant& variant)
288 return variant == tuple;
292 template <
typename... Ts>
293 bool operator!=(
const Variant& variant,
const std::tuple<Ts...>& tuple)
299 template <
typename... Ts>
300 bool operator!=(
const std::tuple<Ts...>& tuple,
const Variant& variant)
302 return variant != tuple;
307 #endif // CPPWAMP_TYPES_TUPLE_HPP