7 #ifndef CPPWAMP_PAYLOAD_HPP
8 #define CPPWAMP_PAYLOAD_HPP
16 #include <initializer_list>
23 #include "internal/integersequence.hpp"
32 template <
typename TDerived,
typename TMessage>
37 template <
typename... Ts>
38 TDerived& withArgs(Ts&&... args);
41 template <
typename... Ts>
42 TDerived& withArgsTuple(
const std::tuple<Ts...>& tuple);
46 TDerived& withArgList(
Array args);
49 TDerived& withKwargs(
Object kwargs);
52 const Array& args()
const &;
58 const Object& kwargs()
const &;
64 Variant& operator[](
size_t index);
67 const Variant& operator[](
size_t index)
const;
73 template <
typename... Ts>
74 size_t convertTo(Ts&... values)
const;
77 template <
typename... Ts>
78 size_t convertToTuple(std::tuple<Ts...>& tuple)
const;
82 template <
typename... Ts>
83 size_t moveTo(Ts&... values);
86 template <
typename... Ts>
87 size_t moveToTuple(std::tuple<Ts...>& tuple);
91 template <
typename... TArgs>
92 explicit Payload(TArgs&&... args);
97 CPPWAMP_HIDDEN
static void bundle(
Array&);
99 template <
typename T,
typename... Ts>
100 CPPWAMP_HIDDEN
static void bundle(
Array&
array, T&& head, Ts&&... tail);
102 template <
typename TTuple,
int... Seq>
103 CPPWAMP_HIDDEN
static Array
104 bundleFromTuple(TTuple&& tuple, internal::IntegerSequence<Seq...>);
106 CPPWAMP_HIDDEN
static void unbundleTo(
const Array&,
size_t&);
108 template <
typename T,
typename... Ts>
109 CPPWAMP_HIDDEN
static void unbundleTo(
const Array&
array,
size_t& index,
110 T& head, Ts&... tail);
112 template <
size_t I,
typename... Ts>
113 CPPWAMP_HIDDEN
static size_t unbundleToTuple(
114 const Array&, std::tuple<Ts...>& tuple, std::true_type);
116 template <
size_t I,
typename... Ts>
117 CPPWAMP_HIDDEN
static size_t unbundleToTuple(
118 const Array&, std::tuple<Ts...>& tuple, std::false_type);
120 CPPWAMP_HIDDEN
static void unbundleAs(
Array&,
size_t&);
122 template <
typename T,
typename... Ts>
123 CPPWAMP_HIDDEN
static void unbundleAs(
Array&
array,
size_t& index, T& head,
126 template <
size_t I,
typename... Ts>
127 CPPWAMP_HIDDEN
static size_t unbundleAsTuple(
128 const Array&, std::tuple<Ts...>& tuple, std::true_type);
130 template <
size_t I,
typename... Ts>
131 CPPWAMP_HIDDEN
static size_t unbundleAsTuple(
132 const Array&, std::tuple<Ts...>& tuple, std::false_type);
145 template <
typename D,
typename M>
146 template <
typename... Ts>
150 bundle(
array, std::forward<Ts>(args)...);
151 return withArgList(std::move(
array));
159 template <
typename D,
typename M>
160 template <
typename... Ts>
163 using Seq =
typename internal::GenIntegerSequence<
sizeof...(Ts)>::type;
164 return withArgList(bundleFromTuple(tuple, Seq{}));
170 template <
typename D,
typename M>
173 this->message().args() = std::move(list);
174 return static_cast<D&
>(*this);
180 template <
typename D,
typename M>
183 this->message().kwargs() = std::move(map);
184 return static_cast<D&
>(*this);
188 template <
typename D,
typename M>
191 return this->message().args();
202 template <
typename D,
typename M>
205 auto&
array = this->message().args();
206 Array result(std::move(array));
212 template <
typename D,
typename M>
215 return this->message().kwargs();
226 template <
typename D,
typename M>
229 auto&
object = this->message().kwargs();
230 Object result(std::move(
object));
241 template <
typename D,
typename M>
244 return this->message().args().
at(index);
253 template <
typename D,
typename M>
256 return this->message().args().
at(index);
264 template <
typename D,
typename M>
267 return this->message().kwargs()[keyword];
286 template <
typename D,
typename M>
287 template <
typename... Ts>
291 unbundleTo(args(), index, values...);
295 template <
typename D,
typename M>
296 template <
typename... Ts>
299 using More = std::integral_constant<bool,
sizeof...(Ts) != 0>;
300 return unbundleToTuple<0>(args(), tuple, More{});
320 template <
typename D,
typename M>
321 template <
typename... Ts>
325 unbundleAs(this->message().args(), index, values...);
330 template <
typename D,
typename M>
331 template <
typename... Ts>
334 using More = std::integral_constant<bool,
sizeof...(Ts) != 0>;
335 return unbundleAsTuple<0>(args(), tuple, More{});
339 template <
typename D,
typename M>
340 template <
typename... TArgs>
342 :
Base(std::forward<TArgs>(args)...)
346 template <
typename D,
typename M>
349 template <
typename D,
typename M>
350 template <
typename T,
typename... Ts>
351 void Payload<D,M>::bundle(
Array& array, T&& head, Ts&&... tail)
354 bundle(array, tail...);
358 template <
typename D,
typename M>
359 template <
typename TTuple,
int... Seq>
360 Array Payload<D,M>::bundleFromTuple(TTuple&& tuple,
361 internal::IntegerSequence<Seq...>)
367 template <
typename D,
typename M>
368 void Payload<D,M>::unbundleTo(
const Array&,
size_t&) {}
370 template <
typename D,
typename M>
371 template <
typename T,
typename... Ts>
372 void Payload<D,M>::unbundleTo(
const Array& array,
size_t& index, T& head,
375 if (index <
array.size())
379 head =
array[index].to<T>();
381 catch (
const error::Conversion& e)
383 std::ostringstream oss;
384 oss <<
"Payload element at index " << index
385 <<
" is not convertible to the target type: " << e.what();
386 throw error::Conversion(oss.str());
389 unbundleTo(array, ++index, tail...);
394 template <
typename D,
typename M>
395 template <
size_t I,
typename... Ts>
396 size_t Payload<D,M>::unbundleToTuple(
397 const Array& array, std::tuple<Ts...>& tuple, std::true_type)
399 if (I <
array.size())
404 std::get<I>(tuple) =
array[I].to<T>();
406 catch (
const error::Conversion& e)
408 std::ostringstream oss;
409 oss <<
"Payload element at index " << I
410 <<
" is not convertible to the target type: " << e.what();
411 throw error::Conversion(oss.str());
414 using More = std::integral_constant<bool, I+1 !=
sizeof...(Ts)>;
415 return unbundleToTuple<I+1, Ts...>(
array, tuple, More{});
420 template <
typename D,
typename M>
421 template <
size_t I,
typename... Ts>
422 size_t Payload<D,M>::unbundleToTuple(
423 const Array& array, std::tuple<Ts...>& tuple, std::false_type)
429 template <
typename D,
typename M>
430 void Payload<D,M>::unbundleAs(
Array&,
size_t&) {}
432 template <
typename D,
typename M>
433 template <
typename T,
typename... Ts>
434 void Payload<D,M>::unbundleAs(
Array& array,
size_t& index, T& head, Ts&... tail)
436 if (index <
array.size())
438 auto& arg =
array[index];
439 if (!arg.template is<T>())
441 std::ostringstream oss;
442 oss <<
"Payload element of type " << typeNameOf(arg)
443 <<
" at index " << index
444 <<
" is not of type: " << typeNameOf<T>();
445 throw error::Access(oss.str());
447 head = std::move(arg.as<T>());
448 unbundleAs(array, ++index, tail...);
453 template <
typename D,
typename M>
454 template <
size_t I,
typename... Ts>
455 size_t Payload<D,M>::unbundleAsTuple(
456 const Array& array, std::tuple<Ts...>& tuple, std::true_type)
458 if (I <
array.size())
461 auto& arg =
array[I];
462 if (!arg.template is<T>())
464 std::ostringstream oss;
465 oss <<
"Payload element of type " << typeNameOf(arg)
467 <<
" is not of type: " << typeNameOf<T>();
468 throw error::Access(oss.str());
470 std::get<I>(tuple) = std::move(arg.as<T>());
471 using More = std::integral_constant<bool, I+1 !=
sizeof...(Ts)>;
472 return unbundleAsTuple<I+1, Ts...>(
array, tuple, More{});
477 template <
typename D,
typename M>
478 template <
size_t I,
typename... Ts>
479 size_t Payload<D,M>::unbundleAsTuple(
480 const Array& array, std::tuple<Ts...>& tuple, std::false_type)
487 #endif // CPPWAMP_PAYLOAD_HPP