/*
    tests/test_smart_ptr.cpp -- binding classes with custom reference counting,
    implicit conversions between types

    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/

#include "object.h"
#include "pybind11_tests.h"

// This breaks on PYBIND11_DECLARE_HOLDER_TYPE
PYBIND11_WARNING_DISABLE_GCC("-Wpedantic")

namespace {

// This is just a wrapper around unique_ptr, but with extra fields to deliberately bloat up the
// holder size to trigger the non-simple-layout internal instance layout for single inheritance
// with large holder type:
template <typename T>
class huge_unique_ptr {
    std::unique_ptr<T> ptr;
    uint64_t padding[10];

public:
    explicit huge_unique_ptr(T *p) : ptr(p) {}
    T *get() { return ptr.get(); }
};

// Simple custom holder that works like unique_ptr
template <typename T>
class custom_unique_ptr {
    std::unique_ptr<T> impl;

public:
    explicit custom_unique_ptr(T *p) : impl(p) {}
    T *get() const { return impl.get(); }
    T *release_ptr() { return impl.release(); }
};

// Simple custom holder that works like shared_ptr and has operator& overload
// To obtain address of an instance of this holder pybind should use std::addressof
// Attempt to get address via operator& may leads to segmentation fault
template <typename T>
class shared_ptr_with_addressof_operator {
    std::shared_ptr<T> impl;

public:
    shared_ptr_with_addressof_operator() = default;
    explicit shared_ptr_with_addressof_operator(T *p) : impl(p) {}
    T *get() const { return impl.get(); }
    T **operator&() { throw std::logic_error("Call of overloaded operator& is not expected"); }
};

// Simple custom holder that works like unique_ptr and has operator& overload
// To obtain address of an instance of this holder pybind should use std::addressof
// Attempt to get address via operator& may leads to segmentation fault
template <typename T>
class unique_ptr_with_addressof_operator {
    std::unique_ptr<T> impl;

public:
    unique_ptr_with_addressof_operator() = default;
    explicit unique_ptr_with_addressof_operator(T *p) : impl(p) {}
    T *get() const { return impl.get(); }
    T *release_ptr() { return impl.release(); }
    T **operator&() { throw std::logic_error("Call of overloaded operator& is not expected"); }
};

// Simple custom holder that imitates smart pointer, that always stores cpointer to const
template <class T>
class const_only_shared_ptr {
    std::shared_ptr<const T> ptr_;

public:
    const_only_shared_ptr() = default;
    explicit const_only_shared_ptr(const T *ptr) : ptr_(ptr) {}
    const T *get() const { return ptr_.get(); }

private:
    // for demonstration purpose only, this imitates smart pointer with a const-only pointer
};

template <typename T>
class shared_ptr_as_custom_holder {
    std::shared_ptr<T> ptr_;

public:
    using element_type = T;

    shared_ptr_as_custom_holder() = default;

    explicit shared_ptr_as_custom_holder(T *) {
        throw std::runtime_error("invalid shared_ptr_as_custom_holder constructor call");
    }

    explicit shared_ptr_as_custom_holder(std::shared_ptr<T> ptr) : ptr_(std::move(ptr)) {}

    T *get() const { return ptr_.get(); }
};

// Custom object with builtin reference counting (see 'object.h' for the implementation)
class MyObject1 : public Object {
public:
    explicit MyObject1(int value) : value(value) { print_created(this, toString()); }
    std::string toString() const override { return "MyObject1[" + std::to_string(value) + "]"; }

protected:
    ~MyObject1() override { print_destroyed(this); }

private:
    int value;
};

// Object managed by a std::shared_ptr<>
class MyObject2 {
public:
    MyObject2(const MyObject2 &) = default;
    explicit MyObject2(int value) : value(value) { print_created(this, toString()); }
    std::string toString() const { return "MyObject2[" + std::to_string(value) + "]"; }
    virtual ~MyObject2() { print_destroyed(this); }

private:
    int value;
};

// Object managed by a std::shared_ptr<>, additionally derives from std::enable_shared_from_this<>
class MyObject3 : public std::enable_shared_from_this<MyObject3> {
public:
    MyObject3(const MyObject3 &) = default;
    explicit MyObject3(int value) : value(value) { print_created(this, toString()); }
    std::string toString() const { return "MyObject3[" + std::to_string(value) + "]"; }
    virtual ~MyObject3() { print_destroyed(this); }

private:
    int value;
};

template <typename T>
std::unordered_set<T *> &pointer_set() {
    // https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables
    static auto singleton = new std::unordered_set<T *>();
    return *singleton;
}

// test_unique_nodelete
// Object with a private destructor
class MyObject4 {
public:
    explicit MyObject4(int value) : value{value} {
        print_created(this);
        pointer_set<MyObject4>().insert(this);
    }
    int value;

    static void cleanupAllInstances() {
        auto tmp = std::move(pointer_set<MyObject4>());
        pointer_set<MyObject4>().clear();
        for (auto *o : tmp) {
            delete o;
        }
    }

private:
    ~MyObject4() {
        pointer_set<MyObject4>().erase(this);
        print_destroyed(this);
    }
};

// test_unique_deleter
// Object with std::unique_ptr<T, D> where D is not matching the base class
// Object with a protected destructor
class MyObject4a {
public:
    explicit MyObject4a(int i) : value{i} {
        print_created(this);
        pointer_set<MyObject4a>().insert(this);
    };
    MyObject4a(const MyObject4a &) = delete;

    int value;

    static void cleanupAllInstances() {
        auto tmp = std::move(pointer_set<MyObject4a>());
        pointer_set<MyObject4a>().clear();
        for (auto *o : tmp) {
            delete o;
        }
    }

protected:
    virtual ~MyObject4a() {
        pointer_set<MyObject4a>().erase(this);
        print_destroyed(this);
    }
};

// Object derived but with public destructor and no Deleter in default holder
class MyObject4b : public MyObject4a {
public:
    explicit MyObject4b(int i) : MyObject4a(i) { print_created(this); }
    MyObject4b(const MyObject4b &) = delete;
    ~MyObject4b() override { print_destroyed(this); }
};

// test_large_holder
class MyObject5 { // managed by huge_unique_ptr
public:
    explicit MyObject5(int value) : value{value} { print_created(this); }
    MyObject5(const MyObject5 &) = delete;
    ~MyObject5() { print_destroyed(this); }
    int value;
};

// test const_only_shared_ptr
class MyObject6 {
public:
    static const_only_shared_ptr<MyObject6> createObject(std::string value) {
        return const_only_shared_ptr<MyObject6>(new MyObject6(std::move(value)));
    }

    const std::string &value() const { return value_; }

private:
    explicit MyObject6(std::string &&value) : value_{std::move(value)} {}
    std::string value_;
};

// test_shared_ptr_and_references
struct SharedPtrRef {
    struct A {
        A() { print_created(this); }
        A(const A &) { print_copy_created(this); }
        A(A &&) noexcept { print_move_created(this); }
        ~A() { print_destroyed(this); }
    };

    A value;
    std::shared_ptr<A> shared = std::make_shared<A>();
};

// test_shared_ptr_from_this_and_references
struct SharedFromThisRef {
    struct B : std::enable_shared_from_this<B> {
        B() { print_created(this); }
        // NOLINTNEXTLINE(bugprone-copy-constructor-init, readability-redundant-member-init)
        B(const B &) : std::enable_shared_from_this<B>() { print_copy_created(this); }
        // NOLINTNEXTLINE(readability-redundant-member-init)
        B(B &&) noexcept : std::enable_shared_from_this<B>() { print_move_created(this); }
        ~B() { print_destroyed(this); }
    };

    B value;
    std::shared_ptr<B> shared = std::make_shared<B>();
};

class Issue6064UnsafePath {
public:
    static std::shared_ptr<Issue6064UnsafePath> create() {
        return {new Issue6064UnsafePath(), [](Issue6064UnsafePath *ptr) { delete ptr; }};
    }

private:
    Issue6064UnsafePath() = default;
    ~Issue6064UnsafePath() = default;
};

// Issue #865: shared_from_this doesn't work with virtual inheritance
struct SharedFromThisVBase : std::enable_shared_from_this<SharedFromThisVBase> {
    SharedFromThisVBase() = default;
    SharedFromThisVBase(const SharedFromThisVBase &) = default;
    virtual ~SharedFromThisVBase() = default;
};
struct SharedFromThisVirt : virtual SharedFromThisVBase {};

// Issue #5989: static_pointer_cast where dynamic_pointer_cast is needed
// (virtual inheritance with shared_ptr holder)
struct SftVirtBase : std::enable_shared_from_this<SftVirtBase> {
    SftVirtBase() = default;
    virtual ~SftVirtBase() = default;
    static std::shared_ptr<SftVirtBase> create() { return std::make_shared<SftVirtBase>(); }
    virtual std::string name() { return "SftVirtBase"; }
};
struct SftVirtDerived : SftVirtBase {
    using SftVirtBase::SftVirtBase;
    static std::shared_ptr<SftVirtDerived> create() { return std::make_shared<SftVirtDerived>(); }
    std::string name() override { return "SftVirtDerived"; }
};
struct SftVirtDerived2 : virtual SftVirtDerived {
    using SftVirtDerived::SftVirtDerived;
    static std::shared_ptr<SftVirtDerived2> create() {
        return std::make_shared<SftVirtDerived2>();
    }
    std::string name() override { return "SftVirtDerived2"; }
    std::string call_name(const std::shared_ptr<SftVirtDerived2> &d2) { return d2->name(); }
};

// test_move_only_holder
struct C {
    C() { print_created(this); }
    C(const C &) = delete;
    ~C() { print_destroyed(this); }
};

// test_holder_with_addressof_operator
struct TypeForHolderWithAddressOf {
    TypeForHolderWithAddressOf() { print_created(this); }
    TypeForHolderWithAddressOf(const TypeForHolderWithAddressOf &) { print_copy_created(this); }
    TypeForHolderWithAddressOf(TypeForHolderWithAddressOf &&) noexcept {
        print_move_created(this);
    }
    ~TypeForHolderWithAddressOf() { print_destroyed(this); }
    std::string toString() const {
        return "TypeForHolderWithAddressOf[" + std::to_string(value) + "]";
    }
    int value = 42;
};

// test_move_only_holder_with_addressof_operator
struct TypeForMoveOnlyHolderWithAddressOf {
    explicit TypeForMoveOnlyHolderWithAddressOf(int value) : value{value} { print_created(this); }
    TypeForMoveOnlyHolderWithAddressOf(const TypeForMoveOnlyHolderWithAddressOf &) = delete;
    ~TypeForMoveOnlyHolderWithAddressOf() { print_destroyed(this); }
    std::string toString() const {
        return "MoveOnlyHolderWithAddressOf[" + std::to_string(value) + "]";
    }
    int value;
};

// test_smart_ptr_from_default
struct HeldByDefaultHolder {};

// test_shared_ptr_gc
// #187: issue involving std::shared_ptr<> return value policy & garbage collection
struct ElementBase {
    virtual ~ElementBase() = default; /* Force creation of virtual table */
    ElementBase() = default;
    ElementBase(const ElementBase &) = delete;
};

