concurrent_static_asserts.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /* Copyright 2023 Christian Mazakas.
  2. * Copyright 2023-2024 Joaquin M Lopez Munoz.
  3. * Distributed under the Boost Software License, Version 1.0.
  4. * (See accompanying file LICENSE_1_0.txt or copy at
  5. * http://www.boost.org/LICENSE_1_0.txt)
  6. *
  7. * See https://www.boost.org/libs/unordered for library home page.
  8. */
  9. #ifndef BOOST_UNORDERED_DETAIL_CONCURRENT_STATIC_ASSERTS_HPP
  10. #define BOOST_UNORDERED_DETAIL_CONCURRENT_STATIC_ASSERTS_HPP
  11. #include <boost/config.hpp>
  12. #include <boost/mp11/algorithm.hpp>
  13. #include <boost/mp11/list.hpp>
  14. #include <boost/unordered/detail/type_traits.hpp>
  15. #define BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) \
  16. static_assert(boost::unordered::detail::is_invocable<F, value_type&>::value, \
  17. "The provided Callable must be invocable with value_type&");
  18. #define BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) \
  19. static_assert( \
  20. boost::unordered::detail::is_invocable<F, value_type const&>::value, \
  21. "The provided Callable must be invocable with value_type const&");
  22. #if BOOST_CXX_VERSION >= 202002L
  23. #define BOOST_UNORDERED_STATIC_ASSERT_EXEC_POLICY(P) \
  24. static_assert(!std::is_base_of<std::execution::parallel_unsequenced_policy, \
  25. ExecPolicy>::value, \
  26. "ExecPolicy must be sequenced."); \
  27. static_assert( \
  28. !std::is_base_of<std::execution::unsequenced_policy, ExecPolicy>::value, \
  29. "ExecPolicy must be sequenced.");
  30. #else
  31. #define BOOST_UNORDERED_STATIC_ASSERT_EXEC_POLICY(P) \
  32. static_assert(!std::is_base_of<std::execution::parallel_unsequenced_policy, \
  33. ExecPolicy>::value, \
  34. "ExecPolicy must be sequenced.");
  35. #endif
  36. #define BOOST_UNORDERED_DETAIL_COMMA ,
  37. #define BOOST_UNORDERED_DETAIL_LAST_ARG(Arg, Args) \
  38. mp11::mp_back<mp11::mp_list<Arg BOOST_UNORDERED_DETAIL_COMMA Args> >
  39. #define BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_INVOCABLE(Arg, Args) \
  40. BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE( \
  41. BOOST_UNORDERED_DETAIL_LAST_ARG(Arg, Args))
  42. #define BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_CONST_INVOCABLE(Arg, Args) \
  43. BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE( \
  44. BOOST_UNORDERED_DETAIL_LAST_ARG(Arg, Args))
  45. #define BOOST_UNORDERED_DETAIL_PENULTIMATE_ARG(Arg1, Arg2, Args) \
  46. mp11::mp_at_c<mp11::mp_list< \
  47. Arg1 BOOST_UNORDERED_DETAIL_COMMA Arg2 BOOST_UNORDERED_DETAIL_COMMA Args \
  48. >, \
  49. mp11::mp_size<mp11::mp_list< \
  50. Arg1 BOOST_UNORDERED_DETAIL_COMMA Arg2 BOOST_UNORDERED_DETAIL_COMMA Args \
  51. >>::value - 2>
  52. #define BOOST_UNORDERED_STATIC_ASSERT_PENULTIMATE_ARG_INVOCABLE( \
  53. Arg1, Arg2, Args) \
  54. BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE( \
  55. BOOST_UNORDERED_DETAIL_PENULTIMATE_ARG(Arg1, Arg2, Args))
  56. #define BOOST_UNORDERED_STATIC_ASSERT_PENULTIMATE_ARG_CONST_INVOCABLE( \
  57. Arg1, Arg2, Args) \
  58. BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE( \
  59. BOOST_UNORDERED_DETAIL_PENULTIMATE_ARG(Arg1, Arg2, Args))
  60. namespace boost {
  61. namespace unordered {
  62. namespace detail {
  63. template <class...> struct is_invocable_helper : std::false_type
  64. {
  65. };
  66. template <class F, class... Args>
  67. struct is_invocable_helper<
  68. void_t<decltype(std::declval<F>()(std::declval<Args>()...))>, F,
  69. Args...> : std::true_type
  70. {
  71. };
  72. template <class F, class... Args>
  73. using is_invocable = is_invocable_helper<void, F, Args...>;
  74. } // namespace detail
  75. } // namespace unordered
  76. } // namespace boost
  77. #if defined(BOOST_NO_CXX20_HDR_CONCEPTS)
  78. #define BOOST_UNORDERED_STATIC_ASSERT_FWD_ITERATOR(Iterator) \
  79. static_assert( \
  80. std::is_base_of< \
  81. std::forward_iterator_tag, \
  82. typename std::iterator_traits<Iterator>::iterator_category>::value, \
  83. "The provided iterator must be at least forward");
  84. #else
  85. #define BOOST_UNORDERED_STATIC_ASSERT_FWD_ITERATOR(Iterator) \
  86. static_assert(std::forward_iterator<Iterator>, \
  87. "The provided iterator must be at least forward");
  88. #endif
  89. #define BOOST_UNORDERED_STATIC_ASSERT_KEY_COMPATIBLE_ITERATOR(Iterator) \
  90. static_assert( \
  91. std::is_same< \
  92. typename std::iterator_traits<Iterator>::value_type, \
  93. key_type>::value || \
  94. detail::are_transparent< \
  95. typename std::iterator_traits<Iterator>::value_type, \
  96. hasher, key_equal>::value, \
  97. "The provided iterator must dereference to a compatible key value");
  98. #define BOOST_UNORDERED_STATIC_ASSERT_BULK_VISIT_ITERATOR(Iterator) \
  99. BOOST_UNORDERED_STATIC_ASSERT_FWD_ITERATOR(Iterator) \
  100. BOOST_UNORDERED_STATIC_ASSERT_KEY_COMPATIBLE_ITERATOR(Iterator)
  101. #endif // BOOST_UNORDERED_DETAIL_CONCURRENT_STATIC_ASSERTS_HPP