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// SPDX-FileCopyrightText: Copyright (C) 2020 Tobias Hienzsch
3
4#ifndef TETL_FUNCTIONAL_NOT_FN_HPP
5#define TETL_FUNCTIONAL_NOT_FN_HPP
6
7#include <etl/_functional/invoke.hpp>
8#include <etl/_type_traits/is_member_pointer.hpp>
9#include <etl/_type_traits/is_pointer.hpp>
10#include <etl/_utility/forward.hpp>
11#include <etl/_utility/move.hpp>
12
13namespace etl {
14
15namespace detail {
16
17template <typename F, typename... Args>
18concept negate_invocable
19 = requires(F&& f, Args&&... args) { not etl::invoke(etl::forward<F>(f), etl::forward<Args>(args)...); };
20
21template <typename F>
22struct not_fn_t {
23 F f;
24
25 template <typename... Args>
26 requires negate_invocable<F&, Args...>
27 constexpr auto operator()(Args&&... args) & noexcept(noexcept(not etl::invoke(f, etl::forward<Args>(args)...)))
28 -> decltype(auto)
29 {
30 return not etl::invoke(f, etl::forward<Args>(args)...);
31 }
32
33 template <typename... Args>
34 requires negate_invocable<F const&, Args...>
35 constexpr auto operator()(Args&&... args) const& noexcept(noexcept(not etl::invoke(f, etl::forward<Args>(args)...)))
36 -> decltype(auto)
37 {
38 return not etl::invoke(f, etl::forward<Args>(args)...);
39 }
40
41 template <typename... Args>
42 requires negate_invocable<F, Args...>
43 constexpr auto
44 operator()(Args&&... args) && noexcept(noexcept(not etl::invoke(etl::move(f), etl::forward<Args>(args)...)))
45 -> decltype(auto)
46 {
47 return not etl::invoke(etl::move(f), etl::forward<Args>(args)...);
48 }
49
50 template <typename... Args>
51 requires negate_invocable<F const, Args...>
52 constexpr auto
53 operator()(Args&&... args) const&& noexcept(noexcept(not etl::invoke(etl::move(f), etl::forward<Args>(args)...)))
54 -> 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
76 operator()(Args&&... args) const 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
Definition adjacent_find.hpp:9
constexpr auto not_fn() noexcept -> detail::stateless_not_fn< ConstFn >
Definition not_fn.hpp:92
constexpr auto not_fn(F &&f) -> detail::not_fn_t< etl::decay_t< F > >
Definition not_fn.hpp:86