Skip to content

Add support for post-construction Init to interface_ptr #156

@thirtytwobits

Description

@thirtytwobits

for systems without exceptions enabled we need a way to call a concrete "init" method after the constructor when using the type-erasers in interface_ptr. The most generalized approach would use a lambda. For example:

    template <typename Interface, typename PmrAllocator, typename... Args>
    CETL_NODISCARD static InterfacePtr<Interface> make_unique_w_initializer(PmrAllocator alloc, std::function<bool(typename PmrAllocator::value_type&)>&& initializer, Args&&... args)
    {
        // Allocate memory for the concrete object.
        // Then try to construct it in-place - it could potentially throw,
        // so RAII will deallocate the memory BUT won't try to destroy the uninitialized object!
        //
        ConcreteRaii<PmrAllocator> concrete_raii{alloc};
        if (auto* const concrete_ptr = concrete_raii.get())
        {
            concrete_raii.construct(std::forward<Args>(args)...);
            if (not initializer(*concrete_ptr)) {
                // Initializer failed. UNDO! UNDO!
                concrete_raii.release();
            }
        }

        // Everything is good, so now we can move ownership of the concrete object to the interface smart pointer.
        //
        return InterfacePtr<Interface>{concrete_raii.release(), PmrInterfaceDeleter<Interface>{alloc, 1}};
    }

Here, the protocol is a pointer is passed into the init method iff allocation succeeds. If the init method returns nullptr then we destroy the object and return a nullptr in the InterfacePtr otherwise we continue normally. Use might look like:

struct MyType : public MyInterface {
    bool Init() {
        return true;
    }
};


auto result = cetl::pmr::InterfaceFactory::make_unique_w_initializer<MyInterface>(concrete_allocator, [](MyType& p) { return p.Init(); });

Additional output from init can be obtained by using the lambda capture. Reliance on the SMO for std::function, of course, applies.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions