variant_rule.hpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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_IMPL_VARIANT_RULE_HPP
  10. #define BOOST_URL_GRAMMAR_IMPL_VARIANT_RULE_HPP
  11. #include <boost/url/grammar/error.hpp>
  12. #include <boost/url/grammar/parse.hpp>
  13. #include <cstdint>
  14. #include <type_traits>
  15. namespace boost {
  16. namespace urls {
  17. namespace grammar {
  18. namespace detail {
  19. // must come first
  20. template<
  21. class R0,
  22. class... Rn,
  23. std::size_t I>
  24. auto
  25. parse_variant(
  26. char const*&,
  27. char const*,
  28. detail::tuple<
  29. R0, Rn...> const&,
  30. std::integral_constant<
  31. std::size_t, I> const&,
  32. std::false_type const&) ->
  33. system::result<variant<
  34. typename R0::value_type,
  35. typename Rn::value_type...>>
  36. {
  37. // no match
  38. BOOST_URL_RETURN_EC(
  39. error::mismatch);
  40. }
  41. template<
  42. class R0,
  43. class... Rn,
  44. std::size_t I>
  45. auto
  46. parse_variant(
  47. char const*& it,
  48. char const* const end,
  49. detail::tuple<
  50. R0, Rn...> const& rn,
  51. std::integral_constant<
  52. std::size_t, I> const&,
  53. std::true_type const&) ->
  54. system::result<variant<
  55. typename R0::value_type,
  56. typename Rn::value_type...>>
  57. {
  58. auto const it0 = it;
  59. auto rv = parse(
  60. it, end, get<I>(rn));
  61. if( rv )
  62. return variant<
  63. typename R0::value_type,
  64. typename Rn::value_type...>{
  65. variant2::in_place_index_t<I>{}, *rv};
  66. it = it0;
  67. return parse_variant(
  68. it, end, rn,
  69. std::integral_constant<
  70. std::size_t, I+1>{},
  71. std::integral_constant<bool,
  72. ((I + 1) < (1 +
  73. sizeof...(Rn)))>{});
  74. }
  75. } // detail
  76. template<class R0, class... Rn>
  77. auto
  78. variant_rule_t<R0, Rn...>::
  79. parse(
  80. char const*& it,
  81. char const* end) const ->
  82. system::result<value_type>
  83. {
  84. return detail::parse_variant(
  85. it, end, rn_,
  86. std::integral_constant<
  87. std::size_t, 0>{},
  88. std::true_type{});
  89. }
  90. //------------------------------------------------
  91. template<class R0, class... Rn>
  92. auto
  93. constexpr
  94. variant_rule(
  95. R0 const& r0,
  96. Rn const&... rn) noexcept ->
  97. variant_rule_t<R0, Rn...>
  98. {
  99. return { r0, rn... };
  100. }
  101. } // grammar
  102. } // urls
  103. } // boost
  104. #endif