tuple_rule.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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_TUPLE_RULE_HPP
  10. #define BOOST_URL_GRAMMAR_TUPLE_RULE_HPP
  11. #include <boost/url/detail/config.hpp>
  12. #include <boost/url/error_types.hpp>
  13. #include <boost/url/grammar/error.hpp>
  14. #include <boost/url/grammar/detail/tuple.hpp>
  15. #include <boost/mp11/algorithm.hpp>
  16. #include <boost/core/empty_value.hpp>
  17. #include <tuple>
  18. namespace boost {
  19. namespace urls {
  20. namespace grammar {
  21. /** Match a series of rules in order
  22. This matches a series of rules in the
  23. order specified. Upon success the input
  24. is adjusted to point to the first
  25. unconsumed character. There is no
  26. implicit specification of linear white
  27. space between each rule.
  28. @par Value Type
  29. @code
  30. using value_type = __see_below__;
  31. @endcode
  32. The sequence rule usually returns a
  33. `std::tuple` containing the the `value_type`
  34. of each corresponding rule in the sequence,
  35. except that `void` values are removed.
  36. However, if there is exactly one non-void
  37. value type `T`, then the sequence rule
  38. returns `system::result<T>` instead of
  39. `system::result<tuple<...>>`.
  40. @par Example
  41. Rules are used with the function @ref parse.
  42. @code
  43. system::result< std::tuple< unsigned char, unsigned char, unsigned char, unsigned char > > rv =
  44. parse( "192.168.0.1",
  45. tuple_rule(
  46. dec_octet_rule,
  47. squelch( delim_rule('.') ),
  48. dec_octet_rule,
  49. squelch( delim_rule('.') ),
  50. dec_octet_rule,
  51. squelch( delim_rule('.') ),
  52. dec_octet_rule ) );
  53. @endcode
  54. @par BNF
  55. @code
  56. sequence = rule1 rule2 rule3...
  57. @endcode
  58. @par Specification
  59. @li <a href="https://datatracker.ietf.org/doc/html/rfc5234#section-3.1"
  60. >3.1. Concatenation (rfc5234)</a>
  61. @param rn A list of one or more rules to match
  62. @see
  63. @ref dec_octet_rule,
  64. @ref delim_rule,
  65. @ref parse,
  66. @ref squelch.
  67. */
  68. #ifdef BOOST_URL_DOCS
  69. template<class... Rules>
  70. constexpr
  71. __implementation_defined__
  72. tuple_rule( Rules... rn ) noexcept;
  73. #else
  74. template<
  75. class R0,
  76. class... Rn>
  77. class tuple_rule_t
  78. : empty_value<
  79. detail::tuple<R0, Rn...>>
  80. {
  81. using T = mp11::mp_remove<
  82. std::tuple<
  83. typename R0::value_type,
  84. typename Rn::value_type...>,
  85. void>;
  86. static constexpr bool IsList =
  87. mp11::mp_size<T>::value != 1;
  88. public:
  89. using value_type =
  90. mp11::mp_eval_if_c<IsList,
  91. T, mp11::mp_first, T>;
  92. template<
  93. class R0_,
  94. class... Rn_>
  95. friend
  96. constexpr
  97. auto
  98. tuple_rule(
  99. R0_ const& r0,
  100. Rn_ const&... rn) noexcept ->
  101. tuple_rule_t<R0_, Rn_...>;
  102. system::result<value_type>
  103. parse(
  104. char const*& it,
  105. char const* end) const;
  106. private:
  107. constexpr
  108. tuple_rule_t(
  109. R0 const& r0,
  110. Rn const&... rn) noexcept
  111. : empty_value<
  112. detail::tuple<R0, Rn...>>(
  113. empty_init,
  114. r0, rn...)
  115. {
  116. }
  117. };
  118. template<
  119. class R0,
  120. class... Rn>
  121. constexpr
  122. auto
  123. tuple_rule(
  124. R0 const& r0,
  125. Rn const&... rn) noexcept ->
  126. tuple_rule_t<
  127. R0, Rn...>
  128. {
  129. return { r0, rn... };
  130. }
  131. #endif
  132. #ifndef BOOST_URL_DOCS
  133. namespace detail {
  134. template<class Rule>
  135. struct squelch_rule_t
  136. : empty_value<Rule>
  137. {
  138. using value_type = void;
  139. constexpr
  140. squelch_rule_t(
  141. Rule const& r) noexcept
  142. : empty_value<Rule>(
  143. empty_init, r)
  144. {
  145. }
  146. system::result<value_type>
  147. parse(
  148. char const*& it,
  149. char const* end) const
  150. {
  151. auto rv = this->get().parse(it, end);
  152. if(rv.error())
  153. return rv.error();
  154. return {}; // void
  155. }
  156. };
  157. } // detail
  158. #endif
  159. /** Squelch the value of a rule
  160. This function returns a new rule which
  161. matches the specified rule, and converts
  162. its value type to `void`. This is useful
  163. for matching delimiters in a grammar,
  164. where the value for the delimiter is not
  165. needed.
  166. @par Value Type
  167. @code
  168. using value_type = void;
  169. @endcode
  170. @par Example 1
  171. With `squelch`:
  172. @code
  173. system::result< std::tuple< decode_view, core::string_view > > rv = parse(
  174. "www.example.com:443",
  175. tuple_rule(
  176. pct_encoded_rule(unreserved_chars + '-' + '.'),
  177. squelch( delim_rule( ':' ) ),
  178. token_rule( digit_chars ) ) );
  179. @endcode
  180. @par Example 2
  181. Without `squelch`:
  182. @code
  183. system::result< std::tuple< decode_view, core::string_view, core::string_view > > rv = parse(
  184. "www.example.com:443",
  185. tuple_rule(
  186. pct_encoded_rule(unreserved_chars + '-' + '.'),
  187. delim_rule( ':' ),
  188. token_rule( digit_chars ) ) );
  189. @endcode
  190. @param r The rule to squelch
  191. @see
  192. @ref delim_rule,
  193. @ref digit_chars,
  194. @ref parse,
  195. @ref tuple_rule,
  196. @ref token_rule,
  197. @ref decode_view,
  198. @ref pct_encoded_rule,
  199. @ref unreserved_chars.
  200. */
  201. template<class Rule>
  202. constexpr
  203. #ifdef BOOST_URL_DOCS
  204. __implementation_defined__
  205. #else
  206. detail::squelch_rule_t<Rule>
  207. #endif
  208. squelch( Rule const& r ) noexcept
  209. {
  210. return { r };
  211. }
  212. } // grammar
  213. } // urls
  214. } // boost
  215. #include <boost/url/grammar/impl/tuple_rule.hpp>
  216. #endif