tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
not_fn.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2
3#ifndef TETL_FUNCTIONAL_NOT_FN_HPP
4#define TETL_FUNCTIONAL_NOT_FN_HPP
5
10#include <etl/_utility/move.hpp>
11
12namespace etl {
13
14namespace detail {
15
16// clang-format off
17template <typename F, typename... Args>
18concept negate_invocable = requires(F&& f, Args&&... args) {
20};
21// clang-format on
22
23template <typename F>
24struct not_fn_t {
25 F f;
26
27 template <typename... Args>
28 requires negate_invocable<F&, Args...>
29 constexpr auto operator()(Args&&... args) & noexcept(noexcept(not etl::invoke(f, etl::forward<Args>(args)...)))
30 -> decltype(auto)
31 {
32 return not etl::invoke(f, etl::forward<Args>(args)...);
33 }
34
35 template <typename... Args>
36 requires negate_invocable<F const&, Args...>
37 constexpr auto operator()(Args&&... args) const& noexcept(noexcept(not etl::invoke(f, etl::forward<Args>(args)...)))
38 -> decltype(auto)
39 {
40 return not etl::invoke(f, etl::forward<Args>(args)...);
41 }
42
43 template <typename... Args>
44 requires negate_invocable<F, Args...>
45 constexpr auto operator()(Args&&... args
46 ) && noexcept(noexcept(not etl::invoke(etl::move(f), etl::forward<Args>(args)...))) -> decltype(auto)
47 {
48 return not etl::invoke(etl::move(f), etl::forward<Args>(args)...);
49 }
50
51 template <typename... Args>
52 requires negate_invocable<F const, Args...>
53 constexpr auto operator()(Args&&... args
54 ) const&& noexcept(noexcept(not etl::invoke(etl::move(f), etl::forward<Args>(args)...))) -> decltype(auto)
55 {
56 return not etl::invoke(etl::move(f), etl::forward<Args>(args)...);
57 }
58
59 template <typename... Args>
60 auto operator()(Args&&...) & -> void = delete;
61
62 template <typename... Args>
63 auto operator()(Args&&...) const& -> void = delete;
64
65 template <typename... Args>
66 auto operator()(Args&&...) && -> void = delete;
67
68 template <typename... Args>
69 auto operator()(Args&&...) const&& -> void = delete;
70};
71
72template <auto ConstFn>
73struct stateless_not_fn {
74 template <typename... Args>
75 constexpr auto operator()(Args&&... args) const
76 noexcept(noexcept(!etl::invoke(ConstFn, etl::forward<Args>(args)...)))
77 -> decltype(!etl::invoke(ConstFn, etl::forward<Args>(args)...))
78 {
79 return !etl::invoke(ConstFn, etl::forward<Args>(args)...);
80 }
81};
82
83} // namespace detail
84
85template <typename F>
86[[nodiscard]] constexpr auto not_fn(F&& f) -> detail::not_fn_t<etl::decay_t<F>>
87{
88 return {etl::forward<F>(f)};
89}
90
91template <auto ConstFn>
92[[nodiscard]] constexpr auto not_fn() noexcept -> detail::stateless_not_fn<ConstFn>
93{
94 if constexpr (etl::is_pointer_v<decltype(ConstFn)> or etl::is_member_pointer_v<decltype(ConstFn)>) {
95 static_assert(ConstFn != nullptr);
96 }
97 return {};
98}
99
100} // namespace etl
101
102#endif // TETL_FUNCTIONAL_NOT_FN_HPP
constexpr auto move(InputIt first, InputIt last, OutputIt destination) -> OutputIt
Moves the elements in the range [first, last), to another range beginning at destination,...
Definition move.hpp:26
Definition adjacent_find.hpp:8
constexpr bool is_pointer_v
Definition is_pointer.hpp:30
constexpr bool is_member_pointer_v
Definition is_member_pointer.hpp:40
constexpr auto not_fn() noexcept -> detail::stateless_not_fn< ConstFn >
Definition not_fn.hpp:92
constexpr auto invoke(F &&f, Args &&... args) -> invoke_result_t< F, Args... >
Definition invoke.hpp:45
constexpr auto forward(remove_reference_t< T > &param) noexcept -> T &&
Forwards lvalues as either lvalues or as rvalues, depending on T. When t is a forwarding reference (a...
Definition forward.hpp:18