concepts.hpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright (C) 2020 T. Zachary Laine
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_PARSER_CONCEPTS_HPP
  7. #define BOOST_PARSER_CONCEPTS_HPP
  8. #include <boost/parser/config.hpp>
  9. #include <boost/parser/parser_fwd.hpp>
  10. #include <boost/parser/detail/text/transcode_view.hpp>
  11. #if defined(BOOST_PARSER_DOXYGEN) || BOOST_PARSER_USE_CONCEPTS
  12. #include <ranges>
  13. namespace boost { namespace parser {
  14. //[ all_concepts
  15. template<typename T>
  16. concept code_unit =
  17. std::same_as<std::remove_cv_t<T>, char> ||
  18. std::same_as<std::remove_cv_t<T>, wchar_t> ||
  19. std::same_as<std::remove_cv_t<T>, char8_t> ||
  20. std::same_as<std::remove_cv_t<T>, char16_t>||
  21. std::same_as<std::remove_cv_t<T>, char32_t>;
  22. template<typename T>
  23. concept parsable_iter =
  24. std::forward_iterator<T> && code_unit<std::iter_value_t<T>>;
  25. //[ parsable_range_like_concept
  26. //[ parsable_range_concept
  27. template<typename T>
  28. concept parsable_range = std::ranges::forward_range<T> &&
  29. code_unit<std::ranges::range_value_t<T>>;
  30. //]
  31. template<typename T>
  32. concept parsable_pointer = std::is_pointer_v<std::remove_cvref_t<T>> &&
  33. code_unit<std::remove_pointer_t<std::remove_cvref_t<T>>>;
  34. template<typename T>
  35. concept parsable_range_like = parsable_range<T> || parsable_pointer<T>;
  36. //]
  37. template<typename T>
  38. concept range_like = std::ranges::range<T> || parsable_pointer<T>;
  39. template<
  40. typename I,
  41. typename S,
  42. typename ErrorHandler,
  43. typename GlobalState>
  44. using minimal_parse_context = decltype(detail::make_context<false, false>(
  45. std::declval<I>(),
  46. std::declval<S>(),
  47. std::declval<bool &>(),
  48. std::declval<int &>(),
  49. std::declval<ErrorHandler const &>(),
  50. std::declval<detail::nope const &>(),
  51. std::declval<detail::symbol_table_tries_t &>(),
  52. std::declval<detail::pending_symbol_table_operations_t &>()));
  53. template<typename T, typename I, typename S, typename GlobalState>
  54. concept error_handler =
  55. requires (
  56. T const & t,
  57. I first,
  58. S last,
  59. parse_error<I> const & e,
  60. diagnostic_kind kind,
  61. std::string_view message,
  62. minimal_parse_context<
  63. I, S, T, GlobalState> const & context) {
  64. { t(first, last, e) } -> std::same_as<error_handler_result>;
  65. t.diagnose(kind, message, context, first);
  66. t.diagnose(kind, message, context);
  67. };
  68. //[ container_concept
  69. template<typename T>
  70. concept container = std::ranges::common_range<T> && requires(T t) {
  71. { t.insert(t.begin(), *t.begin()) }
  72. -> std::same_as<std::ranges::iterator_t<T>>;
  73. };
  74. //]
  75. //]
  76. namespace detail {
  77. template<typename T, typename U>
  78. concept container_and_value_type = container<T> &&
  79. (std::is_same_v<std::ranges::range_value_t<T>, U> ||
  80. (std::is_same_v<T, std::string> && std::is_same_v<U, char32_t>));
  81. }
  82. }}
  83. #endif
  84. #endif