Simple-Utility v2.3.1
Loading...
Searching...
No Matches
BasicClosure.hpp
Go to the documentation of this file.
1// Copyright Dominic Koepke 2019 - 2023.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at
4// https://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef SIMPLE_UTILITY_FUNCTIONAL_BASIC_CLOSURE_HPP
7#define SIMPLE_UTILITY_FUNCTIONAL_BASIC_CLOSURE_HPP
8
9#pragma once
10
11#include <concepts>
12#include <functional>
13#include <type_traits>
14#include <utility>
15
17
18namespace sl::functional
19{
78 template <class T>
80 && std::is_object_v<T>;
81
88 template <template <class> class T>
89 concept invoke_policy = true;
90
97 template <template <class> class T>
98 concept operator_policy = true;
99
106 template <function Fn, template <class> class InvokePolicy, template <class> class... OperatorPolicies>
112 {
113 public:
119 template <class... Args>
120 requires std::constructible_from<Fn, Args...>
121 explicit constexpr BasicClosure(Args&&... args) noexcept(std::is_nothrow_constructible_v<Fn, Args...>)
122 : m_Fn{std::forward<Args>(args)...}
123 {
124 }
125
131 requires std::copy_constructible<Fn> = default;
132
137 BasicClosure& operator =(const BasicClosure&)
138 requires std::is_copy_assignable_v<Fn> = default;
139
145 requires std::move_constructible<Fn> = default;
146
152 requires std::is_move_assignable_v<Fn> = default;
153
157 ~BasicClosure() = default;
158
162 [[nodiscard]]
163 explicit constexpr operator const Fn&() const & noexcept
164 {
165 return m_Fn;
166 }
167
171 [[nodiscard]]
172 explicit constexpr operator Fn&() & noexcept
173 {
174 return m_Fn;
175 }
176
180 [[nodiscard]]
181 explicit constexpr operator const Fn&&() const && noexcept
182 {
183 return std::move(m_Fn);
184 }
185
189 [[nodiscard]]
190 explicit constexpr operator Fn&&() && noexcept
191 {
192 return std::move(m_Fn);
193 }
194
195 private:
196 Fn m_Fn{};
197 };
198
215 template <class T>
217 {
218 using type = T;
219 };
220
227 template <class Fn, template <class> class InvokePolicy, template <class> class... OperatorPolicies>
228 struct unwrap_functional<BasicClosure<Fn, InvokePolicy, OperatorPolicies...>>;
229
236 template <class Fn, template <class> class InvokePolicy, template <class> class... OperatorPolicies>
237 struct unwrap_functional<const BasicClosure<Fn, InvokePolicy, OperatorPolicies...>>;
238
245 template <class Fn, template <class> class InvokePolicy, template <class> class... OperatorPolicies>
246 struct unwrap_functional<const BasicClosure<Fn, InvokePolicy, OperatorPolicies...>&>
247 {
248 using type = const Fn&;
249 };
250
257 template <class Fn, template <class> class InvokePolicy, template <class> class... OperatorPolicies>
258 struct unwrap_functional<BasicClosure<Fn, InvokePolicy, OperatorPolicies...>&>
259 {
260 using type = Fn&;
261 };
262
269 template <class Fn, template <class> class InvokePolicy, template <class> class... OperatorPolicies>
270 struct unwrap_functional<const BasicClosure<Fn, InvokePolicy, OperatorPolicies...>&&>
271 {
272 using type = const Fn&&;
273 };
274
281 template <class Fn, template <class> class InvokePolicy, template <class> class... OperatorPolicies>
282 struct unwrap_functional<BasicClosure<Fn, InvokePolicy, OperatorPolicies...>&&>
283 {
284 using type = Fn&&;
285 };
286
291 template <class T>
293
305 template <class Fn>
306 [[nodiscard]]
307 constexpr unwrap_functional_t<Fn&&>&& forward_unwrapped(std::remove_reference_t<Fn>& fn) noexcept
308 {
309 return static_cast<unwrap_functional_t<Fn&&>&&>(std::forward<Fn>(fn));
310 }
311
324 template <class T>
326
333 template <class Fn, template <class> class InvokePolicy, template <class> class... OperatorPolicies>
334 struct closure_template<BasicClosure<Fn, InvokePolicy, OperatorPolicies...>>
335 {
336 template <class NewFn>
337 using type = BasicClosure<NewFn, InvokePolicy, OperatorPolicies...>;
338 };
339
351 template <template <class> class Closure, class Fn>
352 constexpr Closure<std::remove_cvref_t<Fn>> envelop(
353 Fn&& fn
354 ) noexcept(std::is_nothrow_constructible_v<std::remove_cvref_t<Fn>, Fn>)
355 {
356 return Closure<std::remove_cvref_t<Fn>>{std::forward<Fn>(fn)};
357 }
358}
359
360#endif
The core class, wrapping one functional object and enabling a variety of composing operators for it.
Definition: BasicClosure.hpp:112
BasicClosure(const BasicClosure &)=default
Defaulted copy constructor.
constexpr BasicClosure(Args &&... args) noexcept(std::is_nothrow_constructible_v< Fn, Args... >)
Forwarding constructor, forwarding all of its arguments to its stored functional.
Definition: BasicClosure.hpp:121
BasicClosure(BasicClosure &&)=default
Defaulted move constructor.
Checks whether the T denotes an unqualified type.
Definition: stl_extensions.hpp:60
Determines whether the given type satisfies the constraints of a function type.
Definition: BasicClosure.hpp:79
Determines whether the given type satisfies the constraints of an invoke-policy.
Definition: BasicClosure.hpp:89
Determines whether the given type satisfies the constraints of a operator-policy.
Definition: BasicClosure.hpp:98
typename unwrap_functional< T >::type unwrap_functional_t
Convenient alias for the type member alias to unwrap_functional trait.
Definition: BasicClosure.hpp:292
constexpr unwrap_functional_t< Fn && > && forward_unwrapped(std::remove_reference_t< Fn > &fn) noexcept
Unwraps the functional if stored in a closure. Otherwise forwards as-is.
Definition: BasicClosure.hpp:307
constexpr Closure< std::remove_cvref_t< Fn > > envelop(Fn &&fn) noexcept(std::is_nothrow_constructible_v< std::remove_cvref_t< Fn >, Fn >)
Wraps the given functional into the given closure type.
Definition: BasicClosure.hpp:352
Definition: Arithmetic.hpp:13
Primary template, purposely undefined.
Definition: BasicClosure.hpp:325
Primary template for non BasicClosure types.
Definition: BasicClosure.hpp:217
T type
Definition: BasicClosure.hpp:218