7#ifndef BOOST_REDIS_ADAPTER_RESPONSE_TRAITS_HPP
8#define BOOST_REDIS_ADAPTER_RESPONSE_TRAITS_HPP
10#include <boost/redis/error.hpp>
11#include <boost/redis/resp3/type.hpp>
12#include <boost/redis/ignore.hpp>
13#include <boost/redis/adapter/detail/adapters.hpp>
14#include <boost/redis/adapter/result.hpp>
15#include <boost/redis/adapter/ignore.hpp>
16#include <boost/mp11.hpp>
23namespace 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
70 {
return result_traits<std::decay_t<T>>::adapt(t); }
72template <std::
size_t N>
74 template <
class T1,
class T2>
75 static void assign(T1& dest, T2& from)
77 dest[N].template emplace<N>(internal_adapt(std::get<N>(from)));
78 assigner<N - 1>::assign(dest, from);
84 template <
class T1,
class T2>
85 static void assign(T1& dest, T2& from)
87 dest[0].template emplace<0>(internal_adapt(std::get<0>(from)));
92class static_aggregate_adapter;
95class static_aggregate_adapter<
result<Tuple>> {
97 using adapters_array_type =
103 std::tuple_size<Tuple>::value>;
109 std::size_t aggregate_size_ = 0;
111 adapters_array_type adapters_;
115 explicit static_aggregate_adapter(
result<Tuple>* r =
nullptr)
119 detail::assigner<std::tuple_size<Tuple>::value - 1>::assign(adapters_, r->value());
123 template <
class String>
124 void count(resp3::basic_node<String>
const& elem)
126 if (elem.depth == 1 && is_aggregate(elem.data_type)) {
127 aggregate_size_ = element_multiplicity(elem.data_type) * elem.aggregate_size;
130 if (aggregate_size_ == 0) {
133 aggregate_size_ -= 1;
137 template <
class String>
138 void operator()(resp3::basic_node<String>
const& elem, system::error_code& ec)
142 if (elem.depth == 0) {
143 auto const multiplicity = element_multiplicity(elem.data_type);
144 auto const real_aggr_size = elem.aggregate_size * multiplicity;
145 if (real_aggr_size != std::tuple_size<Tuple>::value)
151 visit([&](
auto& arg){arg(elem, ec);}, adapters_[i_]);
156template <
class... Ts>
157struct result_traits<
result<std::tuple<Ts...>>>
159 using response_type =
result<std::tuple<Ts...>>;
160 using adapter_type = static_aggregate_adapter<response_type>;
161 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.