Line data Source code
1 : //
2 : // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/boostorg/url
8 : //
9 :
10 : #ifndef BOOST_URL_GRAMMAR_IMPL_VARIANT_RULE_HPP
11 : #define BOOST_URL_GRAMMAR_IMPL_VARIANT_RULE_HPP
12 :
13 : #include <boost/url/grammar/error.hpp>
14 : #include <boost/url/grammar/parse.hpp>
15 : #include <boost/static_assert.hpp>
16 : #include <cstdint>
17 : #include <type_traits>
18 :
19 : namespace boost {
20 : namespace urls {
21 : namespace grammar {
22 :
23 : namespace detail {
24 :
25 : // must come first
26 : template<
27 : class R0,
28 : class... Rn,
29 : std::size_t I>
30 : auto
31 733 : parse_variant(
32 : char const*&,
33 : char const*,
34 : detail::tuple<
35 : R0, Rn...> const&,
36 : std::integral_constant<
37 : std::size_t, I> const&,
38 : std::false_type const&) ->
39 : system::result<variant2::variant<
40 : typename R0::value_type,
41 : typename Rn::value_type...>>
42 : {
43 : // no match
44 733 : BOOST_URL_RETURN_EC(
45 : error::mismatch);
46 : }
47 :
48 : template<
49 : class R0,
50 : class... Rn,
51 : std::size_t I>
52 : auto
53 5665 : parse_variant(
54 : char const*& it,
55 : char const* const end,
56 : detail::tuple<
57 : R0, Rn...> const& rn,
58 : std::integral_constant<
59 : std::size_t, I> const&,
60 : std::true_type const&) ->
61 : system::result<variant2::variant<
62 : typename R0::value_type,
63 : typename Rn::value_type...>>
64 : {
65 5665 : auto const it0 = it;
66 5665 : auto rv = parse(
67 : it, end, get<I>(rn));
68 5665 : if( rv )
69 : return variant2::variant<
70 : typename R0::value_type,
71 : typename Rn::value_type...>{
72 2955 : variant2::in_place_index_t<I>{}, *rv};
73 2710 : it = it0;
74 1282 : return parse_variant(
75 : it, end, rn,
76 : std::integral_constant<
77 : std::size_t, I+1>{},
78 : std::integral_constant<bool,
79 : ((I + 1) < (1 +
80 2710 : sizeof...(Rn)))>{});
81 432 : }
82 :
83 : } // detail
84 :
85 : template<class R0, class... Rn>
86 : auto
87 3688 : implementation_defined::variant_rule_t<R0, Rn...>::
88 : parse(
89 : char const*& it,
90 : char const* end) const ->
91 : system::result<value_type>
92 : {
93 724 : return detail::parse_variant(
94 3688 : it, end, rn_,
95 : std::integral_constant<
96 : std::size_t, 0>{},
97 4412 : std::true_type{});
98 : }
99 :
100 : //------------------------------------------------
101 :
102 : template<BOOST_URL_CONSTRAINT(Rule) R0, BOOST_URL_CONSTRAINT(Rule)... Rn>
103 : auto
104 : constexpr
105 2497 : variant_rule(
106 : R0 const& r0,
107 : Rn const&... rn) noexcept ->
108 : implementation_defined::variant_rule_t<R0, Rn...>
109 : {
110 : BOOST_STATIC_ASSERT(
111 : mp11::mp_all<
112 : is_rule<R0>,
113 : is_rule<Rn>...>::value);
114 2497 : return { r0, rn... };
115 : }
116 :
117 : } // grammar
118 : } // urls
119 : } // boost
120 :
121 : #endif
|