concepts.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /// \file
  2. // Range v3 library
  3. //
  4. // Copyright Eric Niebler 2013-present
  5. //
  6. // Use, modification and distribution is subject to the
  7. // Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Project home: https://github.com/ericniebler/range-v3
  12. //
  13. #ifndef RANGES_V3_FUNCTIONAL_CONCEPTS_HPP
  14. #define RANGES_V3_FUNCTIONAL_CONCEPTS_HPP
  15. #include <concepts/concepts.hpp>
  16. #include <range/v3/functional/invoke.hpp>
  17. #include <range/v3/detail/prologue.hpp>
  18. namespace ranges
  19. {
  20. /// \addtogroup group-functional
  21. /// @{
  22. // clang-format off
  23. // WORKAROUND mysterious msvc bug
  24. #if defined(_MSC_VER) && !defined(__clang__)
  25. /// \concept invocable
  26. /// \brief The \c invocable concept
  27. template<typename Fun, typename... Args>
  28. CPP_concept invocable =
  29. std::is_invocable_v<Fun, Args...>;
  30. #else
  31. /// \concept invocable_
  32. /// \brief The \c invocable_ concept
  33. template<typename Fun, typename... Args>
  34. CPP_requires(invocable_,
  35. requires(Fun && fn) //
  36. (
  37. invoke((Fun &&) fn, std::declval<Args>()...)
  38. ));
  39. /// \concept invocable
  40. /// \brief The \c invocable concept
  41. template<typename Fun, typename... Args>
  42. CPP_concept invocable =
  43. CPP_requires_ref(ranges::invocable_, Fun, Args...);
  44. #endif
  45. /// \concept regular_invocable
  46. /// \brief The \c regular_invocable concept
  47. template<typename Fun, typename... Args>
  48. CPP_concept regular_invocable =
  49. invocable<Fun, Args...>;
  50. // Axiom: equality_preserving(invoke(f, args...))
  51. /// \concept predicate_
  52. /// \brief The \c predicate_ concept
  53. template<typename Fun, typename... Args>
  54. CPP_requires(predicate_,
  55. requires(Fun && fn) //
  56. (
  57. concepts::requires_<
  58. convertible_to<
  59. decltype(invoke((Fun &&) fn, std::declval<Args>()...)),
  60. bool>>
  61. ));
  62. /// \concept predicate
  63. /// \brief The \c predicate concept
  64. template<typename Fun, typename... Args>
  65. CPP_concept predicate =
  66. regular_invocable<Fun, Args...> &&
  67. CPP_requires_ref(ranges::predicate_, Fun, Args...);
  68. /// \concept relation
  69. /// \brief The \c relation concept
  70. template<typename R, typename T, typename U>
  71. CPP_concept relation =
  72. predicate<R, T, T> &&
  73. predicate<R, U, U> &&
  74. predicate<R, T, U> &&
  75. predicate<R, U, T>;
  76. /// \concept strict_weak_order
  77. /// \brief The \c strict_weak_order concept
  78. template<typename R, typename T, typename U>
  79. CPP_concept strict_weak_order =
  80. relation<R, T, U>;
  81. // clang-format on
  82. namespace cpp20
  83. {
  84. using ranges::invocable;
  85. using ranges::predicate;
  86. using ranges::regular_invocable;
  87. using ranges::relation;
  88. using ranges::strict_weak_order;
  89. } // namespace cpp20
  90. /// @}
  91. } // namespace ranges
  92. #include <range/v3/detail/epilogue.hpp>
  93. #endif