Cleaning up changes to existing unit tests.

parent 6e9dd601
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
# pragma warning(disable: 4324) // warning C4324: structure was padded due to alignment specifier # pragma warning(disable: 4324) // warning C4324: structure was padded due to alignment specifier
#endif #endif
namespace {
// test_brace_initialization // test_brace_initialization
struct NoBraceInitialization { struct NoBraceInitialization {
NoBraceInitialization(std::vector<int> v) : vec{std::move(v)} {} NoBraceInitialization(std::vector<int> v) : vec{std::move(v)} {}
...@@ -32,14 +34,17 @@ struct NoBraceInitialization { ...@@ -32,14 +34,17 @@ struct NoBraceInitialization {
std::vector<int> vec; std::vector<int> vec;
}; };
// test_mismatched_holder
struct MismatchBase1 { }; struct MismatchBase1 { };
struct MismatchDerived1 : MismatchBase1 { }; struct MismatchDerived1 : MismatchBase1 { };
struct MismatchBase2 { }; struct MismatchBase2 { };
struct MismatchDerived2 : MismatchBase2 { }; struct MismatchDerived2 : MismatchBase2 { };
// test_multiple_instances_with_same_pointer
struct SamePointer {}; struct SamePointer {};
} // namespace
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(MismatchBase1, std::shared_ptr<MismatchBase1>) PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(MismatchBase1, std::shared_ptr<MismatchBase1>)
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(MismatchDerived1, std::unique_ptr<MismatchDerived1>) PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(MismatchDerived1, std::unique_ptr<MismatchDerived1>)
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(MismatchBase2, std::unique_ptr<MismatchBase2>) PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(MismatchBase2, std::unique_ptr<MismatchBase2>)
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include "pybind11_tests.h" #include "pybind11_tests.h"
#include "constructor_stats.h" #include "constructor_stats.h"
namespace {
// Many bases for testing that multiple inheritance from many classes (i.e. requiring extra // Many bases for testing that multiple inheritance from many classes (i.e. requiring extra
// space for holder constructed flags) works. // space for holder constructed flags) works.
template <int N> struct BaseN { template <int N> struct BaseN {
...@@ -43,26 +45,27 @@ int WithStatic2::static_value2 = 2; ...@@ -43,26 +45,27 @@ int WithStatic2::static_value2 = 2;
int VanillaStaticMix1::static_value = 12; int VanillaStaticMix1::static_value = 12;
int VanillaStaticMix2::static_value = 12; int VanillaStaticMix2::static_value = 12;
namespace { // test_multiple_inheritance_virtbase
struct Base1a {
struct Base1a {
Base1a(int i) : i(i) { } Base1a(int i) : i(i) { }
int foo() { return i; } int foo() { return i; }
int i; int i;
}; };
struct Base2a { struct Base2a {
Base2a(int i) : i(i) { } Base2a(int i) : i(i) { }
int bar() { return i; } int bar() { return i; }
int i; int i;
}; };
struct Base12a : Base1a, Base2a { struct Base12a : Base1a, Base2a {
Base12a(int i, int j) : Base1a(i), Base2a(j) { } Base12a(int i, int j) : Base1a(i), Base2a(j) { }
}; };
struct I801B1 { int a = 1; I801B1() = default; I801B1(const I801B1 &) = default; virtual ~I801B1() = default; }; // test_mi_unaligned_base
struct I801B2 { int b = 2; I801B2() = default; I801B2(const I801B2 &) = default; virtual ~I801B2() = default; }; // test_mi_base_return
struct I801C : I801B1, I801B2 {}; struct I801B1 { int a = 1; I801B1() = default; I801B1(const I801B1 &) = default; virtual ~I801B1() = default; };
struct I801D : I801C {}; // Indirect MI struct I801B2 { int b = 2; I801B2() = default; I801B2(const I801B2 &) = default; virtual ~I801B2() = default; };
struct I801C : I801B1, I801B2 {};
struct I801D : I801C {}; // Indirect MI
} // namespace } // namespace
......
...@@ -15,23 +15,7 @@ ...@@ -15,23 +15,7 @@
#include "pybind11_tests.h" #include "pybind11_tests.h"
#include "object.h" #include "object.h"
// Make pybind aware of the ref-counted wrapper type (s): 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.
PYBIND11_DECLARE_HOLDER_TYPE(T, ref<T>, true);
// Make pybind11 aware of the non-standard getter member function
namespace pybind11 { 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
// 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>);
// This is just a wrapper around unique_ptr, but with extra fields to deliberately bloat up the // 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 // holder size to trigger the non-simple-layout internal instance layout for single inheritance with
...@@ -43,7 +27,6 @@ public: ...@@ -43,7 +27,6 @@ public:
huge_unique_ptr(T *p) : ptr(p) {}; huge_unique_ptr(T *p) : ptr(p) {};
T *get() { return ptr.get(); } T *get() { return ptr.get(); }
}; };
PYBIND11_DECLARE_HOLDER_TYPE(T, huge_unique_ptr<T>);
// Simple custom holder that works like unique_ptr // Simple custom holder that works like unique_ptr
template <typename T> template <typename T>
...@@ -54,7 +37,6 @@ public: ...@@ -54,7 +37,6 @@ public:
T* get() const { return impl.get(); } T* get() const { return impl.get(); }
T* release_ptr() { return impl.release(); } T* release_ptr() { return impl.release(); }
}; };
PYBIND11_DECLARE_HOLDER_TYPE(T, custom_unique_ptr<T>);
// Simple custom holder that works like shared_ptr and has operator& overload // 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 // To obtain address of an instance of this holder pybind should use std::addressof
...@@ -68,7 +50,6 @@ public: ...@@ -68,7 +50,6 @@ public:
T* get() const { return impl.get(); } T* get() const { return impl.get(); }
T** operator&() { throw std::logic_error("Call of overloaded operator& is not expected"); } T** operator&() { throw std::logic_error("Call of overloaded operator& is not expected"); }
}; };
PYBIND11_DECLARE_HOLDER_TYPE(T, shared_ptr_with_addressof_operator<T>);
// Simple custom holder that works like unique_ptr and has operator& overload // 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 // To obtain address of an instance of this holder pybind should use std::addressof
...@@ -83,48 +64,46 @@ public: ...@@ -83,48 +64,46 @@ public:
T* release_ptr() { return impl.release(); } T* release_ptr() { return impl.release(); }
T** operator&() { throw std::logic_error("Call of overloaded operator& is not expected"); } T** operator&() { throw std::logic_error("Call of overloaded operator& is not expected"); }
}; };
PYBIND11_DECLARE_HOLDER_TYPE(T, unique_ptr_with_addressof_operator<T>);
namespace { // Custom object with builtin reference counting (see 'object.h' for the implementation)
// Custom object with builtin reference counting (see 'object.h' for the implementation) class MyObject1 : public Object {
class MyObject1 : public Object { public:
public:
MyObject1(int value) : value(value) { print_created(this, toString()); } MyObject1(int value) : value(value) { print_created(this, toString()); }
std::string toString() const override { return "MyObject1[" + std::to_string(value) + "]"; } std::string toString() const override { return "MyObject1[" + std::to_string(value) + "]"; }
protected: protected:
~MyObject1() override { print_destroyed(this); } ~MyObject1() override { print_destroyed(this); }
private: private:
int value; int value;
}; };
// Object managed by a std::shared_ptr<> // Object managed by a std::shared_ptr<>
class MyObject2 { class MyObject2 {
public: public:
MyObject2(const MyObject2 &) = default; MyObject2(const MyObject2 &) = default;
MyObject2(int value) : value(value) { print_created(this, toString()); } MyObject2(int value) : value(value) { print_created(this, toString()); }
std::string toString() const { return "MyObject2[" + std::to_string(value) + "]"; } std::string toString() const { return "MyObject2[" + std::to_string(value) + "]"; }
virtual ~MyObject2() { print_destroyed(this); } virtual ~MyObject2() { print_destroyed(this); }
private: private:
int value; int value;
}; };
// Object managed by a std::shared_ptr<>, additionally derives from std::enable_shared_from_this<> // Object managed by a std::shared_ptr<>, additionally derives from std::enable_shared_from_this<>
class MyObject3 : public std::enable_shared_from_this<MyObject3> { class MyObject3 : public std::enable_shared_from_this<MyObject3> {
public: public:
MyObject3(const MyObject3 &) = default; MyObject3(const MyObject3 &) = default;
MyObject3(int value) : value(value) { print_created(this, toString()); } MyObject3(int value) : value(value) { print_created(this, toString()); }
std::string toString() const { return "MyObject3[" + std::to_string(value) + "]"; } std::string toString() const { return "MyObject3[" + std::to_string(value) + "]"; }
virtual ~MyObject3() { print_destroyed(this); } virtual ~MyObject3() { print_destroyed(this); }
private: private:
int value; int value;
}; };
// test_unique_nodelete // test_unique_nodelete
// Object with a private destructor // Object with a private destructor
class MyObject4; class MyObject4;
static std::unordered_set<MyObject4 *> myobject4_instances; static std::unordered_set<MyObject4 *> myobject4_instances;
class MyObject4 { class MyObject4 {
public: public:
MyObject4(int value) : value{value} { MyObject4(int value) : value{value} {
print_created(this); print_created(this);
myobject4_instances.insert(this); myobject4_instances.insert(this);
...@@ -137,20 +116,20 @@ namespace { ...@@ -137,20 +116,20 @@ namespace {
for (auto o : tmp) for (auto o : tmp)
delete o; delete o;
} }
private: private:
~MyObject4() { ~MyObject4() {
myobject4_instances.erase(this); myobject4_instances.erase(this);
print_destroyed(this); print_destroyed(this);
} }
}; };
// test_unique_deleter // test_unique_deleter
// Object with std::unique_ptr<T, D> where D is not matching the base class // Object with std::unique_ptr<T, D> where D is not matching the base class
// Object with a protected destructor // Object with a protected destructor
class MyObject4a; class MyObject4a;
static std::unordered_set<MyObject4a *> myobject4a_instances; static std::unordered_set<MyObject4a *> myobject4a_instances;
class MyObject4a { class MyObject4a {
public: public:
MyObject4a(int i) { MyObject4a(int i) {
value = i; value = i;
print_created(this); print_created(this);
...@@ -164,30 +143,30 @@ namespace { ...@@ -164,30 +143,30 @@ namespace {
for (auto o : tmp) for (auto o : tmp)
delete o; delete o;
} }
protected: protected:
virtual ~MyObject4a() { virtual ~MyObject4a() {
myobject4a_instances.erase(this); myobject4a_instances.erase(this);
print_destroyed(this); print_destroyed(this);
} }
}; };
// Object derived but with public destructor and no Deleter in default holder // Object derived but with public destructor and no Deleter in default holder
class MyObject4b : public MyObject4a { class MyObject4b : public MyObject4a {
public: public:
MyObject4b(int i) : MyObject4a(i) { print_created(this); } MyObject4b(int i) : MyObject4a(i) { print_created(this); }
~MyObject4b() override { print_destroyed(this); } ~MyObject4b() override { print_destroyed(this); }
}; };
// test_large_holder // test_large_holder
class MyObject5 { // managed by huge_unique_ptr class MyObject5 { // managed by huge_unique_ptr
public: public:
MyObject5(int value) : value{value} { print_created(this); } MyObject5(int value) : value{value} { print_created(this); }
~MyObject5() { print_destroyed(this); } ~MyObject5() { print_destroyed(this); }
int value; int value;
}; };
// test_shared_ptr_and_references // test_shared_ptr_and_references
struct SharedPtrRef { struct SharedPtrRef {
struct A { struct A {
A() { print_created(this); } A() { print_created(this); }
A(const A &) { print_copy_created(this); } A(const A &) { print_copy_created(this); }
...@@ -197,10 +176,10 @@ namespace { ...@@ -197,10 +176,10 @@ namespace {
A value = {}; A value = {};
std::shared_ptr<A> shared = std::make_shared<A>(); std::shared_ptr<A> shared = std::make_shared<A>();
}; };
// test_shared_ptr_from_this_and_references // test_shared_ptr_from_this_and_references
struct SharedFromThisRef { struct SharedFromThisRef {
struct B : std::enable_shared_from_this<B> { struct B : std::enable_shared_from_this<B> {
B() { print_created(this); } B() { print_created(this); }
B(const B &) : std::enable_shared_from_this<B>() { print_copy_created(this); } B(const B &) : std::enable_shared_from_this<B>() { print_copy_created(this); }
...@@ -210,24 +189,24 @@ namespace { ...@@ -210,24 +189,24 @@ namespace {
B value = {}; B value = {};
std::shared_ptr<B> shared = std::make_shared<B>(); std::shared_ptr<B> shared = std::make_shared<B>();
}; };
// Issue #865: shared_from_this doesn't work with virtual inheritance // Issue #865: shared_from_this doesn't work with virtual inheritance
struct SharedFromThisVBase : std::enable_shared_from_this<SharedFromThisVBase> { struct SharedFromThisVBase : std::enable_shared_from_this<SharedFromThisVBase> {
SharedFromThisVBase() = default; SharedFromThisVBase() = default;
SharedFromThisVBase(const SharedFromThisVBase &) = default; SharedFromThisVBase(const SharedFromThisVBase &) = default;
virtual ~SharedFromThisVBase() = default; virtual ~SharedFromThisVBase() = default;
}; };
struct SharedFromThisVirt : virtual SharedFromThisVBase {}; struct SharedFromThisVirt : virtual SharedFromThisVBase {};
// test_move_only_holder // test_move_only_holder
struct C { struct C {
C() { print_created(this); } C() { print_created(this); }
~C() { print_destroyed(this); } ~C() { print_destroyed(this); }
}; };
// test_holder_with_addressof_operator // test_holder_with_addressof_operator
struct TypeForHolderWithAddressOf { struct TypeForHolderWithAddressOf {
TypeForHolderWithAddressOf() { print_created(this); } TypeForHolderWithAddressOf() { print_created(this); }
TypeForHolderWithAddressOf(const TypeForHolderWithAddressOf &) { print_copy_created(this); } TypeForHolderWithAddressOf(const TypeForHolderWithAddressOf &) { print_copy_created(this); }
TypeForHolderWithAddressOf(TypeForHolderWithAddressOf &&) { print_move_created(this); } TypeForHolderWithAddressOf(TypeForHolderWithAddressOf &&) { print_move_created(this); }
...@@ -236,41 +215,63 @@ namespace { ...@@ -236,41 +215,63 @@ namespace {
return "TypeForHolderWithAddressOf[" + std::to_string(value) + "]"; return "TypeForHolderWithAddressOf[" + std::to_string(value) + "]";
} }
int value = 42; int value = 42;
}; };
// test_move_only_holder_with_addressof_operator // test_move_only_holder_with_addressof_operator
struct TypeForMoveOnlyHolderWithAddressOf { struct TypeForMoveOnlyHolderWithAddressOf {
TypeForMoveOnlyHolderWithAddressOf(int value) : value{value} { print_created(this); } TypeForMoveOnlyHolderWithAddressOf(int value) : value{value} { print_created(this); }
~TypeForMoveOnlyHolderWithAddressOf() { print_destroyed(this); } ~TypeForMoveOnlyHolderWithAddressOf() { print_destroyed(this); }
std::string toString() const { std::string toString() const {
return "MoveOnlyHolderWithAddressOf[" + std::to_string(value) + "]"; return "MoveOnlyHolderWithAddressOf[" + std::to_string(value) + "]";
} }
int value; int value;
}; };
// test_smart_ptr_from_default // test_smart_ptr_from_default
struct HeldByDefaultHolder { }; struct HeldByDefaultHolder { };
// test_shared_ptr_gc // test_shared_ptr_gc
// #187: issue involving std::shared_ptr<> return value policy & garbage collection // #187: issue involving std::shared_ptr<> return value policy & garbage collection
struct ElementBase { struct ElementBase {
virtual ~ElementBase() = default; /* Force creation of virtual table */ virtual ~ElementBase() = default; /* Force creation of virtual table */
ElementBase() = default; ElementBase() = default;
ElementBase(const ElementBase&) = delete; ElementBase(const ElementBase&) = delete;
}; };
struct ElementA : ElementBase { struct ElementA : ElementBase {
ElementA(int v) : v(v) { } ElementA(int v) : v(v) { }
int value() { return v; } int value() { return v; }
int v; int v;
}; };
struct ElementList { struct ElementList {
void add(std::shared_ptr<ElementBase> e) { l.push_back(e); } void add(std::shared_ptr<ElementBase> e) { l.push_back(e); }
std::vector<std::shared_ptr<ElementBase>> l; std::vector<std::shared_ptr<ElementBase>> l;
}; };
} // namespace } // 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 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
// Make pybind aware of the ref-counted wrapper type (s):
PYBIND11_DECLARE_HOLDER_TYPE(T, ref<T>, true);
// 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>);
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(Object, ref<Object>) PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(Object, ref<Object>)
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(MyObject1, ref<MyObject1>) PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(MyObject1, ref<MyObject1>)
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(MyObject2, std::shared_ptr<MyObject2>) PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(MyObject2, std::shared_ptr<MyObject2>)
...@@ -295,8 +296,7 @@ PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(ElementList, std::shared_ptr<ElementL ...@@ -295,8 +296,7 @@ PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(ElementList, std::shared_ptr<ElementL
#ifdef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT #ifdef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
// To prevent triggering a static_assert in the smart_holder code. // To prevent triggering a static_assert in the smart_holder code.
// This is a very special case, because the associated test exercises a holder mismatch. // This is a very special case, because the associated test exercises a holder mismatch.
namespace pybind11 { namespace pybind11 { namespace detail {
namespace detail {
template <> template <>
class type_caster<std::shared_ptr<HeldByDefaultHolder>> class type_caster<std::shared_ptr<HeldByDefaultHolder>>
: public copyable_holder_caster<HeldByDefaultHolder, std::shared_ptr<HeldByDefaultHolder>> {}; : public copyable_holder_caster<HeldByDefaultHolder, std::shared_ptr<HeldByDefaultHolder>> {};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment