variant_rule.hpp 3.0 KB

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