Go to the documentation of this file.
12 #include "../pytypes.h"
22 #include <type_traits>
25 #include <unordered_map>
39 #if defined(WITH_THREAD)
42 # if PYBIND11_INTERNALS_VERSION == 4
88 throw cast_error(
"When called outside a bound function, py::cast() cannot "
89 "do Python -> C++ conversions which require the creation "
90 "of temporary values");
107 std::vector<PyTypeObject *>
check;
108 for (
handle parent : reinterpret_borrow<tuple>(
t->tp_bases)) {
109 check.push_back((PyTypeObject *) parent.ptr());
113 for (
size_t i = 0;
i <
check.size();
i++) {
116 if (!PyType_Check((PyObject *)
type)) {
121 auto it = type_dict.find(
type);
122 if (it != type_dict.end()) {
127 for (
auto *tinfo : it->second) {
132 for (
auto *known : bases) {
133 if (known == tinfo) {
139 bases.push_back(tinfo);
142 }
else if (
type->tp_bases) {
145 if (
i + 1 ==
check.size()) {
152 for (
handle parent : reinterpret_borrow<tuple>(
type->tp_bases)) {
153 check.push_back((PyTypeObject *) parent.ptr());
176 return ins.first->second;
189 if (bases.size() > 1) {
191 "pybind11::detail::get_type_info: type has multiple pybind11-registered bases");
193 return bases.front();
198 auto it = locals.find(tp);
199 if (it != locals.end()) {
207 auto it = types.find(tp);
208 if (it != types.end()) {
217 bool throw_if_missing =
false) {
225 if (throw_if_missing) {
226 std::string tname = tp.name();
228 pybind11_fail(
"pybind11::detail::get_type_info: unable to find type info for \""
229 + std::move(tname) +
'"');
241 const detail::type_info *tinfo) {
243 for (
auto it_i = it_instances.first; it_i != it_instances.second; ++it_i) {
245 if (instance_type &&
same_type(*instance_type->cpptype, *tinfo->cpptype)) {
256 const detail::type_info *
type =
nullptr;
271 template <
typename V =
void>
273 return reinterpret_cast<V *&
>(
vh[0]);
276 explicit operator bool()
const {
return value_ptr() !=
nullptr; }
278 template <
typename H>
280 return reinterpret_cast<H &
>(
vh[1]);
360 while (it != endit && it->type != find_type) {
381 bool throw_if_missing ) {
383 if (!find_type || Py_TYPE(
this) == find_type->
type) {
387 detail::values_and_holders vhs(
this);
388 auto it = vhs.find(find_type);
389 if (it != vhs.end()) {
393 if (!throw_if_missing) {
397 #if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
398 pybind11_fail(
"pybind11::detail::instance::get_value_and_holder: `"
400 +
"' is not a pybind11 base of the given `"
404 "pybind11::detail::instance::get_value_and_holder: "
405 "type is not a pybind11 base of the given instance "
406 "(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for type details)");
413 const size_t n_types =
tinfo.size();
417 "instance allocation failed: new instance has no pybind11-registered base types");
436 space +=
t->holder_size_in_ptrs;
438 size_t flags_at = space;
450 throw std::bad_alloc();
475 auto range = instances.equal_range(ptr);
476 for (
auto it =
range.first; it !=
range.second; ++it) {
478 if (vh.type ==
type) {
479 return handle((PyObject *) it->second);
487 #if defined(PYPY_VERSION)
488 return PyThreadState_GET();
490 return _PyThreadState_UncheckedGet();
511 const detail::type_info *tinfo,
512 void *(*copy_constructor)(
const void *),
513 void *(*move_constructor)(
const void *),
514 const void *existing_holder =
nullptr) {
519 void *src =
const_cast<void *
>(_src);
520 if (src ==
nullptr) {
525 return registered_inst;
547 if (copy_constructor) {
548 valueptr = copy_constructor(src);
550 #if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
551 std::string
type_name(tinfo->cpptype->name());
553 throw cast_error(
"return_value_policy = copy, but type " +
type_name
554 +
" is non-copyable!");
556 throw cast_error(
"return_value_policy = copy, but type is "
557 "non-copyable! (#define PYBIND11_DETAILED_ERROR_MESSAGES or "
558 "compile in debug mode for details)");
565 if (move_constructor) {
566 valueptr = move_constructor(src);
567 }
else if (copy_constructor) {
568 valueptr = copy_constructor(src);
570 #if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
571 std::string
type_name(tinfo->cpptype->name());
573 throw cast_error(
"return_value_policy = move, but type " +
type_name
574 +
" is neither movable nor copyable!");
576 throw cast_error(
"return_value_policy = move, but type is neither "
577 "movable nor copyable! "
578 "(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in "
579 "debug mode for details)");
592 throw cast_error(
"unhandled return_value_policy: should not happen!");
595 tinfo->init_instance(
wrapper, existing_holder);
597 return inst.release();
602 auto *&vptr = v_h.value_ptr();
604 if (vptr ==
nullptr) {
606 if (
type->operator_new) {
607 vptr =
type->operator_new(
type->type_size);
609 #if defined(__cpp_aligned_new) && (!defined(_MSC_VER) || _MSC_VER >= 1912)
610 if (
type->type_align > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {
611 vptr = ::operator
new(
type->type_size, std::align_val_t(
type->type_align));
613 vptr = ::operator
new(
type->type_size);
616 vptr = ::operator
new(
type->type_size);
644 if (caster.load(src,
false)) {
655 if (!
hasattr(pytype, local_key)) {
659 type_info *foreign_typeinfo = reinterpret_borrow<capsule>(
getattr(pytype, local_key));
677 template <
typename ThisT>
686 auto &this_ =
static_cast<ThisT &
>(*this);
687 this_.check_holder_compat();
689 PyTypeObject *srctype = Py_TYPE(src.
ptr());
708 if (bases.size() == 1 && (no_cpp_mi || bases.front()->type ==
typeinfo->
type)) {
715 if (bases.size() > 1) {
716 for (
auto *
base : bases) {
729 if (this_.try_implicit_casts(src,
convert)) {
737 auto temp = reinterpret_steal<object>(converter(src.
ptr(),
typeinfo->
type));
738 if (load_impl<ThisT>(temp,
false)) {
743 if (this_.try_direct_conversions(src)) {
752 return load(src,
false);
779 const std::type_info &cast_type,
780 const std::type_info *rtti_type =
nullptr) {
782 return {src,
const_cast<const type_info *
>(tpi)};
786 std::string tname = rtti_type ? rtti_type->name() : cast_type.name();
788 std::string
msg =
"Unregistered type : " + tname;
789 PyErr_SetString(PyExc_TypeError,
msg.c_str());
790 return {
nullptr,
nullptr};
805 template <
typename T>
807 typename std::add_pointer<intrinsic_t<T>>
::type,
808 typename std::add_lvalue_reference<intrinsic_t<T>>
::type>;
817 template <
typename T>
820 typename std::add_pointer<intrinsic_t<T>>
::type,
822 typename std::add_rvalue_reference<intrinsic_t<T>>
::type,
823 typename std::add_lvalue_reference<intrinsic_t<T>>
::type>>;
827 template <
typename Container,
typename SFINAE =
void>
833 template <
typename Container>
836 typename
std::enable_if<
837 std::is_same<typename Container::mapped_type, Container>::value>
::type> {
842 template <
typename Container>
845 typename
std::enable_if<
846 negation<std::is_same<typename Container::mapped_type, Container>>::value>
::type> {
853 template <
typename Container,
typename SFINAE =
void>
859 template <
typename Container>
862 typename
std::enable_if<
863 std::is_same<typename Container::value_type, Container>::value>
::type> {
868 template <
typename Container>
871 typename
std::enable_if<
872 negation<std::is_same<typename Container::value_type, Container>>::value>
::type> {
888 template <
typename T,
bool is_this_a_map>
905 template <
typename A,
typename B>
914 template <
typename Container,
typename SFINAE =
void>
919 template <
typename Container>
922 typename
std::enable_if<container_value_type_traits<Container>::has_value_type>
::type> {
923 static constexpr
bool is_recursive
938 typename Container::value_type,
941 typename Container::value_type,
968 template <
typename Container,
typename SFINAE =
void>
971 template <
typename T>
973 :
all_of<std::is_move_constructible<T>,
974 is_move_constructible<
975 typename recursive_container_traits<T>::type_to_check_recursively>> {};
984 template <
typename T1,
typename T2>
986 :
all_of<is_move_constructible<T1>, is_move_constructible<T2>> {};
990 template <
typename T>
992 :
all_of<std::is_copy_constructible<T>,
993 is_copy_constructible<
994 typename recursive_container_traits<T>::type_to_check_recursively>> {};
1003 template <
typename T1,
typename T2>
1005 :
all_of<is_copy_constructible<T1>, is_copy_constructible<T2>> {};
1008 template <
typename T>
1011 std::is_copy_assignable<T>,
1012 is_copy_assignable<typename recursive_container_traits<T>::type_to_check_recursively>> {
1018 template <
typename T1,
typename T2>
1020 :
all_of<is_copy_assignable<T1>, is_copy_assignable<T2>> {};
1045 template <
typename itype,
typename SFINAE =
void>
1047 static const void *
get(
const itype *src,
const std::type_info *&) {
return src; }
1049 template <
typename itype>
1051 static const void *
get(
const itype *src,
const std::type_info *&
type) {
1052 type = src ? &
typeid(*src) :
nullptr;
1053 return dynamic_cast<const void *
>(src);
1056 template <
typename itype,
typename SFINAE =
void>
1061 template <
typename type>
1067 static constexpr
auto name = const_name<type>();
1077 return cast(&src, policy, parent);
1088 const auto &cast_type =
typeid(
itype);
1089 const std::type_info *instance_type =
nullptr;
1091 if (instance_type && !
same_type(cast_type, *instance_type)) {
1130 template <
typename T>
1138 throw reference_cast_error();
1151 -> decltype(
new T(std::declval<const T>()),
Constructor{}) {
1152 return [](
const void *
arg) ->
void * {
return new T(*
reinterpret_cast<const T *
>(
arg)); };
1157 -> decltype(
new T(std::declval<T &&>()),
Constructor{}) {
1158 return [](
const void *
arg) ->
void * {
1159 return new T(std::move(*
const_cast<T *
>(
reinterpret_cast<const T *
>(
arg))));
1169 handle th((PyObject *) type_data->type);
1170 return th.attr(
"__module__").
cast<std::string>() +
'.'
1171 + th.attr(
"__qualname__").
cast<std::string>();
static loader_life_support ** get_stack_pp()
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size set set xzeroaxis lt lw set x2zeroaxis lt lw set yzeroaxis lt lw set y2zeroaxis lt lw set tics in set ticslevel set tics set mxtics default set mytics default set mx2tics default set my2tics default set xtics border mirror norotate autofreq set ytics border mirror norotate autofreq set ztics border nomirror norotate autofreq set nox2tics set noy2tics set timestamp bottom norotate set rrange[*:*] noreverse nowriteback set trange[*:*] noreverse nowriteback set urange[*:*] noreverse nowriteback set vrange[*:*] noreverse nowriteback set xlabel matrix size set x2label set timefmt d m y n H
std::is_same< bools< Ts::value..., true >, bools< true, Ts::value... > > all_of
bool try_direct_conversions(handle src)
#define PYBIND11_MODULE_LOCAL_ID
static const void * get(const itype *src, const std::type_info *&)
Annotation for function names.
static handle cast(itype &&src, return_value_policy, handle parent)
void *(* module_local_load)(PyObject *, const type_info *)
value_and_holder(size_t index)
Annotation indicating that a class derives from another given type.
std::unordered_set< PyObject * > keep_alive
std::vector< PyObject *(*)(PyObject *, PyTypeObject *)> implicit_conversions
conditional_t< std::is_pointer< typename std::remove_reference< T >::type >::value, typename std::add_pointer< intrinsic_t< T > >::type, conditional_t< std::is_rvalue_reference< T >::value, typename std::add_rvalue_reference< intrinsic_t< T > >::type, typename std::add_lvalue_reference< intrinsic_t< T > >::type > > movable_cast_op_type
constexpr size_t instance_simple_holder_in_ptrs()
nonsimple_values_and_holders nonsimple
return_value_policy
Approach used to cast a previously unknown C++ instance into a Python object.
loader_life_support()
A new patient frame is created when a function is entered.
void *(*)(const void *) Constructor
static constexpr bool has_recursive_mapped_type
type_map< type_info * > registered_types_cpp
detail::type_info * get_global_type_info(const std::type_index &tp)
value_and_holder get_value_and_holder(const type_info *find_type=nullptr, bool throw_if_missing=true)
std::vector< std::pair< const std::type_info *, void *(*)(void *)> > implicit_casts
static constexpr uint8_t status_instance_registered
PYBIND11_NOINLINE void clean_type_id(std::string &name)
const handle & inc_ref() const &
#define PYBIND11_NAMESPACE_END(name)
bool hasattr(handle obj, handle name)
PYBIND11_NOINLINE type_caster_generic(const std::type_info &type_info)
#define PYBIND11_NOINLINE
PyThreadState * get_thread_state_unchecked()
object getattr(handle obj, handle name)
Eigen::Triplet< double > T
static Constructor make_move_constructor(...)
#define PYBIND11_TLS_GET_VALUE(key)
detail::cast_op_type< T > cast_op_type
static Constructor make_copy_constructor(...)
void ** values_and_holders
PYBIND11_NOINLINE internals & get_internals()
Return a reference to the current internals data.
#define PYBIND11_NAMESPACE_BEGIN(name)
static constexpr size_t size_in_ptrs(size_t s)
void * simple_value_holder[1+instance_simple_holder_in_ptrs()]
static std::pair< const void *, const type_info * > src_and_type(const itype *src)
const std::vector< detail::type_info * > & all_type_info(PyTypeObject *type)
bool try_implicit_casts(handle src, bool convert)
detail::type_info * get_local_type_info(const std::type_index &tp)
bool operator!=(const iterator &other) const
const std::type_info * cpptype
PYBIND11_NOINLINE std::string type_info_description(const std::type_info &ti)
static auto make_copy_constructor(const T *) -> decltype(new T(std::declval< const T >()), Constructor
iterator(instance *inst, const type_vec *tinfo)
typename std::conditional< B, T, F >::type conditional_t
std::unordered_multimap< const void *, instance * > registered_instances
The 'instance' type which needs to be standard layout (need to be able to use 'offsetof')
void load_value(value_and_holder &&v_h)
Double_ range(const Point2_ &p, const Point2_ &q)
iterator find(const type_info *find_type)
PYBIND11_NOINLINE handle find_registered_python_instance(void *src, const detail::type_info *tinfo)
static handle cast(const itype &src, return_value_policy policy, handle parent)
void set_instance_registered(bool v=true)
void set_holder_constructed(bool v=true)
bool same_type(const std::type_info &lhs, const std::type_info &rhs)
#define PYBIND11_TLS_REPLACE_VALUE(key, value)
std::string get_fully_qualified_tp_name(PyTypeObject *type)
bool isinstance(handle obj)
typename std::conditional< is_recursive, typename impl_type_to_check_recursively< typename Container::value_type, container_mapped_type_traits< Container >::has_mapped_type >::if_recursive, typename impl_type_to_check_recursively< typename Container::value_type, container_mapped_type_traits< Container >::has_mapped_type >::if_not_recursive >::type type_to_check_recursively
typename intrinsic_type< T >::type intrinsic_t
#define PYBIND11_TLS_KEY_REF
type_caster_base(const std::type_info &info)
static handle handle_of()
typename std::remove_const< A >::type if_recursive
static constexpr bool has_recursive_value_type
value_and_holder & operator*()
void check(bool b, bool ref)
type_map< type_info * > registered_types_cpp
value_and_holder(instance *i, const detail::type_info *type, size_t vpos, size_t index)
PYBIND11_NOINLINE bool load_impl(handle src, bool convert)
bool simple_instance_registered
For simple layout, tracks whether the instance is registered in registered_instances
void deallocate_layout()
Destroys/deallocates all of the above.
Keep patient alive while nurse lives.
PyObject * make_new_instance(PyTypeObject *type)
PYBIND11_NOINLINE detail::type_info * get_type_info(PyTypeObject *type)
bool owned
If true, the pointer is owned which means we're free to manage it with a holder.
static auto make_move_constructor(const T *) -> decltype(new T(std::declval< T && >()), Constructor
EIGEN_DEVICE_FUNC const EIGEN_STRONG_INLINE ArgReturnType arg() const
static constexpr uint8_t status_holder_constructed
Bit values for the non-simple status flags.
PyExc_RuntimeError PYBIND11_NOINLINE void pybind11_fail(const char *reason)
Used internally.
static constexpr bool has_value_type
std::vector< detail::type_info * > type_vec
std::vector< bool(*)(PyObject *, void *&)> * direct_conversions
conditional_t< std::is_pointer< remove_reference_t< T > >::value, typename std::add_pointer< intrinsic_t< T > >::type, typename std::add_lvalue_reference< intrinsic_t< T > >::type > cast_op_type
PYBIND11_NOINLINE handle get_object_handle(const void *ptr, const detail::type_info *type)
static PYBIND11_NOINLINE void * local_load(PyObject *src, const type_info *ti)
PyObject * ptr() const
Return the underlying PyObject * pointer.
~loader_life_support()
... and destroyed after it returns
static PYBIND11_NOINLINE std::pair< const void *, const type_info * > src_and_type(const void *src, const std::type_info &cast_type, const std::type_info *rtti_type=nullptr)
value_and_holder()=default
void keep_alive_impl(handle nurse, handle patient)
bool simple_holder_constructed
For simple layout, tracks whether the holder has been constructed.
void check_holder_compat()
bool instance_registered() const
PYBIND11_NOINLINE handle get_type_handle(const std::type_info &tp, bool throw_if_missing)
bool holder_constructed() const
local_internals & get_local_internals()
Works like get_internals, but for things which are locally registered.
static constexpr bool has_mapped_type
Array< int, Dynamic, 1 > v
PYBIND11_NOINLINE void all_type_info_populate(PyTypeObject *t, std::vector< type_info * > &bases)
PYBIND11_NOINLINE bool try_load_foreign_module_local(handle src)
std::pair< decltype(internals::registered_types_py)::iterator, bool > all_type_info_get_cache(PyTypeObject *type)
std::unordered_map< PyTypeObject *, std::vector< type_info * > > registered_types_py
const std::type_info * cpptype
const type_info * typeinfo
bool load(handle src, bool convert)
static handle cast(const itype *src, return_value_policy policy, handle parent)
static handle cast_holder(const itype *src, const void *holder)
static PYBIND11_NOINLINE handle cast(const void *_src, return_value_policy policy, handle parent, const detail::type_info *tinfo, void *(*copy_constructor)(const void *), void *(*move_constructor)(const void *), const void *existing_holder=nullptr)
values_and_holders(instance *inst)
static BinaryMeasurement< Rot3 > convert(const BetweenFactor< Pose3 >::shared_ptr &f)
value_and_holder * operator->()
bool operator==(const iterator &other) const
typename std::enable_if< B, T >::type enable_if_t
from cpp_future import (convenient aliases from C++14/17)
const detail::type_info * type
static PYBIND11_NOINLINE void add_patient(handle h)
static loader_life_support * get_stack_top()
std::pair< typename std::remove_const< A >::type, B > if_not_recursive
PYBIND11_NOINLINE bool isinstance_generic(handle obj, const std::type_info &tp)
static const void * get(const itype *src, const std::type_info *&type)
loader_life_support * parent
Generic type caster for objects stored on the heap.
static void set_stack_top(loader_life_support *value)
type_caster_generic(const type_info *typeinfo)
gtsam
Author(s):
autogenerated on Sat Jun 1 2024 03:08:31