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
ab7d11f2
Commit
ab7d11f2
authored
Jan 24, 2021
by
Ralf W. Grosse-Kunstleve
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adding py::smart_holder support to py::class_, purging py::classh completely.
parent
eb567866
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
73 additions
and
11 deletions
+73
-11
include/pybind11/cast.h
+3
-1
include/pybind11/classh.h
+0
-0
include/pybind11/detail/classh_type_casters.h
+36
-0
include/pybind11/pybind11.h
+17
-1
tests/classh_module_local_0.cpp
+1
-0
tests/classh_module_local_1.cpp
+2
-1
tests/classh_module_local_2.cpp
+2
-1
tests/test_classh_inheritance.cpp
+6
-5
tests/test_classh_wip.cpp
+3
-1
tests/test_unique_ptr_member.cpp
+3
-1
No files found.
include/pybind11/cast.h
View file @
ab7d11f2
...
@@ -1621,6 +1621,7 @@ using type_caster_holder = conditional_t<is_copy_constructible<holder_type>::val
...
@@ -1621,6 +1621,7 @@ using type_caster_holder = conditional_t<is_copy_constructible<holder_type>::val
copyable_holder_caster
<
type
,
holder_type
>
,
copyable_holder_caster
<
type
,
holder_type
>
,
move_only_holder_caster
<
type
,
holder_type
>>
;
move_only_holder_caster
<
type
,
holder_type
>>
;
template
<
typename
T
,
bool
Value
=
false
>
struct
is_smart_holder
{
static
constexpr
bool
value
=
Value
;
};
template
<
typename
T
,
bool
Value
=
false
>
struct
always_construct_holder
{
static
constexpr
bool
value
=
Value
;
};
template
<
typename
T
,
bool
Value
=
false
>
struct
always_construct_holder
{
static
constexpr
bool
value
=
Value
;
};
/// Create a specialization for custom holder types (silently ignores std::shared_ptr)
/// Create a specialization for custom holder types (silently ignores std::shared_ptr)
...
@@ -1635,7 +1636,8 @@ template <typename T, bool Value = false> struct always_construct_holder { stati
...
@@ -1635,7 +1636,8 @@ template <typename T, bool Value = false> struct always_construct_holder { stati
// PYBIND11_DECLARE_HOLDER_TYPE holder types:
// PYBIND11_DECLARE_HOLDER_TYPE holder types:
template
<
typename
base
,
typename
holder
>
struct
is_holder_type
:
template
<
typename
base
,
typename
holder
>
struct
is_holder_type
:
std
::
is_base_of
<
detail
::
type_caster_holder
<
base
,
holder
>
,
detail
::
type_caster
<
holder
>>
{};
detail
::
any_of
<
std
::
is_base_of
<
detail
::
type_caster_holder
<
base
,
holder
>
,
detail
::
type_caster
<
holder
>>
,
detail
::
is_smart_holder
<
holder
>>
{};
// Specialization for always-supported unique_ptr holders:
// Specialization for always-supported unique_ptr holders:
template
<
typename
base
,
typename
deleter
>
struct
is_holder_type
<
base
,
std
::
unique_ptr
<
base
,
deleter
>>
:
template
<
typename
base
,
typename
deleter
>
struct
is_holder_type
<
base
,
std
::
unique_ptr
<
base
,
deleter
>>
:
std
::
true_type
{};
std
::
true_type
{};
...
...
include/pybind11/classh.h
View file @
ab7d11f2
This diff is collapsed.
Click to expand it.
include/pybind11/detail/classh_type_casters.h
View file @
ab7d11f2
...
@@ -631,5 +631,41 @@ struct classh_type_caster<std::unique_ptr<T const>> : smart_holder_type_caster_l
...
@@ -631,5 +631,41 @@ struct classh_type_caster<std::unique_ptr<T const>> : smart_holder_type_caster_l
} \
} \
}
}
template
<>
struct
is_smart_holder
<
pybindit
::
memory
::
smart_holder
>
:
is_smart_holder
<
pybindit
::
memory
::
smart_holder
,
true
>
{
static
decltype
(
&
modified_type_caster_generic_load_impl
::
local_load
)
get_type_caster_local_load_function_ptr
()
{
return
&
modified_type_caster_generic_load_impl
::
local_load
;
}
template
<
typename
T
>
static
void
init_instance_for_type
(
detail
::
instance
*
inst
,
const
void
*
holder_const_void_ptr
)
{
// Need for const_cast is a consequence of the type_info::init_instance type:
// void (*init_instance)(instance *, const void *);
auto
holder_void_ptr
=
const_cast
<
void
*>
(
holder_const_void_ptr
);
auto
v_h
=
inst
->
get_value_and_holder
(
detail
::
get_type_info
(
typeid
(
T
)));
if
(
!
v_h
.
instance_registered
())
{
register_instance
(
inst
,
v_h
.
value_ptr
(),
v_h
.
type
);
v_h
.
set_instance_registered
();
}
using
holder_type
=
pybindit
::
memory
::
smart_holder
;
if
(
holder_void_ptr
)
{
// Note: inst->owned ignored.
auto
holder_ptr
=
static_cast
<
holder_type
*>
(
holder_void_ptr
);
new
(
std
::
addressof
(
v_h
.
holder
<
holder_type
>
()))
holder_type
(
std
::
move
(
*
holder_ptr
));
}
else
if
(
inst
->
owned
)
{
new
(
std
::
addressof
(
v_h
.
holder
<
holder_type
>
()))
holder_type
(
holder_type
::
from_raw_ptr_take_ownership
(
v_h
.
value_ptr
<
T
>
()));
}
else
{
new
(
std
::
addressof
(
v_h
.
holder
<
holder_type
>
()))
holder_type
(
holder_type
::
from_raw_ptr_unowned
(
v_h
.
value_ptr
<
T
>
()));
}
v_h
.
set_holder_constructed
();
}
};
}
// namespace detail
}
// namespace detail
}
// namespace pybind11
}
// namespace pybind11
include/pybind11/pybind11.h
View file @
ab7d11f2
...
@@ -1294,7 +1294,7 @@ public:
...
@@ -1294,7 +1294,7 @@ public:
/* Process optional arguments, if any */
/* Process optional arguments, if any */
process_attributes
<
Extra
...
>::
init
(
extra
...,
&
record
);
process_attributes
<
Extra
...
>::
init
(
extra
...,
&
record
);
generic_type
::
initialize
(
record
,
&
type_caster_generic
::
local_loa
d
);
generic_type
_initialize
(
recor
d
);
if
(
has_alias
)
{
if
(
has_alias
)
{
auto
&
instances
=
record
.
module_local
?
registered_local_types_cpp
()
:
get_internals
().
registered_types_cpp
;
auto
&
instances
=
record
.
module_local
?
registered_local_types_cpp
()
:
get_internals
().
registered_types_cpp
;
...
@@ -1502,6 +1502,16 @@ public:
...
@@ -1502,6 +1502,16 @@ public:
}
}
private
:
private
:
template
<
typename
H
=
holder_type
,
detail
::
enable_if_t
<!
detail
::
is_smart_holder
<
H
>::
value
,
int
>
=
0
>
void
generic_type_initialize
(
const
detail
::
type_record
&
record
)
{
generic_type
::
initialize
(
record
,
&
detail
::
type_caster_generic
::
local_load
);
}
template
<
typename
H
=
holder_type
,
detail
::
enable_if_t
<
detail
::
is_smart_holder
<
H
>::
value
,
int
>
=
0
>
void
generic_type_initialize
(
const
detail
::
type_record
&
record
)
{
generic_type
::
initialize
(
record
,
detail
::
is_smart_holder
<
H
>::
get_type_caster_local_load_function_ptr
());
}
/// Initialize holder object, variant 1: object derives from enable_shared_from_this
/// Initialize holder object, variant 1: object derives from enable_shared_from_this
template
<
typename
T
>
template
<
typename
T
>
static
void
init_holder
(
detail
::
instance
*
inst
,
detail
::
value_and_holder
&
v_h
,
static
void
init_holder
(
detail
::
instance
*
inst
,
detail
::
value_and_holder
&
v_h
,
...
@@ -1547,6 +1557,7 @@ private:
...
@@ -1547,6 +1557,7 @@ private:
/// instance. Should be called as soon as the `type` value_ptr is set for an instance. Takes an
/// instance. Should be called as soon as the `type` value_ptr is set for an instance. Takes an
/// optional pointer to an existing holder to use; if not specified and the instance is
/// optional pointer to an existing holder to use; if not specified and the instance is
/// `.owned`, a new holder will be constructed to manage the value pointer.
/// `.owned`, a new holder will be constructed to manage the value pointer.
template
<
typename
H
=
holder_type
,
detail
::
enable_if_t
<!
detail
::
is_smart_holder
<
H
>::
value
,
int
>
=
0
>
static
void
init_instance
(
detail
::
instance
*
inst
,
const
void
*
holder_ptr
)
{
static
void
init_instance
(
detail
::
instance
*
inst
,
const
void
*
holder_ptr
)
{
auto
v_h
=
inst
->
get_value_and_holder
(
detail
::
get_type_info
(
typeid
(
type
)));
auto
v_h
=
inst
->
get_value_and_holder
(
detail
::
get_type_info
(
typeid
(
type
)));
if
(
!
v_h
.
instance_registered
())
{
if
(
!
v_h
.
instance_registered
())
{
...
@@ -1556,6 +1567,11 @@ private:
...
@@ -1556,6 +1567,11 @@ private:
init_holder
(
inst
,
v_h
,
(
const
holder_type
*
)
holder_ptr
,
v_h
.
value_ptr
<
type
>
());
init_holder
(
inst
,
v_h
,
(
const
holder_type
*
)
holder_ptr
,
v_h
.
value_ptr
<
type
>
());
}
}
template
<
typename
H
=
holder_type
,
detail
::
enable_if_t
<
detail
::
is_smart_holder
<
H
>::
value
,
int
>
=
0
>
static
void
init_instance
(
detail
::
instance
*
inst
,
const
void
*
holder_ptr
)
{
detail
::
is_smart_holder
<
H
>::
template
init_instance_for_type
<
type
>
(
inst
,
holder_ptr
);
}
/// Deallocates an instance; via holder, if constructed; otherwise via operator delete.
/// Deallocates an instance; via holder, if constructed; otherwise via operator delete.
static
void
dealloc
(
detail
::
value_and_holder
&
v_h
)
{
static
void
dealloc
(
detail
::
value_and_holder
&
v_h
)
{
// We could be deallocating because we are cleaning up after a Python exception.
// We could be deallocating because we are cleaning up after a Python exception.
...
...
tests/classh_module_local_0.cpp
View file @
ab7d11f2
#include <pybind11/classh.h>
#include <pybind11/classh.h>
#include <pybind11/pybind11.h>
#include <string>
#include <string>
...
...
tests/classh_module_local_1.cpp
View file @
ab7d11f2
// Identical to classh_module_local_2.cpp, except 2 replaced with 1.
// Identical to classh_module_local_2.cpp, except 2 replaced with 1.
#include <pybind11/classh.h>
#include <pybind11/classh.h>
#include <pybind11/pybind11.h>
#include <string>
#include <string>
...
@@ -21,7 +22,7 @@ PYBIND11_MODULE(classh_module_local_1, m) {
...
@@ -21,7 +22,7 @@ PYBIND11_MODULE(classh_module_local_1, m) {
namespace
py
=
pybind11
;
namespace
py
=
pybind11
;
using
namespace
pybind11_tests
::
classh_module_local
;
using
namespace
pybind11_tests
::
classh_module_local
;
py
::
class
h
<
atyp
>
(
m
,
"atyp"
,
py
::
module_local
())
py
::
class
_
<
atyp
,
py
::
smart_holder
>
(
m
,
"atyp"
,
py
::
module_local
())
.
def
(
py
::
init
([](
const
std
::
string
&
mtxt
)
{
.
def
(
py
::
init
([](
const
std
::
string
&
mtxt
)
{
atyp
obj
;
atyp
obj
;
obj
.
mtxt
=
mtxt
;
obj
.
mtxt
=
mtxt
;
...
...
tests/classh_module_local_2.cpp
View file @
ab7d11f2
// Identical to classh_module_local_1.cpp, except 1 replaced with 2.
// Identical to classh_module_local_1.cpp, except 1 replaced with 2.
#include <pybind11/classh.h>
#include <pybind11/classh.h>
#include <pybind11/pybind11.h>
#include <string>
#include <string>
...
@@ -21,7 +22,7 @@ PYBIND11_MODULE(classh_module_local_2, m) {
...
@@ -21,7 +22,7 @@ PYBIND11_MODULE(classh_module_local_2, m) {
namespace
py
=
pybind11
;
namespace
py
=
pybind11
;
using
namespace
pybind11_tests
::
classh_module_local
;
using
namespace
pybind11_tests
::
classh_module_local
;
py
::
class
h
<
atyp
>
(
m
,
"atyp"
,
py
::
module_local
())
py
::
class
_
<
atyp
,
py
::
smart_holder
>
(
m
,
"atyp"
,
py
::
module_local
())
.
def
(
py
::
init
([](
const
std
::
string
&
mtxt
)
{
.
def
(
py
::
init
([](
const
std
::
string
&
mtxt
)
{
atyp
obj
;
atyp
obj
;
obj
.
mtxt
=
mtxt
;
obj
.
mtxt
=
mtxt
;
...
...
tests/test_classh_inheritance.cpp
View file @
ab7d11f2
...
@@ -67,8 +67,8 @@ namespace pybind11_tests {
...
@@ -67,8 +67,8 @@ namespace pybind11_tests {
namespace
classh_inheritance
{
namespace
classh_inheritance
{
TEST_SUBMODULE
(
classh_inheritance
,
m
)
{
TEST_SUBMODULE
(
classh_inheritance
,
m
)
{
py
::
class
h
<
base
>
(
m
,
"base"
);
py
::
class
_
<
base
,
py
::
smart_holder
>
(
m
,
"base"
);
py
::
class
h
<
drvd
,
base
>
(
m
,
"drvd"
);
py
::
class
_
<
drvd
,
base
,
py
::
smart_holder
>
(
m
,
"drvd"
);
auto
rvto
=
py
::
return_value_policy
::
take_ownership
;
auto
rvto
=
py
::
return_value_policy
::
take_ownership
;
...
@@ -82,9 +82,10 @@ TEST_SUBMODULE(classh_inheritance, m) {
...
@@ -82,9 +82,10 @@ TEST_SUBMODULE(classh_inheritance, m) {
m
.
def
(
"pass_shcp_base"
,
pass_shcp_base
);
m
.
def
(
"pass_shcp_base"
,
pass_shcp_base
);
m
.
def
(
"pass_shcp_drvd"
,
pass_shcp_drvd
);
m
.
def
(
"pass_shcp_drvd"
,
pass_shcp_drvd
);
py
::
classh
<
base1
>
(
m
,
"base1"
).
def
(
py
::
init
<>
());
// __init__ needed for Python inheritance.
// __init__ needed for Python inheritance.
py
::
classh
<
base2
>
(
m
,
"base2"
).
def
(
py
::
init
<>
());
py
::
class_
<
base1
,
py
::
smart_holder
>
(
m
,
"base1"
).
def
(
py
::
init
<>
());
py
::
classh
<
drvd2
,
base1
,
base2
>
(
m
,
"drvd2"
);
py
::
class_
<
base2
,
py
::
smart_holder
>
(
m
,
"base2"
).
def
(
py
::
init
<>
());
py
::
class_
<
drvd2
,
base1
,
base2
,
py
::
smart_holder
>
(
m
,
"drvd2"
);
m
.
def
(
"rtrn_mptr_drvd2"
,
rtrn_mptr_drvd2
,
rvto
);
m
.
def
(
"rtrn_mptr_drvd2"
,
rtrn_mptr_drvd2
,
rvto
);
m
.
def
(
"rtrn_mptr_drvd2_up_cast1"
,
rtrn_mptr_drvd2_up_cast1
,
rvto
);
m
.
def
(
"rtrn_mptr_drvd2_up_cast1"
,
rtrn_mptr_drvd2_up_cast1
,
rvto
);
...
...
tests/test_classh_wip.cpp
View file @
ab7d11f2
...
@@ -57,7 +57,9 @@ namespace classh_wip {
...
@@ -57,7 +57,9 @@ namespace classh_wip {
TEST_SUBMODULE
(
classh_wip
,
m
)
{
TEST_SUBMODULE
(
classh_wip
,
m
)
{
namespace
py
=
pybind11
;
namespace
py
=
pybind11
;
py
::
classh
<
atyp
>
(
m
,
"atyp"
).
def
(
py
::
init
<>
()).
def
(
py
::
init
([](
const
std
::
string
&
mtxt
)
{
py
::
class_
<
atyp
,
py
::
smart_holder
>
(
m
,
"atyp"
)
.
def
(
py
::
init
<>
())
.
def
(
py
::
init
([](
const
std
::
string
&
mtxt
)
{
atyp
obj
;
atyp
obj
;
obj
.
mtxt
=
mtxt
;
obj
.
mtxt
=
mtxt
;
return
obj
;
return
obj
;
...
...
tests/test_unique_ptr_member.cpp
View file @
ab7d11f2
...
@@ -46,7 +46,9 @@ namespace pybind11_tests {
...
@@ -46,7 +46,9 @@ namespace pybind11_tests {
namespace
unique_ptr_member
{
namespace
unique_ptr_member
{
TEST_SUBMODULE
(
unique_ptr_member
,
m
)
{
TEST_SUBMODULE
(
unique_ptr_member
,
m
)
{
py
::
classh
<
pointee
>
(
m
,
"pointee"
).
def
(
py
::
init
<>
()).
def
(
"get_int"
,
&
pointee
::
get_int
);
py
::
class_
<
pointee
,
py
::
smart_holder
>
(
m
,
"pointee"
)
.
def
(
py
::
init
<>
())
.
def
(
"get_int"
,
&
pointee
::
get_int
);
m
.
def
(
"make_unique_pointee"
,
make_unique_pointee
);
m
.
def
(
"make_unique_pointee"
,
make_unique_pointee
);
...
...
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