struct ElementA : ElementBase {
    explicit ElementA(int v) : v(v) {}
    int value() const { return v; }
    int v;
};

struct ElementList {
    void add(const std::shared_ptr<ElementBase> &e) { l.push_back(e); }
    std::vector<std::shared_ptr<ElementBase>> l;
};

} // namespace

// ref<T> is a wrapper for 'Object' which uses intrusive reference counting
// It is always possible to construct a ref<T> from an Object* pointer without
// possible inconsistencies, hence the 'true' argument at the end.
// Make pybind11 aware of the non-standard getter member function
namespace PYBIND11_NAMESPACE {
namespace detail {
template <typename T>
struct holder_helper<ref<T>> {
    static const T *get(const ref<T> &p) { return p.get_ptr(); }
};
} // namespace detail
} // namespace PYBIND11_NAMESPACE

// Make pybind aware of the ref-counted wrapper type (s):
PYBIND11_DECLARE_HOLDER_TYPE(T, ref<T>, true)
PYBIND11_DECLARE_HOLDER_TYPE(T, const_only_shared_ptr<T>, true)
PYBIND11_DECLARE_HOLDER_TYPE(T, shared_ptr_as_custom_holder<T>)
// The following is not required anymore for std::shared_ptr, but it should compile without error:
PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr<T>)
PYBIND11_DECLARE_HOLDER_TYPE(T, huge_unique_ptr<T>)
PYBIND11_DECLARE_HOLDER_TYPE(T, custom_unique_ptr<T>)
PYBIND11_DECLARE_HOLDER_TYPE(T, shared_ptr_with_addressof_operator<T>)
PYBIND11_DECLARE_HOLDER_TYPE(T, unique_ptr_with_addressof_operator<T>)

