Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
pybind11
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
pybind11
Commits
dc10e8a9
Commit
dc10e8a9
authored
Feb 15, 2021
by
Ralf W. Grosse-Kunstleve
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'test_unique_ptr_member' into pr2672_use_smart_holder_as_default
parents
5cf93a08
a569281f
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
225 additions
and
217 deletions
+225
-217
include/pybind11/cast.h
+9
-9
tests/test_class.cpp
+6
-1
tests/test_multiple_inheritance.cpp
+22
-19
tests/test_smart_ptr.cpp
+188
-188
No files found.
include/pybind11/cast.h
View file @
dc10e8a9
...
@@ -1237,7 +1237,7 @@ struct smart_holder_type_caster_load {
...
@@ -1237,7 +1237,7 @@ struct smart_holder_type_caster_load {
}
}
T
*
loaded_as_raw_ptr_unowned
()
const
{
T
*
loaded_as_raw_ptr_unowned
()
const
{
void
*
void_ptr
=
load_impl
.
unowned_void_ptr_from_direct_conversion
;
// UNTESTED.
void
*
void_ptr
=
load_impl
.
unowned_void_ptr_from_direct_conversion
;
if
(
void_ptr
==
nullptr
)
{
if
(
void_ptr
==
nullptr
)
{
if
(
have_holder
())
{
if
(
have_holder
())
{
throw_if_uninitialized_or_disowned_holder
();
throw_if_uninitialized_or_disowned_holder
();
...
@@ -1259,7 +1259,7 @@ struct smart_holder_type_caster_load {
...
@@ -1259,7 +1259,7 @@ struct smart_holder_type_caster_load {
std
::
shared_ptr
<
T
>
loaded_as_shared_ptr
()
const
{
std
::
shared_ptr
<
T
>
loaded_as_shared_ptr
()
const
{
if
(
load_impl
.
unowned_void_ptr_from_direct_conversion
!=
nullptr
)
if
(
load_impl
.
unowned_void_ptr_from_direct_conversion
!=
nullptr
)
throw
cast_error
(
"Unowned pointer from direct conversion cannot be converted to a"
throw
cast_error
(
"Unowned pointer from direct conversion cannot be converted to a"
" std::shared_ptr."
);
// UNTESTED.
" std::shared_ptr."
);
if
(
!
have_holder
())
return
nullptr
;
if
(
!
have_holder
())
return
nullptr
;
throw_if_uninitialized_or_disowned_holder
();
throw_if_uninitialized_or_disowned_holder
();
std
::
shared_ptr
<
void
>
void_ptr
=
holder
().
template
as_shared_ptr
<
void
>
();
std
::
shared_ptr
<
void
>
void_ptr
=
holder
().
template
as_shared_ptr
<
void
>
();
...
@@ -1270,13 +1270,13 @@ struct smart_holder_type_caster_load {
...
@@ -1270,13 +1270,13 @@ struct smart_holder_type_caster_load {
std
::
unique_ptr
<
T
,
D
>
loaded_as_unique_ptr
(
const
char
*
context
=
"loaded_as_unique_ptr"
)
{
std
::
unique_ptr
<
T
,
D
>
loaded_as_unique_ptr
(
const
char
*
context
=
"loaded_as_unique_ptr"
)
{
if
(
load_impl
.
unowned_void_ptr_from_direct_conversion
!=
nullptr
)
if
(
load_impl
.
unowned_void_ptr_from_direct_conversion
!=
nullptr
)
throw
cast_error
(
"Unowned pointer from direct conversion cannot be converted to a"
throw
cast_error
(
"Unowned pointer from direct conversion cannot be converted to a"
" std::unique_ptr."
);
// UNTESTED.
" std::unique_ptr."
);
if
(
!
have_holder
())
return
nullptr
;
if
(
!
have_holder
())
return
nullptr
;
throw_if_uninitialized_or_disowned_holder
();
throw_if_uninitialized_or_disowned_holder
();
holder
().
template
ensure_compatible_rtti_uqp_del
<
T
,
D
>
(
context
);
holder
().
template
ensure_compatible_rtti_uqp_del
<
T
,
D
>
(
context
);
holder
().
ensure_use_count_1
(
context
);
holder
().
ensure_use_count_1
(
context
);
auto
raw_void_ptr
=
holder
().
template
as_raw_ptr_unowned
<
void
>
();
auto
raw_void_ptr
=
holder
().
template
as_raw_ptr_unowned
<
void
>
();
// MISSING: Safety checks for type conversions
//
SMART_HOLDER_WIP:
MISSING: Safety checks for type conversions
// (T must be polymorphic or meet certain other conditions).
// (T must be polymorphic or meet certain other conditions).
T
*
raw_type_ptr
=
convert_type
(
raw_void_ptr
);
T
*
raw_type_ptr
=
convert_type
(
raw_void_ptr
);
...
@@ -1325,7 +1325,7 @@ private:
...
@@ -1325,7 +1325,7 @@ private:
}
}
};
};
// IMPROVABLE: Formally factor out of type_caster_base.
//
SMART_HOLDER_WIP:
IMPROVABLE: Formally factor out of type_caster_base.
struct
make_constructor
:
private
type_caster_base
<
int
>
{
// Any type, nothing special about int.
struct
make_constructor
:
private
type_caster_base
<
int
>
{
// Any type, nothing special about int.
using
type_caster_base
<
int
>::
Constructor
;
using
type_caster_base
<
int
>::
Constructor
;
using
type_caster_base
<
int
>::
make_copy_constructor
;
using
type_caster_base
<
int
>::
make_copy_constructor
;
...
@@ -1501,7 +1501,7 @@ struct smart_holder_type_caster<std::shared_ptr<T>> : smart_holder_type_caster_l
...
@@ -1501,7 +1501,7 @@ struct smart_holder_type_caster<std::shared_ptr<T>> : smart_holder_type_caster_l
static
handle
cast
(
const
std
::
shared_ptr
<
T
>
&
src
,
return_value_policy
policy
,
handle
parent
)
{
static
handle
cast
(
const
std
::
shared_ptr
<
T
>
&
src
,
return_value_policy
policy
,
handle
parent
)
{
if
(
policy
!=
return_value_policy
::
automatic
if
(
policy
!=
return_value_policy
::
automatic
&&
policy
!=
return_value_policy
::
reference_internal
)
{
&&
policy
!=
return_value_policy
::
reference_internal
)
{
// IMPROVABLE: Error message.
//
SMART_HOLDER_WIP:
IMPROVABLE: Error message.
throw
cast_error
(
"Invalid return_value_policy for shared_ptr."
);
throw
cast_error
(
"Invalid return_value_policy for shared_ptr."
);
}
}
...
@@ -1513,8 +1513,8 @@ struct smart_holder_type_caster<std::shared_ptr<T>> : smart_holder_type_caster_l
...
@@ -1513,8 +1513,8 @@ struct smart_holder_type_caster<std::shared_ptr<T>> : smart_holder_type_caster_l
void
*
src_raw_void_ptr
=
static_cast
<
void
*>
(
src_raw_ptr
);
void
*
src_raw_void_ptr
=
static_cast
<
void
*>
(
src_raw_ptr
);
const
detail
::
type_info
*
tinfo
=
st
.
second
;
const
detail
::
type_info
*
tinfo
=
st
.
second
;
if
(
handle
existing_inst
=
find_registered_python_instance
(
src_raw_void_ptr
,
tinfo
))
if
(
handle
existing_inst
=
find_registered_python_instance
(
src_raw_void_ptr
,
tinfo
))
// MISSING: Enforcement of consistency with existing smart_holder.
//
SMART_HOLDER_WIP:
MISSING: Enforcement of consistency with existing smart_holder.
// MISSING: keep_alive.
//
SMART_HOLDER_WIP:
MISSING: keep_alive.
return
existing_inst
;
return
existing_inst
;
auto
inst
=
reinterpret_steal
<
object
>
(
make_new_instance
(
tinfo
->
type
));
auto
inst
=
reinterpret_steal
<
object
>
(
make_new_instance
(
tinfo
->
type
));
...
@@ -1566,7 +1566,7 @@ struct smart_holder_type_caster<std::unique_ptr<T, D>> : smart_holder_type_caste
...
@@ -1566,7 +1566,7 @@ struct smart_holder_type_caster<std::unique_ptr<T, D>> : smart_holder_type_caste
if
(
policy
!=
return_value_policy
::
automatic
if
(
policy
!=
return_value_policy
::
automatic
&&
policy
!=
return_value_policy
::
reference_internal
&&
policy
!=
return_value_policy
::
reference_internal
&&
policy
!=
return_value_policy
::
move
)
{
&&
policy
!=
return_value_policy
::
move
)
{
// IMPROVABLE: Error message.
//
SMART_HOLDER_WIP:
IMPROVABLE: Error message.
throw
cast_error
(
"Invalid return_value_policy for unique_ptr."
);
throw
cast_error
(
"Invalid return_value_policy for unique_ptr."
);
}
}
...
...
tests/test_class.cpp
View file @
dc10e8a9
...
@@ -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
>
)
...
...
tests/test_multiple_inheritance.cpp
View file @
dc10e8a9
...
@@ -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
...
...
tests/test_smart_ptr.cpp
View file @
dc10e8a9
...
@@ -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,194 +64,214 @@ public:
...
@@ -83,194 +64,214 @@ 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
);
}
}
int
value
;
int
value
;
static
void
cleanupAllInstances
()
{
static
void
cleanupAllInstances
()
{
auto
tmp
=
std
::
move
(
myobject4_instances
);
auto
tmp
=
std
::
move
(
myobject4_instances
);
myobject4_instances
.
clear
();
myobject4_instances
.
clear
();
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
);
myobject4a_instances
.
insert
(
this
);
myobject4a_instances
.
insert
(
this
);
};
int
value
;
static
void
cleanupAllInstances
()
{
auto
tmp
=
std
::
move
(
myobject4a_instances
);
myobject4a_instances
.
clear
();
for
(
auto
o
:
tmp
)
delete
o
;
}
protected
:
virtual
~
MyObject4a
()
{
myobject4a_instances
.
erase
(
this
);
print_destroyed
(
this
);
}
};
};
int
value
;
static
void
cleanupAllInstances
()
{
auto
tmp
=
std
::
move
(
myobject4a_instances
);
myobject4a_instances
.
clear
();
for
(
auto
o
:
tmp
)
delete
o
;
}
protected
:
virtual
~
MyObject4a
()
{
myobject4a_instances
.
erase
(
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
);
}
A
(
A
&&
)
{
print_move_created
(
this
);
}
A
(
A
&&
)
{
print_move_created
(
this
);
}
~
A
()
{
print_destroyed
(
this
);
}
~
A
()
{
print_destroyed
(
this
);
}
};
A
value
=
{};
std
::
shared_ptr
<
A
>
shared
=
std
::
make_shared
<
A
>
();
};
};
// test_shared_ptr_from_this_and_references
A
value
=
{};
struct
SharedFromThisRef
{
std
::
shared_ptr
<
A
>
shared
=
std
::
make_shared
<
A
>
();
struct
B
:
std
::
enable_shared_from_this
<
B
>
{
};
B
()
{
print_created
(
this
);
}
B
(
const
B
&
)
:
std
::
enable_shared_from_this
<
B
>
()
{
print_copy_created
(
this
);
}
B
(
B
&&
)
:
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
>
();
};
// Issue #865: shared_from_this doesn't work with virtual inheritance
// test_shared_ptr_from_this_and_references
struct
SharedFromThisVBase
:
std
::
enable_shared_from_this
<
SharedFromThisVBase
>
{
struct
SharedFromThisRef
{
SharedFromThisVBase
()
=
default
;
struct
B
:
std
::
enable_shared_from_this
<
B
>
{
SharedFromThisVBase
(
const
SharedFromThisVBase
&
)
=
default
;
B
()
{
print_created
(
this
);
}
virtual
~
SharedFromThisVBase
()
=
default
;
B
(
const
B
&
)
:
std
::
enable_shared_from_this
<
B
>
()
{
print_copy_created
(
this
);
}
B
(
B
&&
)
:
std
::
enable_shared_from_this
<
B
>
()
{
print_move_created
(
this
);
}
~
B
()
{
print_destroyed
(
this
);
}
};
};
struct
SharedFromThisVirt
:
virtual
SharedFromThisVBase
{};
// test_move_only_holder
B
value
=
{};
struct
C
{
std
::
shared_ptr
<
B
>
shared
=
std
::
make_shared
<
B
>
();
C
()
{
print_created
(
this
);
}
};
~
C
()
{
print_destroyed
(
this
);
}
};
// test_holder_with_addressof_operator
// Issue #865: shared_from_this doesn't work with virtual inheritance
struct
TypeForHolderWithAddressOf
{
struct
SharedFromThisVBase
:
std
::
enable_shared_from_this
<
SharedFromThisVBase
>
{
TypeForHolderWithAddressOf
()
{
print_created
(
this
);
}
SharedFromThisVBase
()
=
default
;
TypeForHolderWithAddressOf
(
const
TypeForHolderWithAddressOf
&
)
{
print_copy_created
(
this
);
}
SharedFromThisVBase
(
const
SharedFromThisVBase
&
)
=
default
;
TypeForHolderWithAddressOf
(
TypeForHolderWithAddressOf
&&
)
{
print_move_created
(
this
);
}
virtual
~
SharedFromThisVBase
()
=
default
;
~
TypeForHolderWithAddressOf
()
{
print_destroyed
(
this
);
}
};
std
::
string
toString
()
const
{
struct
SharedFromThisVirt
:
virtual
SharedFromThisVBase
{};
return
"TypeForHolderWithAddressOf["
+
std
::
to_string
(
value
)
+
"]"
;
}
int
value
=
42
;
};
// test_move_only_holder_with_addressof_operator
// test_move_only_holder
struct
TypeForMoveOnlyHolderWithAddressOf
{
struct
C
{
TypeForMoveOnlyHolderWithAddressOf
(
int
value
)
:
value
{
value
}
{
print_created
(
this
);
}
C
()
{
print_created
(
this
);
}
~
TypeForMoveOnlyHolderWithAddressOf
()
{
print_destroyed
(
this
);
}
~
C
()
{
print_destroyed
(
this
);
}
std
::
string
toString
()
const
{
};
return
"MoveOnlyHolderWithAddressOf["
+
std
::
to_string
(
value
)
+
"]"
;
}
int
value
;
};
// test_smart_ptr_from_default
// test_holder_with_addressof_operator
struct
HeldByDefaultHolder
{
};
struct
TypeForHolderWithAddressOf
{
TypeForHolderWithAddressOf
()
{
print_created
(
this
);
}
TypeForHolderWithAddressOf
(
const
TypeForHolderWithAddressOf
&
)
{
print_copy_created
(
this
);
}
TypeForHolderWithAddressOf
(
TypeForHolderWithAddressOf
&&
)
{
print_move_created
(
this
);
}
~
TypeForHolderWithAddressOf
()
{
print_destroyed
(
this
);
}
std
::
string
toString
()
const
{
return
"TypeForHolderWithAddressOf["
+
std
::
to_string
(
value
)
+
"]"
;
}
int
value
=
42
;
};
// test_shared_ptr_gc
// test_move_only_holder_with_addressof_operator
// #187: issue involving std::shared_ptr<> return value policy & garbage collection
struct
TypeForMoveOnlyHolderWithAddressOf
{
struct
ElementBase
{
TypeForMoveOnlyHolderWithAddressOf
(
int
value
)
:
value
{
value
}
{
print_created
(
this
);
}
virtual
~
ElementBase
()
=
default
;
/* Force creation of virtual table */
~
TypeForMoveOnlyHolderWithAddressOf
()
{
print_destroyed
(
this
);
}
ElementBase
()
=
default
;
std
::
string
toString
()
const
{
ElementBase
(
const
ElementBase
&
)
=
delete
;
return
"MoveOnlyHolderWithAddressOf["
+
std
::
to_string
(
value
)
+
"]"
;
};
}
int
value
;
};
struct
ElementA
:
ElementBase
{
// test_smart_ptr_from_default
ElementA
(
int
v
)
:
v
(
v
)
{
}
struct
HeldByDefaultHolder
{
};
int
value
()
{
return
v
;
}
int
v
;
// 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
{
ElementA
(
int
v
)
:
v
(
v
)
{
}
int
value
()
{
return
v
;
}
int
v
;
};
struct
ElementList
{
void
add
(
std
::
shared_ptr
<
ElementBase
>
e
)
{
l
.
push_back
(
e
);
}
std
::
vector
<
std
::
shared_ptr
<
ElementBase
>>
l
;
};
struct
ElementList
{
void
add
(
std
::
shared_ptr
<
ElementBase
>
e
)
{
l
.
push_back
(
e
);
}
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
>>
{};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment