variant_rule.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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. #ifndef BOOST_URL_GRAMMAR_VARIANT_RULE_HPP
  10. #define BOOST_URL_GRAMMAR_VARIANT_RULE_HPP
  11. #include <boost/url/detail/config.hpp>
  12. #include <boost/url/error_types.hpp>
  13. #include <boost/url/variant.hpp>
  14. #include <boost/url/grammar/detail/tuple.hpp>
  15. #include <boost/url/grammar/type_traits.hpp>
  16. namespace boost {
  17. namespace urls {
  18. namespace grammar {
  19. namespace implementation_defined {
  20. template<
  21. class R0, class... Rn>
  22. class variant_rule_t
  23. {
  24. public:
  25. using value_type = variant2::variant<
  26. typename R0::value_type,
  27. typename Rn::value_type...>;
  28. auto
  29. parse(
  30. char const*& it,
  31. char const* end) const ->
  32. system::result<value_type>;
  33. constexpr
  34. variant_rule_t(
  35. R0 const& r0,
  36. Rn const&... rn) noexcept
  37. : rn_(r0, rn...)
  38. {
  39. }
  40. private:
  41. detail::tuple<R0, Rn...> rn_;
  42. };
  43. } // implementation_defined
  44. /** Match one of a set of rules
  45. Each specified rule is tried in sequence.
  46. When the first match occurs, the result
  47. is stored and returned in the variant. If
  48. no match occurs, an error is returned.
  49. @param r0 The first rule to match
  50. @param rn A list of one or more rules to match
  51. @return The variant rule
  52. @par Value Type
  53. @code
  54. using value_type = variant< typename Rules::value_type... >;
  55. @endcode
  56. @par Example
  57. Rules are used with the function @ref parse.
  58. @code
  59. // request-target = origin-form
  60. // / absolute-form
  61. // / authority-form
  62. // / asterisk-form
  63. system::result< variant< url_view, url_view, authority_view, core::string_view > > rv = grammar::parse(
  64. "/index.html?width=full",
  65. variant_rule(
  66. origin_form_rule,
  67. absolute_uri_rule,
  68. authority_rule,
  69. delim_rule('*') ) );
  70. @endcode
  71. @par BNF
  72. @code
  73. variant = rule1 / rule2 / rule3...
  74. @endcode
  75. @par Specification
  76. @li <a href="https://datatracker.ietf.org/doc/html/rfc5234#section-3.2"
  77. >3.2. Alternatives (rfc5234)</a>
  78. @li <a href="https://datatracker.ietf.org/doc/html/rfc7230#section-5.3"
  79. >5.3. Request Target (rfc7230)</a>
  80. @see
  81. @ref absolute_uri_rule,
  82. @ref authority_rule,
  83. @ref delim_rule,
  84. @ref parse,
  85. @ref origin_form_rule,
  86. @ref url_view.
  87. */
  88. template<
  89. BOOST_URL_CONSTRAINT(Rule) R0,
  90. BOOST_URL_CONSTRAINT(Rule)... Rn>
  91. constexpr
  92. auto
  93. variant_rule(
  94. R0 const& r0,
  95. Rn const&... rn) noexcept ->
  96. implementation_defined::variant_rule_t<R0, Rn...>;
  97. } // grammar
  98. } // urls
  99. } // boost
  100. #include <boost/url/grammar/impl/variant_rule.hpp>
  101. #endif