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 <cstdint>
16 : #include <type_traits>
17 :
18 : namespace boost {
19 : namespace urls {
20 : namespace grammar {
21 :
22 : namespace detail {
23 :
24 : // must come first
25 : template<
26 : class R0,
27 : class... Rn,
28 : std::size_t I>
29 : auto
30 734 : parse_variant(
31 : char const*&,
32 : char const*,
33 : detail::tuple<
34 : R0, Rn...> const&,
35 : std::integral_constant<
36 : std::size_t, I> const&,
37 : std::false_type const&) ->
38 : system::result<variant<
39 : typename R0::value_type,
40 : typename Rn::value_type...>>
41 : {
42 : // no match
43 734 : BOOST_URL_RETURN_EC(
44 : error::mismatch);
45 : }
46 :
47 : template<
48 : class R0,
49 : class... Rn,
50 : std::size_t I>
51 : auto
52 5663 : parse_variant(
53 : char const*& it,
54 : char const* const end,
55 : detail::tuple<
56 : R0, Rn...> const& rn,
57 : std::integral_constant<
58 : std::size_t, I> const&,
59 : std::true_type const&) ->
60 : system::result<variant<
61 : typename R0::value_type,
62 : typename Rn::value_type...>>
63 : {
64 5663 : auto const it0 = it;
65 5663 : auto rv = parse(
66 : it, end, get<I>(rn));
67 5663 : if( rv )
68 : return variant<
69 : typename R0::value_type,
70 : typename Rn::value_type...>{
71 2952 : variant2::in_place_index_t<I>{}, *rv};
72 2711 : it = it0;
73 1282 : return parse_variant(
74 : it, end, rn,
75 : std::integral_constant<
76 : std::size_t, I+1>{},
77 : std::integral_constant<bool,
78 : ((I + 1) < (1 +
79 2711 : sizeof...(Rn)))>{});
80 432 : }
81 :
82 : } // detail
83 :
84 : template<class R0, class... Rn>
85 : auto
86 3686 : variant_rule_t<R0, Rn...>::
87 : parse(
88 : char const*& it,
89 : char const* end) const ->
90 : system::result<value_type>
91 : {
92 724 : return detail::parse_variant(
93 3686 : it, end, rn_,
94 : std::integral_constant<
95 : std::size_t, 0>{},
96 4410 : std::true_type{});
97 : }
98 :
99 : //------------------------------------------------
100 :
101 : template<class R0, class... Rn>
102 : auto
103 : constexpr
104 2495 : variant_rule(
105 : R0 const& r0,
106 : Rn const&... rn) noexcept ->
107 : variant_rule_t<R0, Rn...>
108 : {
109 2495 : return { r0, rn... };
110 : }
111 :
112 : } // grammar
113 : } // urls
114 : } // boost
115 :
116 : #endif
|