Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:27

0001 //
0002 // Copyright (c) 2022 Vinnie Falco (vinnie dot falco at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/url
0008 //
0009 
0010 #ifndef BOOST_URL_GRAMMAR_IMPL_TUPLE_RULE_HPP
0011 #define BOOST_URL_GRAMMAR_IMPL_TUPLE_RULE_HPP
0012 
0013 #include <boost/url/grammar/parse.hpp>
0014 #include <boost/mp11/integral.hpp>
0015 #include <boost/mp11/list.hpp>
0016 #include <boost/mp11/tuple.hpp>
0017 #include <type_traits>
0018 
0019 namespace boost {
0020 namespace urls {
0021 namespace grammar {
0022 
0023 namespace detail {
0024 
0025 // returns a tuple
0026 template<
0027     bool IsList,
0028     class R0, class... Rn>
0029 struct parse_sequence
0030 {
0031     using R = detail::tuple<R0, Rn...>;
0032 
0033     using L = mp11::mp_list<
0034         typename R0::value_type,
0035         typename Rn::value_type...>;
0036 
0037     using V = mp11::mp_remove<
0038         std::tuple<
0039             system::result<typename R0::value_type>,
0040             system::result<typename Rn::value_type>...>,
0041         system::result<void>>;
0042 
0043     template<std::size_t I>
0044     using is_void = std::is_same<
0045         mp11::mp_at_c<L, I>, void>;
0046 
0047     system::error_code ec;
0048     R const& rn;
0049     V vn;
0050 
0051     explicit
0052     parse_sequence(
0053         R const& rn_) noexcept
0054         : rn(rn_)
0055         , vn(mp11::mp_fill<
0056             V, system::error_code>{})
0057     {
0058     }
0059 
0060     void
0061     apply(
0062         char const*&,
0063         char const*,
0064         ...) const noexcept
0065     {
0066     }
0067 
0068     // for system::result<void>
0069     template<
0070         std::size_t Ir,
0071         std::size_t Iv>
0072     void
0073     apply(
0074         char const*& it,
0075         char const* end,
0076         mp11::mp_size_t<Ir> const&,
0077         mp11::mp_size_t<Iv> const&,
0078         mp11::mp_true const&)
0079     {
0080         system::result<void> rv =
0081             grammar::parse(
0082                 it, end, get<Ir>(rn));
0083         if( !rv )
0084         {
0085             ec = rv.error();
0086             return;
0087         }
0088         apply(it, end,
0089             mp11::mp_size_t<Ir+1>{},
0090             mp11::mp_size_t<Iv>{});
0091     }
0092 
0093     template<
0094         std::size_t Ir,
0095         std::size_t Iv>
0096     void
0097     apply(
0098         char const*& it,
0099         char const* end,
0100         mp11::mp_size_t<Ir> const&,
0101         mp11::mp_size_t<Iv> const&,
0102         mp11::mp_false const&)
0103     {
0104         auto& rv = get<Iv>(vn);
0105         rv = grammar::parse(
0106             it, end, get<Ir>(rn));
0107         if( !rv )
0108         {
0109             ec = rv.error();
0110             return;
0111         }
0112         apply(it, end,
0113             mp11::mp_size_t<Ir+1>{},
0114             mp11::mp_size_t<Iv+1>{});
0115     }
0116 
0117     template<
0118         std::size_t Ir = 0,
0119         std::size_t Iv = 0>
0120     typename std::enable_if<
0121         Ir < 1 + sizeof...(Rn)>::type
0122     apply(
0123         char const*& it,
0124         char const* end,
0125         mp11::mp_size_t<Ir> const& ir = {},
0126         mp11::mp_size_t<Iv> const& iv = {}
0127             ) noexcept
0128     {
0129         apply(it, end, ir, iv, is_void<Ir>{});
0130     }
0131 
0132     struct deref
0133     {
0134         template<class R>
0135         auto
0136         operator()(R const& r) const ->
0137             decltype(*r)
0138         {
0139             return *r;
0140         }
0141     };
0142 
0143     auto
0144     make_result() noexcept ->
0145         system::result<typename tuple_rule_t<
0146             R0, Rn...>::value_type>
0147     {
0148         if(ec.failed())
0149             return ec;
0150         return mp11::tuple_transform(
0151             deref{}, vn);
0152     }
0153 };
0154 
0155 // returns a value_type
0156 template<class R0, class... Rn>
0157 struct parse_sequence<false, R0, Rn...>
0158 {
0159     using R = detail::tuple<R0, Rn...>;
0160 
0161     using L = mp11::mp_list<
0162         typename R0::value_type,
0163         typename Rn::value_type...>;
0164 
0165     using V = mp11::mp_first<
0166         mp11::mp_remove<
0167             mp11::mp_list<
0168                 system::result<typename R0::value_type>,
0169                 system::result<typename Rn::value_type>...>,
0170             system::result<void>>>;
0171 
0172     template<std::size_t I>
0173     using is_void = std::is_same<
0174         mp11::mp_at_c<L, I>, void>;
0175 
0176     R const& rn;
0177     V v;
0178 
0179     explicit
0180     parse_sequence(
0181         R const& rn_) noexcept
0182         : rn(rn_)
0183         , v(system::error_code{})
0184     {
0185     }
0186 
0187     void
0188     apply(
0189         char const*&,
0190         char const*,
0191         ...) const noexcept
0192     {
0193     }
0194 
0195     // for system::result<void>
0196     template<
0197         std::size_t Ir,
0198         std::size_t Iv>
0199     BOOST_URL_NO_INLINE
0200     void
0201     apply(
0202         char const*& it,
0203         char const* end,
0204         mp11::mp_size_t<Ir> const&,
0205         mp11::mp_size_t<Iv> const&,
0206         mp11::mp_true const&)
0207     {
0208         system::result<void> rv =
0209             grammar::parse(
0210                 it, end, get<Ir>(rn));
0211         if( !rv )
0212         {
0213             v = rv.error();
0214             return;
0215         }
0216         apply(it, end,
0217             mp11::mp_size_t<Ir+1>{},
0218             mp11::mp_size_t<Iv>{});
0219     }
0220 
0221     template<
0222         std::size_t Ir,
0223         std::size_t Iv>
0224     void
0225     apply(
0226         char const*& it,
0227         char const* end,
0228         mp11::mp_size_t<Ir> const&,
0229         mp11::mp_size_t<Iv> const&,
0230         mp11::mp_false const&)
0231     {
0232         v = grammar::parse(
0233             it, end, get<Ir>(rn));
0234         if( !v )
0235             return;
0236         apply(it, end,
0237             mp11::mp_size_t<Ir+1>{},
0238             mp11::mp_size_t<Iv+1>{});
0239     }
0240 
0241     template<
0242         std::size_t Ir = 0,
0243         std::size_t Iv = 0>
0244     typename std::enable_if<
0245         Ir < 1 + sizeof...(Rn)>::type
0246     apply(
0247         char const*& it,
0248         char const* end,
0249         mp11::mp_size_t<Ir> const& ir = {},
0250         mp11::mp_size_t<Iv> const& iv = {}
0251             ) noexcept
0252     {
0253         apply(it, end, ir, iv, is_void<Ir>{});
0254     }
0255 
0256     V
0257     make_result() noexcept
0258     {
0259         return v;
0260     }
0261 };
0262 
0263 } // detail
0264 
0265 template<
0266     class R0,
0267     class... Rn>
0268 auto
0269 tuple_rule_t<R0, Rn...>::
0270 parse(
0271     char const*& it,
0272     char const* end) const ->
0273         system::result<value_type>
0274 {
0275     detail::parse_sequence<
0276         IsList, R0, Rn...> t(this->get());
0277     t.apply(it, end);
0278     return t.make_result();
0279 }
0280 
0281 } // grammar
0282 } // urls
0283 } // boost
0284 
0285 #endif