cast.h revision 12037
111986Sandreas.sandberg@arm.com/* 211986Sandreas.sandberg@arm.com pybind11/cast.h: Partial template specializations to cast between 311986Sandreas.sandberg@arm.com C++ and Python types 411986Sandreas.sandberg@arm.com 511986Sandreas.sandberg@arm.com Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch> 611986Sandreas.sandberg@arm.com 711986Sandreas.sandberg@arm.com All rights reserved. Use of this source code is governed by a 811986Sandreas.sandberg@arm.com BSD-style license that can be found in the LICENSE file. 911986Sandreas.sandberg@arm.com*/ 1011986Sandreas.sandberg@arm.com 1111986Sandreas.sandberg@arm.com#pragma once 1211986Sandreas.sandberg@arm.com 1311986Sandreas.sandberg@arm.com#include "pytypes.h" 1411986Sandreas.sandberg@arm.com#include "typeid.h" 1511986Sandreas.sandberg@arm.com#include "descr.h" 1611986Sandreas.sandberg@arm.com#include <array> 1711986Sandreas.sandberg@arm.com#include <limits> 1811986Sandreas.sandberg@arm.com 1911986Sandreas.sandberg@arm.comNAMESPACE_BEGIN(pybind11) 2011986Sandreas.sandberg@arm.comNAMESPACE_BEGIN(detail) 2112037Sandreas.sandberg@arm.cominline PyTypeObject *make_static_property_type(); 2212037Sandreas.sandberg@arm.cominline PyTypeObject *make_default_metaclass(); 2311986Sandreas.sandberg@arm.com 2411986Sandreas.sandberg@arm.com/// Additional type information which does not fit into the PyTypeObject 2511986Sandreas.sandberg@arm.comstruct type_info { 2611986Sandreas.sandberg@arm.com PyTypeObject *type; 2711986Sandreas.sandberg@arm.com size_t type_size; 2812037Sandreas.sandberg@arm.com void *(*operator_new)(size_t); 2911986Sandreas.sandberg@arm.com void (*init_holder)(PyObject *, const void *); 3012037Sandreas.sandberg@arm.com void (*dealloc)(PyObject *); 3111986Sandreas.sandberg@arm.com std::vector<PyObject *(*)(PyObject *, PyTypeObject *)> implicit_conversions; 3211986Sandreas.sandberg@arm.com std::vector<std::pair<const std::type_info *, void *(*)(void *)>> implicit_casts; 3311986Sandreas.sandberg@arm.com std::vector<bool (*)(PyObject *, void *&)> *direct_conversions; 3411986Sandreas.sandberg@arm.com buffer_info *(*get_buffer)(PyObject *, void *) = nullptr; 3511986Sandreas.sandberg@arm.com void *get_buffer_data = nullptr; 3611986Sandreas.sandberg@arm.com /** A simple type never occurs as a (direct or indirect) parent 3711986Sandreas.sandberg@arm.com * of a class that makes use of multiple inheritance */ 3811986Sandreas.sandberg@arm.com bool simple_type = true; 3912037Sandreas.sandberg@arm.com /* for base vs derived holder_type checks */ 4012037Sandreas.sandberg@arm.com bool default_holder = true; 4111986Sandreas.sandberg@arm.com}; 4211986Sandreas.sandberg@arm.com 4311986Sandreas.sandberg@arm.comPYBIND11_NOINLINE inline internals &get_internals() { 4411986Sandreas.sandberg@arm.com static internals *internals_ptr = nullptr; 4511986Sandreas.sandberg@arm.com if (internals_ptr) 4611986Sandreas.sandberg@arm.com return *internals_ptr; 4711986Sandreas.sandberg@arm.com handle builtins(PyEval_GetBuiltins()); 4811986Sandreas.sandberg@arm.com const char *id = PYBIND11_INTERNALS_ID; 4911986Sandreas.sandberg@arm.com if (builtins.contains(id) && isinstance<capsule>(builtins[id])) { 5011986Sandreas.sandberg@arm.com internals_ptr = capsule(builtins[id]); 5111986Sandreas.sandberg@arm.com } else { 5211986Sandreas.sandberg@arm.com internals_ptr = new internals(); 5311986Sandreas.sandberg@arm.com #if defined(WITH_THREAD) 5411986Sandreas.sandberg@arm.com PyEval_InitThreads(); 5511986Sandreas.sandberg@arm.com PyThreadState *tstate = PyThreadState_Get(); 5611986Sandreas.sandberg@arm.com internals_ptr->tstate = PyThread_create_key(); 5711986Sandreas.sandberg@arm.com PyThread_set_key_value(internals_ptr->tstate, tstate); 5811986Sandreas.sandberg@arm.com internals_ptr->istate = tstate->interp; 5911986Sandreas.sandberg@arm.com #endif 6011986Sandreas.sandberg@arm.com builtins[id] = capsule(internals_ptr); 6111986Sandreas.sandberg@arm.com internals_ptr->registered_exception_translators.push_front( 6211986Sandreas.sandberg@arm.com [](std::exception_ptr p) -> void { 6311986Sandreas.sandberg@arm.com try { 6411986Sandreas.sandberg@arm.com if (p) std::rethrow_exception(p); 6511986Sandreas.sandberg@arm.com } catch (error_already_set &e) { e.restore(); return; 6611986Sandreas.sandberg@arm.com } catch (const builtin_exception &e) { e.set_error(); return; 6711986Sandreas.sandberg@arm.com } catch (const std::bad_alloc &e) { PyErr_SetString(PyExc_MemoryError, e.what()); return; 6811986Sandreas.sandberg@arm.com } catch (const std::domain_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; 6911986Sandreas.sandberg@arm.com } catch (const std::invalid_argument &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; 7011986Sandreas.sandberg@arm.com } catch (const std::length_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; 7111986Sandreas.sandberg@arm.com } catch (const std::out_of_range &e) { PyErr_SetString(PyExc_IndexError, e.what()); return; 7211986Sandreas.sandberg@arm.com } catch (const std::range_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; 7311986Sandreas.sandberg@arm.com } catch (const std::exception &e) { PyErr_SetString(PyExc_RuntimeError, e.what()); return; 7411986Sandreas.sandberg@arm.com } catch (...) { 7511986Sandreas.sandberg@arm.com PyErr_SetString(PyExc_RuntimeError, "Caught an unknown exception!"); 7611986Sandreas.sandberg@arm.com return; 7711986Sandreas.sandberg@arm.com } 7811986Sandreas.sandberg@arm.com } 7911986Sandreas.sandberg@arm.com ); 8012037Sandreas.sandberg@arm.com internals_ptr->static_property_type = make_static_property_type(); 8112037Sandreas.sandberg@arm.com internals_ptr->default_metaclass = make_default_metaclass(); 8211986Sandreas.sandberg@arm.com } 8311986Sandreas.sandberg@arm.com return *internals_ptr; 8411986Sandreas.sandberg@arm.com} 8511986Sandreas.sandberg@arm.com 8611986Sandreas.sandberg@arm.comPYBIND11_NOINLINE inline detail::type_info* get_type_info(PyTypeObject *type) { 8711986Sandreas.sandberg@arm.com auto const &type_dict = get_internals().registered_types_py; 8811986Sandreas.sandberg@arm.com do { 8911986Sandreas.sandberg@arm.com auto it = type_dict.find(type); 9011986Sandreas.sandberg@arm.com if (it != type_dict.end()) 9111986Sandreas.sandberg@arm.com return (detail::type_info *) it->second; 9211986Sandreas.sandberg@arm.com type = type->tp_base; 9311986Sandreas.sandberg@arm.com if (!type) 9411986Sandreas.sandberg@arm.com return nullptr; 9511986Sandreas.sandberg@arm.com } while (true); 9611986Sandreas.sandberg@arm.com} 9711986Sandreas.sandberg@arm.com 9811986Sandreas.sandberg@arm.comPYBIND11_NOINLINE inline detail::type_info *get_type_info(const std::type_info &tp, 9911986Sandreas.sandberg@arm.com bool throw_if_missing = false) { 10011986Sandreas.sandberg@arm.com auto &types = get_internals().registered_types_cpp; 10111986Sandreas.sandberg@arm.com 10211986Sandreas.sandberg@arm.com auto it = types.find(std::type_index(tp)); 10311986Sandreas.sandberg@arm.com if (it != types.end()) 10411986Sandreas.sandberg@arm.com return (detail::type_info *) it->second; 10511986Sandreas.sandberg@arm.com if (throw_if_missing) { 10611986Sandreas.sandberg@arm.com std::string tname = tp.name(); 10711986Sandreas.sandberg@arm.com detail::clean_type_id(tname); 10811986Sandreas.sandberg@arm.com pybind11_fail("pybind11::detail::get_type_info: unable to find type info for \"" + tname + "\""); 10911986Sandreas.sandberg@arm.com } 11011986Sandreas.sandberg@arm.com return nullptr; 11111986Sandreas.sandberg@arm.com} 11211986Sandreas.sandberg@arm.com 11311986Sandreas.sandberg@arm.comPYBIND11_NOINLINE inline handle get_type_handle(const std::type_info &tp, bool throw_if_missing) { 11411986Sandreas.sandberg@arm.com detail::type_info *type_info = get_type_info(tp, throw_if_missing); 11511986Sandreas.sandberg@arm.com return handle(type_info ? ((PyObject *) type_info->type) : nullptr); 11611986Sandreas.sandberg@arm.com} 11711986Sandreas.sandberg@arm.com 11811986Sandreas.sandberg@arm.comPYBIND11_NOINLINE inline bool isinstance_generic(handle obj, const std::type_info &tp) { 11912037Sandreas.sandberg@arm.com handle type = detail::get_type_handle(tp, false); 12011986Sandreas.sandberg@arm.com if (!type) 12111986Sandreas.sandberg@arm.com return false; 12212037Sandreas.sandberg@arm.com return isinstance(obj, type); 12311986Sandreas.sandberg@arm.com} 12411986Sandreas.sandberg@arm.com 12511986Sandreas.sandberg@arm.comPYBIND11_NOINLINE inline std::string error_string() { 12611986Sandreas.sandberg@arm.com if (!PyErr_Occurred()) { 12711986Sandreas.sandberg@arm.com PyErr_SetString(PyExc_RuntimeError, "Unknown internal error occurred"); 12811986Sandreas.sandberg@arm.com return "Unknown internal error occurred"; 12911986Sandreas.sandberg@arm.com } 13011986Sandreas.sandberg@arm.com 13111986Sandreas.sandberg@arm.com error_scope scope; // Preserve error state 13211986Sandreas.sandberg@arm.com 13311986Sandreas.sandberg@arm.com std::string errorString; 13411986Sandreas.sandberg@arm.com if (scope.type) { 13511986Sandreas.sandberg@arm.com errorString += handle(scope.type).attr("__name__").cast<std::string>(); 13611986Sandreas.sandberg@arm.com errorString += ": "; 13711986Sandreas.sandberg@arm.com } 13811986Sandreas.sandberg@arm.com if (scope.value) 13911986Sandreas.sandberg@arm.com errorString += (std::string) str(scope.value); 14011986Sandreas.sandberg@arm.com 14111986Sandreas.sandberg@arm.com PyErr_NormalizeException(&scope.type, &scope.value, &scope.trace); 14211986Sandreas.sandberg@arm.com 14311986Sandreas.sandberg@arm.com#if PY_MAJOR_VERSION >= 3 14411986Sandreas.sandberg@arm.com if (scope.trace != nullptr) 14511986Sandreas.sandberg@arm.com PyException_SetTraceback(scope.value, scope.trace); 14611986Sandreas.sandberg@arm.com#endif 14711986Sandreas.sandberg@arm.com 14812037Sandreas.sandberg@arm.com#if !defined(PYPY_VERSION) 14911986Sandreas.sandberg@arm.com if (scope.trace) { 15011986Sandreas.sandberg@arm.com PyTracebackObject *trace = (PyTracebackObject *) scope.trace; 15111986Sandreas.sandberg@arm.com 15211986Sandreas.sandberg@arm.com /* Get the deepest trace possible */ 15311986Sandreas.sandberg@arm.com while (trace->tb_next) 15411986Sandreas.sandberg@arm.com trace = trace->tb_next; 15511986Sandreas.sandberg@arm.com 15611986Sandreas.sandberg@arm.com PyFrameObject *frame = trace->tb_frame; 15711986Sandreas.sandberg@arm.com errorString += "\n\nAt:\n"; 15811986Sandreas.sandberg@arm.com while (frame) { 15911986Sandreas.sandberg@arm.com int lineno = PyFrame_GetLineNumber(frame); 16011986Sandreas.sandberg@arm.com errorString += 16111986Sandreas.sandberg@arm.com " " + handle(frame->f_code->co_filename).cast<std::string>() + 16211986Sandreas.sandberg@arm.com "(" + std::to_string(lineno) + "): " + 16311986Sandreas.sandberg@arm.com handle(frame->f_code->co_name).cast<std::string>() + "\n"; 16411986Sandreas.sandberg@arm.com frame = frame->f_back; 16511986Sandreas.sandberg@arm.com } 16611986Sandreas.sandberg@arm.com trace = trace->tb_next; 16711986Sandreas.sandberg@arm.com } 16812037Sandreas.sandberg@arm.com#endif 16911986Sandreas.sandberg@arm.com 17011986Sandreas.sandberg@arm.com return errorString; 17111986Sandreas.sandberg@arm.com} 17211986Sandreas.sandberg@arm.com 17311986Sandreas.sandberg@arm.comPYBIND11_NOINLINE inline handle get_object_handle(const void *ptr, const detail::type_info *type ) { 17411986Sandreas.sandberg@arm.com auto &instances = get_internals().registered_instances; 17511986Sandreas.sandberg@arm.com auto range = instances.equal_range(ptr); 17611986Sandreas.sandberg@arm.com for (auto it = range.first; it != range.second; ++it) { 17711986Sandreas.sandberg@arm.com auto instance_type = detail::get_type_info(Py_TYPE(it->second)); 17811986Sandreas.sandberg@arm.com if (instance_type && instance_type == type) 17911986Sandreas.sandberg@arm.com return handle((PyObject *) it->second); 18011986Sandreas.sandberg@arm.com } 18111986Sandreas.sandberg@arm.com return handle(); 18211986Sandreas.sandberg@arm.com} 18311986Sandreas.sandberg@arm.com 18411986Sandreas.sandberg@arm.cominline PyThreadState *get_thread_state_unchecked() { 18512037Sandreas.sandberg@arm.com#if defined(PYPY_VERSION) 18612037Sandreas.sandberg@arm.com return PyThreadState_GET(); 18712037Sandreas.sandberg@arm.com#elif PY_VERSION_HEX < 0x03000000 18811986Sandreas.sandberg@arm.com return _PyThreadState_Current; 18911986Sandreas.sandberg@arm.com#elif PY_VERSION_HEX < 0x03050000 19011986Sandreas.sandberg@arm.com return (PyThreadState*) _Py_atomic_load_relaxed(&_PyThreadState_Current); 19111986Sandreas.sandberg@arm.com#elif PY_VERSION_HEX < 0x03050200 19211986Sandreas.sandberg@arm.com return (PyThreadState*) _PyThreadState_Current.value; 19311986Sandreas.sandberg@arm.com#else 19411986Sandreas.sandberg@arm.com return _PyThreadState_UncheckedGet(); 19511986Sandreas.sandberg@arm.com#endif 19611986Sandreas.sandberg@arm.com} 19711986Sandreas.sandberg@arm.com 19811986Sandreas.sandberg@arm.com// Forward declaration 19911986Sandreas.sandberg@arm.cominline void keep_alive_impl(handle nurse, handle patient); 20011986Sandreas.sandberg@arm.com 20111986Sandreas.sandberg@arm.comclass type_caster_generic { 20211986Sandreas.sandberg@arm.compublic: 20311986Sandreas.sandberg@arm.com PYBIND11_NOINLINE type_caster_generic(const std::type_info &type_info) 20411986Sandreas.sandberg@arm.com : typeinfo(get_type_info(type_info)) { } 20511986Sandreas.sandberg@arm.com 20611986Sandreas.sandberg@arm.com PYBIND11_NOINLINE bool load(handle src, bool convert) { 20711986Sandreas.sandberg@arm.com if (!src) 20811986Sandreas.sandberg@arm.com return false; 20911986Sandreas.sandberg@arm.com return load(src, convert, Py_TYPE(src.ptr())); 21011986Sandreas.sandberg@arm.com } 21111986Sandreas.sandberg@arm.com 21211986Sandreas.sandberg@arm.com bool load(handle src, bool convert, PyTypeObject *tobj) { 21311986Sandreas.sandberg@arm.com if (!src || !typeinfo) 21411986Sandreas.sandberg@arm.com return false; 21511986Sandreas.sandberg@arm.com if (src.is_none()) { 21611986Sandreas.sandberg@arm.com value = nullptr; 21711986Sandreas.sandberg@arm.com return true; 21811986Sandreas.sandberg@arm.com } 21911986Sandreas.sandberg@arm.com 22011986Sandreas.sandberg@arm.com if (typeinfo->simple_type) { /* Case 1: no multiple inheritance etc. involved */ 22111986Sandreas.sandberg@arm.com /* Check if we can safely perform a reinterpret-style cast */ 22211986Sandreas.sandberg@arm.com if (PyType_IsSubtype(tobj, typeinfo->type)) { 22311986Sandreas.sandberg@arm.com value = reinterpret_cast<instance<void> *>(src.ptr())->value; 22411986Sandreas.sandberg@arm.com return true; 22511986Sandreas.sandberg@arm.com } 22611986Sandreas.sandberg@arm.com } else { /* Case 2: multiple inheritance */ 22711986Sandreas.sandberg@arm.com /* Check if we can safely perform a reinterpret-style cast */ 22811986Sandreas.sandberg@arm.com if (tobj == typeinfo->type) { 22911986Sandreas.sandberg@arm.com value = reinterpret_cast<instance<void> *>(src.ptr())->value; 23011986Sandreas.sandberg@arm.com return true; 23111986Sandreas.sandberg@arm.com } 23211986Sandreas.sandberg@arm.com 23311986Sandreas.sandberg@arm.com /* If this is a python class, also check the parents recursively */ 23411986Sandreas.sandberg@arm.com auto const &type_dict = get_internals().registered_types_py; 23512037Sandreas.sandberg@arm.com bool new_style_class = PyType_Check((PyObject *) tobj); 23611986Sandreas.sandberg@arm.com if (type_dict.find(tobj) == type_dict.end() && new_style_class && tobj->tp_bases) { 23711986Sandreas.sandberg@arm.com auto parents = reinterpret_borrow<tuple>(tobj->tp_bases); 23811986Sandreas.sandberg@arm.com for (handle parent : parents) { 23911986Sandreas.sandberg@arm.com bool result = load(src, convert, (PyTypeObject *) parent.ptr()); 24011986Sandreas.sandberg@arm.com if (result) 24111986Sandreas.sandberg@arm.com return true; 24211986Sandreas.sandberg@arm.com } 24311986Sandreas.sandberg@arm.com } 24411986Sandreas.sandberg@arm.com 24511986Sandreas.sandberg@arm.com /* Try implicit casts */ 24611986Sandreas.sandberg@arm.com for (auto &cast : typeinfo->implicit_casts) { 24711986Sandreas.sandberg@arm.com type_caster_generic sub_caster(*cast.first); 24811986Sandreas.sandberg@arm.com if (sub_caster.load(src, convert)) { 24911986Sandreas.sandberg@arm.com value = cast.second(sub_caster.value); 25011986Sandreas.sandberg@arm.com return true; 25111986Sandreas.sandberg@arm.com } 25211986Sandreas.sandberg@arm.com } 25311986Sandreas.sandberg@arm.com } 25411986Sandreas.sandberg@arm.com 25511986Sandreas.sandberg@arm.com /* Perform an implicit conversion */ 25611986Sandreas.sandberg@arm.com if (convert) { 25711986Sandreas.sandberg@arm.com for (auto &converter : typeinfo->implicit_conversions) { 25811986Sandreas.sandberg@arm.com temp = reinterpret_steal<object>(converter(src.ptr(), typeinfo->type)); 25911986Sandreas.sandberg@arm.com if (load(temp, false)) 26011986Sandreas.sandberg@arm.com return true; 26111986Sandreas.sandberg@arm.com } 26211986Sandreas.sandberg@arm.com for (auto &converter : *typeinfo->direct_conversions) { 26311986Sandreas.sandberg@arm.com if (converter(src.ptr(), value)) 26411986Sandreas.sandberg@arm.com return true; 26511986Sandreas.sandberg@arm.com } 26611986Sandreas.sandberg@arm.com } 26711986Sandreas.sandberg@arm.com return false; 26811986Sandreas.sandberg@arm.com } 26911986Sandreas.sandberg@arm.com 27011986Sandreas.sandberg@arm.com PYBIND11_NOINLINE static handle cast(const void *_src, return_value_policy policy, handle parent, 27111986Sandreas.sandberg@arm.com const std::type_info *type_info, 27211986Sandreas.sandberg@arm.com const std::type_info *type_info_backup, 27311986Sandreas.sandberg@arm.com void *(*copy_constructor)(const void *), 27411986Sandreas.sandberg@arm.com void *(*move_constructor)(const void *), 27511986Sandreas.sandberg@arm.com const void *existing_holder = nullptr) { 27611986Sandreas.sandberg@arm.com void *src = const_cast<void *>(_src); 27711986Sandreas.sandberg@arm.com if (src == nullptr) 27811986Sandreas.sandberg@arm.com return none().inc_ref(); 27911986Sandreas.sandberg@arm.com 28011986Sandreas.sandberg@arm.com auto &internals = get_internals(); 28111986Sandreas.sandberg@arm.com 28211986Sandreas.sandberg@arm.com auto it = internals.registered_types_cpp.find(std::type_index(*type_info)); 28311986Sandreas.sandberg@arm.com if (it == internals.registered_types_cpp.end()) { 28411986Sandreas.sandberg@arm.com type_info = type_info_backup; 28511986Sandreas.sandberg@arm.com it = internals.registered_types_cpp.find(std::type_index(*type_info)); 28611986Sandreas.sandberg@arm.com } 28711986Sandreas.sandberg@arm.com 28811986Sandreas.sandberg@arm.com if (it == internals.registered_types_cpp.end()) { 28911986Sandreas.sandberg@arm.com std::string tname = type_info->name(); 29011986Sandreas.sandberg@arm.com detail::clean_type_id(tname); 29111986Sandreas.sandberg@arm.com std::string msg = "Unregistered type : " + tname; 29211986Sandreas.sandberg@arm.com PyErr_SetString(PyExc_TypeError, msg.c_str()); 29311986Sandreas.sandberg@arm.com return handle(); 29411986Sandreas.sandberg@arm.com } 29511986Sandreas.sandberg@arm.com 29611986Sandreas.sandberg@arm.com auto tinfo = (const detail::type_info *) it->second; 29711986Sandreas.sandberg@arm.com 29811986Sandreas.sandberg@arm.com auto it_instances = internals.registered_instances.equal_range(src); 29911986Sandreas.sandberg@arm.com for (auto it_i = it_instances.first; it_i != it_instances.second; ++it_i) { 30011986Sandreas.sandberg@arm.com auto instance_type = detail::get_type_info(Py_TYPE(it_i->second)); 30111986Sandreas.sandberg@arm.com if (instance_type && instance_type == tinfo) 30211986Sandreas.sandberg@arm.com return handle((PyObject *) it_i->second).inc_ref(); 30311986Sandreas.sandberg@arm.com } 30411986Sandreas.sandberg@arm.com 30511986Sandreas.sandberg@arm.com auto inst = reinterpret_steal<object>(PyType_GenericAlloc(tinfo->type, 0)); 30611986Sandreas.sandberg@arm.com 30711986Sandreas.sandberg@arm.com auto wrapper = (instance<void> *) inst.ptr(); 30811986Sandreas.sandberg@arm.com 30911986Sandreas.sandberg@arm.com wrapper->value = nullptr; 31011986Sandreas.sandberg@arm.com wrapper->owned = false; 31111986Sandreas.sandberg@arm.com 31211986Sandreas.sandberg@arm.com switch (policy) { 31311986Sandreas.sandberg@arm.com case return_value_policy::automatic: 31411986Sandreas.sandberg@arm.com case return_value_policy::take_ownership: 31511986Sandreas.sandberg@arm.com wrapper->value = src; 31611986Sandreas.sandberg@arm.com wrapper->owned = true; 31711986Sandreas.sandberg@arm.com break; 31811986Sandreas.sandberg@arm.com 31911986Sandreas.sandberg@arm.com case return_value_policy::automatic_reference: 32011986Sandreas.sandberg@arm.com case return_value_policy::reference: 32111986Sandreas.sandberg@arm.com wrapper->value = src; 32211986Sandreas.sandberg@arm.com wrapper->owned = false; 32311986Sandreas.sandberg@arm.com break; 32411986Sandreas.sandberg@arm.com 32511986Sandreas.sandberg@arm.com case return_value_policy::copy: 32611986Sandreas.sandberg@arm.com if (copy_constructor) 32711986Sandreas.sandberg@arm.com wrapper->value = copy_constructor(src); 32811986Sandreas.sandberg@arm.com else 32911986Sandreas.sandberg@arm.com throw cast_error("return_value_policy = copy, but the " 33011986Sandreas.sandberg@arm.com "object is non-copyable!"); 33111986Sandreas.sandberg@arm.com wrapper->owned = true; 33211986Sandreas.sandberg@arm.com break; 33311986Sandreas.sandberg@arm.com 33411986Sandreas.sandberg@arm.com case return_value_policy::move: 33511986Sandreas.sandberg@arm.com if (move_constructor) 33611986Sandreas.sandberg@arm.com wrapper->value = move_constructor(src); 33711986Sandreas.sandberg@arm.com else if (copy_constructor) 33811986Sandreas.sandberg@arm.com wrapper->value = copy_constructor(src); 33911986Sandreas.sandberg@arm.com else 34011986Sandreas.sandberg@arm.com throw cast_error("return_value_policy = move, but the " 34111986Sandreas.sandberg@arm.com "object is neither movable nor copyable!"); 34211986Sandreas.sandberg@arm.com wrapper->owned = true; 34311986Sandreas.sandberg@arm.com break; 34411986Sandreas.sandberg@arm.com 34511986Sandreas.sandberg@arm.com case return_value_policy::reference_internal: 34611986Sandreas.sandberg@arm.com wrapper->value = src; 34711986Sandreas.sandberg@arm.com wrapper->owned = false; 34811986Sandreas.sandberg@arm.com detail::keep_alive_impl(inst, parent); 34911986Sandreas.sandberg@arm.com break; 35011986Sandreas.sandberg@arm.com 35111986Sandreas.sandberg@arm.com default: 35211986Sandreas.sandberg@arm.com throw cast_error("unhandled return_value_policy: should not happen!"); 35311986Sandreas.sandberg@arm.com } 35411986Sandreas.sandberg@arm.com 35511986Sandreas.sandberg@arm.com tinfo->init_holder(inst.ptr(), existing_holder); 35611986Sandreas.sandberg@arm.com 35711986Sandreas.sandberg@arm.com internals.registered_instances.emplace(wrapper->value, inst.ptr()); 35811986Sandreas.sandberg@arm.com 35911986Sandreas.sandberg@arm.com return inst.release(); 36011986Sandreas.sandberg@arm.com } 36111986Sandreas.sandberg@arm.com 36211986Sandreas.sandberg@arm.comprotected: 36311986Sandreas.sandberg@arm.com const type_info *typeinfo = nullptr; 36411986Sandreas.sandberg@arm.com void *value = nullptr; 36511986Sandreas.sandberg@arm.com object temp; 36611986Sandreas.sandberg@arm.com}; 36711986Sandreas.sandberg@arm.com 36811986Sandreas.sandberg@arm.com/* Determine suitable casting operator */ 36911986Sandreas.sandberg@arm.comtemplate <typename T> 37011986Sandreas.sandberg@arm.comusing cast_op_type = typename std::conditional<std::is_pointer<typename std::remove_reference<T>::type>::value, 37111986Sandreas.sandberg@arm.com typename std::add_pointer<intrinsic_t<T>>::type, 37211986Sandreas.sandberg@arm.com typename std::add_lvalue_reference<intrinsic_t<T>>::type>::type; 37311986Sandreas.sandberg@arm.com 37411986Sandreas.sandberg@arm.com// std::is_copy_constructible isn't quite enough: it lets std::vector<T> (and similar) through when 37511986Sandreas.sandberg@arm.com// T is non-copyable, but code containing such a copy constructor fails to actually compile. 37611986Sandreas.sandberg@arm.comtemplate <typename T, typename SFINAE = void> struct is_copy_constructible : std::is_copy_constructible<T> {}; 37711986Sandreas.sandberg@arm.com 37811986Sandreas.sandberg@arm.com// Specialization for types that appear to be copy constructible but also look like stl containers 37911986Sandreas.sandberg@arm.com// (we specifically check for: has `value_type` and `reference` with `reference = value_type&`): if 38011986Sandreas.sandberg@arm.com// so, copy constructability depends on whether the value_type is copy constructible. 38111986Sandreas.sandberg@arm.comtemplate <typename Container> struct is_copy_constructible<Container, enable_if_t< 38211986Sandreas.sandberg@arm.com std::is_copy_constructible<Container>::value && 38311986Sandreas.sandberg@arm.com std::is_same<typename Container::value_type &, typename Container::reference>::value 38411986Sandreas.sandberg@arm.com >> : std::is_copy_constructible<typename Container::value_type> {}; 38511986Sandreas.sandberg@arm.com 38611986Sandreas.sandberg@arm.com/// Generic type caster for objects stored on the heap 38711986Sandreas.sandberg@arm.comtemplate <typename type> class type_caster_base : public type_caster_generic { 38811986Sandreas.sandberg@arm.com using itype = intrinsic_t<type>; 38911986Sandreas.sandberg@arm.compublic: 39011986Sandreas.sandberg@arm.com static PYBIND11_DESCR name() { return type_descr(_<type>()); } 39111986Sandreas.sandberg@arm.com 39211986Sandreas.sandberg@arm.com type_caster_base() : type_caster_base(typeid(type)) { } 39311986Sandreas.sandberg@arm.com explicit type_caster_base(const std::type_info &info) : type_caster_generic(info) { } 39411986Sandreas.sandberg@arm.com 39511986Sandreas.sandberg@arm.com static handle cast(const itype &src, return_value_policy policy, handle parent) { 39611986Sandreas.sandberg@arm.com if (policy == return_value_policy::automatic || policy == return_value_policy::automatic_reference) 39711986Sandreas.sandberg@arm.com policy = return_value_policy::copy; 39811986Sandreas.sandberg@arm.com return cast(&src, policy, parent); 39911986Sandreas.sandberg@arm.com } 40011986Sandreas.sandberg@arm.com 40111986Sandreas.sandberg@arm.com static handle cast(itype &&src, return_value_policy, handle parent) { 40211986Sandreas.sandberg@arm.com return cast(&src, return_value_policy::move, parent); 40311986Sandreas.sandberg@arm.com } 40411986Sandreas.sandberg@arm.com 40511986Sandreas.sandberg@arm.com static handle cast(const itype *src, return_value_policy policy, handle parent) { 40611986Sandreas.sandberg@arm.com return type_caster_generic::cast( 40711986Sandreas.sandberg@arm.com src, policy, parent, src ? &typeid(*src) : nullptr, &typeid(type), 40811986Sandreas.sandberg@arm.com make_copy_constructor(src), make_move_constructor(src)); 40911986Sandreas.sandberg@arm.com } 41011986Sandreas.sandberg@arm.com 41112037Sandreas.sandberg@arm.com static handle cast_holder(const itype *src, const void *holder) { 41212037Sandreas.sandberg@arm.com return type_caster_generic::cast( 41312037Sandreas.sandberg@arm.com src, return_value_policy::take_ownership, {}, 41412037Sandreas.sandberg@arm.com src ? &typeid(*src) : nullptr, &typeid(type), 41512037Sandreas.sandberg@arm.com nullptr, nullptr, holder); 41612037Sandreas.sandberg@arm.com } 41712037Sandreas.sandberg@arm.com 41811986Sandreas.sandberg@arm.com template <typename T> using cast_op_type = pybind11::detail::cast_op_type<T>; 41911986Sandreas.sandberg@arm.com 42011986Sandreas.sandberg@arm.com operator itype*() { return (type *) value; } 42111986Sandreas.sandberg@arm.com operator itype&() { if (!value) throw reference_cast_error(); return *((itype *) value); } 42211986Sandreas.sandberg@arm.com 42311986Sandreas.sandberg@arm.comprotected: 42411986Sandreas.sandberg@arm.com typedef void *(*Constructor)(const void *stream); 42511986Sandreas.sandberg@arm.com#if !defined(_MSC_VER) 42611986Sandreas.sandberg@arm.com /* Only enabled when the types are {copy,move}-constructible *and* when the type 42711986Sandreas.sandberg@arm.com does not have a private operator new implementaton. */ 42811986Sandreas.sandberg@arm.com template <typename T = type, typename = enable_if_t<is_copy_constructible<T>::value>> static auto make_copy_constructor(const T *value) -> decltype(new T(*value), Constructor(nullptr)) { 42911986Sandreas.sandberg@arm.com return [](const void *arg) -> void * { return new T(*((const T *) arg)); }; } 43011986Sandreas.sandberg@arm.com template <typename T = type> static auto make_move_constructor(const T *value) -> decltype(new T(std::move(*((T *) value))), Constructor(nullptr)) { 43112037Sandreas.sandberg@arm.com return [](const void *arg) -> void * { return (void *) new T(std::move(*const_cast<T *>(reinterpret_cast<const T *>(arg)))); }; } 43211986Sandreas.sandberg@arm.com#else 43311986Sandreas.sandberg@arm.com /* Visual Studio 2015's SFINAE implementation doesn't yet handle the above robustly in all situations. 43411986Sandreas.sandberg@arm.com Use a workaround that only tests for constructibility for now. */ 43511986Sandreas.sandberg@arm.com template <typename T = type, typename = enable_if_t<is_copy_constructible<T>::value>> 43611986Sandreas.sandberg@arm.com static Constructor make_copy_constructor(const T *value) { 43711986Sandreas.sandberg@arm.com return [](const void *arg) -> void * { return new T(*((const T *)arg)); }; } 43811986Sandreas.sandberg@arm.com template <typename T = type, typename = enable_if_t<std::is_move_constructible<T>::value>> 43911986Sandreas.sandberg@arm.com static Constructor make_move_constructor(const T *value) { 44011986Sandreas.sandberg@arm.com return [](const void *arg) -> void * { return (void *) new T(std::move(*((T *)arg))); }; } 44111986Sandreas.sandberg@arm.com#endif 44211986Sandreas.sandberg@arm.com 44311986Sandreas.sandberg@arm.com static Constructor make_copy_constructor(...) { return nullptr; } 44411986Sandreas.sandberg@arm.com static Constructor make_move_constructor(...) { return nullptr; } 44511986Sandreas.sandberg@arm.com}; 44611986Sandreas.sandberg@arm.com 44711986Sandreas.sandberg@arm.comtemplate <typename type, typename SFINAE = void> class type_caster : public type_caster_base<type> { }; 44811986Sandreas.sandberg@arm.comtemplate <typename type> using make_caster = type_caster<intrinsic_t<type>>; 44911986Sandreas.sandberg@arm.com 45011986Sandreas.sandberg@arm.com// Shortcut for calling a caster's `cast_op_type` cast operator for casting a type_caster to a T 45111986Sandreas.sandberg@arm.comtemplate <typename T> typename make_caster<T>::template cast_op_type<T> cast_op(make_caster<T> &caster) { 45211986Sandreas.sandberg@arm.com return caster.operator typename make_caster<T>::template cast_op_type<T>(); 45311986Sandreas.sandberg@arm.com} 45411986Sandreas.sandberg@arm.comtemplate <typename T> typename make_caster<T>::template cast_op_type<T> cast_op(make_caster<T> &&caster) { 45511986Sandreas.sandberg@arm.com return cast_op<T>(caster); 45611986Sandreas.sandberg@arm.com} 45711986Sandreas.sandberg@arm.com 45811986Sandreas.sandberg@arm.comtemplate <typename type> class type_caster<std::reference_wrapper<type>> : public type_caster_base<type> { 45911986Sandreas.sandberg@arm.compublic: 46011986Sandreas.sandberg@arm.com static handle cast(const std::reference_wrapper<type> &src, return_value_policy policy, handle parent) { 46111986Sandreas.sandberg@arm.com return type_caster_base<type>::cast(&src.get(), policy, parent); 46211986Sandreas.sandberg@arm.com } 46311986Sandreas.sandberg@arm.com template <typename T> using cast_op_type = std::reference_wrapper<type>; 46411986Sandreas.sandberg@arm.com operator std::reference_wrapper<type>() { return std::ref(*((type *) this->value)); } 46511986Sandreas.sandberg@arm.com}; 46611986Sandreas.sandberg@arm.com 46711986Sandreas.sandberg@arm.com#define PYBIND11_TYPE_CASTER(type, py_name) \ 46811986Sandreas.sandberg@arm.com protected: \ 46911986Sandreas.sandberg@arm.com type value; \ 47011986Sandreas.sandberg@arm.com public: \ 47111986Sandreas.sandberg@arm.com static PYBIND11_DESCR name() { return type_descr(py_name); } \ 47211986Sandreas.sandberg@arm.com static handle cast(const type *src, return_value_policy policy, handle parent) { \ 47312037Sandreas.sandberg@arm.com if (!src) return none().release(); \ 47411986Sandreas.sandberg@arm.com return cast(*src, policy, parent); \ 47511986Sandreas.sandberg@arm.com } \ 47611986Sandreas.sandberg@arm.com operator type*() { return &value; } \ 47711986Sandreas.sandberg@arm.com operator type&() { return value; } \ 47811986Sandreas.sandberg@arm.com template <typename _T> using cast_op_type = pybind11::detail::cast_op_type<_T> 47911986Sandreas.sandberg@arm.com 48011986Sandreas.sandberg@arm.com 48112037Sandreas.sandberg@arm.comtemplate <typename CharT> using is_std_char_type = any_of< 48212037Sandreas.sandberg@arm.com std::is_same<CharT, char>, /* std::string */ 48312037Sandreas.sandberg@arm.com std::is_same<CharT, char16_t>, /* std::u16string */ 48412037Sandreas.sandberg@arm.com std::is_same<CharT, char32_t>, /* std::u32string */ 48512037Sandreas.sandberg@arm.com std::is_same<CharT, wchar_t> /* std::wstring */ 48612037Sandreas.sandberg@arm.com>; 48712037Sandreas.sandberg@arm.com 48811986Sandreas.sandberg@arm.comtemplate <typename T> 48912037Sandreas.sandberg@arm.comstruct type_caster<T, enable_if_t<std::is_arithmetic<T>::value && !is_std_char_type<T>::value>> { 49012037Sandreas.sandberg@arm.com using _py_type_0 = conditional_t<sizeof(T) <= sizeof(long), long, long long>; 49112037Sandreas.sandberg@arm.com using _py_type_1 = conditional_t<std::is_signed<T>::value, _py_type_0, typename std::make_unsigned<_py_type_0>::type>; 49212037Sandreas.sandberg@arm.com using py_type = conditional_t<std::is_floating_point<T>::value, double, _py_type_1>; 49311986Sandreas.sandberg@arm.compublic: 49411986Sandreas.sandberg@arm.com 49512037Sandreas.sandberg@arm.com bool load(handle src, bool convert) { 49611986Sandreas.sandberg@arm.com py_type py_value; 49711986Sandreas.sandberg@arm.com 49812037Sandreas.sandberg@arm.com if (!src) 49911986Sandreas.sandberg@arm.com return false; 50012037Sandreas.sandberg@arm.com 50112037Sandreas.sandberg@arm.com if (std::is_floating_point<T>::value) { 50212037Sandreas.sandberg@arm.com if (convert || PyFloat_Check(src.ptr())) 50312037Sandreas.sandberg@arm.com py_value = (py_type) PyFloat_AsDouble(src.ptr()); 50412037Sandreas.sandberg@arm.com else 50512037Sandreas.sandberg@arm.com return false; 50611986Sandreas.sandberg@arm.com } else if (sizeof(T) <= sizeof(long)) { 50711986Sandreas.sandberg@arm.com if (PyFloat_Check(src.ptr())) 50811986Sandreas.sandberg@arm.com return false; 50911986Sandreas.sandberg@arm.com if (std::is_signed<T>::value) 51011986Sandreas.sandberg@arm.com py_value = (py_type) PyLong_AsLong(src.ptr()); 51111986Sandreas.sandberg@arm.com else 51211986Sandreas.sandberg@arm.com py_value = (py_type) PyLong_AsUnsignedLong(src.ptr()); 51311986Sandreas.sandberg@arm.com } else { 51411986Sandreas.sandberg@arm.com if (PyFloat_Check(src.ptr())) 51511986Sandreas.sandberg@arm.com return false; 51611986Sandreas.sandberg@arm.com if (std::is_signed<T>::value) 51711986Sandreas.sandberg@arm.com py_value = (py_type) PYBIND11_LONG_AS_LONGLONG(src.ptr()); 51811986Sandreas.sandberg@arm.com else 51911986Sandreas.sandberg@arm.com py_value = (py_type) PYBIND11_LONG_AS_UNSIGNED_LONGLONG(src.ptr()); 52011986Sandreas.sandberg@arm.com } 52111986Sandreas.sandberg@arm.com 52211986Sandreas.sandberg@arm.com if ((py_value == (py_type) -1 && PyErr_Occurred()) || 52311986Sandreas.sandberg@arm.com (std::is_integral<T>::value && sizeof(py_type) != sizeof(T) && 52411986Sandreas.sandberg@arm.com (py_value < (py_type) std::numeric_limits<T>::min() || 52511986Sandreas.sandberg@arm.com py_value > (py_type) std::numeric_limits<T>::max()))) { 52611986Sandreas.sandberg@arm.com#if PY_VERSION_HEX < 0x03000000 52711986Sandreas.sandberg@arm.com bool type_error = PyErr_ExceptionMatches(PyExc_SystemError); 52811986Sandreas.sandberg@arm.com#else 52911986Sandreas.sandberg@arm.com bool type_error = PyErr_ExceptionMatches(PyExc_TypeError); 53011986Sandreas.sandberg@arm.com#endif 53111986Sandreas.sandberg@arm.com PyErr_Clear(); 53212037Sandreas.sandberg@arm.com if (type_error && convert && PyNumber_Check(src.ptr())) { 53311986Sandreas.sandberg@arm.com auto tmp = reinterpret_borrow<object>(std::is_floating_point<T>::value 53411986Sandreas.sandberg@arm.com ? PyNumber_Float(src.ptr()) 53511986Sandreas.sandberg@arm.com : PyNumber_Long(src.ptr())); 53611986Sandreas.sandberg@arm.com PyErr_Clear(); 53711986Sandreas.sandberg@arm.com return load(tmp, false); 53811986Sandreas.sandberg@arm.com } 53911986Sandreas.sandberg@arm.com return false; 54011986Sandreas.sandberg@arm.com } 54111986Sandreas.sandberg@arm.com 54211986Sandreas.sandberg@arm.com value = (T) py_value; 54311986Sandreas.sandberg@arm.com return true; 54411986Sandreas.sandberg@arm.com } 54511986Sandreas.sandberg@arm.com 54611986Sandreas.sandberg@arm.com static handle cast(T src, return_value_policy /* policy */, handle /* parent */) { 54711986Sandreas.sandberg@arm.com if (std::is_floating_point<T>::value) { 54811986Sandreas.sandberg@arm.com return PyFloat_FromDouble((double) src); 54911986Sandreas.sandberg@arm.com } else if (sizeof(T) <= sizeof(long)) { 55011986Sandreas.sandberg@arm.com if (std::is_signed<T>::value) 55111986Sandreas.sandberg@arm.com return PyLong_FromLong((long) src); 55211986Sandreas.sandberg@arm.com else 55311986Sandreas.sandberg@arm.com return PyLong_FromUnsignedLong((unsigned long) src); 55411986Sandreas.sandberg@arm.com } else { 55511986Sandreas.sandberg@arm.com if (std::is_signed<T>::value) 55611986Sandreas.sandberg@arm.com return PyLong_FromLongLong((long long) src); 55711986Sandreas.sandberg@arm.com else 55811986Sandreas.sandberg@arm.com return PyLong_FromUnsignedLongLong((unsigned long long) src); 55911986Sandreas.sandberg@arm.com } 56011986Sandreas.sandberg@arm.com } 56111986Sandreas.sandberg@arm.com 56211986Sandreas.sandberg@arm.com PYBIND11_TYPE_CASTER(T, _<std::is_integral<T>::value>("int", "float")); 56311986Sandreas.sandberg@arm.com}; 56411986Sandreas.sandberg@arm.com 56511986Sandreas.sandberg@arm.comtemplate<typename T> struct void_caster { 56611986Sandreas.sandberg@arm.compublic: 56711986Sandreas.sandberg@arm.com bool load(handle, bool) { return false; } 56811986Sandreas.sandberg@arm.com static handle cast(T, return_value_policy /* policy */, handle /* parent */) { 56911986Sandreas.sandberg@arm.com return none().inc_ref(); 57011986Sandreas.sandberg@arm.com } 57111986Sandreas.sandberg@arm.com PYBIND11_TYPE_CASTER(T, _("None")); 57211986Sandreas.sandberg@arm.com}; 57311986Sandreas.sandberg@arm.com 57411986Sandreas.sandberg@arm.comtemplate <> class type_caster<void_type> : public void_caster<void_type> {}; 57511986Sandreas.sandberg@arm.com 57611986Sandreas.sandberg@arm.comtemplate <> class type_caster<void> : public type_caster<void_type> { 57711986Sandreas.sandberg@arm.compublic: 57811986Sandreas.sandberg@arm.com using type_caster<void_type>::cast; 57911986Sandreas.sandberg@arm.com 58011986Sandreas.sandberg@arm.com bool load(handle h, bool) { 58111986Sandreas.sandberg@arm.com if (!h) { 58211986Sandreas.sandberg@arm.com return false; 58311986Sandreas.sandberg@arm.com } else if (h.is_none()) { 58411986Sandreas.sandberg@arm.com value = nullptr; 58511986Sandreas.sandberg@arm.com return true; 58611986Sandreas.sandberg@arm.com } 58711986Sandreas.sandberg@arm.com 58811986Sandreas.sandberg@arm.com /* Check if this is a capsule */ 58911986Sandreas.sandberg@arm.com if (isinstance<capsule>(h)) { 59011986Sandreas.sandberg@arm.com value = reinterpret_borrow<capsule>(h); 59111986Sandreas.sandberg@arm.com return true; 59211986Sandreas.sandberg@arm.com } 59311986Sandreas.sandberg@arm.com 59411986Sandreas.sandberg@arm.com /* Check if this is a C++ type */ 59511986Sandreas.sandberg@arm.com if (get_type_info((PyTypeObject *) h.get_type().ptr())) { 59611986Sandreas.sandberg@arm.com value = ((instance<void> *) h.ptr())->value; 59711986Sandreas.sandberg@arm.com return true; 59811986Sandreas.sandberg@arm.com } 59911986Sandreas.sandberg@arm.com 60011986Sandreas.sandberg@arm.com /* Fail */ 60111986Sandreas.sandberg@arm.com return false; 60211986Sandreas.sandberg@arm.com } 60311986Sandreas.sandberg@arm.com 60411986Sandreas.sandberg@arm.com static handle cast(const void *ptr, return_value_policy /* policy */, handle /* parent */) { 60511986Sandreas.sandberg@arm.com if (ptr) 60611986Sandreas.sandberg@arm.com return capsule(ptr).release(); 60711986Sandreas.sandberg@arm.com else 60811986Sandreas.sandberg@arm.com return none().inc_ref(); 60911986Sandreas.sandberg@arm.com } 61011986Sandreas.sandberg@arm.com 61111986Sandreas.sandberg@arm.com template <typename T> using cast_op_type = void*&; 61211986Sandreas.sandberg@arm.com operator void *&() { return value; } 61311986Sandreas.sandberg@arm.com static PYBIND11_DESCR name() { return type_descr(_("capsule")); } 61411986Sandreas.sandberg@arm.comprivate: 61511986Sandreas.sandberg@arm.com void *value = nullptr; 61611986Sandreas.sandberg@arm.com}; 61711986Sandreas.sandberg@arm.com 61811986Sandreas.sandberg@arm.comtemplate <> class type_caster<std::nullptr_t> : public type_caster<void_type> { }; 61911986Sandreas.sandberg@arm.com 62011986Sandreas.sandberg@arm.comtemplate <> class type_caster<bool> { 62111986Sandreas.sandberg@arm.compublic: 62211986Sandreas.sandberg@arm.com bool load(handle src, bool) { 62311986Sandreas.sandberg@arm.com if (!src) return false; 62411986Sandreas.sandberg@arm.com else if (src.ptr() == Py_True) { value = true; return true; } 62511986Sandreas.sandberg@arm.com else if (src.ptr() == Py_False) { value = false; return true; } 62611986Sandreas.sandberg@arm.com else return false; 62711986Sandreas.sandberg@arm.com } 62811986Sandreas.sandberg@arm.com static handle cast(bool src, return_value_policy /* policy */, handle /* parent */) { 62911986Sandreas.sandberg@arm.com return handle(src ? Py_True : Py_False).inc_ref(); 63011986Sandreas.sandberg@arm.com } 63111986Sandreas.sandberg@arm.com PYBIND11_TYPE_CASTER(bool, _("bool")); 63211986Sandreas.sandberg@arm.com}; 63311986Sandreas.sandberg@arm.com 63412037Sandreas.sandberg@arm.com// Helper class for UTF-{8,16,32} C++ stl strings: 63512037Sandreas.sandberg@arm.comtemplate <typename CharT, class Traits, class Allocator> 63612037Sandreas.sandberg@arm.comstruct type_caster<std::basic_string<CharT, Traits, Allocator>, enable_if_t<is_std_char_type<CharT>::value>> { 63712037Sandreas.sandberg@arm.com // Simplify life by being able to assume standard char sizes (the standard only guarantees 63812037Sandreas.sandberg@arm.com // minimums), but Python requires exact sizes 63912037Sandreas.sandberg@arm.com static_assert(!std::is_same<CharT, char>::value || sizeof(CharT) == 1, "Unsupported char size != 1"); 64012037Sandreas.sandberg@arm.com static_assert(!std::is_same<CharT, char16_t>::value || sizeof(CharT) == 2, "Unsupported char16_t size != 2"); 64112037Sandreas.sandberg@arm.com static_assert(!std::is_same<CharT, char32_t>::value || sizeof(CharT) == 4, "Unsupported char32_t size != 4"); 64212037Sandreas.sandberg@arm.com // wchar_t can be either 16 bits (Windows) or 32 (everywhere else) 64312037Sandreas.sandberg@arm.com static_assert(!std::is_same<CharT, wchar_t>::value || sizeof(CharT) == 2 || sizeof(CharT) == 4, 64412037Sandreas.sandberg@arm.com "Unsupported wchar_t size != 2/4"); 64512037Sandreas.sandberg@arm.com static constexpr size_t UTF_N = 8 * sizeof(CharT); 64612037Sandreas.sandberg@arm.com 64712037Sandreas.sandberg@arm.com using StringType = std::basic_string<CharT, Traits, Allocator>; 64812037Sandreas.sandberg@arm.com 64911986Sandreas.sandberg@arm.com bool load(handle src, bool) { 65012037Sandreas.sandberg@arm.com#if PY_MAJOR_VERSION < 3 65111986Sandreas.sandberg@arm.com object temp; 65212037Sandreas.sandberg@arm.com#endif 65311986Sandreas.sandberg@arm.com handle load_src = src; 65411986Sandreas.sandberg@arm.com if (!src) { 65511986Sandreas.sandberg@arm.com return false; 65611986Sandreas.sandberg@arm.com } else if (!PyUnicode_Check(load_src.ptr())) { 65712037Sandreas.sandberg@arm.com#if PY_MAJOR_VERSION >= 3 65812037Sandreas.sandberg@arm.com return false; 65912037Sandreas.sandberg@arm.com // The below is a guaranteed failure in Python 3 when PyUnicode_Check returns false 66012037Sandreas.sandberg@arm.com#else 66112037Sandreas.sandberg@arm.com if (!PYBIND11_BYTES_CHECK(load_src.ptr())) 66212037Sandreas.sandberg@arm.com return false; 66311986Sandreas.sandberg@arm.com temp = reinterpret_steal<object>(PyUnicode_FromObject(load_src.ptr())); 66411986Sandreas.sandberg@arm.com if (!temp) { PyErr_Clear(); return false; } 66511986Sandreas.sandberg@arm.com load_src = temp; 66612037Sandreas.sandberg@arm.com#endif 66711986Sandreas.sandberg@arm.com } 66812037Sandreas.sandberg@arm.com 66912037Sandreas.sandberg@arm.com object utfNbytes = reinterpret_steal<object>(PyUnicode_AsEncodedString( 67012037Sandreas.sandberg@arm.com load_src.ptr(), UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr)); 67112037Sandreas.sandberg@arm.com if (!utfNbytes) { PyErr_Clear(); return false; } 67212037Sandreas.sandberg@arm.com 67312037Sandreas.sandberg@arm.com const CharT *buffer = reinterpret_cast<const CharT *>(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr())); 67412037Sandreas.sandberg@arm.com size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT); 67512037Sandreas.sandberg@arm.com if (UTF_N > 8) { buffer++; length--; } // Skip BOM for UTF-16/32 67612037Sandreas.sandberg@arm.com value = StringType(buffer, length); 67711986Sandreas.sandberg@arm.com return true; 67811986Sandreas.sandberg@arm.com } 67911986Sandreas.sandberg@arm.com 68012037Sandreas.sandberg@arm.com static handle cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) { 68112037Sandreas.sandberg@arm.com const char *buffer = reinterpret_cast<const char *>(src.c_str()); 68212037Sandreas.sandberg@arm.com ssize_t nbytes = ssize_t(src.size() * sizeof(CharT)); 68312037Sandreas.sandberg@arm.com handle s = decode_utfN(buffer, nbytes); 68412037Sandreas.sandberg@arm.com if (!s) throw error_already_set(); 68512037Sandreas.sandberg@arm.com return s; 68611986Sandreas.sandberg@arm.com } 68711986Sandreas.sandberg@arm.com 68812037Sandreas.sandberg@arm.com PYBIND11_TYPE_CASTER(StringType, _(PYBIND11_STRING_NAME)); 68912037Sandreas.sandberg@arm.com 69012037Sandreas.sandberg@arm.comprivate: 69112037Sandreas.sandberg@arm.com static handle decode_utfN(const char *buffer, ssize_t nbytes) { 69212037Sandreas.sandberg@arm.com#if !defined(PYPY_VERSION) 69312037Sandreas.sandberg@arm.com return 69412037Sandreas.sandberg@arm.com UTF_N == 8 ? PyUnicode_DecodeUTF8(buffer, nbytes, nullptr) : 69512037Sandreas.sandberg@arm.com UTF_N == 16 ? PyUnicode_DecodeUTF16(buffer, nbytes, nullptr, nullptr) : 69612037Sandreas.sandberg@arm.com PyUnicode_DecodeUTF32(buffer, nbytes, nullptr, nullptr); 69712037Sandreas.sandberg@arm.com#else 69812037Sandreas.sandberg@arm.com // PyPy seems to have multiple problems related to PyUnicode_UTF*: the UTF8 version 69912037Sandreas.sandberg@arm.com // sometimes segfaults for unknown reasons, while the UTF16 and 32 versions require a 70012037Sandreas.sandberg@arm.com // non-const char * arguments, which is also a nuissance, so bypass the whole thing by just 70112037Sandreas.sandberg@arm.com // passing the encoding as a string value, which works properly: 70212037Sandreas.sandberg@arm.com return PyUnicode_Decode(buffer, nbytes, UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr); 70312037Sandreas.sandberg@arm.com#endif 70412037Sandreas.sandberg@arm.com } 70511986Sandreas.sandberg@arm.com}; 70611986Sandreas.sandberg@arm.com 70712037Sandreas.sandberg@arm.com// Type caster for C-style strings. We basically use a std::string type caster, but also add the 70812037Sandreas.sandberg@arm.com// ability to use None as a nullptr char* (which the string caster doesn't allow). 70912037Sandreas.sandberg@arm.comtemplate <typename CharT> struct type_caster<CharT, enable_if_t<is_std_char_type<CharT>::value>> { 71012037Sandreas.sandberg@arm.com using StringType = std::basic_string<CharT>; 71112037Sandreas.sandberg@arm.com using StringCaster = type_caster<StringType>; 71212037Sandreas.sandberg@arm.com StringCaster str_caster; 71312037Sandreas.sandberg@arm.com bool none = false; 71411986Sandreas.sandberg@arm.compublic: 71511986Sandreas.sandberg@arm.com bool load(handle src, bool convert) { 71612037Sandreas.sandberg@arm.com if (!src) return false; 71712037Sandreas.sandberg@arm.com if (src.is_none()) { 71812037Sandreas.sandberg@arm.com // Defer accepting None to other overloads (if we aren't in convert mode): 71912037Sandreas.sandberg@arm.com if (!convert) return false; 72012037Sandreas.sandberg@arm.com none = true; 72112037Sandreas.sandberg@arm.com return true; 72212037Sandreas.sandberg@arm.com } 72312037Sandreas.sandberg@arm.com return str_caster.load(src, convert); 72411986Sandreas.sandberg@arm.com } 72511986Sandreas.sandberg@arm.com 72612037Sandreas.sandberg@arm.com static handle cast(const CharT *src, return_value_policy policy, handle parent) { 72712037Sandreas.sandberg@arm.com if (src == nullptr) return pybind11::none().inc_ref(); 72812037Sandreas.sandberg@arm.com return StringCaster::cast(StringType(src), policy, parent); 72911986Sandreas.sandberg@arm.com } 73011986Sandreas.sandberg@arm.com 73112037Sandreas.sandberg@arm.com static handle cast(CharT src, return_value_policy policy, handle parent) { 73212037Sandreas.sandberg@arm.com if (std::is_same<char, CharT>::value) { 73312037Sandreas.sandberg@arm.com handle s = PyUnicode_DecodeLatin1((const char *) &src, 1, nullptr); 73412037Sandreas.sandberg@arm.com if (!s) throw error_already_set(); 73512037Sandreas.sandberg@arm.com return s; 73612037Sandreas.sandberg@arm.com } 73712037Sandreas.sandberg@arm.com return StringCaster::cast(StringType(1, src), policy, parent); 73811986Sandreas.sandberg@arm.com } 73911986Sandreas.sandberg@arm.com 74012037Sandreas.sandberg@arm.com operator CharT*() { return none ? nullptr : const_cast<CharT *>(static_cast<StringType &>(str_caster).c_str()); } 74112037Sandreas.sandberg@arm.com operator CharT() { 74212037Sandreas.sandberg@arm.com if (none) 74312037Sandreas.sandberg@arm.com throw value_error("Cannot convert None to a character"); 74412037Sandreas.sandberg@arm.com 74512037Sandreas.sandberg@arm.com auto &value = static_cast<StringType &>(str_caster); 74612037Sandreas.sandberg@arm.com size_t str_len = value.size(); 74712037Sandreas.sandberg@arm.com if (str_len == 0) 74812037Sandreas.sandberg@arm.com throw value_error("Cannot convert empty string to a character"); 74912037Sandreas.sandberg@arm.com 75012037Sandreas.sandberg@arm.com // If we're in UTF-8 mode, we have two possible failures: one for a unicode character that 75112037Sandreas.sandberg@arm.com // is too high, and one for multiple unicode characters (caught later), so we need to figure 75212037Sandreas.sandberg@arm.com // out how long the first encoded character is in bytes to distinguish between these two 75312037Sandreas.sandberg@arm.com // errors. We also allow want to allow unicode characters U+0080 through U+00FF, as those 75412037Sandreas.sandberg@arm.com // can fit into a single char value. 75512037Sandreas.sandberg@arm.com if (StringCaster::UTF_N == 8 && str_len > 1 && str_len <= 4) { 75612037Sandreas.sandberg@arm.com unsigned char v0 = static_cast<unsigned char>(value[0]); 75712037Sandreas.sandberg@arm.com size_t char0_bytes = !(v0 & 0x80) ? 1 : // low bits only: 0-127 75812037Sandreas.sandberg@arm.com (v0 & 0xE0) == 0xC0 ? 2 : // 0b110xxxxx - start of 2-byte sequence 75912037Sandreas.sandberg@arm.com (v0 & 0xF0) == 0xE0 ? 3 : // 0b1110xxxx - start of 3-byte sequence 76012037Sandreas.sandberg@arm.com 4; // 0b11110xxx - start of 4-byte sequence 76112037Sandreas.sandberg@arm.com 76212037Sandreas.sandberg@arm.com if (char0_bytes == str_len) { 76312037Sandreas.sandberg@arm.com // If we have a 128-255 value, we can decode it into a single char: 76412037Sandreas.sandberg@arm.com if (char0_bytes == 2 && (v0 & 0xFC) == 0xC0) { // 0x110000xx 0x10xxxxxx 76512037Sandreas.sandberg@arm.com return static_cast<CharT>(((v0 & 3) << 6) + (static_cast<unsigned char>(value[1]) & 0x3F)); 76612037Sandreas.sandberg@arm.com } 76712037Sandreas.sandberg@arm.com // Otherwise we have a single character, but it's > U+00FF 76812037Sandreas.sandberg@arm.com throw value_error("Character code point not in range(0x100)"); 76912037Sandreas.sandberg@arm.com } 77012037Sandreas.sandberg@arm.com } 77112037Sandreas.sandberg@arm.com 77212037Sandreas.sandberg@arm.com // UTF-16 is much easier: we can only have a surrogate pair for values above U+FFFF, thus a 77312037Sandreas.sandberg@arm.com // surrogate pair with total length 2 instantly indicates a range error (but not a "your 77412037Sandreas.sandberg@arm.com // string was too long" error). 77512037Sandreas.sandberg@arm.com else if (StringCaster::UTF_N == 16 && str_len == 2) { 77612037Sandreas.sandberg@arm.com char16_t v0 = static_cast<char16_t>(value[0]); 77712037Sandreas.sandberg@arm.com if (v0 >= 0xD800 && v0 < 0xE000) 77812037Sandreas.sandberg@arm.com throw value_error("Character code point not in range(0x10000)"); 77912037Sandreas.sandberg@arm.com } 78012037Sandreas.sandberg@arm.com 78112037Sandreas.sandberg@arm.com if (str_len != 1) 78212037Sandreas.sandberg@arm.com throw value_error("Expected a character, but multi-character string found"); 78312037Sandreas.sandberg@arm.com 78412037Sandreas.sandberg@arm.com return value[0]; 78512037Sandreas.sandberg@arm.com } 78611986Sandreas.sandberg@arm.com 78711986Sandreas.sandberg@arm.com static PYBIND11_DESCR name() { return type_descr(_(PYBIND11_STRING_NAME)); } 78812037Sandreas.sandberg@arm.com template <typename _T> using cast_op_type = typename std::remove_reference<pybind11::detail::cast_op_type<_T>>::type; 78911986Sandreas.sandberg@arm.com}; 79011986Sandreas.sandberg@arm.com 79111986Sandreas.sandberg@arm.comtemplate <typename T1, typename T2> class type_caster<std::pair<T1, T2>> { 79211986Sandreas.sandberg@arm.com typedef std::pair<T1, T2> type; 79311986Sandreas.sandberg@arm.compublic: 79411986Sandreas.sandberg@arm.com bool load(handle src, bool convert) { 79511986Sandreas.sandberg@arm.com if (!isinstance<sequence>(src)) 79611986Sandreas.sandberg@arm.com return false; 79711986Sandreas.sandberg@arm.com const auto seq = reinterpret_borrow<sequence>(src); 79811986Sandreas.sandberg@arm.com if (seq.size() != 2) 79911986Sandreas.sandberg@arm.com return false; 80011986Sandreas.sandberg@arm.com return first.load(seq[0], convert) && second.load(seq[1], convert); 80111986Sandreas.sandberg@arm.com } 80211986Sandreas.sandberg@arm.com 80311986Sandreas.sandberg@arm.com static handle cast(const type &src, return_value_policy policy, handle parent) { 80411986Sandreas.sandberg@arm.com auto o1 = reinterpret_steal<object>(make_caster<T1>::cast(src.first, policy, parent)); 80511986Sandreas.sandberg@arm.com auto o2 = reinterpret_steal<object>(make_caster<T2>::cast(src.second, policy, parent)); 80611986Sandreas.sandberg@arm.com if (!o1 || !o2) 80711986Sandreas.sandberg@arm.com return handle(); 80811986Sandreas.sandberg@arm.com tuple result(2); 80911986Sandreas.sandberg@arm.com PyTuple_SET_ITEM(result.ptr(), 0, o1.release().ptr()); 81011986Sandreas.sandberg@arm.com PyTuple_SET_ITEM(result.ptr(), 1, o2.release().ptr()); 81111986Sandreas.sandberg@arm.com return result.release(); 81211986Sandreas.sandberg@arm.com } 81311986Sandreas.sandberg@arm.com 81411986Sandreas.sandberg@arm.com static PYBIND11_DESCR name() { 81511986Sandreas.sandberg@arm.com return type_descr( 81611986Sandreas.sandberg@arm.com _("Tuple[") + make_caster<T1>::name() + _(", ") + make_caster<T2>::name() + _("]") 81711986Sandreas.sandberg@arm.com ); 81811986Sandreas.sandberg@arm.com } 81911986Sandreas.sandberg@arm.com 82011986Sandreas.sandberg@arm.com template <typename T> using cast_op_type = type; 82111986Sandreas.sandberg@arm.com 82211986Sandreas.sandberg@arm.com operator type() { 82311986Sandreas.sandberg@arm.com return type(cast_op<T1>(first), cast_op<T2>(second)); 82411986Sandreas.sandberg@arm.com } 82511986Sandreas.sandberg@arm.comprotected: 82611986Sandreas.sandberg@arm.com make_caster<T1> first; 82711986Sandreas.sandberg@arm.com make_caster<T2> second; 82811986Sandreas.sandberg@arm.com}; 82911986Sandreas.sandberg@arm.com 83011986Sandreas.sandberg@arm.comtemplate <typename... Tuple> class type_caster<std::tuple<Tuple...>> { 83111986Sandreas.sandberg@arm.com using type = std::tuple<Tuple...>; 83211986Sandreas.sandberg@arm.com using indices = make_index_sequence<sizeof...(Tuple)>; 83311986Sandreas.sandberg@arm.com static constexpr auto size = sizeof...(Tuple); 83411986Sandreas.sandberg@arm.com 83511986Sandreas.sandberg@arm.compublic: 83611986Sandreas.sandberg@arm.com bool load(handle src, bool convert) { 83711986Sandreas.sandberg@arm.com if (!isinstance<sequence>(src)) 83811986Sandreas.sandberg@arm.com return false; 83911986Sandreas.sandberg@arm.com const auto seq = reinterpret_borrow<sequence>(src); 84011986Sandreas.sandberg@arm.com if (seq.size() != size) 84111986Sandreas.sandberg@arm.com return false; 84211986Sandreas.sandberg@arm.com return load_impl(seq, convert, indices{}); 84311986Sandreas.sandberg@arm.com } 84411986Sandreas.sandberg@arm.com 84511986Sandreas.sandberg@arm.com static handle cast(const type &src, return_value_policy policy, handle parent) { 84611986Sandreas.sandberg@arm.com return cast_impl(src, policy, parent, indices{}); 84711986Sandreas.sandberg@arm.com } 84811986Sandreas.sandberg@arm.com 84911986Sandreas.sandberg@arm.com static PYBIND11_DESCR name() { 85011986Sandreas.sandberg@arm.com return type_descr(_("Tuple[") + detail::concat(make_caster<Tuple>::name()...) + _("]")); 85111986Sandreas.sandberg@arm.com } 85211986Sandreas.sandberg@arm.com 85311986Sandreas.sandberg@arm.com template <typename T> using cast_op_type = type; 85411986Sandreas.sandberg@arm.com 85511986Sandreas.sandberg@arm.com operator type() { return implicit_cast(indices{}); } 85611986Sandreas.sandberg@arm.com 85711986Sandreas.sandberg@arm.comprotected: 85811986Sandreas.sandberg@arm.com template <size_t... Is> 85911986Sandreas.sandberg@arm.com type implicit_cast(index_sequence<Is...>) { return type(cast_op<Tuple>(std::get<Is>(value))...); } 86011986Sandreas.sandberg@arm.com 86111986Sandreas.sandberg@arm.com static constexpr bool load_impl(const sequence &, bool, index_sequence<>) { return true; } 86211986Sandreas.sandberg@arm.com 86311986Sandreas.sandberg@arm.com template <size_t... Is> 86411986Sandreas.sandberg@arm.com bool load_impl(const sequence &seq, bool convert, index_sequence<Is...>) { 86511986Sandreas.sandberg@arm.com for (bool r : {std::get<Is>(value).load(seq[Is], convert)...}) 86611986Sandreas.sandberg@arm.com if (!r) 86711986Sandreas.sandberg@arm.com return false; 86811986Sandreas.sandberg@arm.com return true; 86911986Sandreas.sandberg@arm.com } 87011986Sandreas.sandberg@arm.com 87111986Sandreas.sandberg@arm.com static handle cast_impl(const type &, return_value_policy, handle, 87211986Sandreas.sandberg@arm.com index_sequence<>) { return tuple().release(); } 87311986Sandreas.sandberg@arm.com 87411986Sandreas.sandberg@arm.com /* Implementation: Convert a C++ tuple into a Python tuple */ 87511986Sandreas.sandberg@arm.com template <size_t... Is> 87611986Sandreas.sandberg@arm.com static handle cast_impl(const type &src, return_value_policy policy, handle parent, index_sequence<Is...>) { 87711986Sandreas.sandberg@arm.com std::array<object, size> entries {{ 87811986Sandreas.sandberg@arm.com reinterpret_steal<object>(make_caster<Tuple>::cast(std::get<Is>(src), policy, parent))... 87911986Sandreas.sandberg@arm.com }}; 88011986Sandreas.sandberg@arm.com for (const auto &entry: entries) 88111986Sandreas.sandberg@arm.com if (!entry) 88211986Sandreas.sandberg@arm.com return handle(); 88311986Sandreas.sandberg@arm.com tuple result(size); 88411986Sandreas.sandberg@arm.com int counter = 0; 88511986Sandreas.sandberg@arm.com for (auto & entry: entries) 88611986Sandreas.sandberg@arm.com PyTuple_SET_ITEM(result.ptr(), counter++, entry.release().ptr()); 88711986Sandreas.sandberg@arm.com return result.release(); 88811986Sandreas.sandberg@arm.com } 88911986Sandreas.sandberg@arm.com 89011986Sandreas.sandberg@arm.com std::tuple<make_caster<Tuple>...> value; 89111986Sandreas.sandberg@arm.com}; 89211986Sandreas.sandberg@arm.com 89312037Sandreas.sandberg@arm.com/// Helper class which abstracts away certain actions. Users can provide specializations for 89412037Sandreas.sandberg@arm.com/// custom holders, but it's only necessary if the type has a non-standard interface. 89512037Sandreas.sandberg@arm.comtemplate <typename T> 89612037Sandreas.sandberg@arm.comstruct holder_helper { 89712037Sandreas.sandberg@arm.com static auto get(const T &p) -> decltype(p.get()) { return p.get(); } 89812037Sandreas.sandberg@arm.com}; 89912037Sandreas.sandberg@arm.com 90011986Sandreas.sandberg@arm.com/// Type caster for holder types like std::shared_ptr, etc. 90112037Sandreas.sandberg@arm.comtemplate <typename type, typename holder_type> 90212037Sandreas.sandberg@arm.comstruct copyable_holder_caster : public type_caster_base<type> { 90311986Sandreas.sandberg@arm.compublic: 90411986Sandreas.sandberg@arm.com using base = type_caster_base<type>; 90511986Sandreas.sandberg@arm.com using base::base; 90611986Sandreas.sandberg@arm.com using base::cast; 90711986Sandreas.sandberg@arm.com using base::typeinfo; 90811986Sandreas.sandberg@arm.com using base::value; 90911986Sandreas.sandberg@arm.com using base::temp; 91011986Sandreas.sandberg@arm.com 91111986Sandreas.sandberg@arm.com PYBIND11_NOINLINE bool load(handle src, bool convert) { 91211986Sandreas.sandberg@arm.com return load(src, convert, Py_TYPE(src.ptr())); 91311986Sandreas.sandberg@arm.com } 91411986Sandreas.sandberg@arm.com 91511986Sandreas.sandberg@arm.com bool load(handle src, bool convert, PyTypeObject *tobj) { 91611986Sandreas.sandberg@arm.com if (!src || !typeinfo) 91711986Sandreas.sandberg@arm.com return false; 91811986Sandreas.sandberg@arm.com if (src.is_none()) { 91911986Sandreas.sandberg@arm.com value = nullptr; 92011986Sandreas.sandberg@arm.com return true; 92111986Sandreas.sandberg@arm.com } 92211986Sandreas.sandberg@arm.com 92312037Sandreas.sandberg@arm.com if (typeinfo->default_holder) 92412037Sandreas.sandberg@arm.com throw cast_error("Unable to load a custom holder type from a default-holder instance"); 92512037Sandreas.sandberg@arm.com 92611986Sandreas.sandberg@arm.com if (typeinfo->simple_type) { /* Case 1: no multiple inheritance etc. involved */ 92711986Sandreas.sandberg@arm.com /* Check if we can safely perform a reinterpret-style cast */ 92811986Sandreas.sandberg@arm.com if (PyType_IsSubtype(tobj, typeinfo->type)) 92911986Sandreas.sandberg@arm.com return load_value_and_holder(src); 93011986Sandreas.sandberg@arm.com } else { /* Case 2: multiple inheritance */ 93111986Sandreas.sandberg@arm.com /* Check if we can safely perform a reinterpret-style cast */ 93211986Sandreas.sandberg@arm.com if (tobj == typeinfo->type) 93311986Sandreas.sandberg@arm.com return load_value_and_holder(src); 93411986Sandreas.sandberg@arm.com 93511986Sandreas.sandberg@arm.com /* If this is a python class, also check the parents recursively */ 93611986Sandreas.sandberg@arm.com auto const &type_dict = get_internals().registered_types_py; 93712037Sandreas.sandberg@arm.com bool new_style_class = PyType_Check((PyObject *) tobj); 93811986Sandreas.sandberg@arm.com if (type_dict.find(tobj) == type_dict.end() && new_style_class && tobj->tp_bases) { 93911986Sandreas.sandberg@arm.com auto parents = reinterpret_borrow<tuple>(tobj->tp_bases); 94011986Sandreas.sandberg@arm.com for (handle parent : parents) { 94111986Sandreas.sandberg@arm.com bool result = load(src, convert, (PyTypeObject *) parent.ptr()); 94211986Sandreas.sandberg@arm.com if (result) 94311986Sandreas.sandberg@arm.com return true; 94411986Sandreas.sandberg@arm.com } 94511986Sandreas.sandberg@arm.com } 94611986Sandreas.sandberg@arm.com 94711986Sandreas.sandberg@arm.com if (try_implicit_casts(src, convert)) 94811986Sandreas.sandberg@arm.com return true; 94911986Sandreas.sandberg@arm.com } 95011986Sandreas.sandberg@arm.com 95111986Sandreas.sandberg@arm.com if (convert) { 95211986Sandreas.sandberg@arm.com for (auto &converter : typeinfo->implicit_conversions) { 95311986Sandreas.sandberg@arm.com temp = reinterpret_steal<object>(converter(src.ptr(), typeinfo->type)); 95411986Sandreas.sandberg@arm.com if (load(temp, false)) 95511986Sandreas.sandberg@arm.com return true; 95611986Sandreas.sandberg@arm.com } 95711986Sandreas.sandberg@arm.com } 95811986Sandreas.sandberg@arm.com 95911986Sandreas.sandberg@arm.com return false; 96011986Sandreas.sandberg@arm.com } 96111986Sandreas.sandberg@arm.com 96211986Sandreas.sandberg@arm.com bool load_value_and_holder(handle src) { 96311986Sandreas.sandberg@arm.com auto inst = (instance<type, holder_type> *) src.ptr(); 96411986Sandreas.sandberg@arm.com value = (void *) inst->value; 96511986Sandreas.sandberg@arm.com if (inst->holder_constructed) { 96611986Sandreas.sandberg@arm.com holder = inst->holder; 96711986Sandreas.sandberg@arm.com return true; 96811986Sandreas.sandberg@arm.com } else { 96911986Sandreas.sandberg@arm.com throw cast_error("Unable to cast from non-held to held instance (T& to Holder<T>) " 97011986Sandreas.sandberg@arm.com#if defined(NDEBUG) 97111986Sandreas.sandberg@arm.com "(compile in debug mode for type information)"); 97211986Sandreas.sandberg@arm.com#else 97311986Sandreas.sandberg@arm.com "of type '" + type_id<holder_type>() + "''"); 97411986Sandreas.sandberg@arm.com#endif 97511986Sandreas.sandberg@arm.com } 97611986Sandreas.sandberg@arm.com } 97711986Sandreas.sandberg@arm.com 97811986Sandreas.sandberg@arm.com template <typename T = holder_type, detail::enable_if_t<!std::is_constructible<T, const T &, type*>::value, int> = 0> 97911986Sandreas.sandberg@arm.com bool try_implicit_casts(handle, bool) { return false; } 98011986Sandreas.sandberg@arm.com 98111986Sandreas.sandberg@arm.com template <typename T = holder_type, detail::enable_if_t<std::is_constructible<T, const T &, type*>::value, int> = 0> 98211986Sandreas.sandberg@arm.com bool try_implicit_casts(handle src, bool convert) { 98311986Sandreas.sandberg@arm.com for (auto &cast : typeinfo->implicit_casts) { 98412037Sandreas.sandberg@arm.com copyable_holder_caster sub_caster(*cast.first); 98511986Sandreas.sandberg@arm.com if (sub_caster.load(src, convert)) { 98611986Sandreas.sandberg@arm.com value = cast.second(sub_caster.value); 98711986Sandreas.sandberg@arm.com holder = holder_type(sub_caster.holder, (type *) value); 98811986Sandreas.sandberg@arm.com return true; 98911986Sandreas.sandberg@arm.com } 99011986Sandreas.sandberg@arm.com } 99111986Sandreas.sandberg@arm.com return false; 99211986Sandreas.sandberg@arm.com } 99311986Sandreas.sandberg@arm.com 99411986Sandreas.sandberg@arm.com explicit operator type*() { return this->value; } 99511986Sandreas.sandberg@arm.com explicit operator type&() { return *(this->value); } 99611986Sandreas.sandberg@arm.com explicit operator holder_type*() { return &holder; } 99711986Sandreas.sandberg@arm.com 99811986Sandreas.sandberg@arm.com // Workaround for Intel compiler bug 99911986Sandreas.sandberg@arm.com // see pybind11 issue 94 100011986Sandreas.sandberg@arm.com #if defined(__ICC) || defined(__INTEL_COMPILER) 100111986Sandreas.sandberg@arm.com operator holder_type&() { return holder; } 100211986Sandreas.sandberg@arm.com #else 100311986Sandreas.sandberg@arm.com explicit operator holder_type&() { return holder; } 100411986Sandreas.sandberg@arm.com #endif 100511986Sandreas.sandberg@arm.com 100611986Sandreas.sandberg@arm.com static handle cast(const holder_type &src, return_value_policy, handle) { 100712037Sandreas.sandberg@arm.com const auto *ptr = holder_helper<holder_type>::get(src); 100812037Sandreas.sandberg@arm.com return type_caster_base<type>::cast_holder(ptr, &src); 100911986Sandreas.sandberg@arm.com } 101011986Sandreas.sandberg@arm.com 101111986Sandreas.sandberg@arm.comprotected: 101211986Sandreas.sandberg@arm.com holder_type holder; 101311986Sandreas.sandberg@arm.com}; 101411986Sandreas.sandberg@arm.com 101511986Sandreas.sandberg@arm.com/// Specialize for the common std::shared_ptr, so users don't need to 101611986Sandreas.sandberg@arm.comtemplate <typename T> 101712037Sandreas.sandberg@arm.comclass type_caster<std::shared_ptr<T>> : public copyable_holder_caster<T, std::shared_ptr<T>> { }; 101812037Sandreas.sandberg@arm.com 101912037Sandreas.sandberg@arm.comtemplate <typename type, typename holder_type> 102012037Sandreas.sandberg@arm.comstruct move_only_holder_caster { 102112037Sandreas.sandberg@arm.com static handle cast(holder_type &&src, return_value_policy, handle) { 102212037Sandreas.sandberg@arm.com auto *ptr = holder_helper<holder_type>::get(src); 102312037Sandreas.sandberg@arm.com return type_caster_base<type>::cast_holder(ptr, &src); 102412037Sandreas.sandberg@arm.com } 102512037Sandreas.sandberg@arm.com static PYBIND11_DESCR name() { return type_caster_base<type>::name(); } 102612037Sandreas.sandberg@arm.com}; 102712037Sandreas.sandberg@arm.com 102812037Sandreas.sandberg@arm.comtemplate <typename type, typename deleter> 102912037Sandreas.sandberg@arm.comclass type_caster<std::unique_ptr<type, deleter>> 103012037Sandreas.sandberg@arm.com : public move_only_holder_caster<type, std::unique_ptr<type, deleter>> { }; 103112037Sandreas.sandberg@arm.com 103212037Sandreas.sandberg@arm.comtemplate <typename type, typename holder_type> 103312037Sandreas.sandberg@arm.comusing type_caster_holder = conditional_t<std::is_copy_constructible<holder_type>::value, 103412037Sandreas.sandberg@arm.com copyable_holder_caster<type, holder_type>, 103512037Sandreas.sandberg@arm.com move_only_holder_caster<type, holder_type>>; 103612037Sandreas.sandberg@arm.com 103712037Sandreas.sandberg@arm.comtemplate <typename T, bool Value = false> struct always_construct_holder { static constexpr bool value = Value; }; 103811986Sandreas.sandberg@arm.com 103911986Sandreas.sandberg@arm.com/// Create a specialization for custom holder types (silently ignores std::shared_ptr) 104012037Sandreas.sandberg@arm.com#define PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type, ...) \ 104111986Sandreas.sandberg@arm.com namespace pybind11 { namespace detail { \ 104211986Sandreas.sandberg@arm.com template <typename type> \ 104312037Sandreas.sandberg@arm.com struct always_construct_holder<holder_type> : always_construct_holder<void, ##__VA_ARGS__> { }; \ 104412037Sandreas.sandberg@arm.com template <typename type> \ 104511986Sandreas.sandberg@arm.com class type_caster<holder_type, enable_if_t<!is_shared_ptr<holder_type>::value>> \ 104611986Sandreas.sandberg@arm.com : public type_caster_holder<type, holder_type> { }; \ 104711986Sandreas.sandberg@arm.com }} 104811986Sandreas.sandberg@arm.com 104911986Sandreas.sandberg@arm.com// PYBIND11_DECLARE_HOLDER_TYPE holder types: 105011986Sandreas.sandberg@arm.comtemplate <typename base, typename holder> struct is_holder_type : 105111986Sandreas.sandberg@arm.com std::is_base_of<detail::type_caster_holder<base, holder>, detail::type_caster<holder>> {}; 105211986Sandreas.sandberg@arm.com// Specialization for always-supported unique_ptr holders: 105311986Sandreas.sandberg@arm.comtemplate <typename base, typename deleter> struct is_holder_type<base, std::unique_ptr<base, deleter>> : 105411986Sandreas.sandberg@arm.com std::true_type {}; 105511986Sandreas.sandberg@arm.com 105611986Sandreas.sandberg@arm.comtemplate <typename T> struct handle_type_name { static PYBIND11_DESCR name() { return _<T>(); } }; 105711986Sandreas.sandberg@arm.comtemplate <> struct handle_type_name<bytes> { static PYBIND11_DESCR name() { return _(PYBIND11_BYTES_NAME); } }; 105811986Sandreas.sandberg@arm.comtemplate <> struct handle_type_name<args> { static PYBIND11_DESCR name() { return _("*args"); } }; 105911986Sandreas.sandberg@arm.comtemplate <> struct handle_type_name<kwargs> { static PYBIND11_DESCR name() { return _("**kwargs"); } }; 106011986Sandreas.sandberg@arm.com 106111986Sandreas.sandberg@arm.comtemplate <typename type> 106211986Sandreas.sandberg@arm.comstruct pyobject_caster { 106311986Sandreas.sandberg@arm.com template <typename T = type, enable_if_t<std::is_same<T, handle>::value, int> = 0> 106411986Sandreas.sandberg@arm.com bool load(handle src, bool /* convert */) { value = src; return static_cast<bool>(value); } 106511986Sandreas.sandberg@arm.com 106611986Sandreas.sandberg@arm.com template <typename T = type, enable_if_t<std::is_base_of<object, T>::value, int> = 0> 106711986Sandreas.sandberg@arm.com bool load(handle src, bool /* convert */) { 106811986Sandreas.sandberg@arm.com if (!isinstance<type>(src)) 106911986Sandreas.sandberg@arm.com return false; 107011986Sandreas.sandberg@arm.com value = reinterpret_borrow<type>(src); 107111986Sandreas.sandberg@arm.com return true; 107211986Sandreas.sandberg@arm.com } 107311986Sandreas.sandberg@arm.com 107411986Sandreas.sandberg@arm.com static handle cast(const handle &src, return_value_policy /* policy */, handle /* parent */) { 107511986Sandreas.sandberg@arm.com return src.inc_ref(); 107611986Sandreas.sandberg@arm.com } 107711986Sandreas.sandberg@arm.com PYBIND11_TYPE_CASTER(type, handle_type_name<type>::name()); 107811986Sandreas.sandberg@arm.com}; 107911986Sandreas.sandberg@arm.com 108011986Sandreas.sandberg@arm.comtemplate <typename T> 108111986Sandreas.sandberg@arm.comclass type_caster<T, enable_if_t<is_pyobject<T>::value>> : public pyobject_caster<T> { }; 108211986Sandreas.sandberg@arm.com 108311986Sandreas.sandberg@arm.com// Our conditions for enabling moving are quite restrictive: 108411986Sandreas.sandberg@arm.com// At compile time: 108511986Sandreas.sandberg@arm.com// - T needs to be a non-const, non-pointer, non-reference type 108611986Sandreas.sandberg@arm.com// - type_caster<T>::operator T&() must exist 108711986Sandreas.sandberg@arm.com// - the type must be move constructible (obviously) 108811986Sandreas.sandberg@arm.com// At run-time: 108911986Sandreas.sandberg@arm.com// - if the type is non-copy-constructible, the object must be the sole owner of the type (i.e. it 109011986Sandreas.sandberg@arm.com// must have ref_count() == 1)h 109111986Sandreas.sandberg@arm.com// If any of the above are not satisfied, we fall back to copying. 109212037Sandreas.sandberg@arm.comtemplate <typename T> using move_is_plain_type = satisfies_none_of<T, 109312037Sandreas.sandberg@arm.com std::is_void, std::is_pointer, std::is_reference, std::is_const 109412037Sandreas.sandberg@arm.com>; 109511986Sandreas.sandberg@arm.comtemplate <typename T, typename SFINAE = void> struct move_always : std::false_type {}; 109612037Sandreas.sandberg@arm.comtemplate <typename T> struct move_always<T, enable_if_t<all_of< 109712037Sandreas.sandberg@arm.com move_is_plain_type<T>, 109812037Sandreas.sandberg@arm.com negation<std::is_copy_constructible<T>>, 109912037Sandreas.sandberg@arm.com std::is_move_constructible<T>, 110012037Sandreas.sandberg@arm.com std::is_same<decltype(std::declval<make_caster<T>>().operator T&()), T&> 110112037Sandreas.sandberg@arm.com>::value>> : std::true_type {}; 110211986Sandreas.sandberg@arm.comtemplate <typename T, typename SFINAE = void> struct move_if_unreferenced : std::false_type {}; 110312037Sandreas.sandberg@arm.comtemplate <typename T> struct move_if_unreferenced<T, enable_if_t<all_of< 110412037Sandreas.sandberg@arm.com move_is_plain_type<T>, 110512037Sandreas.sandberg@arm.com negation<move_always<T>>, 110612037Sandreas.sandberg@arm.com std::is_move_constructible<T>, 110712037Sandreas.sandberg@arm.com std::is_same<decltype(std::declval<make_caster<T>>().operator T&()), T&> 110812037Sandreas.sandberg@arm.com>::value>> : std::true_type {}; 110912037Sandreas.sandberg@arm.comtemplate <typename T> using move_never = none_of<move_always<T>, move_if_unreferenced<T>>; 111011986Sandreas.sandberg@arm.com 111111986Sandreas.sandberg@arm.com// Detect whether returning a `type` from a cast on type's type_caster is going to result in a 111211986Sandreas.sandberg@arm.com// reference or pointer to a local variable of the type_caster. Basically, only 111311986Sandreas.sandberg@arm.com// non-reference/pointer `type`s and reference/pointers from a type_caster_generic are safe; 111411986Sandreas.sandberg@arm.com// everything else returns a reference/pointer to a local variable. 111511986Sandreas.sandberg@arm.comtemplate <typename type> using cast_is_temporary_value_reference = bool_constant< 111611986Sandreas.sandberg@arm.com (std::is_reference<type>::value || std::is_pointer<type>::value) && 111711986Sandreas.sandberg@arm.com !std::is_base_of<type_caster_generic, make_caster<type>>::value 111811986Sandreas.sandberg@arm.com>; 111911986Sandreas.sandberg@arm.com 112012037Sandreas.sandberg@arm.com// When a value returned from a C++ function is being cast back to Python, we almost always want to 112112037Sandreas.sandberg@arm.com// force `policy = move`, regardless of the return value policy the function/method was declared 112212037Sandreas.sandberg@arm.com// with. Some classes (most notably Eigen::Ref and related) need to avoid this, and so can do so by 112312037Sandreas.sandberg@arm.com// specializing this struct. 112412037Sandreas.sandberg@arm.comtemplate <typename Return, typename SFINAE = void> struct return_value_policy_override { 112512037Sandreas.sandberg@arm.com static return_value_policy policy(return_value_policy p) { 112612037Sandreas.sandberg@arm.com return !std::is_lvalue_reference<Return>::value && !std::is_pointer<Return>::value 112712037Sandreas.sandberg@arm.com ? return_value_policy::move : p; 112812037Sandreas.sandberg@arm.com } 112912037Sandreas.sandberg@arm.com}; 113012037Sandreas.sandberg@arm.com 113111986Sandreas.sandberg@arm.com// Basic python -> C++ casting; throws if casting fails 113211986Sandreas.sandberg@arm.comtemplate <typename T, typename SFINAE> type_caster<T, SFINAE> &load_type(type_caster<T, SFINAE> &conv, const handle &handle) { 113311986Sandreas.sandberg@arm.com if (!conv.load(handle, true)) { 113411986Sandreas.sandberg@arm.com#if defined(NDEBUG) 113511986Sandreas.sandberg@arm.com throw cast_error("Unable to cast Python instance to C++ type (compile in debug mode for details)"); 113611986Sandreas.sandberg@arm.com#else 113711986Sandreas.sandberg@arm.com throw cast_error("Unable to cast Python instance of type " + 113811986Sandreas.sandberg@arm.com (std::string) str(handle.get_type()) + " to C++ type '" + type_id<T>() + "''"); 113911986Sandreas.sandberg@arm.com#endif 114011986Sandreas.sandberg@arm.com } 114111986Sandreas.sandberg@arm.com return conv; 114211986Sandreas.sandberg@arm.com} 114311986Sandreas.sandberg@arm.com// Wrapper around the above that also constructs and returns a type_caster 114411986Sandreas.sandberg@arm.comtemplate <typename T> make_caster<T> load_type(const handle &handle) { 114511986Sandreas.sandberg@arm.com make_caster<T> conv; 114611986Sandreas.sandberg@arm.com load_type(conv, handle); 114711986Sandreas.sandberg@arm.com return conv; 114811986Sandreas.sandberg@arm.com} 114911986Sandreas.sandberg@arm.com 115011986Sandreas.sandberg@arm.comNAMESPACE_END(detail) 115111986Sandreas.sandberg@arm.com 115211986Sandreas.sandberg@arm.com// pytype -> C++ type 115311986Sandreas.sandberg@arm.comtemplate <typename T, detail::enable_if_t<!detail::is_pyobject<T>::value, int> = 0> 115411986Sandreas.sandberg@arm.comT cast(const handle &handle) { 115511986Sandreas.sandberg@arm.com using namespace detail; 115611986Sandreas.sandberg@arm.com static_assert(!cast_is_temporary_value_reference<T>::value, 115711986Sandreas.sandberg@arm.com "Unable to cast type to reference: value is local to type caster"); 115811986Sandreas.sandberg@arm.com return cast_op<T>(load_type<T>(handle)); 115911986Sandreas.sandberg@arm.com} 116011986Sandreas.sandberg@arm.com 116111986Sandreas.sandberg@arm.com// pytype -> pytype (calls converting constructor) 116211986Sandreas.sandberg@arm.comtemplate <typename T, detail::enable_if_t<detail::is_pyobject<T>::value, int> = 0> 116311986Sandreas.sandberg@arm.comT cast(const handle &handle) { return T(reinterpret_borrow<object>(handle)); } 116411986Sandreas.sandberg@arm.com 116511986Sandreas.sandberg@arm.com// C++ type -> py::object 116611986Sandreas.sandberg@arm.comtemplate <typename T, detail::enable_if_t<!detail::is_pyobject<T>::value, int> = 0> 116711986Sandreas.sandberg@arm.comobject cast(const T &value, return_value_policy policy = return_value_policy::automatic_reference, 116811986Sandreas.sandberg@arm.com handle parent = handle()) { 116911986Sandreas.sandberg@arm.com if (policy == return_value_policy::automatic) 117011986Sandreas.sandberg@arm.com policy = std::is_pointer<T>::value ? return_value_policy::take_ownership : return_value_policy::copy; 117111986Sandreas.sandberg@arm.com else if (policy == return_value_policy::automatic_reference) 117211986Sandreas.sandberg@arm.com policy = std::is_pointer<T>::value ? return_value_policy::reference : return_value_policy::copy; 117311986Sandreas.sandberg@arm.com return reinterpret_steal<object>(detail::make_caster<T>::cast(value, policy, parent)); 117411986Sandreas.sandberg@arm.com} 117511986Sandreas.sandberg@arm.com 117611986Sandreas.sandberg@arm.comtemplate <typename T> T handle::cast() const { return pybind11::cast<T>(*this); } 117711986Sandreas.sandberg@arm.comtemplate <> inline void handle::cast() const { return; } 117811986Sandreas.sandberg@arm.com 117911986Sandreas.sandberg@arm.comtemplate <typename T> 118012037Sandreas.sandberg@arm.comdetail::enable_if_t<!detail::move_never<T>::value, T> move(object &&obj) { 118111986Sandreas.sandberg@arm.com if (obj.ref_count() > 1) 118211986Sandreas.sandberg@arm.com#if defined(NDEBUG) 118311986Sandreas.sandberg@arm.com throw cast_error("Unable to cast Python instance to C++ rvalue: instance has multiple references" 118411986Sandreas.sandberg@arm.com " (compile in debug mode for details)"); 118511986Sandreas.sandberg@arm.com#else 118611986Sandreas.sandberg@arm.com throw cast_error("Unable to move from Python " + (std::string) str(obj.get_type()) + 118711986Sandreas.sandberg@arm.com " instance to C++ " + type_id<T>() + " instance: instance has multiple references"); 118811986Sandreas.sandberg@arm.com#endif 118911986Sandreas.sandberg@arm.com 119011986Sandreas.sandberg@arm.com // Move into a temporary and return that, because the reference may be a local value of `conv` 119111986Sandreas.sandberg@arm.com T ret = std::move(detail::load_type<T>(obj).operator T&()); 119211986Sandreas.sandberg@arm.com return ret; 119311986Sandreas.sandberg@arm.com} 119411986Sandreas.sandberg@arm.com 119511986Sandreas.sandberg@arm.com// Calling cast() on an rvalue calls pybind::cast with the object rvalue, which does: 119611986Sandreas.sandberg@arm.com// - If we have to move (because T has no copy constructor), do it. This will fail if the moved 119711986Sandreas.sandberg@arm.com// object has multiple references, but trying to copy will fail to compile. 119811986Sandreas.sandberg@arm.com// - If both movable and copyable, check ref count: if 1, move; otherwise copy 119911986Sandreas.sandberg@arm.com// - Otherwise (not movable), copy. 120011986Sandreas.sandberg@arm.comtemplate <typename T> detail::enable_if_t<detail::move_always<T>::value, T> cast(object &&object) { 120111986Sandreas.sandberg@arm.com return move<T>(std::move(object)); 120211986Sandreas.sandberg@arm.com} 120311986Sandreas.sandberg@arm.comtemplate <typename T> detail::enable_if_t<detail::move_if_unreferenced<T>::value, T> cast(object &&object) { 120411986Sandreas.sandberg@arm.com if (object.ref_count() > 1) 120511986Sandreas.sandberg@arm.com return cast<T>(object); 120611986Sandreas.sandberg@arm.com else 120711986Sandreas.sandberg@arm.com return move<T>(std::move(object)); 120811986Sandreas.sandberg@arm.com} 120911986Sandreas.sandberg@arm.comtemplate <typename T> detail::enable_if_t<detail::move_never<T>::value, T> cast(object &&object) { 121011986Sandreas.sandberg@arm.com return cast<T>(object); 121111986Sandreas.sandberg@arm.com} 121211986Sandreas.sandberg@arm.com 121311986Sandreas.sandberg@arm.comtemplate <typename T> T object::cast() const & { return pybind11::cast<T>(*this); } 121411986Sandreas.sandberg@arm.comtemplate <typename T> T object::cast() && { return pybind11::cast<T>(std::move(*this)); } 121511986Sandreas.sandberg@arm.comtemplate <> inline void object::cast() const & { return; } 121611986Sandreas.sandberg@arm.comtemplate <> inline void object::cast() && { return; } 121711986Sandreas.sandberg@arm.com 121811986Sandreas.sandberg@arm.comNAMESPACE_BEGIN(detail) 121911986Sandreas.sandberg@arm.com 122011986Sandreas.sandberg@arm.com// Declared in pytypes.h: 122111986Sandreas.sandberg@arm.comtemplate <typename T, enable_if_t<!is_pyobject<T>::value, int>> 122211986Sandreas.sandberg@arm.comobject object_or_cast(T &&o) { return pybind11::cast(std::forward<T>(o)); } 122311986Sandreas.sandberg@arm.com 122411986Sandreas.sandberg@arm.comstruct overload_unused {}; // Placeholder type for the unneeded (and dead code) static variable in the OVERLOAD_INT macro 122511986Sandreas.sandberg@arm.comtemplate <typename ret_type> using overload_caster_t = conditional_t< 122611986Sandreas.sandberg@arm.com cast_is_temporary_value_reference<ret_type>::value, make_caster<ret_type>, overload_unused>; 122711986Sandreas.sandberg@arm.com 122811986Sandreas.sandberg@arm.com// Trampoline use: for reference/pointer types to value-converted values, we do a value cast, then 122911986Sandreas.sandberg@arm.com// store the result in the given variable. For other types, this is a no-op. 123011986Sandreas.sandberg@arm.comtemplate <typename T> enable_if_t<cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&o, make_caster<T> &caster) { 123111986Sandreas.sandberg@arm.com return cast_op<T>(load_type(caster, o)); 123211986Sandreas.sandberg@arm.com} 123311986Sandreas.sandberg@arm.comtemplate <typename T> enable_if_t<!cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&, overload_unused &) { 123411986Sandreas.sandberg@arm.com pybind11_fail("Internal error: cast_ref fallback invoked"); } 123511986Sandreas.sandberg@arm.com 123611986Sandreas.sandberg@arm.com// Trampoline use: Having a pybind11::cast with an invalid reference type is going to static_assert, even 123711986Sandreas.sandberg@arm.com// though if it's in dead code, so we provide a "trampoline" to pybind11::cast that only does anything in 123811986Sandreas.sandberg@arm.com// cases where pybind11::cast is valid. 123911986Sandreas.sandberg@arm.comtemplate <typename T> enable_if_t<!cast_is_temporary_value_reference<T>::value, T> cast_safe(object &&o) { 124011986Sandreas.sandberg@arm.com return pybind11::cast<T>(std::move(o)); } 124111986Sandreas.sandberg@arm.comtemplate <typename T> enable_if_t<cast_is_temporary_value_reference<T>::value, T> cast_safe(object &&) { 124211986Sandreas.sandberg@arm.com pybind11_fail("Internal error: cast_safe fallback invoked"); } 124311986Sandreas.sandberg@arm.comtemplate <> inline void cast_safe<void>(object &&) {} 124411986Sandreas.sandberg@arm.com 124511986Sandreas.sandberg@arm.comNAMESPACE_END(detail) 124611986Sandreas.sandberg@arm.com 124711986Sandreas.sandberg@arm.comtemplate <return_value_policy policy = return_value_policy::automatic_reference, 124811986Sandreas.sandberg@arm.com typename... Args> tuple make_tuple(Args&&... args_) { 124911986Sandreas.sandberg@arm.com const size_t size = sizeof...(Args); 125011986Sandreas.sandberg@arm.com std::array<object, size> args { 125111986Sandreas.sandberg@arm.com { reinterpret_steal<object>(detail::make_caster<Args>::cast( 125211986Sandreas.sandberg@arm.com std::forward<Args>(args_), policy, nullptr))... } 125311986Sandreas.sandberg@arm.com }; 125411986Sandreas.sandberg@arm.com for (auto &arg_value : args) { 125511986Sandreas.sandberg@arm.com if (!arg_value) { 125611986Sandreas.sandberg@arm.com#if defined(NDEBUG) 125711986Sandreas.sandberg@arm.com throw cast_error("make_tuple(): unable to convert arguments to Python object (compile in debug mode for details)"); 125811986Sandreas.sandberg@arm.com#else 125911986Sandreas.sandberg@arm.com throw cast_error("make_tuple(): unable to convert arguments of types '" + 126011986Sandreas.sandberg@arm.com (std::string) type_id<std::tuple<Args...>>() + "' to Python object"); 126111986Sandreas.sandberg@arm.com#endif 126211986Sandreas.sandberg@arm.com } 126311986Sandreas.sandberg@arm.com } 126411986Sandreas.sandberg@arm.com tuple result(size); 126511986Sandreas.sandberg@arm.com int counter = 0; 126611986Sandreas.sandberg@arm.com for (auto &arg_value : args) 126711986Sandreas.sandberg@arm.com PyTuple_SET_ITEM(result.ptr(), counter++, arg_value.release().ptr()); 126811986Sandreas.sandberg@arm.com return result; 126911986Sandreas.sandberg@arm.com} 127011986Sandreas.sandberg@arm.com 127112037Sandreas.sandberg@arm.com/// \ingroup annotations 127212037Sandreas.sandberg@arm.com/// Annotation for arguments 127311986Sandreas.sandberg@arm.comstruct arg { 127412037Sandreas.sandberg@arm.com /// Constructs an argument with the name of the argument; if null or omitted, this is a positional argument. 127512037Sandreas.sandberg@arm.com constexpr explicit arg(const char *name = nullptr) : name(name), flag_noconvert(false) { } 127612037Sandreas.sandberg@arm.com /// Assign a value to this argument 127711986Sandreas.sandberg@arm.com template <typename T> arg_v operator=(T &&value) const; 127812037Sandreas.sandberg@arm.com /// Indicate that the type should not be converted in the type caster 127912037Sandreas.sandberg@arm.com arg &noconvert(bool flag = true) { flag_noconvert = flag; return *this; } 128011986Sandreas.sandberg@arm.com 128112037Sandreas.sandberg@arm.com const char *name; ///< If non-null, this is a named kwargs argument 128212037Sandreas.sandberg@arm.com bool flag_noconvert : 1; ///< If set, do not allow conversion (requires a supporting type caster!) 128311986Sandreas.sandberg@arm.com}; 128411986Sandreas.sandberg@arm.com 128512037Sandreas.sandberg@arm.com/// \ingroup annotations 128612037Sandreas.sandberg@arm.com/// Annotation for arguments with values 128711986Sandreas.sandberg@arm.comstruct arg_v : arg { 128812037Sandreas.sandberg@arm.comprivate: 128911986Sandreas.sandberg@arm.com template <typename T> 129012037Sandreas.sandberg@arm.com arg_v(arg &&base, T &&x, const char *descr = nullptr) 129112037Sandreas.sandberg@arm.com : arg(base), 129211986Sandreas.sandberg@arm.com value(reinterpret_steal<object>( 129311986Sandreas.sandberg@arm.com detail::make_caster<T>::cast(x, return_value_policy::automatic, {}) 129411986Sandreas.sandberg@arm.com )), 129511986Sandreas.sandberg@arm.com descr(descr) 129611986Sandreas.sandberg@arm.com#if !defined(NDEBUG) 129711986Sandreas.sandberg@arm.com , type(type_id<T>()) 129811986Sandreas.sandberg@arm.com#endif 129911986Sandreas.sandberg@arm.com { } 130011986Sandreas.sandberg@arm.com 130112037Sandreas.sandberg@arm.compublic: 130212037Sandreas.sandberg@arm.com /// Direct construction with name, default, and description 130312037Sandreas.sandberg@arm.com template <typename T> 130412037Sandreas.sandberg@arm.com arg_v(const char *name, T &&x, const char *descr = nullptr) 130512037Sandreas.sandberg@arm.com : arg_v(arg(name), std::forward<T>(x), descr) { } 130612037Sandreas.sandberg@arm.com 130712037Sandreas.sandberg@arm.com /// Called internally when invoking `py::arg("a") = value` 130812037Sandreas.sandberg@arm.com template <typename T> 130912037Sandreas.sandberg@arm.com arg_v(const arg &base, T &&x, const char *descr = nullptr) 131012037Sandreas.sandberg@arm.com : arg_v(arg(base), std::forward<T>(x), descr) { } 131112037Sandreas.sandberg@arm.com 131212037Sandreas.sandberg@arm.com /// Same as `arg::noconvert()`, but returns *this as arg_v&, not arg& 131312037Sandreas.sandberg@arm.com arg_v &noconvert(bool flag = true) { arg::noconvert(flag); return *this; } 131412037Sandreas.sandberg@arm.com 131512037Sandreas.sandberg@arm.com /// The default value 131611986Sandreas.sandberg@arm.com object value; 131712037Sandreas.sandberg@arm.com /// The (optional) description of the default value 131811986Sandreas.sandberg@arm.com const char *descr; 131911986Sandreas.sandberg@arm.com#if !defined(NDEBUG) 132012037Sandreas.sandberg@arm.com /// The C++ type name of the default value (only available when compiled in debug mode) 132111986Sandreas.sandberg@arm.com std::string type; 132211986Sandreas.sandberg@arm.com#endif 132311986Sandreas.sandberg@arm.com}; 132411986Sandreas.sandberg@arm.com 132511986Sandreas.sandberg@arm.comtemplate <typename T> 132612037Sandreas.sandberg@arm.comarg_v arg::operator=(T &&value) const { return {std::move(*this), std::forward<T>(value)}; } 132711986Sandreas.sandberg@arm.com 132811986Sandreas.sandberg@arm.com/// Alias for backward compatibility -- to be removed in version 2.0 132911986Sandreas.sandberg@arm.comtemplate <typename /*unused*/> using arg_t = arg_v; 133011986Sandreas.sandberg@arm.com 133111986Sandreas.sandberg@arm.cominline namespace literals { 133212037Sandreas.sandberg@arm.com/** \rst 133312037Sandreas.sandberg@arm.com String literal version of `arg` 133412037Sandreas.sandberg@arm.com \endrst */ 133511986Sandreas.sandberg@arm.comconstexpr arg operator"" _a(const char *name, size_t) { return arg(name); } 133611986Sandreas.sandberg@arm.com} 133711986Sandreas.sandberg@arm.com 133811986Sandreas.sandberg@arm.comNAMESPACE_BEGIN(detail) 133911986Sandreas.sandberg@arm.com 134012037Sandreas.sandberg@arm.com// forward declaration 134112037Sandreas.sandberg@arm.comstruct function_record; 134212037Sandreas.sandberg@arm.com 134312037Sandreas.sandberg@arm.com/// Internal data associated with a single function call 134412037Sandreas.sandberg@arm.comstruct function_call { 134512037Sandreas.sandberg@arm.com function_call(function_record &f, handle p); // Implementation in attr.h 134612037Sandreas.sandberg@arm.com 134712037Sandreas.sandberg@arm.com /// The function data: 134812037Sandreas.sandberg@arm.com const function_record &func; 134912037Sandreas.sandberg@arm.com 135012037Sandreas.sandberg@arm.com /// Arguments passed to the function: 135112037Sandreas.sandberg@arm.com std::vector<handle> args; 135212037Sandreas.sandberg@arm.com 135312037Sandreas.sandberg@arm.com /// The `convert` value the arguments should be loaded with 135412037Sandreas.sandberg@arm.com std::vector<bool> args_convert; 135512037Sandreas.sandberg@arm.com 135612037Sandreas.sandberg@arm.com /// The parent, if any 135712037Sandreas.sandberg@arm.com handle parent; 135812037Sandreas.sandberg@arm.com}; 135912037Sandreas.sandberg@arm.com 136012037Sandreas.sandberg@arm.com 136111986Sandreas.sandberg@arm.com/// Helper class which loads arguments for C++ functions called from Python 136211986Sandreas.sandberg@arm.comtemplate <typename... Args> 136311986Sandreas.sandberg@arm.comclass argument_loader { 136411986Sandreas.sandberg@arm.com using indices = make_index_sequence<sizeof...(Args)>; 136511986Sandreas.sandberg@arm.com 136612037Sandreas.sandberg@arm.com template <typename Arg> using argument_is_args = std::is_same<intrinsic_t<Arg>, args>; 136712037Sandreas.sandberg@arm.com template <typename Arg> using argument_is_kwargs = std::is_same<intrinsic_t<Arg>, kwargs>; 136812037Sandreas.sandberg@arm.com // Get args/kwargs argument positions relative to the end of the argument list: 136912037Sandreas.sandberg@arm.com static constexpr auto args_pos = constexpr_first<argument_is_args, Args...>() - (int) sizeof...(Args), 137012037Sandreas.sandberg@arm.com kwargs_pos = constexpr_first<argument_is_kwargs, Args...>() - (int) sizeof...(Args); 137112037Sandreas.sandberg@arm.com 137212037Sandreas.sandberg@arm.com static constexpr bool args_kwargs_are_last = kwargs_pos >= - 1 && args_pos >= kwargs_pos - 1; 137312037Sandreas.sandberg@arm.com 137412037Sandreas.sandberg@arm.com static_assert(args_kwargs_are_last, "py::args/py::kwargs are only permitted as the last argument(s) of a function"); 137512037Sandreas.sandberg@arm.com 137611986Sandreas.sandberg@arm.compublic: 137712037Sandreas.sandberg@arm.com static constexpr bool has_kwargs = kwargs_pos < 0; 137812037Sandreas.sandberg@arm.com static constexpr bool has_args = args_pos < 0; 137911986Sandreas.sandberg@arm.com 138011986Sandreas.sandberg@arm.com static PYBIND11_DESCR arg_names() { return detail::concat(make_caster<Args>::name()...); } 138111986Sandreas.sandberg@arm.com 138212037Sandreas.sandberg@arm.com bool load_args(function_call &call) { 138312037Sandreas.sandberg@arm.com return load_impl_sequence(call, indices{}); 138411986Sandreas.sandberg@arm.com } 138511986Sandreas.sandberg@arm.com 138611986Sandreas.sandberg@arm.com template <typename Return, typename Func> 138711986Sandreas.sandberg@arm.com enable_if_t<!std::is_void<Return>::value, Return> call(Func &&f) { 138811986Sandreas.sandberg@arm.com return call_impl<Return>(std::forward<Func>(f), indices{}); 138911986Sandreas.sandberg@arm.com } 139011986Sandreas.sandberg@arm.com 139111986Sandreas.sandberg@arm.com template <typename Return, typename Func> 139211986Sandreas.sandberg@arm.com enable_if_t<std::is_void<Return>::value, void_type> call(Func &&f) { 139311986Sandreas.sandberg@arm.com call_impl<Return>(std::forward<Func>(f), indices{}); 139411986Sandreas.sandberg@arm.com return void_type(); 139511986Sandreas.sandberg@arm.com } 139611986Sandreas.sandberg@arm.com 139711986Sandreas.sandberg@arm.comprivate: 139811986Sandreas.sandberg@arm.com 139912037Sandreas.sandberg@arm.com static bool load_impl_sequence(function_call &, index_sequence<>) { return true; } 140011986Sandreas.sandberg@arm.com 140111986Sandreas.sandberg@arm.com template <size_t... Is> 140212037Sandreas.sandberg@arm.com bool load_impl_sequence(function_call &call, index_sequence<Is...>) { 140312037Sandreas.sandberg@arm.com for (bool r : {std::get<Is>(value).load(call.args[Is], call.args_convert[Is])...}) 140411986Sandreas.sandberg@arm.com if (!r) 140511986Sandreas.sandberg@arm.com return false; 140611986Sandreas.sandberg@arm.com return true; 140711986Sandreas.sandberg@arm.com } 140811986Sandreas.sandberg@arm.com 140911986Sandreas.sandberg@arm.com template <typename Return, typename Func, size_t... Is> 141011986Sandreas.sandberg@arm.com Return call_impl(Func &&f, index_sequence<Is...>) { 141111986Sandreas.sandberg@arm.com return std::forward<Func>(f)(cast_op<Args>(std::get<Is>(value))...); 141211986Sandreas.sandberg@arm.com } 141311986Sandreas.sandberg@arm.com 141411986Sandreas.sandberg@arm.com std::tuple<make_caster<Args>...> value; 141511986Sandreas.sandberg@arm.com}; 141611986Sandreas.sandberg@arm.com 141711986Sandreas.sandberg@arm.com/// Helper class which collects only positional arguments for a Python function call. 141811986Sandreas.sandberg@arm.com/// A fancier version below can collect any argument, but this one is optimal for simple calls. 141911986Sandreas.sandberg@arm.comtemplate <return_value_policy policy> 142011986Sandreas.sandberg@arm.comclass simple_collector { 142111986Sandreas.sandberg@arm.compublic: 142211986Sandreas.sandberg@arm.com template <typename... Ts> 142311986Sandreas.sandberg@arm.com explicit simple_collector(Ts &&...values) 142411986Sandreas.sandberg@arm.com : m_args(pybind11::make_tuple<policy>(std::forward<Ts>(values)...)) { } 142511986Sandreas.sandberg@arm.com 142611986Sandreas.sandberg@arm.com const tuple &args() const & { return m_args; } 142711986Sandreas.sandberg@arm.com dict kwargs() const { return {}; } 142811986Sandreas.sandberg@arm.com 142911986Sandreas.sandberg@arm.com tuple args() && { return std::move(m_args); } 143011986Sandreas.sandberg@arm.com 143111986Sandreas.sandberg@arm.com /// Call a Python function and pass the collected arguments 143211986Sandreas.sandberg@arm.com object call(PyObject *ptr) const { 143311986Sandreas.sandberg@arm.com PyObject *result = PyObject_CallObject(ptr, m_args.ptr()); 143411986Sandreas.sandberg@arm.com if (!result) 143511986Sandreas.sandberg@arm.com throw error_already_set(); 143611986Sandreas.sandberg@arm.com return reinterpret_steal<object>(result); 143711986Sandreas.sandberg@arm.com } 143811986Sandreas.sandberg@arm.com 143911986Sandreas.sandberg@arm.comprivate: 144011986Sandreas.sandberg@arm.com tuple m_args; 144111986Sandreas.sandberg@arm.com}; 144211986Sandreas.sandberg@arm.com 144311986Sandreas.sandberg@arm.com/// Helper class which collects positional, keyword, * and ** arguments for a Python function call 144411986Sandreas.sandberg@arm.comtemplate <return_value_policy policy> 144511986Sandreas.sandberg@arm.comclass unpacking_collector { 144611986Sandreas.sandberg@arm.compublic: 144711986Sandreas.sandberg@arm.com template <typename... Ts> 144811986Sandreas.sandberg@arm.com explicit unpacking_collector(Ts &&...values) { 144911986Sandreas.sandberg@arm.com // Tuples aren't (easily) resizable so a list is needed for collection, 145011986Sandreas.sandberg@arm.com // but the actual function call strictly requires a tuple. 145111986Sandreas.sandberg@arm.com auto args_list = list(); 145211986Sandreas.sandberg@arm.com int _[] = { 0, (process(args_list, std::forward<Ts>(values)), 0)... }; 145311986Sandreas.sandberg@arm.com ignore_unused(_); 145411986Sandreas.sandberg@arm.com 145511986Sandreas.sandberg@arm.com m_args = std::move(args_list); 145611986Sandreas.sandberg@arm.com } 145711986Sandreas.sandberg@arm.com 145811986Sandreas.sandberg@arm.com const tuple &args() const & { return m_args; } 145911986Sandreas.sandberg@arm.com const dict &kwargs() const & { return m_kwargs; } 146011986Sandreas.sandberg@arm.com 146111986Sandreas.sandberg@arm.com tuple args() && { return std::move(m_args); } 146211986Sandreas.sandberg@arm.com dict kwargs() && { return std::move(m_kwargs); } 146311986Sandreas.sandberg@arm.com 146411986Sandreas.sandberg@arm.com /// Call a Python function and pass the collected arguments 146511986Sandreas.sandberg@arm.com object call(PyObject *ptr) const { 146611986Sandreas.sandberg@arm.com PyObject *result = PyObject_Call(ptr, m_args.ptr(), m_kwargs.ptr()); 146711986Sandreas.sandberg@arm.com if (!result) 146811986Sandreas.sandberg@arm.com throw error_already_set(); 146911986Sandreas.sandberg@arm.com return reinterpret_steal<object>(result); 147011986Sandreas.sandberg@arm.com } 147111986Sandreas.sandberg@arm.com 147211986Sandreas.sandberg@arm.comprivate: 147311986Sandreas.sandberg@arm.com template <typename T> 147411986Sandreas.sandberg@arm.com void process(list &args_list, T &&x) { 147511986Sandreas.sandberg@arm.com auto o = reinterpret_steal<object>(detail::make_caster<T>::cast(std::forward<T>(x), policy, {})); 147611986Sandreas.sandberg@arm.com if (!o) { 147711986Sandreas.sandberg@arm.com#if defined(NDEBUG) 147811986Sandreas.sandberg@arm.com argument_cast_error(); 147911986Sandreas.sandberg@arm.com#else 148011986Sandreas.sandberg@arm.com argument_cast_error(std::to_string(args_list.size()), type_id<T>()); 148111986Sandreas.sandberg@arm.com#endif 148211986Sandreas.sandberg@arm.com } 148311986Sandreas.sandberg@arm.com args_list.append(o); 148411986Sandreas.sandberg@arm.com } 148511986Sandreas.sandberg@arm.com 148611986Sandreas.sandberg@arm.com void process(list &args_list, detail::args_proxy ap) { 148711986Sandreas.sandberg@arm.com for (const auto &a : ap) 148811986Sandreas.sandberg@arm.com args_list.append(a); 148911986Sandreas.sandberg@arm.com } 149011986Sandreas.sandberg@arm.com 149111986Sandreas.sandberg@arm.com void process(list &/*args_list*/, arg_v a) { 149212037Sandreas.sandberg@arm.com if (!a.name) 149312037Sandreas.sandberg@arm.com#if defined(NDEBUG) 149412037Sandreas.sandberg@arm.com nameless_argument_error(); 149512037Sandreas.sandberg@arm.com#else 149612037Sandreas.sandberg@arm.com nameless_argument_error(a.type); 149712037Sandreas.sandberg@arm.com#endif 149812037Sandreas.sandberg@arm.com 149911986Sandreas.sandberg@arm.com if (m_kwargs.contains(a.name)) { 150011986Sandreas.sandberg@arm.com#if defined(NDEBUG) 150111986Sandreas.sandberg@arm.com multiple_values_error(); 150211986Sandreas.sandberg@arm.com#else 150311986Sandreas.sandberg@arm.com multiple_values_error(a.name); 150411986Sandreas.sandberg@arm.com#endif 150511986Sandreas.sandberg@arm.com } 150611986Sandreas.sandberg@arm.com if (!a.value) { 150711986Sandreas.sandberg@arm.com#if defined(NDEBUG) 150811986Sandreas.sandberg@arm.com argument_cast_error(); 150911986Sandreas.sandberg@arm.com#else 151011986Sandreas.sandberg@arm.com argument_cast_error(a.name, a.type); 151111986Sandreas.sandberg@arm.com#endif 151211986Sandreas.sandberg@arm.com } 151311986Sandreas.sandberg@arm.com m_kwargs[a.name] = a.value; 151411986Sandreas.sandberg@arm.com } 151511986Sandreas.sandberg@arm.com 151611986Sandreas.sandberg@arm.com void process(list &/*args_list*/, detail::kwargs_proxy kp) { 151711986Sandreas.sandberg@arm.com if (!kp) 151811986Sandreas.sandberg@arm.com return; 151911986Sandreas.sandberg@arm.com for (const auto &k : reinterpret_borrow<dict>(kp)) { 152011986Sandreas.sandberg@arm.com if (m_kwargs.contains(k.first)) { 152111986Sandreas.sandberg@arm.com#if defined(NDEBUG) 152211986Sandreas.sandberg@arm.com multiple_values_error(); 152311986Sandreas.sandberg@arm.com#else 152411986Sandreas.sandberg@arm.com multiple_values_error(str(k.first)); 152511986Sandreas.sandberg@arm.com#endif 152611986Sandreas.sandberg@arm.com } 152711986Sandreas.sandberg@arm.com m_kwargs[k.first] = k.second; 152811986Sandreas.sandberg@arm.com } 152911986Sandreas.sandberg@arm.com } 153011986Sandreas.sandberg@arm.com 153112037Sandreas.sandberg@arm.com [[noreturn]] static void nameless_argument_error() { 153212037Sandreas.sandberg@arm.com throw type_error("Got kwargs without a name; only named arguments " 153312037Sandreas.sandberg@arm.com "may be passed via py::arg() to a python function call. " 153412037Sandreas.sandberg@arm.com "(compile in debug mode for details)"); 153512037Sandreas.sandberg@arm.com } 153612037Sandreas.sandberg@arm.com [[noreturn]] static void nameless_argument_error(std::string type) { 153712037Sandreas.sandberg@arm.com throw type_error("Got kwargs without a name of type '" + type + "'; only named " 153812037Sandreas.sandberg@arm.com "arguments may be passed via py::arg() to a python function call. "); 153912037Sandreas.sandberg@arm.com } 154011986Sandreas.sandberg@arm.com [[noreturn]] static void multiple_values_error() { 154111986Sandreas.sandberg@arm.com throw type_error("Got multiple values for keyword argument " 154211986Sandreas.sandberg@arm.com "(compile in debug mode for details)"); 154311986Sandreas.sandberg@arm.com } 154411986Sandreas.sandberg@arm.com 154511986Sandreas.sandberg@arm.com [[noreturn]] static void multiple_values_error(std::string name) { 154611986Sandreas.sandberg@arm.com throw type_error("Got multiple values for keyword argument '" + name + "'"); 154711986Sandreas.sandberg@arm.com } 154811986Sandreas.sandberg@arm.com 154911986Sandreas.sandberg@arm.com [[noreturn]] static void argument_cast_error() { 155011986Sandreas.sandberg@arm.com throw cast_error("Unable to convert call argument to Python object " 155111986Sandreas.sandberg@arm.com "(compile in debug mode for details)"); 155211986Sandreas.sandberg@arm.com } 155311986Sandreas.sandberg@arm.com 155411986Sandreas.sandberg@arm.com [[noreturn]] static void argument_cast_error(std::string name, std::string type) { 155511986Sandreas.sandberg@arm.com throw cast_error("Unable to convert call argument '" + name 155611986Sandreas.sandberg@arm.com + "' of type '" + type + "' to Python object"); 155711986Sandreas.sandberg@arm.com } 155811986Sandreas.sandberg@arm.com 155911986Sandreas.sandberg@arm.comprivate: 156011986Sandreas.sandberg@arm.com tuple m_args; 156111986Sandreas.sandberg@arm.com dict m_kwargs; 156211986Sandreas.sandberg@arm.com}; 156311986Sandreas.sandberg@arm.com 156411986Sandreas.sandberg@arm.com/// Collect only positional arguments for a Python function call 156511986Sandreas.sandberg@arm.comtemplate <return_value_policy policy, typename... Args, 156612037Sandreas.sandberg@arm.com typename = enable_if_t<all_of<is_positional<Args>...>::value>> 156711986Sandreas.sandberg@arm.comsimple_collector<policy> collect_arguments(Args &&...args) { 156811986Sandreas.sandberg@arm.com return simple_collector<policy>(std::forward<Args>(args)...); 156911986Sandreas.sandberg@arm.com} 157011986Sandreas.sandberg@arm.com 157111986Sandreas.sandberg@arm.com/// Collect all arguments, including keywords and unpacking (only instantiated when needed) 157211986Sandreas.sandberg@arm.comtemplate <return_value_policy policy, typename... Args, 157312037Sandreas.sandberg@arm.com typename = enable_if_t<!all_of<is_positional<Args>...>::value>> 157411986Sandreas.sandberg@arm.comunpacking_collector<policy> collect_arguments(Args &&...args) { 157511986Sandreas.sandberg@arm.com // Following argument order rules for generalized unpacking according to PEP 448 157611986Sandreas.sandberg@arm.com static_assert( 157711986Sandreas.sandberg@arm.com constexpr_last<is_positional, Args...>() < constexpr_first<is_keyword_or_ds, Args...>() 157811986Sandreas.sandberg@arm.com && constexpr_last<is_s_unpacking, Args...>() < constexpr_first<is_ds_unpacking, Args...>(), 157911986Sandreas.sandberg@arm.com "Invalid function call: positional args must precede keywords and ** unpacking; " 158011986Sandreas.sandberg@arm.com "* unpacking must precede ** unpacking" 158111986Sandreas.sandberg@arm.com ); 158211986Sandreas.sandberg@arm.com return unpacking_collector<policy>(std::forward<Args>(args)...); 158311986Sandreas.sandberg@arm.com} 158411986Sandreas.sandberg@arm.com 158511986Sandreas.sandberg@arm.comtemplate <typename Derived> 158611986Sandreas.sandberg@arm.comtemplate <return_value_policy policy, typename... Args> 158711986Sandreas.sandberg@arm.comobject object_api<Derived>::operator()(Args &&...args) const { 158811986Sandreas.sandberg@arm.com return detail::collect_arguments<policy>(std::forward<Args>(args)...).call(derived().ptr()); 158911986Sandreas.sandberg@arm.com} 159011986Sandreas.sandberg@arm.com 159111986Sandreas.sandberg@arm.comtemplate <typename Derived> 159211986Sandreas.sandberg@arm.comtemplate <return_value_policy policy, typename... Args> 159311986Sandreas.sandberg@arm.comobject object_api<Derived>::call(Args &&...args) const { 159411986Sandreas.sandberg@arm.com return operator()<policy>(std::forward<Args>(args)...); 159511986Sandreas.sandberg@arm.com} 159611986Sandreas.sandberg@arm.com 159711986Sandreas.sandberg@arm.comNAMESPACE_END(detail) 159811986Sandreas.sandberg@arm.com 159911986Sandreas.sandberg@arm.com#define PYBIND11_MAKE_OPAQUE(Type) \ 160011986Sandreas.sandberg@arm.com namespace pybind11 { namespace detail { \ 160111986Sandreas.sandberg@arm.com template<> class type_caster<Type> : public type_caster_base<Type> { }; \ 160211986Sandreas.sandberg@arm.com }} 160311986Sandreas.sandberg@arm.com 160411986Sandreas.sandberg@arm.comNAMESPACE_END(pybind11) 1605