namespace holder_caster_traits_test {
struct example_base {};
} // namespace holder_caster_traits_test

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail)

// Negate this condition to demonstrate "ambiguous template instantiation" compilation error:
#if defined(PYBIND11_HAS_INTERNALS_WITH_SMART_HOLDER_SUPPORT)
template <typename ExampleType>
struct copyable_holder_caster_shared_ptr_with_smart_holder_support_enabled<
    ExampleType,
    enable_if_t<std::is_base_of<holder_caster_traits_test::example_base, ExampleType>::value>>
    : std::false_type {};
#endif

template <typename ExampleType, typename HolderType>
struct copyable_holder_caster<
    ExampleType,
    HolderType,
    enable_if_t<std::is_base_of<holder_caster_traits_test::example_base, ExampleType>::value>> {
    static constexpr auto name = const_name<ExampleType>();

    static handle cast(const HolderType &, return_value_policy, handle) {
        return str("copyable_holder_caster_traits_test").release();
    }
};

// Negate this condition to demonstrate "ambiguous template instantiation" compilation error:
#if defined(PYBIND11_HAS_INTERNALS_WITH_SMART_HOLDER_SUPPORT)
template <typename ExampleType>
struct move_only_holder_caster_unique_ptr_with_smart_holder_support_enabled<
    ExampleType,
    enable_if_t<std::is_base_of<holder_caster_traits_test::example_base, ExampleType>::value>>
    : std::false_type {};
