3#ifndef TETL_FUNCTIONAL_INPLACE_FUNCTION_HPP
4#define TETL_FUNCTIONAL_INPLACE_FUNCTION_HPP
38template <
typename R,
typename... Args>
39struct inplace_func_vtable {
40 using storage_ptr_t =
void*;
42 using invoke_ptr_t = R (*)(storage_ptr_t, Args&&...);
43 using process_ptr_t = void (*)(storage_ptr_t, storage_ptr_t);
44 using destructor_ptr_t = void (*)(storage_ptr_t);
46 invoke_ptr_t
const invoke_ptr;
47 process_ptr_t
const copy_ptr;
48 process_ptr_t
const relocate_ptr;
49 destructor_ptr_t
const destructor_ptr;
51 explicit constexpr inplace_func_vtable()
52 : invoke_ptr{[](storage_ptr_t , Args&&... ) -> R {
53 etl::
raise<etl::bad_function_call>(
"empty inplace_func_vtable");
55 , copy_ptr{[](storage_ptr_t , storage_ptr_t ) ->
void {}}
56 , relocate_ptr{[](storage_ptr_t , storage_ptr_t ) ->
void {}}
57 , destructor_ptr{[](storage_ptr_t ) ->
void {}}
62 explicit constexpr inplace_func_vtable(wrapper<C> )
63 : invoke_ptr{[](storage_ptr_t storagePtr, Args&&... args) -> R {
64 return (*static_cast<C*>(storagePtr))(static_cast<Args&&>(args)...);
66 , copy_ptr{[](storage_ptr_t dstPtr, storage_ptr_t srcPtr) ->
void {
67 ::new (dstPtr) C{(*
static_cast<C*
>(srcPtr))};
69 , relocate_ptr{[](storage_ptr_t dstPtr, storage_ptr_t srcPtr) ->
void {
70 ::new (dstPtr) C{
etl::move(*
static_cast<C*
>(srcPtr))};
71 static_cast<C*
>(srcPtr)->~C();
73 , destructor_ptr{[](storage_ptr_t srcPtr) ->
void {
static_cast<C*
>(srcPtr)->~C(); }}
77 inplace_func_vtable(inplace_func_vtable
const&) =
delete;
78 inplace_func_vtable(inplace_func_vtable&&) =
delete;
80 auto operator=(inplace_func_vtable
const&) -> inplace_func_vtable& =
delete;
81 auto operator=(inplace_func_vtable&&) -> inplace_func_vtable& =
delete;
83 ~inplace_func_vtable() =
default;
86template <
typename R,
typename... Args>
87inline constexpr auto empty_vtable = inplace_func_vtable<R, Args...>{};
89template <
size_t DstCap,
size_t DstAlign,
size_t SrcCap,
size_t SrcAlign>
91 static_assert(DstCap >= SrcCap);
92 static_assert(DstAlign % SrcAlign == 0);
97template <
typename Signature,
size_t Capacity = sizeof(
void*),
size_t Alignment = alignof(aligned_storage_t<Capacity>)>
104template <
typename Sig,
size_t Cap,
size_t Align>
108template <
typename R,
typename... Args,
size_t Capacity,
size_t Alignment>
112 using vtable_t = detail::inplace_func_vtable<R, Args...>;
113 using vtable_ptr_t = vtable_t
const*;
115 template <
typename,
size_t,
size_t>
128 template <
typename T,
typename C = decay_t<T>>
129 requires(!detail::is_inplace_function<C>::value && is_invocable_r_v<R, C&, Args...>)
134 sizeof(C) <= Capacity,
135 "inplace_function cannot be constructed from object with this (large) size"
138 Alignment %
alignof(C) == 0,
139 "inplace_function cannot be constructed from object with this (large) alignment"
142 static constexpr vtable_t
const vt{detail::wrapper<C>{}};
148 template <
size_t Cap,
size_t Align>
154 "conversion not allowed"
158 template <
size_t Cap,
size_t Align>
164 "conversion not allowed"
176 : _vtable{other._vtable}
215 [[nodiscard]]
explicit constexpr operator bool() const noexcept
217 return _vtable !=
etl::addressof(detail::empty_vtable<R, Args...>);
223 auto tmp = storage_t{};
233 typename vtable_t::process_ptr_t process,
234 typename vtable_t::storage_ptr_t storage
241 vtable_ptr_t _vtable;
242 storage_t
mutable _storage;
248template <
typename R,
typename... Args,
size_t Capacity,
size_t Alignment>
260template <
typename R,
typename... Args,
size_t Capacity,
size_t Alignment>
261[[nodiscard]]
constexpr auto
264 return !
static_cast<bool>(f);
270template <
typename R,
typename... Args,
size_t Capacity,
size_t Alignment>
271[[nodiscard]]
constexpr auto
274 return static_cast<bool>(f);
280template <
typename R,
typename... Args,
size_t Capacity,
size_t Alignment>
281[[nodiscard]]
constexpr auto
284 return !
static_cast<bool>(f);
290template <
typename R,
typename... Args,
size_t Capacity,
size_t Alignment>
291[[nodiscard]]
constexpr auto
294 return static_cast<bool>(f);
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_copy_constructible_v
Definition is_copy_constructible.hpp:30
constexpr auto operator==(inplace_function< R(Args...), Capacity, Alignment > const &f, nullptr_t) noexcept -> bool
Compares a etl::inplace_function with a null pointer. Empty functions (that is, functions without a c...
Definition inplace_function.hpp:262
constexpr auto addressof(T &arg) noexcept -> T *
Obtains the actual address of the object or function arg, even in presence of overloaded operator&.
Definition addressof.hpp:15
constexpr auto operator!=(inplace_function< R(Args...), Capacity, Alignment > const &f, nullptr_t) noexcept -> bool
Compares a etl::inplace_function with a null pointer. Empty functions (that is, functions without a c...
Definition inplace_function.hpp:272
TETL_NO_INLINE TETL_COLD auto raise(char const *msg, etl::source_location const loc=etl::source_location::current()) -> void
Definition raise.hpp:17
constexpr auto exchange(T &obj, U &&newValue) noexcept(etl::is_nothrow_move_constructible_v< T > and etl::is_nothrow_assignable_v< T &, U >) -> T
Replaces the value of obj with new_value and returns the old value of obj.
Definition exchange.hpp:16
bool_constant< true > true_type
Definition bool_constant.hpp:13
auto swap(inplace_function< R(Args...), Capacity, Alignment > &lhs, inplace_function< R(Args...), Capacity, Alignment > &rhs) noexcept -> void
Overloads the etl::swap algorithm for etl::inplace_function. Exchanges the state of lhs with that of ...
Definition inplace_function.hpp:249
bool_constant< false > false_type
Definition bool_constant.hpp:14
typename aligned_storage< Len, Align >::type aligned_storage_t
Definition aligned_storage.hpp:57
constexpr auto forward(remove_reference_t< T > ¶m) noexcept -> T &&
Forwards lvalues as either lvalues or as rvalues, depending on T. When t is a forwarding reference (a...
Definition forward.hpp:18
decltype(nullptr) nullptr_t
etl::nullptr_t is the type of the null pointer literal, nullptr. It is a distinct type that is not it...
Definition nullptr_t.hpp:13
constexpr bad_function_call(char const *what)
Definition inplace_function.hpp:25
constexpr bad_function_call()=default
constexpr exception()=default
constexpr auto what() const noexcept -> char const *
Definition exception.hpp:16
auto operator()(Args... args) const -> R
Invokes the stored callable function target with the parameters args.
Definition inplace_function.hpp:209
inplace_function(inplace_function< R(Args...), Cap, Align > const &other)
Definition inplace_function.hpp:149
inplace_function(inplace_function &&other) noexcept
Definition inplace_function.hpp:181
inplace_function(inplace_function const &other)
Definition inplace_function.hpp:175
inplace_function(inplace_function< R(Args...), Cap, Align > &&other) noexcept
Definition inplace_function.hpp:159
integral_constant< size_t, Capacity > capacity
Definition inplace_function.hpp:119
inplace_function() noexcept
Creates an empty function.
Definition inplace_function.hpp:123
auto operator=(inplace_function other) noexcept -> inplace_function &
Definition inplace_function.hpp:196
inplace_function(nullptr_t) noexcept
Creates an empty function.
Definition inplace_function.hpp:170
~inplace_function()
Destroys the etl::inplace_function instance. If the etl::inplace_function is not empty,...
Definition inplace_function.hpp:206
inplace_function(T &&closure)
Definition inplace_function.hpp:130
auto swap(inplace_function &other) noexcept -> void
Exchanges the stored callable objects of *this and other.
Definition inplace_function.hpp:221
friend struct inplace_function
Definition inplace_function.hpp:116
auto operator=(nullptr_t) noexcept -> inplace_function &
Assigns a new target to etl::inplace_function. Drops the current target. *this is empty after the cal...
Definition inplace_function.hpp:189
integral_constant< size_t, Alignment > alignment
Definition inplace_function.hpp:120
Definition inplace_function.hpp:98
Definition integral_constant.hpp:9
static constexpr bool value
Definition integral_constant.hpp:10