7#ifndef BOOST_REDIS_ADAPTER_RESPONSE_TRAITS_HPP
8#define BOOST_REDIS_ADAPTER_RESPONSE_TRAITS_HPP
10#include <boost/redis/adapter/detail/adapters.hpp>
11#include <boost/redis/adapter/ignore.hpp>
12#include <boost/redis/adapter/result.hpp>
13#include <boost/redis/error.hpp>
14#include <boost/redis/ignore.hpp>
15#include <boost/redis/resp3/type.hpp>
17#include <boost/mp11.hpp>
24namespace boost::redis::adapter::detail {
31template <
class Result>
33 using adapter_type = wrapper<typename std::decay<Result>::type>;
34 static auto adapt(Result& r)
noexcept {
return adapter_type{&r}; }
40 using adapter_type =
ignore;
41 static auto adapt(response_type)
noexcept {
return adapter_type{}; }
47 using adapter_type =
ignore;
48 static auto adapt(response_type)
noexcept {
return adapter_type{}; }
52struct result_traits<
result<resp3::basic_node<T>>> {
54 using adapter_type = adapter::detail::general_simple<response_type>;
55 static auto adapt(response_type& v)
noexcept {
return adapter_type{&v}; }
58template <
class String,
class Allocator>
59struct result_traits<
result<std::vector<resp3::basic_node<String>, Allocator>>> {
61 using adapter_type = adapter::detail::general_aggregate<response_type>;
62 static auto adapt(response_type& v)
noexcept {
return adapter_type{&v}; }
66using adapter_t =
typename result_traits<std::decay_t<T>>::adapter_type;
69auto internal_adapt(T& t)
noexcept
71 return result_traits<std::decay_t<T>>::adapt(t);
74template <std::
size_t N>
76 template <
class T1,
class T2>
77 static void assign(T1& dest, T2& from)
79 dest[N].template emplace<N>(internal_adapt(std::get<N>(from)));
80 assigner<N - 1>::assign(dest, from);
86 template <
class T1,
class T2>
87 static void assign(T1& dest, T2& from)
89 dest[0].template emplace<0>(internal_adapt(std::get<0>(from)));
94class static_aggregate_adapter;
97class static_aggregate_adapter<
result<Tuple>> {
99 using adapters_array_type = std::array<
100 mp11::mp_rename<mp11::mp_transform<adapter_t, Tuple>, std::variant>,
101 std::tuple_size<Tuple>::value>;
107 std::size_t aggregate_size_ = 0;
109 adapters_array_type adapters_;
113 explicit static_aggregate_adapter(
result<Tuple>* r =
nullptr)
117 detail::assigner<std::tuple_size<Tuple>::value - 1>::assign(adapters_, r->value());
121 template <
class String>
122 void count(resp3::basic_node<String>
const& elem)
124 if (elem.depth == 1 && is_aggregate(elem.data_type)) {
125 aggregate_size_ = element_multiplicity(elem.data_type) * elem.aggregate_size;
128 if (aggregate_size_ == 0) {
131 aggregate_size_ -= 1;
135 template <
class String>
136 void operator()(resp3::basic_node<String>
const& elem, system::error_code& ec)
140 if (elem.depth == 0) {
141 auto const multiplicity = element_multiplicity(elem.data_type);
142 auto const real_aggr_size = elem.aggregate_size * multiplicity;
143 if (real_aggr_size != std::tuple_size<Tuple>::value)
158template <
class... Ts>
159struct result_traits<
result<std::tuple<Ts...>>> {
160 using response_type =
result<std::tuple<Ts...>>;
161 using adapter_type = static_aggregate_adapter<response_type>;
162 static auto adapt(response_type& r)
noexcept {
return adapter_type{&r}; }
ignore_t ignore
Global ignore object.
system::result< Value, error > result
Stores response to individual Redis commands.
std::decay_t< decltype(std::ignore)> ignore_t
Type used to ignore responses.
@ incompatible_size
Aggregate container has incompatible size.