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
6005632b
Commit
6005632b
authored
Feb 15, 2021
by
Ralf W. Grosse-Kunstleve
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
clang-format cleanup of most smart_holder code.
parent
45388b46
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
101 additions
and
72 deletions
+101
-72
include/pybind11/cast.h
+26
-19
include/pybind11/detail/smart_holder_init_inline_include.h
+15
-9
include/pybind11/detail/smart_holder_type_casters_inline_include.h
+26
-23
include/pybind11/pybind11.h
+34
-21
No files found.
include/pybind11/cast.h
View file @
6005632b
// clang-format off
/*
pybind11/cast.h: Partial template specializations to cast between
C++ and Python types
...
...
@@ -955,6 +956,7 @@ protected:
static
Constructor
make_move_constructor
(...)
{
return
nullptr
;
}
};
// clang-format on
// Tag to be used as base class, inspected by is_smart_holder_type_caster<T> test.
struct
is_smart_holder_type_caster_base_tag
{};
...
...
@@ -974,26 +976,29 @@ PYBIND11_NAMESPACE_BEGIN(detail)
#ifndef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
#define PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(T, ...)
#
define PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(T, ...)
template
<
typename
T
>
class
type_caster_for_class_
:
public
type_caster_base
<
T
>
{};
template
<
typename
T
>
class
type_caster_for_class_
:
public
type_caster_base
<
T
>
{};
#else
#
define PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(T, ...)
\
namespace pybind11 {
\
namespace detail {
\
template <>
\
class type_caster<T> : public type_caster_base<T> {};
\
template <>
\
class type_caster<__VA_ARGS__> : public type_caster_holder<T, __VA_ARGS__> {};
\
}
\
}
#
define PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(T, ...)
\
namespace pybind11 {
\
namespace detail {
\
template <>
\
class type_caster<T> : public type_caster_base<T> {};
\
template <>
\
class type_caster<__VA_ARGS__> : public type_caster_holder<T, __VA_ARGS__> {};
\
}
\
}
template
<
typename
T
>
class
type_caster_for_class_
:
public
smart_holder_type_caster
<
T
>
{};
template
<
typename
T
>
class
type_caster_for_class_
:
public
smart_holder_type_caster
<
T
>
{};
template
<
typename
T
>
class
type_caster_for_class_
<
std
::
shared_ptr
<
T
>>
:
public
smart_holder_type_caster
<
std
::
shared_ptr
<
T
>>
{};
class
type_caster_for_class_
<
std
::
shared_ptr
<
T
>>
:
public
smart_holder_type_caster
<
std
::
shared_ptr
<
T
>>
{};
template
<
typename
T
>
class
type_caster_for_class_
<
std
::
shared_ptr
<
T
const
>>
...
...
@@ -1007,20 +1012,22 @@ template <typename T, typename D>
class
type_caster_for_class_
<
std
::
unique_ptr
<
T
const
,
D
>>
:
public
smart_holder_type_caster
<
std
::
unique_ptr
<
T
const
,
D
>>
{};
#define PYBIND11_SMART_HOLDER_TYPE_CASTERS(T)
#
define PYBIND11_SMART_HOLDER_TYPE_CASTERS(T)
#endif
template
<
typename
type
,
typename
SFINAE
=
void
>
class
type_caster
:
public
type_caster_for_class_
<
type
>
{
};
template
<
typename
type
,
typename
SFINAE
=
void
>
class
type_caster
:
public
type_caster_for_class_
<
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
;
static
constexpr
bool
value
=
std
::
is_base_of
<
is_smart_holder_type_caster_base_tag
,
make_caster
<
T
>>::
value
;
};
// clang-format off
// 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
)
{
...
...
include/pybind11/detail/smart_holder_init_inline_include.h
View file @
6005632b
#ifndef PYBIND11_DETAIL_INIT_H_SMART_HOLDER_INIT_INLINE_INCLUDE_SAFETY_GUARD
#error "THIS FILE MUST ONLY BE INCLUDED FROM pybind11/detail/init.h"
#
error "THIS FILE MUST ONLY BE INCLUDED FROM pybind11/detail/init.h"
#endif
template
<
typename
Class
,
typename
D
=
std
::
default_delete
<
Cpp
<
Class
>>
,
template
<
typename
Class
,
typename
D
=
std
::
default_delete
<
Cpp
<
Class
>>
,
detail
::
enable_if_t
<
detail
::
is_smart_holder_type_caster
<
Cpp
<
Class
>>::
value
,
int
>
=
0
>
void
construct
(
value_and_holder
&
v_h
,
std
::
unique_ptr
<
Cpp
<
Class
>
,
D
>
&&
unq_ptr
,
bool
need_alias
)
{
auto
*
ptr
=
unq_ptr
.
get
();
...
...
@@ -10,17 +11,20 @@ void construct(value_and_holder &v_h, std::unique_ptr<Cpp<Class>, D> &&unq_ptr,
if
(
Class
::
has_alias
&&
need_alias
)
throw
type_error
(
"pybind11::init(): construction failed: returned std::unique_ptr pointee "
"is not an alias instance"
);
auto
smhldr
=
smart_holder
::
from_unique_ptr
(
std
::
move
(
unq_ptr
));
auto
smhldr
=
smart_holder
::
from_unique_ptr
(
std
::
move
(
unq_ptr
));
v_h
.
value_ptr
()
=
ptr
;
v_h
.
type
->
init_instance
(
v_h
.
inst
,
&
smhldr
);
}
template
<
typename
Class
,
typename
D
=
std
::
default_delete
<
Alias
<
Class
>>
,
template
<
typename
Class
,
typename
D
=
std
::
default_delete
<
Alias
<
Class
>>
,
detail
::
enable_if_t
<
detail
::
is_smart_holder_type_caster
<
Alias
<
Class
>>::
value
,
int
>
=
0
>
void
construct
(
value_and_holder
&
v_h
,
std
::
unique_ptr
<
Alias
<
Class
>
,
D
>
&&
unq_ptr
,
bool
/*need_alias*/
)
{
void
construct
(
value_and_holder
&
v_h
,
std
::
unique_ptr
<
Alias
<
Class
>
,
D
>
&&
unq_ptr
,
bool
/*need_alias*/
)
{
auto
*
ptr
=
unq_ptr
.
get
();
no_nullptr
(
ptr
);
auto
smhldr
=
smart_holder
::
from_unique_ptr
(
std
::
move
(
unq_ptr
));
auto
smhldr
=
smart_holder
::
from_unique_ptr
(
std
::
move
(
unq_ptr
));
v_h
.
value_ptr
()
=
ptr
;
v_h
.
type
->
init_instance
(
v_h
.
inst
,
&
smhldr
);
}
...
...
@@ -33,17 +37,19 @@ void construct(value_and_holder &v_h, std::shared_ptr<Cpp<Class>> &&shd_ptr, boo
if
(
Class
::
has_alias
&&
need_alias
)
throw
type_error
(
"pybind11::init(): construction failed: returned std::shared_ptr pointee "
"is not an alias instance"
);
auto
smhldr
=
smart_holder
::
from_shared_ptr
(
std
::
move
(
shd_ptr
));
auto
smhldr
=
smart_holder
::
from_shared_ptr
(
std
::
move
(
shd_ptr
));
v_h
.
value_ptr
()
=
ptr
;
v_h
.
type
->
init_instance
(
v_h
.
inst
,
&
smhldr
);
}
template
<
typename
Class
,
detail
::
enable_if_t
<
detail
::
is_smart_holder_type_caster
<
Alias
<
Class
>>::
value
,
int
>
=
0
>
void
construct
(
value_and_holder
&
v_h
,
std
::
shared_ptr
<
Alias
<
Class
>>
&&
shd_ptr
,
bool
/*need_alias*/
)
{
void
construct
(
value_and_holder
&
v_h
,
std
::
shared_ptr
<
Alias
<
Class
>>
&&
shd_ptr
,
bool
/*need_alias*/
)
{
auto
*
ptr
=
shd_ptr
.
get
();
no_nullptr
(
ptr
);
auto
smhldr
=
smart_holder
::
from_shared_ptr
(
std
::
move
(
shd_ptr
));
auto
smhldr
=
smart_holder
::
from_shared_ptr
(
std
::
move
(
shd_ptr
));
v_h
.
value_ptr
()
=
ptr
;
v_h
.
type
->
init_instance
(
v_h
.
inst
,
&
smhldr
);
}
include/pybind11/detail/smart_holder_type_casters_inline_include.h
View file @
6005632b
#ifndef PYBIND11_CAST_H_SMART_HOLDER_TYPE_CASTERS_INLINE_INCLUDE_SAFETY_GUARD
#error "THIS FILE MUST ONLY BE INCLUDED FROM pybind11/cast.h"
#
error "THIS FILE MUST ONLY BE INCLUDED FROM pybind11/cast.h"
#endif
#include "smart_holder_poc.h"
...
...
@@ -294,7 +294,8 @@ struct smart_holder_type_caster_load {
T
&
loaded_as_lvalue_ref
()
const
{
T
*
raw_ptr
=
loaded_as_raw_ptr_unowned
();
if
(
raw_ptr
==
nullptr
)
throw
reference_cast_error
();
if
(
raw_ptr
==
nullptr
)
throw
reference_cast_error
();
return
*
raw_ptr
;
}
...
...
@@ -302,7 +303,8 @@ struct smart_holder_type_caster_load {
if
(
load_impl
.
unowned_void_ptr_from_direct_conversion
!=
nullptr
)
throw
cast_error
(
"Unowned pointer from direct conversion cannot be converted to a"
" std::shared_ptr."
);
if
(
!
have_holder
())
return
nullptr
;
if
(
!
have_holder
())
return
nullptr
;
throw_if_uninitialized_or_disowned_holder
();
std
::
shared_ptr
<
void
>
void_ptr
=
holder
().
template
as_shared_ptr
<
void
>
();
return
std
::
shared_ptr
<
T
>
(
void_ptr
,
convert_type
(
void_ptr
.
get
()));
...
...
@@ -313,7 +315,8 @@ struct smart_holder_type_caster_load {
if
(
load_impl
.
unowned_void_ptr_from_direct_conversion
!=
nullptr
)
throw
cast_error
(
"Unowned pointer from direct conversion cannot be converted to a"
" std::unique_ptr."
);
if
(
!
have_holder
())
return
nullptr
;
if
(
!
have_holder
())
return
nullptr
;
throw_if_uninitialized_or_disowned_holder
();
holder
().
template
ensure_compatible_rtti_uqp_del
<
T
,
D
>
(
context
);
holder
().
ensure_use_count_1
(
context
);
...
...
@@ -663,25 +666,25 @@ struct smart_holder_type_caster<std::unique_ptr<T const, D>>
};
#ifndef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
#
define PYBIND11_SMART_HOLDER_TYPE_CASTERS(T)
\
namespace pybind11 {
\
namespace detail {
\
template <>
\
class type_caster<T> : public smart_holder_type_caster<T> {};
\
template <>
\
class type_caster<std::shared_ptr<T>> : public smart_holder_type_caster<std::shared_ptr<T>> {
\
};
\
template <>
\
class type_caster<std::shared_ptr<T const>>
\
: public smart_holder_type_caster<std::shared_ptr<T const>> {};
\
template <typename D>
\
class type_caster<std::unique_ptr<T, D>>
\
: public smart_holder_type_caster<std::unique_ptr<T, D>> {};
\
template <typename D>
\
class type_caster<std::unique_ptr<T const, D>>
\
: public smart_holder_type_caster<std::unique_ptr<T const, D>> {};
\
}
\
}
#
define PYBIND11_SMART_HOLDER_TYPE_CASTERS(T)
\
namespace pybind11 {
\
namespace detail {
\
template <>
\
class type_caster<T> : public smart_holder_type_caster<T> {};
\
template <>
\
class type_caster<std::shared_ptr<T>>
\
: public smart_holder_type_caster<std::shared_ptr<T>> {};
\
template <>
\
class type_caster<std::shared_ptr<T const>>
\
: public smart_holder_type_caster<std::shared_ptr<T const>> {};
\
template <typename D>
\
class type_caster<std::unique_ptr<T, D>>
\
: public smart_holder_type_caster<std::unique_ptr<T, D>> {};
\
template <typename D>
\
class type_caster<std::unique_ptr<T const, D>>
\
: public smart_holder_type_caster<std::unique_ptr<T const, D>> {};
\
}
\
}
#endif
PYBIND11_NAMESPACE_END
(
detail
)
...
...
include/pybind11/pybind11.h
View file @
6005632b
// clang-format off
/*
pybind11/pybind11.h: Main header file of the C++11 python
binding generator library
...
...
@@ -1240,22 +1241,26 @@ auto method_adaptor(Return (Class::*pmf)(Args...) const) -> Return (Derived::*)(
return
pmf
;
}
// clang-format on
template
<
typename
T
>
#ifndef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
using
default_holder_type
=
std
::
unique_ptr
<
T
>
;
#else
using
default_holder_type
=
smart_holder
;
#endif
// clang-format off
template
<
typename
type_
,
typename
...
options
>
class
class_
:
public
detail
::
generic_type
{
template
<
typename
T
>
using
is_subtype
=
detail
::
is_strict_base_of
<
type_
,
T
>
;
template
<
typename
T
>
using
is_base
=
detail
::
is_strict_base_of
<
T
,
type_
>
;
template
<
typename
T
>
// clang-format on
using
is_holder
=
detail
::
any_of
<
detail
::
is_holder_type
<
type_
,
T
>
,
detail
::
all_of
<
detail
::
negation
<
is_base
<
T
>>
,
detail
::
negation
<
is_subtype
<
T
>>
,
detail
::
is_smart_holder_type_caster
<
type_
>>>
;
// clang-format off
// struct instead of using here to help MSVC:
template
<
typename
T
>
struct
is_valid_class_option
:
detail
::
any_of
<
is_holder
<
T
>
,
is_subtype
<
T
>
,
is_base
<
T
>>
{};
...
...
@@ -1286,18 +1291,24 @@ public:
none_of
<
std
::
is_same
<
multiple_inheritance
,
Extra
>
...
>::
value
),
// no multiple_inheritance attr
"Error: multiple inheritance bases must be specified via class_ template options"
);
static
constexpr
bool
holder_is_smart_holder
=
std
::
is_same
<
holder_type
,
smart_holder
>::
value
;
static
constexpr
bool
type_caster_type_is_smart_holder_type_caster
=
detail
::
is_smart_holder_type_caster
<
type
>::
value
;
static
constexpr
bool
type_caster_type_is_type_caster_base_subtype
=
std
::
is_base_of
<
detail
::
type_caster_base
<
type
>
,
detail
::
type_caster
<
type
>>::
value
;
// clang-format on
static
constexpr
bool
holder_is_smart_holder
=
std
::
is_same
<
holder_type
,
smart_holder
>::
value
;
static
constexpr
bool
type_caster_type_is_smart_holder_type_caster
=
detail
::
is_smart_holder_type_caster
<
type
>::
value
;
static
constexpr
bool
type_caster_type_is_type_caster_base_subtype
=
std
::
is_base_of
<
detail
::
type_caster_base
<
type
>
,
detail
::
type_caster
<
type
>>::
value
;
// Necessary conditions, but not strict.
static_assert
(
!
(
detail
::
is_instantiation
<
std
::
unique_ptr
,
holder_type
>::
value
&&
type_caster_type_is_smart_holder_type_caster
),
"py::class_ holder vs type_caster mismatch:"
" missing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(T, std::unique_ptr<T>)?"
);
static_assert
(
!
(
detail
::
is_instantiation
<
std
::
shared_ptr
,
holder_type
>::
value
&&
type_caster_type_is_smart_holder_type_caster
),
"py::class_ holder vs type_caster mismatch:"
" missing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(T, std::shared_ptr<T>)?"
);
static_assert
(
!
(
detail
::
is_instantiation
<
std
::
unique_ptr
,
holder_type
>::
value
&&
type_caster_type_is_smart_holder_type_caster
),
"py::class_ holder vs type_caster mismatch:"
" missing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(T, std::unique_ptr<T>)?"
);
static_assert
(
!
(
detail
::
is_instantiation
<
std
::
shared_ptr
,
holder_type
>::
value
&&
type_caster_type_is_smart_holder_type_caster
),
"py::class_ holder vs type_caster mismatch:"
" missing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(T, std::shared_ptr<T>)?"
);
static_assert
(
!
(
holder_is_smart_holder
&&
type_caster_type_is_type_caster_base_subtype
),
"py::class_ holder vs type_caster mismatch:"
" missing PYBIND11_SMART_HOLDER_TYPE_CASTERS(T)?"
);
...
...
@@ -1312,6 +1323,7 @@ public:
" missing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(T, ...)"
" or collision with custom py::detail::type_caster<T>?"
);
#endif
// clang-format off
type_record
record
;
record
.
scope
=
scope
;
record
.
name
=
name
;
...
...
@@ -1322,7 +1334,7 @@ public:
record
.
init_instance
=
init_instance
;
record
.
dealloc
=
dealloc
;
// A
better
name would be uses_unique_ptr_holder.
// A
more fitting
name would be uses_unique_ptr_holder.
record
.
default_holder
=
detail
::
is_instantiation
<
std
::
unique_ptr
,
holder_type
>::
value
;
set_operator_new
<
type
>
(
&
record
);
...
...
@@ -1541,19 +1553,19 @@ public:
}
private
:
template
<
typename
T
=
type
,
detail
::
enable_if_t
<!
detail
::
is_smart_holder_type_caster
<
T
>::
value
,
int
>
=
0
>
// clang-format on
template
<
typename
T
=
type
,
detail
::
enable_if_t
<!
detail
::
is_smart_holder_type_caster
<
T
>::
value
,
int
>
=
0
>
void
generic_type_initialize
(
const
detail
::
type_record
&
record
)
{
generic_type
::
initialize
(
record
,
&
detail
::
type_caster_generic
::
local_load
);
}
template
<
typename
T
=
type
,
detail
::
enable_if_t
<
detail
::
is_smart_holder_type_caster
<
T
>::
value
,
int
>
=
0
>
template
<
typename
T
=
type
,
detail
::
enable_if_t
<
detail
::
is_smart_holder_type_caster
<
T
>::
value
,
int
>
=
0
>
void
generic_type_initialize
(
const
detail
::
type_record
&
record
)
{
generic_type
::
initialize
(
record
,
detail
::
type_caster
<
T
>::
get_local_load_function_ptr
());
}
// clang-format off
/// Initialize holder object, variant 1: object derives from enable_shared_from_this
template
<
typename
T
>
...
...
@@ -1611,12 +1623,13 @@ private:
init_holder
(
inst
,
v_h
,
(
const
holder_type
*
)
holder_ptr
,
v_h
.
value_ptr
<
type
>
());
}
template
<
typename
T
=
type
,
detail
::
enable_if_t
<
detail
::
is_smart_holder_type_caster
<
T
>::
value
,
int
>
=
0
>
// clang-format on
template
<
typename
T
=
type
,
detail
::
enable_if_t
<
detail
::
is_smart_holder_type_caster
<
T
>::
value
,
int
>
=
0
>
static
void
init_instance
(
detail
::
instance
*
inst
,
const
void
*
holder_ptr
)
{
detail
::
type_caster
<
T
>::
template
init_instance_for_type
<
type
>
(
inst
,
holder_ptr
);
}
// clang-format off
/// Deallocates an instance; via holder, if constructed; otherwise via operator delete.
static
void
dealloc
(
detail
::
value_and_holder
&
v_h
)
{
...
...
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