cxx icon indicating copy to clipboard operation
cxx copied to clipboard

Interaction with custom holder types

Open ADKaster opened this issue 3 years ago • 0 comments

pybind11 has the notion of a "custom holder type" that allows declaring a non-::std wrapper type for types passed to and from python from C++.

https://pybind11.readthedocs.io/en/stable/advanced/smart_ptrs.html#custom-smart-pointers

Has there been any activity on supporting a feature like this for cxx?

For fun I started looking at how hard it would be to create rust bindings for the SerenityOS set of libraries, and pretty much immediately ran into the problem that all reference-counted types use a custom intrusive reference count CRTP pattern.

i.e., the custom AK::RefPtr type knows how to call T::ref() and T::unref(), while the reference count and actual implementation happens in class Foo : public RefCounted<Foo>.

The only way that makes sense to me to bind this category of types as I start looking into this is to introduce a wrapper type that owns a RefPtr to the type in question, and then expose a factory function to create a unique_ptr<FooWrapper>, like so in a shim header:

class Foo; // Actual C++ type I wanted to bind

class FooWrapper
{
public:
    explicit FooWrapper(NonnullRefPtr<Foo> impl) : m_impl(std::move(impl)) {}
    
    Foo& pin_mut() { return *m_impl; }
    Foo const& pin() const { return *m_impl; }
private:
     NonnullRefPtr<Foo> m_impl;
};

inline std:;unique_ptr<FooWrapper> create_foo(FooCtorArgs args)
{
    return std::make_unique<FooWrapper>(make_ref_counted<Foo>(std::move(args)));
}

This adds an unfortunate level of indirection, and an extra heap allocation for my types.

Is there another, more obvious way to solve this problem?

I suspect that copy + paste of the SharedPtr<T> implementation with the type names changed to my custom reference counted pointer type would get me 90% of the way there, but surely there's other folks who are trying to do similar things?

ADKaster avatar Jan 20 '23 09:01 ADKaster