You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

not_fn.hpp 2.8KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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_NOT_FN_HPP
  14. #define RANGES_V3_FUNCTIONAL_NOT_FN_HPP
  15. #include <type_traits>
  16. #include <concepts/concepts.hpp>
  17. #include <range/v3/range_fwd.hpp>
  18. #include <range/v3/functional/concepts.hpp>
  19. #include <range/v3/functional/invoke.hpp>
  20. #include <range/v3/utility/static_const.hpp>
  21. namespace ranges
  22. {
  23. /// \addtogroup group-functional
  24. /// @{
  25. template<typename FD>
  26. struct logical_negate
  27. {
  28. private:
  29. CPP_assert(same_as<FD, detail::decay_t<FD>> && move_constructible<FD>);
  30. RANGES_NO_UNIQUE_ADDRESS FD pred_;
  31. public:
  32. CPP_member
  33. constexpr CPP_ctor(logical_negate)()( //
  34. noexcept(std::is_nothrow_default_constructible<FD>::value) //
  35. requires default_constructible<FD>)
  36. {}
  37. template<typename T>
  38. explicit constexpr CPP_ctor(logical_negate)(T && pred)( //
  39. requires(!defer::same_as<detail::decay_t<T>, logical_negate>) &&
  40. defer::constructible_from<FD, T>)
  41. : pred_(static_cast<T &&>(pred))
  42. {}
  43. template<typename... Args>
  44. constexpr auto operator()(Args &&... args) & -> CPP_ret(bool)( //
  45. requires predicate<FD &, Args...>)
  46. {
  47. return !invoke(pred_, static_cast<Args &&>(args)...);
  48. }
  49. /// \overload
  50. template<typename... Args>
  51. constexpr auto operator()(Args &&... args) const & -> CPP_ret(bool)( //
  52. requires predicate<FD const &, Args...>)
  53. {
  54. return !invoke(pred_, static_cast<Args &&>(args)...);
  55. }
  56. /// \overload
  57. template<typename... Args>
  58. constexpr auto operator()(Args &&... args) && -> CPP_ret(bool)( //
  59. requires predicate<FD, Args...>)
  60. {
  61. return !invoke(static_cast<FD &&>(pred_), static_cast<Args &&>(args)...);
  62. }
  63. };
  64. struct not_fn_fn
  65. {
  66. template<typename Pred>
  67. constexpr auto operator()(Pred && pred) const
  68. -> CPP_ret(logical_negate<detail::decay_t<Pred>>)( //
  69. requires move_constructible<detail::decay_t<Pred>> &&
  70. constructible_from<detail::decay_t<Pred>, Pred>)
  71. {
  72. return logical_negate<detail::decay_t<Pred>>{(Pred &&) pred};
  73. }
  74. };
  75. /// \ingroup group-functional
  76. /// \sa `not_fn_fn`
  77. RANGES_INLINE_VARIABLE(not_fn_fn, not_fn)
  78. namespace cpp20
  79. {
  80. using ranges::not_fn;
  81. }
  82. /// @}
  83. } // namespace ranges
  84. #endif