#endif

template <typename ExampleType, typename HolderType>
struct move_only_holder_caster<
    ExampleType,
    HolderType,
    enable_if_t<std::is_base_of<holder_caster_traits_test::example_base, ExampleType>::value>> {
    static constexpr auto name = const_name<ExampleType>();

    static handle cast(const HolderType &, return_value_policy, handle) {
        return str("move_only_holder_caster_traits_test").release();
    }
};

PYBIND11_NAMESPACE_END(detail)
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

namespace holder_caster_traits_test {

struct example_drvd : example_base {};

void wrap(py::module_ &m) {
    m.def("return_std_shared_ptr_example_drvd",
          // NOLINTNEXTLINE(modernize-make-shared)
          []() { return std::shared_ptr<example_drvd>(new example_drvd()); });
    m.def("return_std_unique_ptr_example_drvd",
          []() { return std::unique_ptr<example_drvd>(new example_drvd()); });
}

} // namespace holder_caster_traits_test

TEST_SUBMODULE(smart_ptr, m) {
    // Please do not interleave `struct` and `class` definitions with bindings code,
    // but implement `struct`s and `class`es in the anonymous namespace above.
    // This helps keeping the smart_holder branch in sync with master.

    // test_smart_ptr

    // Object implementation in `object.h`
    py::class_<Object, ref<Object>> obj(m, "Object");
    obj.def("getRefCount", &Object::getRefCount);

    py::class_<MyObject1, ref<MyObject1>>(m, "MyObject1", obj).def(py::init<int>());
    py::implicitly_convertible<py::int_, MyObject1>();

    m.def("make_object_1", []() -> Object * { return new MyObject1(1); });
    m.def("make_object_2", []() -> ref<Object> { return ref<Object>(new MyObject1(2)); });
    m.def("make_myobject1_1", []() -> MyObject1 * { return new MyObject1(4); });
    m.def("make_myobject1_2", []() -> ref<MyObject1> { return ref<MyObject1>(new MyObject1(5)); });
    m.def("print_object_1", [](const Object *obj) { py::print(obj->toString()); });
    m.def("print_object_2", [](ref<Object> obj) { py::print(obj->toString()); });
    m.def("print_object_3", [](const ref<Object> &obj) { py::print(obj->toString()); });
    m.def("print_object_4", [](const ref<Object> *obj) { py::print((*obj)->toString()); });
    m.def("print_myobject1_1", [](const MyObject1 *obj) { py::print(obj->toString()); });
    m.def("print_myobject1_2", [](ref<MyObject1> obj) { py::print(obj->toString()); });
    m.def("print_myobject1_3", [](const ref<MyObject1> &obj) { py::print(obj->toString()); });
    m.def("print_myobject1_4", [](const ref<MyObject1> *obj) { py::print((*obj)->toString()); });

    // Expose constructor stats for the ref type
    m.def("cstats_ref", &ConstructorStats::get<ref_tag>);

    py::class_<MyObject2, std::shared_ptr<MyObject2>>(m, "MyObject2").def(py::init<int>());
    m.def("make_myobject2_1", []() { return new MyObject2(6); });
    m.def("make_myobject2_2", []() { return std::make_shared<MyObject2>(7); });
    m.def("print_myobject2_1", [](const MyObject2 *obj) { py::print(obj->toString()); });
    // NOLINTNEXTLINE(performance-unnecessary-value-param)
    m.def("print_myobject2_2", [](std::shared_ptr<MyObject2> obj) { py::print(obj->toString()); });
    m.def("print_myobject2_3",
          [](const std::shared_ptr<MyObject2> &obj) { py::print(obj->toString()); });
    m.def("print_myobject2_4",
          [](const std::shared_ptr<MyObject2> *obj) { py::print((*obj)->toString()); });

    py::class_<MyObject3, std::shared_ptr<MyObject3>>(m, "MyObject3").def(py::init<int>());
    m.def("make_myobject3_1", []() { return new MyObject3(8); });
    m.def("make_myobject3_2", []() { return std::make_shared<MyObject3>(9); });
    m.def("print_myobject3_1", [](const MyObject3 *obj) { py::print(obj->toString()); });
    // NOLINTNEXTLINE(performance-unnecessary-value-param)
    m.def("print_myobject3_2", [](std::shared_ptr<MyObject3> obj) { py::print(obj->toString()); });
    m.def("print_myobject3_3",
          [](const std::shared_ptr<MyObject3> &obj) { py::print(obj->toString()); });
    m.def("print_myobject3_4",
          [](const std::shared_ptr<MyObject3> *obj) { py::print((*obj)->toString()); });

    // test_smart_ptr_refcounting
    m.def("test_object1_refcounting", []() {
        auto o = ref<MyObject1>(new MyObject1(0));
        bool good = o->getRefCount() == 1;
        py::object o2 = py::cast(o, py::return_value_policy::reference);
        // always request (partial) ownership for objects with intrusive
        // reference counting even when using the 'reference' RVP
        good &= o->getRefCount() == 2;
        return good;
    });

    // test_unique_nodelete
    py::class_<MyObject4, std::unique_ptr<MyObject4, py::nodelete>>(m, "MyObject4")
        .def(py::init<int>())
        .def_readwrite("value", &MyObject4::value)
        .def_static("cleanup_all_instances", &MyObject4::cleanupAllInstances);

    // test_unique_deleter
    py::class_<MyObject4a, std::unique_ptr<MyObject4a, py::nodelete>>(m, "MyObject4a")
        .def(py::init<int>())
        .def_readwrite("value", &MyObject4a::value)
        .def_static("cleanup_all_instances", &MyObject4a::cleanupAllInstances);

    py::class_<MyObject4b, MyObject4a, std::unique_ptr<MyObject4b>>(m, "MyObject4b")
        .def(py::init<int>());

    // test_large_holder
    py::class_<MyObject5, huge_unique_ptr<MyObject5>>(m, "MyObject5")
        .def(py::init<int>())
        .def_readwrite("value", &MyObject5::value);

    py::class_<MyObject6, const_only_shared_ptr<MyObject6>>(m, "MyObject6")
        .def(py::init([](const std::string &value) { return MyObject6::createObject(value); }))
        .def_property_readonly("value", &MyObject6::value);

    py::class_<Issue6064UnsafePath, shared_ptr_as_custom_holder<Issue6064UnsafePath>>(
        m, "Issue6064UnsafePath");
    m.def("get_issue6064_unsafe_path_shared_ptr", []() { return Issue6064UnsafePath::create(); });

    // test_shared_ptr_and_references
    using A = SharedPtrRef::A;
    py::class_<A, std::shared_ptr<A>>(m, "A");
    py::class_<SharedPtrRef, std::unique_ptr<SharedPtrRef>>(m, "SharedPtrRef")
        .def(py::init<>())
        .def_readonly("ref", &SharedPtrRef::value)
        .def_property_readonly(
            "copy", [](const SharedPtrRef &s) { return s.value; }, py::return_value_policy::copy)
        .def_readonly("holder_ref", &SharedPtrRef::shared)
        .def_property_readonly(
            "holder_copy",
            [](const SharedPtrRef &s) { return s.shared; },
            py::return_value_policy::copy)
        .def("set_ref", [](SharedPtrRef &, const A &) { return true; })
        // NOLINTNEXTLINE(performance-unnecessary-value-param)
        .def("set_holder", [](SharedPtrRef &, std::shared_ptr<A>) { return true; });

    // test_shared_ptr_from_this_and_references
    using B = SharedFromThisRef::B;
    py::class_<B, std::shared_ptr<B>>(m, "B");
    py::class_<SharedFromThisRef, std::unique_ptr<SharedFromThisRef>>(m, "SharedFromThisRef")
        .def(py::init<>())
        .def_readonly("bad_wp", &SharedFromThisRef::value)
        .def_property_readonly("ref",
                               [](const SharedFromThisRef &s) -> const B & { return *s.shared; })
        .def_property_readonly(
            "copy",
            [](const SharedFromThisRef &s) { return s.value; },
            py::return_value_policy::copy)
        .def_readonly("holder_ref", &SharedFromThisRef::shared)
        .def_property_readonly(
            "holder_copy",
            [](const SharedFromThisRef &s) { return s.shared; },
            py::return_value_policy::copy)
        .def("set_ref", [](SharedFromThisRef &, const B &) { return true; })
        // NOLINTNEXTLINE(performance-unnecessary-value-param)
        .def("set_holder", [](SharedFromThisRef &, std::shared_ptr<B>) { return true; });

    // Issue #865: shared_from_this doesn't work with virtual inheritance
    static std::shared_ptr<SharedFromThisVirt> sft(new SharedFromThisVirt());
    py::class_<SharedFromThisVirt, std::shared_ptr<SharedFromThisVirt>>(m, "SharedFromThisVirt")
        .def_static("get", []() { return sft.get(); });

    // Issue #5989: static_pointer_cast where dynamic_pointer_cast is needed
    py::class_<SftVirtBase, std::shared_ptr<SftVirtBase>>(m, "SftVirtBase")
        .def(py::init<>(&SftVirtBase::create))
        .def("name", &SftVirtBase::name);
    py::class_<SftVirtDerived, SftVirtBase, std::shared_ptr<SftVirtDerived>>(m, "SftVirtDerived")
        .def(py::init<>(&SftVirtDerived::create));
    py::class_<SftVirtDerived2, SftVirtDerived, std::shared_ptr<SftVirtDerived2>>(
        m, "SftVirtDerived2")
        .def(py::init<>(&SftVirtDerived2::create))
        .def("call_name", &SftVirtDerived2::call_name, py::arg("d2"));

    // test_move_only_holder
    py::class_<C, custom_unique_ptr<C>>(m, "TypeWithMoveOnlyHolder")
        .def_static("make", []() { return custom_unique_ptr<C>(new C); })
        .def_static("make_as_object", []() { return py::cast(custom_unique_ptr<C>(new C)); });
    m.def("get_type_with_move_only_holder_shared_ptr", []() { return std::make_shared<C>(); });

    // test_holder_with_addressof_operator
    using HolderWithAddressOf = shared_ptr_with_addressof_operator<TypeForHolderWithAddressOf>;
    py::class_<TypeForHolderWithAddressOf, HolderWithAddressOf>(m, "TypeForHolderWithAddressOf")
        .def_static("make", []() { return HolderWithAddressOf(new TypeForHolderWithAddressOf); })
        .def("get", [](const HolderWithAddressOf &self) { return self.get(); })
        .def("print_object_1",
             [](const TypeForHolderWithAddressOf *obj) { py::print(obj->toString()); })
        // NOLINTNEXTLINE(performance-unnecessary-value-param)
        .def("print_object_2", [](HolderWithAddressOf obj) { py::print(obj.get()->toString()); })
        .def("print_object_3",
             [](const HolderWithAddressOf &obj) { py::print(obj.get()->toString()); })
        .def("print_object_4",
             [](const HolderWithAddressOf *obj) { py::print((*obj).get()->toString()); });

    // test_move_only_holder_with_addressof_operator
    using MoveOnlyHolderWithAddressOf
        = unique_ptr_with_addressof_operator<TypeForMoveOnlyHolderWithAddressOf>;
    py::class_<TypeForMoveOnlyHolderWithAddressOf, MoveOnlyHolderWithAddressOf>(
        m, "TypeForMoveOnlyHolderWithAddressOf")
        .def_static("make",
                    []() {
                        return MoveOnlyHolderWithAddressOf(
                            new TypeForMoveOnlyHolderWithAddressOf(0));
                    })
        .def_readwrite("value", &TypeForMoveOnlyHolderWithAddressOf::value)
        .def("print_object",
             [](const TypeForMoveOnlyHolderWithAddressOf *obj) { py::print(obj->toString()); });

    // test_smart_ptr_from_default
    py::class_<HeldByDefaultHolder, std::unique_ptr<HeldByDefaultHolder>>(m, "HeldByDefaultHolder")
        .def(py::init<>())
        // NOLINTNEXTLINE(performance-unnecessary-value-param)
        .def_static("load_shared_ptr", [](std::shared_ptr<HeldByDefaultHolder>) {});

    // test_shared_ptr_gc
    // #187: issue involving std::shared_ptr<> return value policy & garbage collection
    py::class_<ElementBase, std::shared_ptr<ElementBase>>(m, "ElementBase");

    py::class_<ElementA, ElementBase, std::shared_ptr<ElementA>>(m, "ElementA")
        .def(py::init<int>())
        .def("value", &ElementA::value);

    py::class_<ElementList, std::shared_ptr<ElementList>>(m, "ElementList")
        .def(py::init<>())
        .def("add", &ElementList::add)
        .def("get", [](ElementList &el) {
            py::list list;
            for (auto &e : el.l) {
                list.append(py::cast(e));
            }
            return list;
        });

    // NOLINTNEXTLINE(bugprone-incorrect-enable-shared-from-this)
    class PrivateESFT : /* implicit private */ std::enable_shared_from_this<PrivateESFT> {};
    struct ContainerUsingPrivateESFT {
        std::shared_ptr<PrivateESFT> ptr;
    };
    py::class_<ContainerUsingPrivateESFT>(m, "ContainerUsingPrivateESFT")
        .def(py::init<>())
        .def_readwrite("ptr",
                       &ContainerUsingPrivateESFT::ptr); // <- access ESFT through shared_ptr

    holder_caster_traits_test::wrap(m);
}
