Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:51:19

0001 /* Copyright (c) 2018-2023 Marcelo Zimbres Silva (mzimbres@gmail.com)
0002  *
0003  * Distributed under the Boost Software License, Version 1.0. (See
0004  * accompanying file LICENSE.txt)
0005  */
0006 
0007 #ifndef BOOST_REDIS_ADAPTER_DETAIL_RESPONSE_TRAITS_HPP
0008 #define BOOST_REDIS_ADAPTER_DETAIL_RESPONSE_TRAITS_HPP
0009 
0010 #include <boost/redis/resp3/node.hpp>
0011 #include <boost/redis/response.hpp>
0012 #include <boost/redis/adapter/detail/result_traits.hpp>
0013 #include <boost/mp11.hpp>
0014 #include <boost/system.hpp>
0015 
0016 #include <tuple>
0017 #include <limits>
0018 #include <string_view>
0019 #include <variant>
0020 
0021 namespace boost::redis::adapter::detail
0022 {
0023 
0024 class ignore_adapter {
0025 public:
0026    template <class String>
0027    void operator()(std::size_t, resp3::basic_node<String> const& nd, system::error_code& ec)
0028    {
0029       switch (nd.data_type) {
0030          case resp3::type::simple_error: ec = redis::error::resp3_simple_error; break;
0031          case resp3::type::blob_error: ec = redis::error::resp3_blob_error; break;
0032          case resp3::type::null: ec = redis::error::resp3_null; break;
0033          default:;
0034       }
0035    }
0036 
0037    [[nodiscard]]
0038    auto get_supported_response_size() const noexcept
0039       { return static_cast<std::size_t>(-1);}
0040 };
0041 
0042 template <class Response>
0043 class static_adapter {
0044 private:
0045    static constexpr auto size = std::tuple_size<Response>::value;
0046    using adapter_tuple = mp11::mp_transform<adapter_t, Response>;
0047    using variant_type = mp11::mp_rename<adapter_tuple, std::variant>;
0048    using adapters_array_type = std::array<variant_type, size>;
0049 
0050    adapters_array_type adapters_;
0051 
0052 public:
0053    explicit static_adapter(Response& r)
0054    {
0055       assigner<size - 1>::assign(adapters_, r);
0056    }
0057 
0058    [[nodiscard]]
0059    auto get_supported_response_size() const noexcept
0060       { return size;}
0061 
0062    template <class String>
0063    void operator()(std::size_t i, resp3::basic_node<String> const& nd, system::error_code& ec)
0064    {
0065       using std::visit;
0066       // I am usure whether this should be an error or an assertion.
0067       BOOST_ASSERT(i < adapters_.size());
0068       visit([&](auto& arg){arg(nd, ec);}, adapters_.at(i));
0069    }
0070 };
0071 
0072 template <class Vector>
0073 class vector_adapter {
0074 private:
0075    using adapter_type = typename result_traits<Vector>::adapter_type;
0076    adapter_type adapter_;
0077 
0078 public:
0079    explicit vector_adapter(Vector& v)
0080    : adapter_{internal_adapt(v)}
0081    { }
0082 
0083    [[nodiscard]]
0084    auto
0085    get_supported_response_size() const noexcept
0086       { return static_cast<std::size_t>(-1);}
0087 
0088    template <class String>
0089    void operator()(std::size_t, resp3::basic_node<String> const& nd, system::error_code& ec)
0090    {
0091       adapter_(nd, ec);
0092    }
0093 };
0094 
0095 template <class>
0096 struct response_traits;
0097 
0098 template <>
0099 struct response_traits<ignore_t> {
0100    using response_type = ignore_t;
0101    using adapter_type = detail::ignore_adapter;
0102 
0103    static auto adapt(response_type&) noexcept
0104       { return detail::ignore_adapter{}; }
0105 };
0106 
0107 template <>
0108 struct response_traits<result<ignore_t>> {
0109    using response_type = result<ignore_t>;
0110    using adapter_type = detail::ignore_adapter;
0111 
0112    static auto adapt(response_type&) noexcept
0113       { return detail::ignore_adapter{}; }
0114 };
0115 
0116 template <class String, class Allocator>
0117 struct response_traits<result<std::vector<resp3::basic_node<String>, Allocator>>> {
0118    using response_type = result<std::vector<resp3::basic_node<String>, Allocator>>;
0119    using adapter_type = vector_adapter<response_type>;
0120 
0121    static auto adapt(response_type& v) noexcept
0122       { return adapter_type{v}; }
0123 };
0124 
0125 template <class ...Ts>
0126 struct response_traits<response<Ts...>> {
0127    using response_type = response<Ts...>;
0128    using adapter_type = static_adapter<response_type>;
0129 
0130    static auto adapt(response_type& r) noexcept
0131       { return adapter_type{r}; }
0132 };
0133 
0134 template <class Adapter>
0135 class wrapper {
0136 public:
0137    explicit wrapper(Adapter adapter) : adapter_{adapter} {}
0138 
0139    template <class String>
0140    void operator()(resp3::basic_node<String> const& nd, system::error_code& ec)
0141       { return adapter_(0, nd, ec); }
0142 
0143    [[nodiscard]]
0144    auto get_supported_response_size() const noexcept
0145       { return adapter_.get_supported_response_size();}
0146 
0147 private:
0148    Adapter adapter_;
0149 };
0150 
0151 template <class Adapter>
0152 auto make_adapter_wrapper(Adapter adapter)
0153 {
0154    return wrapper{adapter};
0155 }
0156 
0157 } // boost::redis::adapter::detail
0158 
0159 #endif // BOOST_REDIS_ADAPTER_DETAIL_RESPONSE_TRAITS_HPP