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
2e573bb7
Commit
2e573bb7
authored
Feb 14, 2021
by
Ralf W. Grosse-Kunstleve
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Introducing is_smart_holder_type_caster_base_tag, to keep smart_holder code more disconnected.
parent
593587b2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
27 additions
and
23 deletions
+27
-23
include/pybind11/cast.h
+15
-23
tests/test_smart_ptr.cpp
+12
-0
No files found.
include/pybind11/cast.h
View file @
2e573bb7
...
@@ -959,6 +959,12 @@ protected:
...
@@ -959,6 +959,12 @@ protected:
static
Constructor
make_move_constructor
(...)
{
return
nullptr
;
}
static
Constructor
make_move_constructor
(...)
{
return
nullptr
;
}
};
};
// Tag to be used as base class, inspected by is_smart_holder_type_caster<T> test.
struct
is_smart_holder_type_caster_base_tag
{};
template
<
typename
T
>
struct
is_smart_holder_type_caster
;
//DETAIL/SMART_HOLDER_TYPE_CASTERS_H/BEGIN/////////////////////////////////////////////////////////
//DETAIL/SMART_HOLDER_TYPE_CASTERS_H/BEGIN/////////////////////////////////////////////////////////
//FWD begin
//FWD begin
...
@@ -1185,7 +1191,7 @@ public:
...
@@ -1185,7 +1191,7 @@ public:
};
};
// clang-format on
// clang-format on
struct
smart_holder_type_caster_class_hooks
{
struct
smart_holder_type_caster_class_hooks
:
is_smart_holder_type_caster_base_tag
{
static
decltype
(
&
modified_type_caster_generic_load_impl
::
local_load
)
static
decltype
(
&
modified_type_caster_generic_load_impl
::
local_load
)
get_local_load_function_ptr
()
{
get_local_load_function_ptr
()
{
return
&
modified_type_caster_generic_load_impl
::
local_load
;
return
&
modified_type_caster_generic_load_impl
::
local_load
;
...
@@ -1219,17 +1225,11 @@ struct smart_holder_type_caster_class_hooks {
...
@@ -1219,17 +1225,11 @@ struct smart_holder_type_caster_class_hooks {
};
};
template
<
typename
T
>
template
<
typename
T
>
inline
bool
check_is_smart_holder_type_caster
();
template
<
typename
T
>
struct
smart_holder_type_caster_load
{
struct
smart_holder_type_caster_load
{
using
holder_type
=
pybindit
::
memory
::
smart_holder
;
using
holder_type
=
pybindit
::
memory
::
smart_holder
;
bool
load
(
handle
src
,
bool
convert
)
{
bool
load
(
handle
src
,
bool
convert
)
{
if
(
!
check_is_smart_holder_type_caster
<
T
>
())
{
static_assert
(
is_smart_holder_type_caster
<
T
>::
value
,
"Internal consistency error."
);
throw
cast_error
(
"Unable to load a smart-pointer type from a non-smart_holder instance."
);
}
load_impl
=
modified_type_caster_generic_load_impl
(
typeid
(
T
));
load_impl
=
modified_type_caster_generic_load_impl
(
typeid
(
T
));
if
(
!
load_impl
.
load
(
src
,
convert
))
if
(
!
load_impl
.
load
(
src
,
convert
))
return
false
;
return
false
;
...
@@ -1685,6 +1685,13 @@ template <typename type, typename SFINAE = void> class type_caster : public type
...
@@ -1685,6 +1685,13 @@ template <typename type, typename SFINAE = void> class type_caster : public type
template
<
typename
type
>
using
make_caster
=
type_caster
<
intrinsic_t
<
type
>>
;
template
<
typename
type
>
using
make_caster
=
type_caster
<
intrinsic_t
<
type
>>
;
template
<
typename
T
>
struct
is_smart_holder_type_caster
{
static
constexpr
bool
value
=
std
::
is_base_of
<
is_smart_holder_type_caster_base_tag
,
make_caster
<
T
>>::
value
;
};
// Shortcut for calling a caster's `cast_op_type` cast operator for casting a type_caster to a T
// Shortcut for calling a caster's `cast_op_type` cast operator for casting a type_caster to a T
template
<
typename
T
>
typename
make_caster
<
T
>::
template
cast_op_type
<
T
>
cast_op
(
make_caster
<
T
>
&
caster
)
{
template
<
typename
T
>
typename
make_caster
<
T
>::
template
cast_op_type
<
T
>
cast_op
(
make_caster
<
T
>
&
caster
)
{
return
caster
.
operator
typename
make_caster
<
T
>::
template
cast_op_type
<
T
>
();
return
caster
.
operator
typename
make_caster
<
T
>::
template
cast_op_type
<
T
>
();
...
@@ -2452,21 +2459,6 @@ template <typename T> struct move_if_unreferenced<T, enable_if_t<all_of<
...
@@ -2452,21 +2459,6 @@ template <typename T> struct move_if_unreferenced<T, enable_if_t<all_of<
>::
value
>>
:
std
::
true_type
{};
>::
value
>>
:
std
::
true_type
{};
template
<
typename
T
>
using
move_never
=
none_of
<
move_always
<
T
>
,
move_if_unreferenced
<
T
>>
;
template
<
typename
T
>
using
move_never
=
none_of
<
move_always
<
T
>
,
move_if_unreferenced
<
T
>>
;
template
<
typename
T
,
typename
SFINAE
=
void
>
struct
is_smart_holder_type_caster
:
std
::
false_type
{};
template
<
typename
T
>
struct
is_smart_holder_type_caster
<
T
,
typename
std
::
enable_if
<
std
::
is_base_of
<
smart_holder_type_caster_class_hooks
,
make_caster
<
T
>>::
value
>::
type
>
:
std
::
true_type
{};
template
<
typename
T
>
inline
bool
check_is_smart_holder_type_caster
()
{
return
is_smart_holder_type_caster
<
T
>::
value
;
}
// Detect whether returning a `type` from a cast on type's type_caster is going to result in a
// Detect whether returning a `type` from a cast on type's type_caster is going to result in a
// reference or pointer to a local variable of the type_caster. Basically, only
// reference or pointer to a local variable of the type_caster. Basically, only
// non-reference/pointer `type`s and reference/pointers from a type_caster_generic are safe;
// non-reference/pointer `type`s and reference/pointers from a type_caster_generic are safe;
...
...
tests/test_smart_ptr.cpp
View file @
2e573bb7
...
@@ -292,6 +292,18 @@ PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(ElementBase, std::shared_ptr<ElementB
...
@@ -292,6 +292,18 @@ PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(ElementBase, std::shared_ptr<ElementB
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS
(
ElementA
,
std
::
shared_ptr
<
ElementA
>
)
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS
(
ElementA
,
std
::
shared_ptr
<
ElementA
>
)
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS
(
ElementList
,
std
::
shared_ptr
<
ElementList
>
)
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS
(
ElementList
,
std
::
shared_ptr
<
ElementList
>
)
#ifdef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
// 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.
namespace
pybind11
{
namespace
detail
{
template
<>
class
type_caster
<
std
::
shared_ptr
<
HeldByDefaultHolder
>>
:
public
copyable_holder_caster
<
HeldByDefaultHolder
,
std
::
shared_ptr
<
HeldByDefaultHolder
>>
{};
}
// namespace detail
}
// namespace pybind11
#endif
TEST_SUBMODULE
(
smart_ptr
,
m
)
{
TEST_SUBMODULE
(
smart_ptr
,
m
)
{
// test_smart_ptr
// test_smart_ptr
...
...
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