Date: Mon, 20 May 2024 22:59:45 +0100
On Mon, May 20, 2024 at 9:51 PM Sebastian Wittmeier via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> This feature request could be also made to a standard library function.
>
> // Calls the constructor and a setup function. With guaranteed RVO.
>
> T std::factory<T>(params, ..., setup)
>
> No need for other language changes or any special exception handling.
I've tried to implement it here:
https://godbolt.org/z/v99dvGqnn
And here it is copy-pasted:
namespace std {
namespace details {
template<typename T>
struct Derived : T {
template<typename... Params, typename Setup>
Derived(Params&&... args, Setup &&arg) : T(
static_cast<Params&&>(args)... )
{
static_assert( sizeof (Derived) == sizeof (T) );
static_assert( alignof(Derived) == alignof(T) );
static_cast<Setup&&>(arg)( static_cast<T*>(this) );
}
template<typename Setup>
struct Maker {
template<typename... Params>
static Derived Make(Params&&... args, Setup &&setup)
{
return Derived{ static_cast<Params&&>(args)...,
static_cast<Setup&&>(setup) };
}
};
};
}
template<typename T, typename... Params, typename Setup>
T factory(Params&&... args, Setup &&setup)
{
using namespace details;
auto const f1 = &Derived<T>::template Maker<Setup&&>::template
Make<Params&&...>;
auto const f2 = *static_cast<T(*const
*)(Params&&...,Setup&&)>(static_cast<void const*>(&f1));
return f2( static_cast<Setup&&>(setup) );
}
}
#include <mutex>
using std::mutex;
mutex FuncReturnsLockedMutex(void)
{
return std::factory<mutex>( [](mutex *p){p->lock();} );
}
int main(void)
{
mutex m = FuncReturnsLockedMutex();
m.unlock();
}
<std-proposals_at_[hidden]> wrote:
>
> This feature request could be also made to a standard library function.
>
> // Calls the constructor and a setup function. With guaranteed RVO.
>
> T std::factory<T>(params, ..., setup)
>
> No need for other language changes or any special exception handling.
I've tried to implement it here:
https://godbolt.org/z/v99dvGqnn
And here it is copy-pasted:
namespace std {
namespace details {
template<typename T>
struct Derived : T {
template<typename... Params, typename Setup>
Derived(Params&&... args, Setup &&arg) : T(
static_cast<Params&&>(args)... )
{
static_assert( sizeof (Derived) == sizeof (T) );
static_assert( alignof(Derived) == alignof(T) );
static_cast<Setup&&>(arg)( static_cast<T*>(this) );
}
template<typename Setup>
struct Maker {
template<typename... Params>
static Derived Make(Params&&... args, Setup &&setup)
{
return Derived{ static_cast<Params&&>(args)...,
static_cast<Setup&&>(setup) };
}
};
};
}
template<typename T, typename... Params, typename Setup>
T factory(Params&&... args, Setup &&setup)
{
using namespace details;
auto const f1 = &Derived<T>::template Maker<Setup&&>::template
Make<Params&&...>;
auto const f2 = *static_cast<T(*const
*)(Params&&...,Setup&&)>(static_cast<void const*>(&f1));
return f2( static_cast<Setup&&>(setup) );
}
}
#include <mutex>
using std::mutex;
mutex FuncReturnsLockedMutex(void)
{
return std::factory<mutex>( [](mutex *p){p->lock();} );
}
int main(void)
{
mutex m = FuncReturnsLockedMutex();
m.unlock();
}
Received on 2024-05-20 21:59:57