variant_rule.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. result< variant< url_view, url_view, authority_view, 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. @ref variant.
  59. */
  60. #ifdef BOOST_URL_DOCS
  61. template<class... Rules>
  62. constexpr
  63. __implementation_defined__
  64. variant_rule( Rules... rn ) noexcept;
  65. #else
  66. template<
  67. class R0, class... Rn>
  68. class variant_rule_t
  69. {
  70. public:
  71. using value_type = variant<
  72. typename R0::value_type,
  73. typename Rn::value_type...>;
  74. auto
  75. parse(
  76. char const*& it,
  77. char const* end) const ->
  78. result<value_type>;
  79. template<
  80. class R0_,
  81. class... Rn_>
  82. friend
  83. constexpr
  84. auto
  85. variant_rule(
  86. R0_ const& r0,
  87. Rn_ const&... rn) noexcept ->
  88. variant_rule_t<R0_, Rn_...>;
  89. private:
  90. constexpr
  91. variant_rule_t(
  92. R0 const& r0,
  93. Rn const&... rn) noexcept
  94. : rn_(r0, rn...)
  95. {
  96. }
  97. detail::tuple<R0, Rn...> rn_;
  98. };
  99. template<
  100. class R0,
  101. class... Rn>
  102. constexpr
  103. auto
  104. variant_rule(
  105. R0 const& r0,
  106. Rn const&... rn) noexcept ->
  107. variant_rule_t<R0, Rn...>;
  108. #endif
  109. } // grammar
  110. } // urls
  111. } // boost
  112. #include <boost/url/grammar/impl/variant_rule.hpp>
  113. #endif