}
};
+namespace _denc {
+ template<size_t... I>
+ struct indices {};
+
+ template<size_t ...S>
+ struct build_indices_helper;
+ template<size_t N, size_t ...Is>
+ struct build_indices_helper<N, N, Is...> {
+ using type = indices<Is...>;
+ };
+ template<size_t N, size_t I, size_t ...Is>
+ struct build_indices_helper<N, I, Is...> {
+ using type = typename build_indices_helper<N, I + 1, Is..., I>::type;
+ };
+
+ template<size_t I>
+ struct build_indices {
+ using type = typename build_indices_helper<I, 1, 0>::type;
+ };
+ template<>
+ struct build_indices<0> {
+ using type = indices<>;
+ };
+ template<>
+ struct build_indices<1> {
+ using type = indices<0>;
+ };
+
+ template<size_t I>
+ using build_indices_t = typename build_indices<I>::type;
+
+ template<typename ...Ts>
+ struct tuple_traits;
+ template<typename T, typename ...Ts>
+ struct tuple_traits<T, Ts...> {
+ static constexpr bool supported = (denc_traits<T>::supported &&
+ tuple_traits<Ts...>::supported);
+ static constexpr bool bounded = (denc_traits<T>::bounded &&
+ tuple_traits<Ts...>::bounded);
+ static constexpr bool featured = (denc_traits<T>::featured ||
+ tuple_traits<Ts...>::featured);
+ };
+ template<>
+ struct tuple_traits<> {
+ static constexpr bool supported = true;
+ static constexpr bool bounded = true;
+ static constexpr bool featured = false;
+ };
+}
+
+template<typename ...Ts>
+struct denc_traits<
+ std::tuple<Ts...>,
+ typename std::enable_if<_denc::tuple_traits<Ts...>::supported != 0>::type> {
+private:
+ static_assert(sizeof...(Ts) > 0,
+ "Zero-length tuples are not supported.");
+ using container = std::tuple<Ts...>;
+
+ template<typename T, size_t I, size_t J, size_t ...Is>
+ static void bound_encode_helper_nfnb(const T& s, size_t& p,
+ _denc::indices<I, J, Is...>) {
+ denc(std::get<I>(s), p);
+ bound_encode_helper_nfnb(s, p, _denc::indices<J, Is...>{});
+ }
+ template<typename T, size_t I>
+ static void bound_encode_helper_nfnb(const T& s, size_t& p,
+ _denc::indices<I>) {
+ denc(std::get<I>(s), p);
+ }
+
+ template<typename T, size_t I, size_t J, size_t ...Is>
+ static void bound_encode_helper_nfb(const T& s, size_t& p,
+ _denc::indices<I, J, Is...>) {
+ denc(*(typename std::tuple_element<I, T>::type *)nullptr, p);
+ bound_encode_helper_nfb(s, p, _denc::indices<J, Is...>{});
+ }
+ template<typename T, size_t I>
+ static void bound_encode_helper_nfb(const T& s, size_t& p,
+ _denc::indices<I>) {
+ denc(*(typename std::tuple_element<I, T>::type *)nullptr, p);
+ }
+
+ template<typename T, size_t I, size_t J, size_t ...Is>
+ static void bound_encode_helper_fnb(const T& s, size_t& p, uint64_t f,
+ _denc::indices<I, J, Is...>) {
+ denc(std::get<I>(s), p, f);
+ bound_encode_helper_fnb(s, p, f, _denc::indices<J, Is...>{});
+ }
+ template<typename T, size_t I>
+ static void bound_encode_helper_fnb(const T& s, size_t& p, uint64_t f,
+ _denc::indices<I>) {
+ denc(std::get<I>(s), p, f);
+ }
+
+ template<typename T, size_t I, size_t J, size_t ...Is>
+ static void bound_encode_helper_fb(const T& s, size_t& p, uint64_t f,
+ _denc::indices<I, J, Is...>) {
+ denc(*(typename std::tuple_element<I, T>::type *)nullptr, p);
+ bound_encode_helper_fb(s, p, f, _denc::indices<J, Is...>{});
+ }
+ template<typename T, size_t I>
+ static void bound_encode_helper_fb(const T& s, size_t& p, uint64_t f,
+ _denc::indices<I>) {
+ denc(*(typename std::tuple_element<I, T>::type *)nullptr, p, f);
+ }
+
+ template<typename T, size_t I, size_t J, size_t ...Is>
+ static void encode_helper_nf(const T& s, buffer::list::contiguous_appender& p,
+ _denc::indices<I, J, Is...>) {
+ denc(std::get<I>(s), p);
+ encode_helper_nf(s, p, _denc::indices<J, Is...>{});
+ }
+ template<typename T, size_t I>
+ static void encode_helper_nf(const T& s, buffer::list::contiguous_appender& p,
+ _denc::indices<I>) {
+ denc(std::get<I>(s), p);
+ }
+
+ template<typename T, size_t I, size_t J, size_t ...Is>
+ static void encode_helper_f(const T& s, buffer::list::contiguous_appender& p,
+ uint64_t f, _denc::indices<I, J, Is...>) {
+ denc(std::get<I>(s), p, f);
+ encode_helper_nf(s, p, f, _denc::indices<J, Is...>{});
+ }
+ template<typename T, size_t I>
+ static void encode_helper_f(const T& s, buffer::list::contiguous_appender& p,
+ uint64_t f, _denc::indices<I>) {
+ denc(std::get<I>(s), p, f);
+ }
+
+ template<typename T, size_t I, size_t J, size_t ...Is>
+ static void decode_helper(T& s, buffer::ptr::iterator& p,
+ _denc::indices<I, J, Is...>) {
+ denc(std::get<I>(s), p);
+ decode_helper(s, p, _denc::indices<J, Is...>{});
+ }
+ template<typename T, size_t I>
+ static void decode_helper(T& s, buffer::ptr::iterator& p,
+ _denc::indices<I>) {
+ denc(std::get<I>(s), p);
+ }
+
+public:
+ using traits = _denc::tuple_traits<Ts...>;
+
+ enum { supported = true };
+ enum { featured = traits::featured };
+ enum { bounded = traits::bounded };
+
+
+ template<typename U = traits>
+ static typename std::enable_if<U::supported &&
+ !traits::bounded &&
+ !traits::featured>::type
+ bound_encode(const container& s, size_t& p) {
+ bound_encode_helper_nfnb(s, p, _denc::build_indices_t<sizeof...(Ts)>{});
+ }
+ template<typename U = traits>
+ static typename std::enable_if<U::supported &&
+ traits::bounded &&
+ !traits::featured, void>::type
+ bound_encode(const container& s, size_t& p) {
+ bound_encode_helper_nfb(s, p, _denc::build_indices_t<sizeof...(Ts)>{});
+ }
+ template<typename U = traits>
+ static typename std::enable_if<U::traits &&
+ !traits::bounded &&
+ traits::featured, void>::type
+ bound_encode(const container& s, size_t& p, uint64_t f) {
+ bound_encode_helper_fnb(s, p, _denc::build_indices_t<sizeof...(Ts)>{});
+ }
+ template<typename U = traits>
+ static typename std::enable_if<U::traits &&
+ traits::bounded &&
+ traits::featured>::type
+ bound_encode(const container& s, size_t& p, uint64_t f) {
+ bound_encode_helper_fb(s, p, _denc::build_indices_t<sizeof...(Ts)>{});
+ }
+
+ template<typename U = traits>
+ static typename std::enable_if<U::supported &&
+ !traits::featured>::type
+ encode(const container& s, buffer::list::contiguous_appender& p) {
+ encode_helper_nf(s, p, _denc::build_indices_t<sizeof...(Ts)>{});
+ }
+ template<typename U = traits>
+ static typename std::enable_if<U::supported &&
+ traits::featured>::type
+ encode(const container& s, buffer::list::contiguous_appender& p,
+ uint64_t f) {
+ encode_helper_f(s, p, f, _denc::build_indices_t<sizeof...(Ts)>{});
+ }
+
+ static void decode(container& s, buffer::ptr::iterator& p, uint64_t f = 0) {
+ decode_helper(s, p, _denc::build_indices_t<sizeof...(Ts)>{});
+ }
+};
// ----------------------------------------------------------------------
// class helpers