1  
//
1  
//
2  
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
2  
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
 
3 +
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
3  
//
4  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// 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  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
7  
//
7  
// Official repository: https://github.com/boostorg/url
8  
// Official repository: https://github.com/boostorg/url
8  
//
9  
//
9  

10  

10  
#ifndef BOOST_URL_GRAMMAR_IMPL_VARIANT_RULE_HPP
11  
#ifndef BOOST_URL_GRAMMAR_IMPL_VARIANT_RULE_HPP
11  
#define BOOST_URL_GRAMMAR_IMPL_VARIANT_RULE_HPP
12  
#define BOOST_URL_GRAMMAR_IMPL_VARIANT_RULE_HPP
12  

13  

13  
#include <boost/url/grammar/error.hpp>
14  
#include <boost/url/grammar/error.hpp>
14  
#include <boost/url/grammar/parse.hpp>
15  
#include <boost/url/grammar/parse.hpp>
15  
#include <boost/core/detail/static_assert.hpp>
16  
#include <boost/core/detail/static_assert.hpp>
16  
#include <cstdint>
17  
#include <cstdint>
17  
#include <type_traits>
18  
#include <type_traits>
18  

19  

19  
namespace boost {
20  
namespace boost {
20  
namespace urls {
21  
namespace urls {
21  
namespace grammar {
22  
namespace grammar {
22  

23  

23  
namespace detail {
24  
namespace detail {
24  

25  

25  
// must come first
26  
// must come first
26  
template<
27  
template<
27  
    class R0,
28  
    class R0,
28  
    class... Rn,
29  
    class... Rn,
29  
    std::size_t I>
30  
    std::size_t I>
 
31 +
BOOST_URL_CXX14_CONSTEXPR
30  
auto
32  
auto
31  
parse_variant(
33  
parse_variant(
32  
    char const*&,
34  
    char const*&,
33  
    char const*,
35  
    char const*,
34  
    detail::tuple<
36  
    detail::tuple<
35  
        R0, Rn...> const&,
37  
        R0, Rn...> const&,
36  
    std::integral_constant<
38  
    std::integral_constant<
37  
        std::size_t, I> const&,
39  
        std::size_t, I> const&,
38  
    std::false_type const&) ->
40  
    std::false_type const&) ->
39  
        system::result<variant2::variant<
41  
        system::result<variant2::variant<
40  
            typename R0::value_type,
42  
            typename R0::value_type,
41  
            typename Rn::value_type...>>
43  
            typename Rn::value_type...>>
42  
{
44  
{
43  
    // no match
45  
    // no match
44 -
    BOOST_URL_RETURN_EC(
46 +
    BOOST_URL_CONSTEXPR_RETURN_EC(
45  
        error::mismatch);
47  
        error::mismatch);
46  
}
48  
}
47  

49  

48  
template<
50  
template<
49  
    class R0,
51  
    class R0,
50  
    class... Rn,
52  
    class... Rn,
51  
    std::size_t I>
53  
    std::size_t I>
 
54 +
BOOST_URL_CXX14_CONSTEXPR
52  
auto
55  
auto
53  
parse_variant(
56  
parse_variant(
54  
    char const*& it,
57  
    char const*& it,
55  
    char const* const end,
58  
    char const* const end,
56  
    detail::tuple<
59  
    detail::tuple<
57  
        R0, Rn...> const& rn,
60  
        R0, Rn...> const& rn,
58  
    std::integral_constant<
61  
    std::integral_constant<
59  
        std::size_t, I> const&,
62  
        std::size_t, I> const&,
60  
    std::true_type const&) ->
63  
    std::true_type const&) ->
61  
        system::result<variant2::variant<
64  
        system::result<variant2::variant<
62  
            typename R0::value_type,
65  
            typename R0::value_type,
63  
            typename Rn::value_type...>>
66  
            typename Rn::value_type...>>
64  
{
67  
{
65  
    auto const it0 = it;
68  
    auto const it0 = it;
66  
    auto rv = parse(
69  
    auto rv = parse(
67  
        it, end, get<I>(rn));
70  
        it, end, get<I>(rn));
68  
    if( rv )
71  
    if( rv )
69  
        return variant2::variant<
72  
        return variant2::variant<
70  
            typename R0::value_type,
73  
            typename R0::value_type,
71  
            typename Rn::value_type...>{
74  
            typename Rn::value_type...>{
72  
                variant2::in_place_index_t<I>{}, *rv};
75  
                variant2::in_place_index_t<I>{}, *rv};
73  
    it = it0;
76  
    it = it0;
74  
    return parse_variant(
77  
    return parse_variant(
75  
        it, end, rn,
78  
        it, end, rn,
76  
        std::integral_constant<
79  
        std::integral_constant<
77  
            std::size_t, I+1>{},
80  
            std::size_t, I+1>{},
78  
        std::integral_constant<bool,
81  
        std::integral_constant<bool,
79  
            ((I + 1) < (1 +
82  
            ((I + 1) < (1 +
80  
                sizeof...(Rn)))>{});
83  
                sizeof...(Rn)))>{});
81  
}
84  
}
82  

85  

83  
} // detail
86  
} // detail
84  

87  

85  
template<class R0, class... Rn>
88  
template<class R0, class... Rn>
 
89 +
BOOST_URL_CXX14_CONSTEXPR
86  
auto
90  
auto
87  
implementation_defined::variant_rule_t<R0, Rn...>::
91  
implementation_defined::variant_rule_t<R0, Rn...>::
88  
parse(
92  
parse(
89  
    char const*& it,
93  
    char const*& it,
90  
    char const* end) const ->
94  
    char const* end) const ->
91  
        system::result<value_type>
95  
        system::result<value_type>
92  
{
96  
{
93  
    return detail::parse_variant(
97  
    return detail::parse_variant(
94  
        it, end, rn_,
98  
        it, end, rn_,
95  
        std::integral_constant<
99  
        std::integral_constant<
96  
            std::size_t, 0>{},
100  
            std::size_t, 0>{},
97  
        std::true_type{});
101  
        std::true_type{});
98  
}
102  
}
99  

103  

100  
//------------------------------------------------
104  
//------------------------------------------------
101  

105  

102  
template<BOOST_URL_CONSTRAINT(Rule) R0, BOOST_URL_CONSTRAINT(Rule)... Rn>
106  
template<BOOST_URL_CONSTRAINT(Rule) R0, BOOST_URL_CONSTRAINT(Rule)... Rn>
103  
auto
107  
auto
104  
constexpr
108  
constexpr
105  
variant_rule(
109  
variant_rule(
106  
    R0 const& r0,
110  
    R0 const& r0,
107  
    Rn const&... rn) noexcept ->
111  
    Rn const&... rn) noexcept ->
108  
        implementation_defined::variant_rule_t<R0, Rn...>
112  
        implementation_defined::variant_rule_t<R0, Rn...>
109  
{
113  
{
110  
    BOOST_CORE_STATIC_ASSERT(
114  
    BOOST_CORE_STATIC_ASSERT(
111  
        mp11::mp_all<
115  
        mp11::mp_all<
112  
            is_rule<R0>,
116  
            is_rule<R0>,
113  
            is_rule<Rn>...>::value);
117  
            is_rule<Rn>...>::value);
114  
    return { r0, rn... };
118  
    return { r0, rn... };
115  
}
119  
}
116  

120  

117  
} // grammar
121  
} // grammar
118  
} // urls
122  
} // urls
119  
} // boost
123  
} // boost
120  

124  

121  
#endif
125  
#endif