-
-
Notifications
You must be signed in to change notification settings - Fork 411
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support etl::inplace_function #1046
base: master
Are you sure you want to change the base?
Support etl::inplace_function #1046
Conversation
using dtor_func_t = void (*)(storage_ptr_t); | ||
|
||
const invoke_func_t invoke_func{[](storage_ptr_t, Args&&...) -> R | ||
{ return R(); }}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::function
throws std::bad_function_call
if operator() is called on an empty object while etl::inplace_function
safely returns a default-constructed object in this case.
That means type typename R
is required to be default-constructible.
void
type is fine here ( https://timsong-cpp.github.io/cppwp/std14/expr.type.conv )
But this will not compile since std::is_default_constructible_v<Type_a>
is false:
struct Type_a
{
Type_a(int32_t val) : val_(val) {}
int32_t val_;
};
etl::inplace_function<Type_a()> func0;
This deviation from std::function
is by designed and also tested in test_inplace_function.cpp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In etl::delegate
an ETL error is raised.
ETL_ASSERT(is_valid(), ETL_ERROR(delegate_uninitialised));
Also in etl::delegate
there are call_if
and call_or
member functions that handle uninitialised objects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to make it raise etl::bad_inplace_function_call
when an empty etl::inplace_function
is invoked with operator()
. (Similar to std::bad_function_call
)
std::function
does not support call_if()
and call_or()
. Do you suggest adding these 2 member func?
https://github.com/ETLCPP/etl | ||
https://www.etlcpp.com | ||
|
||
Copyright(c) 2025 BMW AG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How close a copy is this of the implementations that 'inspired' you?
There may be copyright implications.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The closest open source implementation is SG14 inplace_function.
etl::inplace_function
compiled object memory layout will be almost identical (except alignment).
The main differences:
- etl is compatible with c++11 while others, including SG14, typically requires c++14
- etl one has no member/non-member function
swap()
,operator==(nullptr_t)
,operator!=(nullptr_t)
. - etl does not utilize aligned storage, which will be deprecated in c++23.
- etl renames most of the class and variable names, except the name "inplace_function", which can be renamed too.
- etl simplifies some template meta programming with etl type_traits header
- move almost all stuffs in private namespace into private sections of classes.
typename T, | ||
typename C = etl::decay_t<T>, | ||
typename = etl::enable_if_t< | ||
!private_inplace_function::is_inplace_function<C>::value && etl::is_invocable_r<R, C&, Args...>::value>> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class has limited usefulness as is restricted to STL and C++14 and above.
Many of the users of the ETL do not/cannot use the STL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
etl::is_invocable_r
depends on ETL_USING_CPP11
but not STL.
I updated to make etl::inplace_function
compatible to c++11.
Provide similar api to std::function. Store a callable inside the inplace_function object's member field in a type-erasure way. The member field, i.e. storage or buffer, has a compile-time fixed size. The size is specify either by the macro ETL_INPLACE_FUNCTION_DEFAULT_CAPACITY or a non-type template parameter. The implementation is inspired by: 1. SG14 inplace_function 2. folly::Function 3. function2
f20d0ab
to
af095d7
Compare
Provide similar api to std::function.
Current use case is mainly to hold a r-value lambda object, which etl::delegate is unsuitable since etl::delegate does not extend the lifetime of r-value lambda object.
Store a callable inside the inplace_function object's member field in a type-erasure way.
The member field, i.e. storage or buffer, has a compile-time fixed size.
The size is specified either by the macro ETL_INPLACE_FUNCTION_DEFAULT_CAPACITY or a non-type template parameter.
The implementation is inspired by: