C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::elide

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
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();
}

Received on 2024-05-20 21:59:57