#include <array>
#include <limits>
#include <tuple>
+#include <type_traits>
#if defined(PYBIND11_CPP17)
# if defined(__has_include)
#include <string_view>
#endif
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+# define PYBIND11_HAS_U8STRING
+#endif
+
NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
NAMESPACE_BEGIN(detail)
}
struct value_and_holder {
- instance *inst;
- size_t index;
- const detail::type_info *type;
- void **vh;
+ instance *inst = nullptr;
+ size_t index = 0u;
+ const detail::type_info *type = nullptr;
+ void **vh = nullptr;
// Main constructor for a found value/holder:
value_and_holder(instance *i, const detail::type_info *type, size_t vpos, size_t index) :
{}
// Default constructor (used to signal a value-and-holder not found by get_value_and_holder())
- value_and_holder() : inst{nullptr} {}
+ value_and_holder() {}
// Used for past-the-end iterator
value_and_holder(size_t index) : index{index} {}
struct iterator {
private:
- instance *inst;
- const type_vec *types;
+ instance *inst = nullptr;
+ const type_vec *types = nullptr;
value_and_holder curr;
friend struct values_and_holders;
iterator(instance *inst, const type_vec *tinfo)
case return_value_policy::copy:
if (copy_constructor)
valueptr = copy_constructor(src);
- else
- throw cast_error("return_value_policy = copy, but the "
- "object is non-copyable!");
+ else {
+#if defined(NDEBUG)
+ throw cast_error("return_value_policy = copy, but type is "
+ "non-copyable! (compile in debug mode for details)");
+#else
+ std::string type_name(tinfo->cpptype->name());
+ detail::clean_type_id(type_name);
+ throw cast_error("return_value_policy = copy, but type " +
+ type_name + " is non-copyable!");
+#endif
+ }
wrapper->owned = true;
break;
valueptr = move_constructor(src);
else if (copy_constructor)
valueptr = copy_constructor(src);
- else
- throw cast_error("return_value_policy = move, but the "
- "object is neither movable nor copyable!");
+ else {
+#if defined(NDEBUG)
+ throw cast_error("return_value_policy = move, but type is neither "
+ "movable nor copyable! "
+ "(compile in debug mode for details)");
+#else
+ std::string type_name(tinfo->cpptype->name());
+ detail::clean_type_id(type_name);
+ throw cast_error("return_value_policy = move, but type " +
+ type_name + " is neither movable nor copyable!");
+#endif
+ }
wrapper->owned = true;
break;
// Lazy allocation for unallocated values:
if (vptr == nullptr) {
auto *type = v_h.type ? v_h.type : typeinfo;
- vptr = type->operator_new(type->type_size);
+ if (type->operator_new) {
+ vptr = type->operator_new(type->type_size);
+ } else {
+ #if defined(__cpp_aligned_new) && (!defined(_MSC_VER) || _MSC_VER >= 1912)
+ if (type->type_align > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
+ vptr = ::operator new(type->type_size,
+ std::align_val_t(type->type_align));
+ else
+ #endif
+ vptr = ::operator new(type->type_size);
+ }
}
value = vptr;
}
// so, copy constructability depends on whether the value_type is copy constructible.
template <typename Container> struct is_copy_constructible<Container, enable_if_t<all_of<
std::is_copy_constructible<Container>,
- std::is_same<typename Container::value_type &, typename Container::reference>
+ std::is_same<typename Container::value_type &, typename Container::reference>,
+ // Avoid infinite recursion
+ negation<std::is_same<Container, typename Container::value_type>>
>::value>> : is_copy_constructible<typename Container::value_type> {};
-#if !defined(PYBIND11_CPP17)
-// Likewise for std::pair before C++17 (which mandates that the copy constructor not exist when the
-// two types aren't themselves copy constructible).
+// Likewise for std::pair
+// (after C++17 it is mandatory that the copy constructor not exist when the two types aren't themselves
+// copy constructible, but this can not be relied upon when T1 or T2 are themselves containers).
template <typename T1, typename T2> struct is_copy_constructible<std::pair<T1, T2>>
: all_of<is_copy_constructible<T1>, is_copy_constructible<T2>> {};
-#endif
+
+// The same problems arise with std::is_copy_assignable, so we use the same workaround.
+template <typename T, typename SFINAE = void> struct is_copy_assignable : std::is_copy_assignable<T> {};
+template <typename Container> struct is_copy_assignable<Container, enable_if_t<all_of<
+ std::is_copy_assignable<Container>,
+ std::is_same<typename Container::value_type &, typename Container::reference>
+ >::value>> : is_copy_assignable<typename Container::value_type> {};
+template <typename T1, typename T2> struct is_copy_assignable<std::pair<T1, T2>>
+ : all_of<is_copy_assignable<T1>, is_copy_assignable<T2>> {};
+
+NAMESPACE_END(detail)
+
+// polymorphic_type_hook<itype>::get(src, tinfo) determines whether the object pointed
+// to by `src` actually is an instance of some class derived from `itype`.
+// If so, it sets `tinfo` to point to the std::type_info representing that derived
+// type, and returns a pointer to the start of the most-derived object of that type
+// (in which `src` is a subobject; this will be the same address as `src` in most
+// single inheritance cases). If not, or if `src` is nullptr, it simply returns `src`
+// and leaves `tinfo` at its default value of nullptr.
+//
+// The default polymorphic_type_hook just returns src. A specialization for polymorphic
+// types determines the runtime type of the passed object and adjusts the this-pointer
+// appropriately via dynamic_cast<void*>. This is what enables a C++ Animal* to appear
+// to Python as a Dog (if Dog inherits from Animal, Animal is polymorphic, Dog is
+// registered with pybind11, and this Animal is in fact a Dog).
+//
+// You may specialize polymorphic_type_hook yourself for types that want to appear
+// polymorphic to Python but do not use C++ RTTI. (This is a not uncommon pattern
+// in performance-sensitive applications, used most notably in LLVM.)
+template <typename itype, typename SFINAE = void>
+struct polymorphic_type_hook
+{
+ static const void *get(const itype *src, const std::type_info*&) { return src; }
+};
+template <typename itype>
+struct polymorphic_type_hook<itype, detail::enable_if_t<std::is_polymorphic<itype>::value>>
+{
+ static const void *get(const itype *src, const std::type_info*& type) {
+ type = src ? &typeid(*src) : nullptr;
+ return dynamic_cast<const void*>(src);
+ }
+};
+
+NAMESPACE_BEGIN(detail)
/// Generic type caster for objects stored on the heap
template <typename type> class type_caster_base : public type_caster_generic {
using itype = intrinsic_t<type>;
+
public:
- static PYBIND11_DESCR name() { return type_descr(_<type>()); }
+ static constexpr auto name = _<type>();
type_caster_base() : type_caster_base(typeid(type)) { }
explicit type_caster_base(const std::type_info &info) : type_caster_generic(info) { }
return cast(&src, return_value_policy::move, parent);
}
- // Returns a (pointer, type_info) pair taking care of necessary RTTI type lookup for a
- // polymorphic type. If the instance isn't derived, returns the non-RTTI base version.
- template <typename T = itype, enable_if_t<std::is_polymorphic<T>::value, int> = 0>
+ // Returns a (pointer, type_info) pair taking care of necessary type lookup for a
+ // polymorphic type (using RTTI by default, but can be overridden by specializing
+ // polymorphic_type_hook). If the instance isn't derived, returns the base version.
static std::pair<const void *, const type_info *> src_and_type(const itype *src) {
- const void *vsrc = src;
auto &cast_type = typeid(itype);
const std::type_info *instance_type = nullptr;
- if (vsrc) {
- instance_type = &typeid(*src);
- if (!same_type(cast_type, *instance_type)) {
- // This is a base pointer to a derived type; if it is a pybind11-registered type, we
- // can get the correct derived pointer (which may be != base pointer) by a
- // dynamic_cast to most derived type:
- if (auto *tpi = get_type_info(*instance_type))
- return {dynamic_cast<const void *>(src), const_cast<const type_info *>(tpi)};
- }
+ const void *vsrc = polymorphic_type_hook<itype>::get(src, instance_type);
+ if (instance_type && !same_type(cast_type, *instance_type)) {
+ // This is a base pointer to a derived type. If the derived type is registered
+ // with pybind11, we want to make the full derived object available.
+ // In the typical case where itype is polymorphic, we get the correct
+ // derived pointer (which may be != base pointer) by a dynamic_cast to
+ // most derived type. If itype is not polymorphic, we won't get here
+ // except via a user-provided specialization of polymorphic_type_hook,
+ // and the user has promised that no this-pointer adjustment is
+ // required in that case, so it's OK to use static_cast.
+ if (const auto *tpi = get_type_info(*instance_type))
+ return {vsrc, tpi};
}
// Otherwise we have either a nullptr, an `itype` pointer, or an unknown derived pointer, so
// don't do a cast
- return type_caster_generic::src_and_type(vsrc, cast_type, instance_type);
- }
-
- // Non-polymorphic type, so no dynamic casting; just call the generic version directly
- template <typename T = itype, enable_if_t<!std::is_polymorphic<T>::value, int> = 0>
- static std::pair<const void *, const type_info *> src_and_type(const itype *src) {
- return type_caster_generic::src_and_type(src, typeid(itype));
+ return type_caster_generic::src_and_type(src, cast_type, instance_type);
}
static handle cast(const itype *src, return_value_policy policy, handle parent) {
nullptr, nullptr, holder);
}
- template <typename T> using cast_op_type = cast_op_type<T>;
+ template <typename T> using cast_op_type = detail::cast_op_type<T>;
operator itype*() { return (type *) value; }
operator itype&() { if (!value) throw reference_cast_error(); return *((itype *) value); }
"std::reference_wrapper<T> caster requires T to have a caster with an `T &` operator");
public:
bool load(handle src, bool convert) { return subcaster.load(src, convert); }
- static PYBIND11_DESCR name() { return caster_t::name(); }
+ static constexpr auto name = caster_t::name;
static handle cast(const std::reference_wrapper<type> &src, return_value_policy policy, handle parent) {
// It is definitely wrong to take ownership of this pointer, so mask that rvp
if (policy == return_value_policy::take_ownership || policy == return_value_policy::automatic)
protected: \
type value; \
public: \
- static PYBIND11_DESCR name() { return type_descr(py_name); } \
+ static constexpr auto name = py_name; \
template <typename T_, enable_if_t<std::is_same<type, remove_cv_t<T_>>::value, int> = 0> \
static handle cast(T_ *src, return_value_policy policy, handle parent) { \
if (!src) return none().release(); \
template <typename CharT> using is_std_char_type = any_of<
std::is_same<CharT, char>, /* std::string */
+#if defined(PYBIND11_HAS_U8STRING)
+ std::is_same<CharT, char8_t>, /* std::u8string */
+#endif
std::is_same<CharT, char16_t>, /* std::u16string */
std::is_same<CharT, char32_t>, /* std::u32string */
std::is_same<CharT, wchar_t> /* std::wstring */
}
bool py_err = py_value == (py_type) -1 && PyErr_Occurred();
+
+ // Protect std::numeric_limits::min/max with parentheses
if (py_err || (std::is_integral<T>::value && sizeof(py_type) != sizeof(T) &&
- (py_value < (py_type) std::numeric_limits<T>::min() ||
- py_value > (py_type) std::numeric_limits<T>::max()))) {
+ (py_value < (py_type) (std::numeric_limits<T>::min)() ||
+ py_value > (py_type) (std::numeric_limits<T>::max)()))) {
bool type_error = py_err && PyErr_ExceptionMatches(
#if PY_VERSION_HEX < 0x03000000 && !defined(PYPY_VERSION)
PyExc_SystemError
return true;
}
- static handle cast(T src, return_value_policy /* policy */, handle /* parent */) {
- if (std::is_floating_point<T>::value) {
- return PyFloat_FromDouble((double) src);
- } else if (sizeof(T) <= sizeof(long)) {
- if (std::is_signed<T>::value)
- return PyLong_FromLong((long) src);
- else
- return PyLong_FromUnsignedLong((unsigned long) src);
- } else {
- if (std::is_signed<T>::value)
- return PyLong_FromLongLong((long long) src);
- else
- return PyLong_FromUnsignedLongLong((unsigned long long) src);
- }
+ template<typename U = T>
+ static typename std::enable_if<std::is_floating_point<U>::value, handle>::type
+ cast(U src, return_value_policy /* policy */, handle /* parent */) {
+ return PyFloat_FromDouble((double) src);
+ }
+
+ template<typename U = T>
+ static typename std::enable_if<!std::is_floating_point<U>::value && std::is_signed<U>::value && (sizeof(U) <= sizeof(long)), handle>::type
+ cast(U src, return_value_policy /* policy */, handle /* parent */) {
+ return PYBIND11_LONG_FROM_SIGNED((long) src);
+ }
+
+ template<typename U = T>
+ static typename std::enable_if<!std::is_floating_point<U>::value && std::is_unsigned<U>::value && (sizeof(U) <= sizeof(unsigned long)), handle>::type
+ cast(U src, return_value_policy /* policy */, handle /* parent */) {
+ return PYBIND11_LONG_FROM_UNSIGNED((unsigned long) src);
+ }
+
+ template<typename U = T>
+ static typename std::enable_if<!std::is_floating_point<U>::value && std::is_signed<U>::value && (sizeof(U) > sizeof(long)), handle>::type
+ cast(U src, return_value_policy /* policy */, handle /* parent */) {
+ return PyLong_FromLongLong((long long) src);
+ }
+
+ template<typename U = T>
+ static typename std::enable_if<!std::is_floating_point<U>::value && std::is_unsigned<U>::value && (sizeof(U) > sizeof(unsigned long)), handle>::type
+ cast(U src, return_value_policy /* policy */, handle /* parent */) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) src);
}
PYBIND11_TYPE_CASTER(T, _<std::is_integral<T>::value>("int", "float"));
template <typename T> using cast_op_type = void*&;
operator void *&() { return value; }
- static PYBIND11_DESCR name() { return type_descr(_("capsule")); }
+ static constexpr auto name = _("capsule");
private:
void *value = nullptr;
};
if (res == 0 || res == 1) {
value = (bool) res;
return true;
+ } else {
+ PyErr_Clear();
}
}
return false;
// Simplify life by being able to assume standard char sizes (the standard only guarantees
// minimums, but Python requires exact sizes)
static_assert(!std::is_same<CharT, char>::value || sizeof(CharT) == 1, "Unsupported char size != 1");
+#if defined(PYBIND11_HAS_U8STRING)
+ static_assert(!std::is_same<CharT, char8_t>::value || sizeof(CharT) == 1, "Unsupported char8_t size != 1");
+#endif
static_assert(!std::is_same<CharT, char16_t>::value || sizeof(CharT) == 2, "Unsupported char16_t size != 2");
static_assert(!std::is_same<CharT, char32_t>::value || sizeof(CharT) == 4, "Unsupported char32_t size != 4");
// wchar_t can be either 16 bits (Windows) or 32 (everywhere else)
#if PY_MAJOR_VERSION >= 3
return load_bytes(load_src);
#else
- if (sizeof(CharT) == 1) {
+ if (std::is_same<CharT, char>::value) {
return load_bytes(load_src);
}
// without any encoding/decoding attempt). For other C++ char sizes this is a no-op.
// which supports loading a unicode from a str, doesn't take this path.
template <typename C = CharT>
- bool load_bytes(enable_if_t<sizeof(C) == 1, handle> src) {
+ bool load_bytes(enable_if_t<std::is_same<C, char>::value, handle> src) {
if (PYBIND11_BYTES_CHECK(src.ptr())) {
// We were passed a Python 3 raw bytes; accept it into a std::string or char*
// without any encoding attempt.
}
template <typename C = CharT>
- bool load_bytes(enable_if_t<sizeof(C) != 1, handle>) { return false; }
+ bool load_bytes(enable_if_t<!std::is_same<C, char>::value, handle>) { return false; }
};
template <typename CharT, class Traits, class Allocator>
return one_char;
}
- static PYBIND11_DESCR name() { return type_descr(_(PYBIND11_STRING_NAME)); }
+ static constexpr auto name = _(PYBIND11_STRING_NAME);
template <typename _T> using cast_op_type = pybind11::detail::cast_op_type<_T>;
};
return cast_impl(std::forward<T>(src), policy, parent, indices{});
}
- static PYBIND11_DESCR name() {
- return type_descr(_("Tuple[") + detail::concat(make_caster<Ts>::name()...) + _("]"));
- }
+ static constexpr auto name = _("Tuple[") + concat(make_caster<Ts>::name...) + _("]");
template <typename T> using cast_op_type = type;
template <size_t... Is>
bool load_impl(const sequence &seq, bool convert, index_sequence<Is...>) {
+#ifdef __cpp_fold_expressions
+ if ((... || !std::get<Is>(subcasters).load(seq[Is], convert)))
+ return false;
+#else
for (bool r : {std::get<Is>(subcasters).load(seq[Is], convert)...})
if (!r)
return false;
+#endif
return true;
}
auto *ptr = holder_helper<holder_type>::get(src);
return type_caster_base<type>::cast_holder(ptr, std::addressof(src));
}
- static PYBIND11_DESCR name() { return type_caster_base<type>::name(); }
+ static constexpr auto name = type_caster_base<type>::name;
};
template <typename type, typename deleter>
template <typename base, typename deleter> struct is_holder_type<base, std::unique_ptr<base, deleter>> :
std::true_type {};
-template <typename T> struct handle_type_name { static PYBIND11_DESCR name() { return _<T>(); } };
-template <> struct handle_type_name<bytes> { static PYBIND11_DESCR name() { return _(PYBIND11_BYTES_NAME); } };
-template <> struct handle_type_name<args> { static PYBIND11_DESCR name() { return _("*args"); } };
-template <> struct handle_type_name<kwargs> { static PYBIND11_DESCR name() { return _("**kwargs"); } };
+template <typename T> struct handle_type_name { static constexpr auto name = _<T>(); };
+template <> struct handle_type_name<bytes> { static constexpr auto name = _(PYBIND11_BYTES_NAME); };
+template <> struct handle_type_name<args> { static constexpr auto name = _("*args"); };
+template <> struct handle_type_name<kwargs> { static constexpr auto name = _("**kwargs"); };
template <typename type>
struct pyobject_caster {
static handle cast(const handle &src, return_value_policy /* policy */, handle /* parent */) {
return src.inc_ref();
}
- PYBIND11_TYPE_CASTER(type, handle_type_name<type>::name());
+ PYBIND11_TYPE_CASTER(type, handle_type_name<type>::name);
};
template <typename T>
// everything else returns a reference/pointer to a local variable.
template <typename type> using cast_is_temporary_value_reference = bool_constant<
(std::is_reference<type>::value || std::is_pointer<type>::value) &&
- !std::is_base_of<type_caster_generic, make_caster<type>>::value
+ !std::is_base_of<type_caster_generic, make_caster<type>>::value &&
+ !std::is_same<intrinsic_t<type>, void>::value
>;
// When a value returned from a C++ function is being cast back to Python, we almost always want to
template <typename Return> struct return_value_policy_override<Return,
detail::enable_if_t<std::is_base_of<type_caster_generic, make_caster<Return>>::value, void>> {
static return_value_policy policy(return_value_policy p) {
- return !std::is_lvalue_reference<Return>::value && !std::is_pointer<Return>::value
- ? return_value_policy::move : p;
+ return !std::is_lvalue_reference<Return>::value &&
+ !std::is_pointer<Return>::value
+ ? return_value_policy::move : p;
}
};
/// Internal data associated with a single function call
struct function_call {
- function_call(function_record &f, handle p); // Implementation in attr.h
+ function_call(const function_record &f, handle p); // Implementation in attr.h
/// The function data:
const function_record &func;
static constexpr bool has_kwargs = kwargs_pos < 0;
static constexpr bool has_args = args_pos < 0;
- static PYBIND11_DESCR arg_names() { return detail::concat(make_caster<Args>::name()...); }
+ static constexpr auto arg_names = concat(type_descr(make_caster<Args>::name)...);
bool load_args(function_call &call) {
return load_impl_sequence(call, indices{});
template <size_t... Is>
bool load_impl_sequence(function_call &call, index_sequence<Is...>) {
+#ifdef __cpp_fold_expressions
+ if ((... || !std::get<Is>(argcasters).load(call.args[Is], call.args_convert[Is])))
+ return false;
+#else
for (bool r : {std::get<Is>(argcasters).load(call.args[Is], call.args_convert[Is])...})
if (!r)
return false;
+#endif
return true;
}
template <typename Return, typename Func, size_t... Is, typename Guard>
- Return call_impl(Func &&f, index_sequence<Is...>, Guard &&) {
+ Return call_impl(Func &&f, index_sequence<Is...>, Guard &&) && {
return std::forward<Func>(f)(cast_op<Args>(std::move(std::get<Is>(argcasters)))...);
}
NAMESPACE_END(detail)
-#define PYBIND11_MAKE_OPAQUE(Type) \
+#define PYBIND11_MAKE_OPAQUE(...) \
namespace pybind11 { namespace detail { \
- template<> class type_caster<Type> : public type_caster_base<Type> { }; \
+ template<> class type_caster<__VA_ARGS__> : public type_caster_base<__VA_ARGS__> { }; \
}}
+/// Lets you pass a type containing a `,` through a macro parameter without needing a separate
+/// typedef, e.g.: `PYBIND11_OVERLOAD(PYBIND11_TYPE(ReturnType<A, B>), PYBIND11_TYPE(Parent<C, D>), f, arg)`
+#define PYBIND11_TYPE(...) __VA_ARGS__
+
NAMESPACE_END(PYBIND11_NAMESPACE)