pybind11.h revision 11986
111986Sandreas.sandberg@arm.com/* 211986Sandreas.sandberg@arm.com pybind11/pybind11.h: Main header file of the C++11 python 311986Sandreas.sandberg@arm.com binding generator library 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#if defined(_MSC_VER) 1411986Sandreas.sandberg@arm.com# pragma warning(push) 1511986Sandreas.sandberg@arm.com# pragma warning(disable: 4100) // warning C4100: Unreferenced formal parameter 1611986Sandreas.sandberg@arm.com# pragma warning(disable: 4127) // warning C4127: Conditional expression is constant 1711986Sandreas.sandberg@arm.com# pragma warning(disable: 4512) // warning C4512: Assignment operator was implicitly defined as deleted 1811986Sandreas.sandberg@arm.com# pragma warning(disable: 4800) // warning C4800: 'int': forcing value to bool 'true' or 'false' (performance warning) 1911986Sandreas.sandberg@arm.com# pragma warning(disable: 4996) // warning C4996: The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name 2011986Sandreas.sandberg@arm.com# pragma warning(disable: 4702) // warning C4702: unreachable code 2111986Sandreas.sandberg@arm.com# pragma warning(disable: 4522) // warning C4522: multiple assignment operators specified 2211986Sandreas.sandberg@arm.com#elif defined(__INTEL_COMPILER) 2311986Sandreas.sandberg@arm.com# pragma warning(push) 2411986Sandreas.sandberg@arm.com# pragma warning(disable: 186) // pointless comparison of unsigned integer with zero 2511986Sandreas.sandberg@arm.com# pragma warning(disable: 1334) // the "template" keyword used for syntactic disambiguation may only be used within a template 2611986Sandreas.sandberg@arm.com# pragma warning(disable: 2196) // warning #2196: routine is both "inline" and "noinline" 2711986Sandreas.sandberg@arm.com#elif defined(__GNUG__) && !defined(__clang__) 2811986Sandreas.sandberg@arm.com# pragma GCC diagnostic push 2911986Sandreas.sandberg@arm.com# pragma GCC diagnostic ignored "-Wunused-but-set-parameter" 3011986Sandreas.sandberg@arm.com# pragma GCC diagnostic ignored "-Wunused-but-set-variable" 3111986Sandreas.sandberg@arm.com# pragma GCC diagnostic ignored "-Wmissing-field-initializers" 3211986Sandreas.sandberg@arm.com# pragma GCC diagnostic ignored "-Wstrict-aliasing" 3311986Sandreas.sandberg@arm.com# pragma GCC diagnostic ignored "-Wattributes" 3411986Sandreas.sandberg@arm.com#endif 3511986Sandreas.sandberg@arm.com 3611986Sandreas.sandberg@arm.com#include "attr.h" 3711986Sandreas.sandberg@arm.com#include "options.h" 3811986Sandreas.sandberg@arm.com 3911986Sandreas.sandberg@arm.comNAMESPACE_BEGIN(pybind11) 4011986Sandreas.sandberg@arm.com 4111986Sandreas.sandberg@arm.com/// Wraps an arbitrary C++ function/method/lambda function/.. into a callable Python object 4211986Sandreas.sandberg@arm.comclass cpp_function : public function { 4311986Sandreas.sandberg@arm.compublic: 4411986Sandreas.sandberg@arm.com cpp_function() { } 4511986Sandreas.sandberg@arm.com 4611986Sandreas.sandberg@arm.com /// Construct a cpp_function from a vanilla function pointer 4711986Sandreas.sandberg@arm.com template <typename Return, typename... Args, typename... Extra> 4811986Sandreas.sandberg@arm.com cpp_function(Return (*f)(Args...), const Extra&... extra) { 4911986Sandreas.sandberg@arm.com initialize(f, f, extra...); 5011986Sandreas.sandberg@arm.com } 5111986Sandreas.sandberg@arm.com 5211986Sandreas.sandberg@arm.com /// Construct a cpp_function from a lambda function (possibly with internal state) 5311986Sandreas.sandberg@arm.com template <typename Func, typename... Extra> cpp_function(Func &&f, const Extra&... extra) { 5411986Sandreas.sandberg@arm.com initialize(std::forward<Func>(f), 5511986Sandreas.sandberg@arm.com (typename detail::remove_class<decltype( 5611986Sandreas.sandberg@arm.com &std::remove_reference<Func>::type::operator())>::type *) nullptr, extra...); 5711986Sandreas.sandberg@arm.com } 5811986Sandreas.sandberg@arm.com 5911986Sandreas.sandberg@arm.com /// Construct a cpp_function from a class method (non-const) 6011986Sandreas.sandberg@arm.com template <typename Return, typename Class, typename... Arg, typename... Extra> 6111986Sandreas.sandberg@arm.com cpp_function(Return (Class::*f)(Arg...), const Extra&... extra) { 6211986Sandreas.sandberg@arm.com initialize([f](Class *c, Arg... args) -> Return { return (c->*f)(args...); }, 6311986Sandreas.sandberg@arm.com (Return (*) (Class *, Arg...)) nullptr, extra...); 6411986Sandreas.sandberg@arm.com } 6511986Sandreas.sandberg@arm.com 6611986Sandreas.sandberg@arm.com /// Construct a cpp_function from a class method (const) 6711986Sandreas.sandberg@arm.com template <typename Return, typename Class, typename... Arg, typename... Extra> 6811986Sandreas.sandberg@arm.com cpp_function(Return (Class::*f)(Arg...) const, const Extra&... extra) { 6911986Sandreas.sandberg@arm.com initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(args...); }, 7011986Sandreas.sandberg@arm.com (Return (*)(const Class *, Arg ...)) nullptr, extra...); 7111986Sandreas.sandberg@arm.com } 7211986Sandreas.sandberg@arm.com 7311986Sandreas.sandberg@arm.com /// Return the function name 7411986Sandreas.sandberg@arm.com object name() const { return attr("__name__"); } 7511986Sandreas.sandberg@arm.com 7611986Sandreas.sandberg@arm.comprotected: 7711986Sandreas.sandberg@arm.com /// Space optimization: don't inline this frequently instantiated fragment 7811986Sandreas.sandberg@arm.com PYBIND11_NOINLINE detail::function_record *make_function_record() { 7911986Sandreas.sandberg@arm.com return new detail::function_record(); 8011986Sandreas.sandberg@arm.com } 8111986Sandreas.sandberg@arm.com 8211986Sandreas.sandberg@arm.com /// Special internal constructor for functors, lambda functions, etc. 8311986Sandreas.sandberg@arm.com template <typename Func, typename Return, typename... Args, typename... Extra> 8411986Sandreas.sandberg@arm.com void initialize(Func &&f, Return (*)(Args...), const Extra&... extra) { 8511986Sandreas.sandberg@arm.com static_assert(detail::expected_num_args<Extra...>(sizeof...(Args)), 8611986Sandreas.sandberg@arm.com "The number of named arguments does not match the function signature"); 8711986Sandreas.sandberg@arm.com 8811986Sandreas.sandberg@arm.com struct capture { typename std::remove_reference<Func>::type f; }; 8911986Sandreas.sandberg@arm.com 9011986Sandreas.sandberg@arm.com /* Store the function including any extra state it might have (e.g. a lambda capture object) */ 9111986Sandreas.sandberg@arm.com auto rec = make_function_record(); 9211986Sandreas.sandberg@arm.com 9311986Sandreas.sandberg@arm.com /* Store the capture object directly in the function record if there is enough space */ 9411986Sandreas.sandberg@arm.com if (sizeof(capture) <= sizeof(rec->data)) { 9511986Sandreas.sandberg@arm.com /* Without these pragmas, GCC warns that there might not be 9611986Sandreas.sandberg@arm.com enough space to use the placement new operator. However, the 9711986Sandreas.sandberg@arm.com 'if' statement above ensures that this is the case. */ 9811986Sandreas.sandberg@arm.com#if defined(__GNUG__) && !defined(__clang__) && __GNUC__ >= 6 9911986Sandreas.sandberg@arm.com# pragma GCC diagnostic push 10011986Sandreas.sandberg@arm.com# pragma GCC diagnostic ignored "-Wplacement-new" 10111986Sandreas.sandberg@arm.com#endif 10211986Sandreas.sandberg@arm.com new ((capture *) &rec->data) capture { std::forward<Func>(f) }; 10311986Sandreas.sandberg@arm.com#if defined(__GNUG__) && !defined(__clang__) && __GNUC__ >= 6 10411986Sandreas.sandberg@arm.com# pragma GCC diagnostic pop 10511986Sandreas.sandberg@arm.com#endif 10611986Sandreas.sandberg@arm.com if (!std::is_trivially_destructible<Func>::value) 10711986Sandreas.sandberg@arm.com rec->free_data = [](detail::function_record *r) { ((capture *) &r->data)->~capture(); }; 10811986Sandreas.sandberg@arm.com } else { 10911986Sandreas.sandberg@arm.com rec->data[0] = new capture { std::forward<Func>(f) }; 11011986Sandreas.sandberg@arm.com rec->free_data = [](detail::function_record *r) { delete ((capture *) r->data[0]); }; 11111986Sandreas.sandberg@arm.com } 11211986Sandreas.sandberg@arm.com 11311986Sandreas.sandberg@arm.com /* Type casters for the function arguments and return value */ 11411986Sandreas.sandberg@arm.com using cast_in = detail::argument_loader<Args...>; 11511986Sandreas.sandberg@arm.com using cast_out = detail::make_caster< 11611986Sandreas.sandberg@arm.com detail::conditional_t<std::is_void<Return>::value, detail::void_type, Return> 11711986Sandreas.sandberg@arm.com >; 11811986Sandreas.sandberg@arm.com 11911986Sandreas.sandberg@arm.com /* Dispatch code which converts function arguments and performs the actual function call */ 12011986Sandreas.sandberg@arm.com rec->impl = [](detail::function_record *rec, handle args, handle kwargs, handle parent) -> handle { 12111986Sandreas.sandberg@arm.com cast_in args_converter; 12211986Sandreas.sandberg@arm.com 12311986Sandreas.sandberg@arm.com /* Try to cast the function arguments into the C++ domain */ 12411986Sandreas.sandberg@arm.com if (!args_converter.load_args(args, kwargs, true)) 12511986Sandreas.sandberg@arm.com return PYBIND11_TRY_NEXT_OVERLOAD; 12611986Sandreas.sandberg@arm.com 12711986Sandreas.sandberg@arm.com /* Invoke call policy pre-call hook */ 12811986Sandreas.sandberg@arm.com detail::process_attributes<Extra...>::precall(args); 12911986Sandreas.sandberg@arm.com 13011986Sandreas.sandberg@arm.com /* Get a pointer to the capture object */ 13111986Sandreas.sandberg@arm.com capture *cap = (capture *) (sizeof(capture) <= sizeof(rec->data) 13211986Sandreas.sandberg@arm.com ? &rec->data : rec->data[0]); 13311986Sandreas.sandberg@arm.com 13411986Sandreas.sandberg@arm.com /* Override policy for rvalues -- always move */ 13511986Sandreas.sandberg@arm.com constexpr auto is_rvalue = !std::is_pointer<Return>::value 13611986Sandreas.sandberg@arm.com && !std::is_lvalue_reference<Return>::value; 13711986Sandreas.sandberg@arm.com const auto policy = is_rvalue ? return_value_policy::move : rec->policy; 13811986Sandreas.sandberg@arm.com 13911986Sandreas.sandberg@arm.com /* Perform the function call */ 14011986Sandreas.sandberg@arm.com handle result = cast_out::cast(args_converter.template call<Return>(cap->f), 14111986Sandreas.sandberg@arm.com policy, parent); 14211986Sandreas.sandberg@arm.com 14311986Sandreas.sandberg@arm.com /* Invoke call policy post-call hook */ 14411986Sandreas.sandberg@arm.com detail::process_attributes<Extra...>::postcall(args, result); 14511986Sandreas.sandberg@arm.com 14611986Sandreas.sandberg@arm.com return result; 14711986Sandreas.sandberg@arm.com }; 14811986Sandreas.sandberg@arm.com 14911986Sandreas.sandberg@arm.com /* Process any user-provided function attributes */ 15011986Sandreas.sandberg@arm.com detail::process_attributes<Extra...>::init(extra..., rec); 15111986Sandreas.sandberg@arm.com 15211986Sandreas.sandberg@arm.com /* Generate a readable signature describing the function's arguments and return value types */ 15311986Sandreas.sandberg@arm.com using detail::descr; using detail::_; 15411986Sandreas.sandberg@arm.com PYBIND11_DESCR signature = _("(") + cast_in::arg_names() + _(") -> ") + cast_out::name(); 15511986Sandreas.sandberg@arm.com 15611986Sandreas.sandberg@arm.com /* Register the function with Python from generic (non-templated) code */ 15711986Sandreas.sandberg@arm.com initialize_generic(rec, signature.text(), signature.types(), sizeof...(Args)); 15811986Sandreas.sandberg@arm.com 15911986Sandreas.sandberg@arm.com if (cast_in::has_args) rec->has_args = true; 16011986Sandreas.sandberg@arm.com if (cast_in::has_kwargs) rec->has_kwargs = true; 16111986Sandreas.sandberg@arm.com 16211986Sandreas.sandberg@arm.com /* Stash some additional information used by an important optimization in 'functional.h' */ 16311986Sandreas.sandberg@arm.com using FunctionType = Return (*)(Args...); 16411986Sandreas.sandberg@arm.com constexpr bool is_function_ptr = 16511986Sandreas.sandberg@arm.com std::is_convertible<Func, FunctionType>::value && 16611986Sandreas.sandberg@arm.com sizeof(capture) == sizeof(void *); 16711986Sandreas.sandberg@arm.com if (is_function_ptr) { 16811986Sandreas.sandberg@arm.com rec->is_stateless = true; 16911986Sandreas.sandberg@arm.com rec->data[1] = (void *) &typeid(FunctionType); 17011986Sandreas.sandberg@arm.com } 17111986Sandreas.sandberg@arm.com } 17211986Sandreas.sandberg@arm.com 17311986Sandreas.sandberg@arm.com /// Register a function call with Python (generic non-templated code goes here) 17411986Sandreas.sandberg@arm.com void initialize_generic(detail::function_record *rec, const char *text, 17511986Sandreas.sandberg@arm.com const std::type_info *const *types, size_t args) { 17611986Sandreas.sandberg@arm.com 17711986Sandreas.sandberg@arm.com /* Create copies of all referenced C-style strings */ 17811986Sandreas.sandberg@arm.com rec->name = strdup(rec->name ? rec->name : ""); 17911986Sandreas.sandberg@arm.com if (rec->doc) rec->doc = strdup(rec->doc); 18011986Sandreas.sandberg@arm.com for (auto &a: rec->args) { 18111986Sandreas.sandberg@arm.com if (a.name) 18211986Sandreas.sandberg@arm.com a.name = strdup(a.name); 18311986Sandreas.sandberg@arm.com if (a.descr) 18411986Sandreas.sandberg@arm.com a.descr = strdup(a.descr); 18511986Sandreas.sandberg@arm.com else if (a.value) 18611986Sandreas.sandberg@arm.com a.descr = strdup(a.value.attr("__repr__")().cast<std::string>().c_str()); 18711986Sandreas.sandberg@arm.com } 18811986Sandreas.sandberg@arm.com 18911986Sandreas.sandberg@arm.com /* Generate a proper function signature */ 19011986Sandreas.sandberg@arm.com std::string signature; 19111986Sandreas.sandberg@arm.com size_t type_depth = 0, char_index = 0, type_index = 0, arg_index = 0; 19211986Sandreas.sandberg@arm.com while (true) { 19311986Sandreas.sandberg@arm.com char c = text[char_index++]; 19411986Sandreas.sandberg@arm.com if (c == '\0') 19511986Sandreas.sandberg@arm.com break; 19611986Sandreas.sandberg@arm.com 19711986Sandreas.sandberg@arm.com if (c == '{') { 19811986Sandreas.sandberg@arm.com // Write arg name for everything except *args, **kwargs and return type. 19911986Sandreas.sandberg@arm.com if (type_depth == 0 && text[char_index] != '*' && arg_index < args) { 20011986Sandreas.sandberg@arm.com if (!rec->args.empty()) { 20111986Sandreas.sandberg@arm.com signature += rec->args[arg_index].name; 20211986Sandreas.sandberg@arm.com } else if (arg_index == 0 && rec->is_method) { 20311986Sandreas.sandberg@arm.com signature += "self"; 20411986Sandreas.sandberg@arm.com } else { 20511986Sandreas.sandberg@arm.com signature += "arg" + std::to_string(arg_index - (rec->is_method ? 1 : 0)); 20611986Sandreas.sandberg@arm.com } 20711986Sandreas.sandberg@arm.com signature += ": "; 20811986Sandreas.sandberg@arm.com } 20911986Sandreas.sandberg@arm.com ++type_depth; 21011986Sandreas.sandberg@arm.com } else if (c == '}') { 21111986Sandreas.sandberg@arm.com --type_depth; 21211986Sandreas.sandberg@arm.com if (type_depth == 0) { 21311986Sandreas.sandberg@arm.com if (arg_index < rec->args.size() && rec->args[arg_index].descr) { 21411986Sandreas.sandberg@arm.com signature += "="; 21511986Sandreas.sandberg@arm.com signature += rec->args[arg_index].descr; 21611986Sandreas.sandberg@arm.com } 21711986Sandreas.sandberg@arm.com arg_index++; 21811986Sandreas.sandberg@arm.com } 21911986Sandreas.sandberg@arm.com } else if (c == '%') { 22011986Sandreas.sandberg@arm.com const std::type_info *t = types[type_index++]; 22111986Sandreas.sandberg@arm.com if (!t) 22211986Sandreas.sandberg@arm.com pybind11_fail("Internal error while parsing type signature (1)"); 22311986Sandreas.sandberg@arm.com if (auto tinfo = detail::get_type_info(*t)) { 22411986Sandreas.sandberg@arm.com signature += tinfo->type->tp_name; 22511986Sandreas.sandberg@arm.com } else { 22611986Sandreas.sandberg@arm.com std::string tname(t->name()); 22711986Sandreas.sandberg@arm.com detail::clean_type_id(tname); 22811986Sandreas.sandberg@arm.com signature += tname; 22911986Sandreas.sandberg@arm.com } 23011986Sandreas.sandberg@arm.com } else { 23111986Sandreas.sandberg@arm.com signature += c; 23211986Sandreas.sandberg@arm.com } 23311986Sandreas.sandberg@arm.com } 23411986Sandreas.sandberg@arm.com if (type_depth != 0 || types[type_index] != nullptr) 23511986Sandreas.sandberg@arm.com pybind11_fail("Internal error while parsing type signature (2)"); 23611986Sandreas.sandberg@arm.com 23711986Sandreas.sandberg@arm.com #if !defined(PYBIND11_CPP14) 23811986Sandreas.sandberg@arm.com delete[] types; 23911986Sandreas.sandberg@arm.com delete[] text; 24011986Sandreas.sandberg@arm.com #endif 24111986Sandreas.sandberg@arm.com 24211986Sandreas.sandberg@arm.com#if PY_MAJOR_VERSION < 3 24311986Sandreas.sandberg@arm.com if (strcmp(rec->name, "__next__") == 0) { 24411986Sandreas.sandberg@arm.com std::free(rec->name); 24511986Sandreas.sandberg@arm.com rec->name = strdup("next"); 24611986Sandreas.sandberg@arm.com } else if (strcmp(rec->name, "__bool__") == 0) { 24711986Sandreas.sandberg@arm.com std::free(rec->name); 24811986Sandreas.sandberg@arm.com rec->name = strdup("__nonzero__"); 24911986Sandreas.sandberg@arm.com } 25011986Sandreas.sandberg@arm.com#endif 25111986Sandreas.sandberg@arm.com rec->signature = strdup(signature.c_str()); 25211986Sandreas.sandberg@arm.com rec->args.shrink_to_fit(); 25311986Sandreas.sandberg@arm.com rec->is_constructor = !strcmp(rec->name, "__init__") || !strcmp(rec->name, "__setstate__"); 25411986Sandreas.sandberg@arm.com rec->nargs = (uint16_t) args; 25511986Sandreas.sandberg@arm.com 25611986Sandreas.sandberg@arm.com#if PY_MAJOR_VERSION < 3 25711986Sandreas.sandberg@arm.com if (rec->sibling && PyMethod_Check(rec->sibling.ptr())) 25811986Sandreas.sandberg@arm.com rec->sibling = PyMethod_GET_FUNCTION(rec->sibling.ptr()); 25911986Sandreas.sandberg@arm.com#endif 26011986Sandreas.sandberg@arm.com 26111986Sandreas.sandberg@arm.com detail::function_record *chain = nullptr, *chain_start = rec; 26211986Sandreas.sandberg@arm.com if (rec->sibling) { 26311986Sandreas.sandberg@arm.com if (PyCFunction_Check(rec->sibling.ptr())) { 26411986Sandreas.sandberg@arm.com auto rec_capsule = reinterpret_borrow<capsule>(PyCFunction_GetSelf(rec->sibling.ptr())); 26511986Sandreas.sandberg@arm.com chain = (detail::function_record *) rec_capsule; 26611986Sandreas.sandberg@arm.com /* Never append a method to an overload chain of a parent class; 26711986Sandreas.sandberg@arm.com instead, hide the parent's overloads in this case */ 26811986Sandreas.sandberg@arm.com if (chain->scope != rec->scope) 26911986Sandreas.sandberg@arm.com chain = nullptr; 27011986Sandreas.sandberg@arm.com } 27111986Sandreas.sandberg@arm.com // Don't trigger for things like the default __init__, which are wrapper_descriptors that we are intentionally replacing 27211986Sandreas.sandberg@arm.com else if (!rec->sibling.is_none() && rec->name[0] != '_') 27311986Sandreas.sandberg@arm.com pybind11_fail("Cannot overload existing non-function object \"" + std::string(rec->name) + 27411986Sandreas.sandberg@arm.com "\" with a function of the same name"); 27511986Sandreas.sandberg@arm.com } 27611986Sandreas.sandberg@arm.com 27711986Sandreas.sandberg@arm.com if (!chain) { 27811986Sandreas.sandberg@arm.com /* No existing overload was found, create a new function object */ 27911986Sandreas.sandberg@arm.com rec->def = new PyMethodDef(); 28011986Sandreas.sandberg@arm.com memset(rec->def, 0, sizeof(PyMethodDef)); 28111986Sandreas.sandberg@arm.com rec->def->ml_name = rec->name; 28211986Sandreas.sandberg@arm.com rec->def->ml_meth = reinterpret_cast<PyCFunction>(*dispatcher); 28311986Sandreas.sandberg@arm.com rec->def->ml_flags = METH_VARARGS | METH_KEYWORDS; 28411986Sandreas.sandberg@arm.com 28511986Sandreas.sandberg@arm.com capsule rec_capsule(rec, [](PyObject *o) { 28611986Sandreas.sandberg@arm.com destruct((detail::function_record *) PyCapsule_GetPointer(o, nullptr)); 28711986Sandreas.sandberg@arm.com }); 28811986Sandreas.sandberg@arm.com 28911986Sandreas.sandberg@arm.com object scope_module; 29011986Sandreas.sandberg@arm.com if (rec->scope) { 29111986Sandreas.sandberg@arm.com if (hasattr(rec->scope, "__module__")) { 29211986Sandreas.sandberg@arm.com scope_module = rec->scope.attr("__module__"); 29311986Sandreas.sandberg@arm.com } else if (hasattr(rec->scope, "__name__")) { 29411986Sandreas.sandberg@arm.com scope_module = rec->scope.attr("__name__"); 29511986Sandreas.sandberg@arm.com } 29611986Sandreas.sandberg@arm.com } 29711986Sandreas.sandberg@arm.com 29811986Sandreas.sandberg@arm.com m_ptr = PyCFunction_NewEx(rec->def, rec_capsule.ptr(), scope_module.ptr()); 29911986Sandreas.sandberg@arm.com if (!m_ptr) 30011986Sandreas.sandberg@arm.com pybind11_fail("cpp_function::cpp_function(): Could not allocate function object"); 30111986Sandreas.sandberg@arm.com } else { 30211986Sandreas.sandberg@arm.com /* Append at the end of the overload chain */ 30311986Sandreas.sandberg@arm.com m_ptr = rec->sibling.ptr(); 30411986Sandreas.sandberg@arm.com inc_ref(); 30511986Sandreas.sandberg@arm.com chain_start = chain; 30611986Sandreas.sandberg@arm.com while (chain->next) 30711986Sandreas.sandberg@arm.com chain = chain->next; 30811986Sandreas.sandberg@arm.com chain->next = rec; 30911986Sandreas.sandberg@arm.com } 31011986Sandreas.sandberg@arm.com 31111986Sandreas.sandberg@arm.com std::string signatures; 31211986Sandreas.sandberg@arm.com int index = 0; 31311986Sandreas.sandberg@arm.com /* Create a nice pydoc rec including all signatures and 31411986Sandreas.sandberg@arm.com docstrings of the functions in the overload chain */ 31511986Sandreas.sandberg@arm.com if (chain && options::show_function_signatures()) { 31611986Sandreas.sandberg@arm.com // First a generic signature 31711986Sandreas.sandberg@arm.com signatures += rec->name; 31811986Sandreas.sandberg@arm.com signatures += "(*args, **kwargs)\n"; 31911986Sandreas.sandberg@arm.com signatures += "Overloaded function.\n\n"; 32011986Sandreas.sandberg@arm.com } 32111986Sandreas.sandberg@arm.com // Then specific overload signatures 32211986Sandreas.sandberg@arm.com for (auto it = chain_start; it != nullptr; it = it->next) { 32311986Sandreas.sandberg@arm.com if (options::show_function_signatures()) { 32411986Sandreas.sandberg@arm.com if (chain) 32511986Sandreas.sandberg@arm.com signatures += std::to_string(++index) + ". "; 32611986Sandreas.sandberg@arm.com signatures += rec->name; 32711986Sandreas.sandberg@arm.com signatures += it->signature; 32811986Sandreas.sandberg@arm.com signatures += "\n"; 32911986Sandreas.sandberg@arm.com } 33011986Sandreas.sandberg@arm.com if (it->doc && strlen(it->doc) > 0 && options::show_user_defined_docstrings()) { 33111986Sandreas.sandberg@arm.com if (options::show_function_signatures()) signatures += "\n"; 33211986Sandreas.sandberg@arm.com signatures += it->doc; 33311986Sandreas.sandberg@arm.com if (options::show_function_signatures()) signatures += "\n"; 33411986Sandreas.sandberg@arm.com } 33511986Sandreas.sandberg@arm.com if (it->next) 33611986Sandreas.sandberg@arm.com signatures += "\n"; 33711986Sandreas.sandberg@arm.com } 33811986Sandreas.sandberg@arm.com 33911986Sandreas.sandberg@arm.com /* Install docstring */ 34011986Sandreas.sandberg@arm.com PyCFunctionObject *func = (PyCFunctionObject *) m_ptr; 34111986Sandreas.sandberg@arm.com if (func->m_ml->ml_doc) 34211986Sandreas.sandberg@arm.com std::free((char *) func->m_ml->ml_doc); 34311986Sandreas.sandberg@arm.com func->m_ml->ml_doc = strdup(signatures.c_str()); 34411986Sandreas.sandberg@arm.com 34511986Sandreas.sandberg@arm.com if (rec->is_method) { 34611986Sandreas.sandberg@arm.com m_ptr = PYBIND11_INSTANCE_METHOD_NEW(m_ptr, rec->scope.ptr()); 34711986Sandreas.sandberg@arm.com if (!m_ptr) 34811986Sandreas.sandberg@arm.com pybind11_fail("cpp_function::cpp_function(): Could not allocate instance method object"); 34911986Sandreas.sandberg@arm.com Py_DECREF(func); 35011986Sandreas.sandberg@arm.com } 35111986Sandreas.sandberg@arm.com } 35211986Sandreas.sandberg@arm.com 35311986Sandreas.sandberg@arm.com /// When a cpp_function is GCed, release any memory allocated by pybind11 35411986Sandreas.sandberg@arm.com static void destruct(detail::function_record *rec) { 35511986Sandreas.sandberg@arm.com while (rec) { 35611986Sandreas.sandberg@arm.com detail::function_record *next = rec->next; 35711986Sandreas.sandberg@arm.com if (rec->free_data) 35811986Sandreas.sandberg@arm.com rec->free_data(rec); 35911986Sandreas.sandberg@arm.com std::free((char *) rec->name); 36011986Sandreas.sandberg@arm.com std::free((char *) rec->doc); 36111986Sandreas.sandberg@arm.com std::free((char *) rec->signature); 36211986Sandreas.sandberg@arm.com for (auto &arg: rec->args) { 36311986Sandreas.sandberg@arm.com std::free((char *) arg.name); 36411986Sandreas.sandberg@arm.com std::free((char *) arg.descr); 36511986Sandreas.sandberg@arm.com arg.value.dec_ref(); 36611986Sandreas.sandberg@arm.com } 36711986Sandreas.sandberg@arm.com if (rec->def) { 36811986Sandreas.sandberg@arm.com std::free((char *) rec->def->ml_doc); 36911986Sandreas.sandberg@arm.com delete rec->def; 37011986Sandreas.sandberg@arm.com } 37111986Sandreas.sandberg@arm.com delete rec; 37211986Sandreas.sandberg@arm.com rec = next; 37311986Sandreas.sandberg@arm.com } 37411986Sandreas.sandberg@arm.com } 37511986Sandreas.sandberg@arm.com 37611986Sandreas.sandberg@arm.com /// Main dispatch logic for calls to functions bound using pybind11 37711986Sandreas.sandberg@arm.com static PyObject *dispatcher(PyObject *self, PyObject *args, PyObject *kwargs) { 37811986Sandreas.sandberg@arm.com /* Iterator over the list of potentially admissible overloads */ 37911986Sandreas.sandberg@arm.com detail::function_record *overloads = (detail::function_record *) PyCapsule_GetPointer(self, nullptr), 38011986Sandreas.sandberg@arm.com *it = overloads; 38111986Sandreas.sandberg@arm.com 38211986Sandreas.sandberg@arm.com /* Need to know how many arguments + keyword arguments there are to pick the right overload */ 38311986Sandreas.sandberg@arm.com size_t nargs = (size_t) PyTuple_GET_SIZE(args), 38411986Sandreas.sandberg@arm.com nkwargs = kwargs ? (size_t) PyDict_Size(kwargs) : 0; 38511986Sandreas.sandberg@arm.com 38611986Sandreas.sandberg@arm.com handle parent = nargs > 0 ? PyTuple_GET_ITEM(args, 0) : nullptr, 38711986Sandreas.sandberg@arm.com result = PYBIND11_TRY_NEXT_OVERLOAD; 38811986Sandreas.sandberg@arm.com try { 38911986Sandreas.sandberg@arm.com for (; it != nullptr; it = it->next) { 39011986Sandreas.sandberg@arm.com auto args_ = reinterpret_borrow<tuple>(args); 39111986Sandreas.sandberg@arm.com size_t kwargs_consumed = 0; 39211986Sandreas.sandberg@arm.com 39311986Sandreas.sandberg@arm.com /* For each overload: 39411986Sandreas.sandberg@arm.com 1. If the required list of arguments is longer than the 39511986Sandreas.sandberg@arm.com actually provided amount, create a copy of the argument 39611986Sandreas.sandberg@arm.com list and fill in any available keyword/default arguments. 39711986Sandreas.sandberg@arm.com 2. Ensure that all keyword arguments were "consumed" 39811986Sandreas.sandberg@arm.com 3. Call the function call dispatcher (function_record::impl) 39911986Sandreas.sandberg@arm.com */ 40011986Sandreas.sandberg@arm.com size_t nargs_ = nargs; 40111986Sandreas.sandberg@arm.com if (nargs < it->args.size()) { 40211986Sandreas.sandberg@arm.com nargs_ = it->args.size(); 40311986Sandreas.sandberg@arm.com args_ = tuple(nargs_); 40411986Sandreas.sandberg@arm.com for (size_t i = 0; i < nargs; ++i) { 40511986Sandreas.sandberg@arm.com handle item = PyTuple_GET_ITEM(args, i); 40611986Sandreas.sandberg@arm.com PyTuple_SET_ITEM(args_.ptr(), i, item.inc_ref().ptr()); 40711986Sandreas.sandberg@arm.com } 40811986Sandreas.sandberg@arm.com 40911986Sandreas.sandberg@arm.com int arg_ctr = 0; 41011986Sandreas.sandberg@arm.com for (auto const &it2 : it->args) { 41111986Sandreas.sandberg@arm.com int index = arg_ctr++; 41211986Sandreas.sandberg@arm.com if (PyTuple_GET_ITEM(args_.ptr(), index)) 41311986Sandreas.sandberg@arm.com continue; 41411986Sandreas.sandberg@arm.com 41511986Sandreas.sandberg@arm.com handle value; 41611986Sandreas.sandberg@arm.com if (kwargs) 41711986Sandreas.sandberg@arm.com value = PyDict_GetItemString(kwargs, it2.name); 41811986Sandreas.sandberg@arm.com 41911986Sandreas.sandberg@arm.com if (value) 42011986Sandreas.sandberg@arm.com kwargs_consumed++; 42111986Sandreas.sandberg@arm.com else if (it2.value) 42211986Sandreas.sandberg@arm.com value = it2.value; 42311986Sandreas.sandberg@arm.com 42411986Sandreas.sandberg@arm.com if (value) { 42511986Sandreas.sandberg@arm.com PyTuple_SET_ITEM(args_.ptr(), index, value.inc_ref().ptr()); 42611986Sandreas.sandberg@arm.com } else { 42711986Sandreas.sandberg@arm.com kwargs_consumed = (size_t) -1; /* definite failure */ 42811986Sandreas.sandberg@arm.com break; 42911986Sandreas.sandberg@arm.com } 43011986Sandreas.sandberg@arm.com } 43111986Sandreas.sandberg@arm.com } 43211986Sandreas.sandberg@arm.com 43311986Sandreas.sandberg@arm.com try { 43411986Sandreas.sandberg@arm.com if ((kwargs_consumed == nkwargs || it->has_kwargs) && 43511986Sandreas.sandberg@arm.com (nargs_ == it->nargs || it->has_args)) 43611986Sandreas.sandberg@arm.com result = it->impl(it, args_, kwargs, parent); 43711986Sandreas.sandberg@arm.com } catch (reference_cast_error &) { 43811986Sandreas.sandberg@arm.com result = PYBIND11_TRY_NEXT_OVERLOAD; 43911986Sandreas.sandberg@arm.com } 44011986Sandreas.sandberg@arm.com 44111986Sandreas.sandberg@arm.com if (result.ptr() != PYBIND11_TRY_NEXT_OVERLOAD) 44211986Sandreas.sandberg@arm.com break; 44311986Sandreas.sandberg@arm.com } 44411986Sandreas.sandberg@arm.com } catch (error_already_set &e) { 44511986Sandreas.sandberg@arm.com e.restore(); 44611986Sandreas.sandberg@arm.com return nullptr; 44711986Sandreas.sandberg@arm.com } catch (...) { 44811986Sandreas.sandberg@arm.com /* When an exception is caught, give each registered exception 44911986Sandreas.sandberg@arm.com translator a chance to translate it to a Python exception 45011986Sandreas.sandberg@arm.com in reverse order of registration. 45111986Sandreas.sandberg@arm.com 45211986Sandreas.sandberg@arm.com A translator may choose to do one of the following: 45311986Sandreas.sandberg@arm.com 45411986Sandreas.sandberg@arm.com - catch the exception and call PyErr_SetString or PyErr_SetObject 45511986Sandreas.sandberg@arm.com to set a standard (or custom) Python exception, or 45611986Sandreas.sandberg@arm.com - do nothing and let the exception fall through to the next translator, or 45711986Sandreas.sandberg@arm.com - delegate translation to the next translator by throwing a new type of exception. */ 45811986Sandreas.sandberg@arm.com 45911986Sandreas.sandberg@arm.com auto last_exception = std::current_exception(); 46011986Sandreas.sandberg@arm.com auto ®istered_exception_translators = pybind11::detail::get_internals().registered_exception_translators; 46111986Sandreas.sandberg@arm.com for (auto& translator : registered_exception_translators) { 46211986Sandreas.sandberg@arm.com try { 46311986Sandreas.sandberg@arm.com translator(last_exception); 46411986Sandreas.sandberg@arm.com } catch (...) { 46511986Sandreas.sandberg@arm.com last_exception = std::current_exception(); 46611986Sandreas.sandberg@arm.com continue; 46711986Sandreas.sandberg@arm.com } 46811986Sandreas.sandberg@arm.com return nullptr; 46911986Sandreas.sandberg@arm.com } 47011986Sandreas.sandberg@arm.com PyErr_SetString(PyExc_SystemError, "Exception escaped from default exception translator!"); 47111986Sandreas.sandberg@arm.com return nullptr; 47211986Sandreas.sandberg@arm.com } 47311986Sandreas.sandberg@arm.com 47411986Sandreas.sandberg@arm.com if (result.ptr() == PYBIND11_TRY_NEXT_OVERLOAD) { 47511986Sandreas.sandberg@arm.com if (overloads->is_operator) 47611986Sandreas.sandberg@arm.com return handle(Py_NotImplemented).inc_ref().ptr(); 47711986Sandreas.sandberg@arm.com 47811986Sandreas.sandberg@arm.com std::string msg = std::string(overloads->name) + "(): incompatible " + 47911986Sandreas.sandberg@arm.com std::string(overloads->is_constructor ? "constructor" : "function") + 48011986Sandreas.sandberg@arm.com " arguments. The following argument types are supported:\n"; 48111986Sandreas.sandberg@arm.com 48211986Sandreas.sandberg@arm.com int ctr = 0; 48311986Sandreas.sandberg@arm.com for (detail::function_record *it2 = overloads; it2 != nullptr; it2 = it2->next) { 48411986Sandreas.sandberg@arm.com msg += " "+ std::to_string(++ctr) + ". "; 48511986Sandreas.sandberg@arm.com 48611986Sandreas.sandberg@arm.com bool wrote_sig = false; 48711986Sandreas.sandberg@arm.com if (overloads->is_constructor) { 48811986Sandreas.sandberg@arm.com // For a constructor, rewrite `(self: Object, arg0, ...) -> NoneType` as `Object(arg0, ...)` 48911986Sandreas.sandberg@arm.com std::string sig = it2->signature; 49011986Sandreas.sandberg@arm.com size_t start = sig.find('(') + 7; // skip "(self: " 49111986Sandreas.sandberg@arm.com if (start < sig.size()) { 49211986Sandreas.sandberg@arm.com // End at the , for the next argument 49311986Sandreas.sandberg@arm.com size_t end = sig.find(", "), next = end + 2; 49411986Sandreas.sandberg@arm.com size_t ret = sig.rfind(" -> "); 49511986Sandreas.sandberg@arm.com // Or the ), if there is no comma: 49611986Sandreas.sandberg@arm.com if (end >= sig.size()) next = end = sig.find(')'); 49711986Sandreas.sandberg@arm.com if (start < end && next < sig.size()) { 49811986Sandreas.sandberg@arm.com msg.append(sig, start, end - start); 49911986Sandreas.sandberg@arm.com msg += '('; 50011986Sandreas.sandberg@arm.com msg.append(sig, next, ret - next); 50111986Sandreas.sandberg@arm.com wrote_sig = true; 50211986Sandreas.sandberg@arm.com } 50311986Sandreas.sandberg@arm.com } 50411986Sandreas.sandberg@arm.com } 50511986Sandreas.sandberg@arm.com if (!wrote_sig) msg += it2->signature; 50611986Sandreas.sandberg@arm.com 50711986Sandreas.sandberg@arm.com msg += "\n"; 50811986Sandreas.sandberg@arm.com } 50911986Sandreas.sandberg@arm.com msg += "\nInvoked with: "; 51011986Sandreas.sandberg@arm.com auto args_ = reinterpret_borrow<tuple>(args); 51111986Sandreas.sandberg@arm.com for (size_t ti = overloads->is_constructor ? 1 : 0; ti < args_.size(); ++ti) { 51211986Sandreas.sandberg@arm.com msg += pybind11::repr(args_[ti]); 51311986Sandreas.sandberg@arm.com if ((ti + 1) != args_.size() ) 51411986Sandreas.sandberg@arm.com msg += ", "; 51511986Sandreas.sandberg@arm.com } 51611986Sandreas.sandberg@arm.com PyErr_SetString(PyExc_TypeError, msg.c_str()); 51711986Sandreas.sandberg@arm.com return nullptr; 51811986Sandreas.sandberg@arm.com } else if (!result) { 51911986Sandreas.sandberg@arm.com std::string msg = "Unable to convert function return value to a " 52011986Sandreas.sandberg@arm.com "Python type! The signature was\n\t"; 52111986Sandreas.sandberg@arm.com msg += it->signature; 52211986Sandreas.sandberg@arm.com PyErr_SetString(PyExc_TypeError, msg.c_str()); 52311986Sandreas.sandberg@arm.com return nullptr; 52411986Sandreas.sandberg@arm.com } else { 52511986Sandreas.sandberg@arm.com if (overloads->is_constructor) { 52611986Sandreas.sandberg@arm.com /* When a constructor ran successfully, the corresponding 52711986Sandreas.sandberg@arm.com holder type (e.g. std::unique_ptr) must still be initialized. */ 52811986Sandreas.sandberg@arm.com PyObject *inst = PyTuple_GET_ITEM(args, 0); 52911986Sandreas.sandberg@arm.com auto tinfo = detail::get_type_info(Py_TYPE(inst)); 53011986Sandreas.sandberg@arm.com tinfo->init_holder(inst, nullptr); 53111986Sandreas.sandberg@arm.com } 53211986Sandreas.sandberg@arm.com return result.ptr(); 53311986Sandreas.sandberg@arm.com } 53411986Sandreas.sandberg@arm.com } 53511986Sandreas.sandberg@arm.com}; 53611986Sandreas.sandberg@arm.com 53711986Sandreas.sandberg@arm.com/// Wrapper for Python extension modules 53811986Sandreas.sandberg@arm.comclass module : public object { 53911986Sandreas.sandberg@arm.compublic: 54011986Sandreas.sandberg@arm.com PYBIND11_OBJECT_DEFAULT(module, object, PyModule_Check) 54111986Sandreas.sandberg@arm.com 54211986Sandreas.sandberg@arm.com explicit module(const char *name, const char *doc = nullptr) { 54311986Sandreas.sandberg@arm.com if (!options::show_user_defined_docstrings()) doc = nullptr; 54411986Sandreas.sandberg@arm.com#if PY_MAJOR_VERSION >= 3 54511986Sandreas.sandberg@arm.com PyModuleDef *def = new PyModuleDef(); 54611986Sandreas.sandberg@arm.com memset(def, 0, sizeof(PyModuleDef)); 54711986Sandreas.sandberg@arm.com def->m_name = name; 54811986Sandreas.sandberg@arm.com def->m_doc = doc; 54911986Sandreas.sandberg@arm.com def->m_size = -1; 55011986Sandreas.sandberg@arm.com Py_INCREF(def); 55111986Sandreas.sandberg@arm.com m_ptr = PyModule_Create(def); 55211986Sandreas.sandberg@arm.com#else 55311986Sandreas.sandberg@arm.com m_ptr = Py_InitModule3(name, nullptr, doc); 55411986Sandreas.sandberg@arm.com#endif 55511986Sandreas.sandberg@arm.com if (m_ptr == nullptr) 55611986Sandreas.sandberg@arm.com pybind11_fail("Internal error in module::module()"); 55711986Sandreas.sandberg@arm.com inc_ref(); 55811986Sandreas.sandberg@arm.com } 55911986Sandreas.sandberg@arm.com 56011986Sandreas.sandberg@arm.com template <typename Func, typename... Extra> 56111986Sandreas.sandberg@arm.com module &def(const char *name_, Func &&f, const Extra& ... extra) { 56211986Sandreas.sandberg@arm.com cpp_function func(std::forward<Func>(f), name(name_), scope(*this), 56311986Sandreas.sandberg@arm.com sibling(getattr(*this, name_, none())), extra...); 56411986Sandreas.sandberg@arm.com // NB: allow overwriting here because cpp_function sets up a chain with the intention of 56511986Sandreas.sandberg@arm.com // overwriting (and has already checked internally that it isn't overwriting non-functions). 56611986Sandreas.sandberg@arm.com add_object(name_, func, true /* overwrite */); 56711986Sandreas.sandberg@arm.com return *this; 56811986Sandreas.sandberg@arm.com } 56911986Sandreas.sandberg@arm.com 57011986Sandreas.sandberg@arm.com module def_submodule(const char *name, const char *doc = nullptr) { 57111986Sandreas.sandberg@arm.com std::string full_name = std::string(PyModule_GetName(m_ptr)) 57211986Sandreas.sandberg@arm.com + std::string(".") + std::string(name); 57311986Sandreas.sandberg@arm.com auto result = reinterpret_borrow<module>(PyImport_AddModule(full_name.c_str())); 57411986Sandreas.sandberg@arm.com if (doc && options::show_user_defined_docstrings()) 57511986Sandreas.sandberg@arm.com result.attr("__doc__") = pybind11::str(doc); 57611986Sandreas.sandberg@arm.com attr(name) = result; 57711986Sandreas.sandberg@arm.com return result; 57811986Sandreas.sandberg@arm.com } 57911986Sandreas.sandberg@arm.com 58011986Sandreas.sandberg@arm.com static module import(const char *name) { 58111986Sandreas.sandberg@arm.com PyObject *obj = PyImport_ImportModule(name); 58211986Sandreas.sandberg@arm.com if (!obj) 58311986Sandreas.sandberg@arm.com throw error_already_set(); 58411986Sandreas.sandberg@arm.com return reinterpret_steal<module>(obj); 58511986Sandreas.sandberg@arm.com } 58611986Sandreas.sandberg@arm.com 58711986Sandreas.sandberg@arm.com // Adds an object to the module using the given name. Throws if an object with the given name 58811986Sandreas.sandberg@arm.com // already exists. 58911986Sandreas.sandberg@arm.com // 59011986Sandreas.sandberg@arm.com // overwrite should almost always be false: attempting to overwrite objects that pybind11 has 59111986Sandreas.sandberg@arm.com // established will, in most cases, break things. 59211986Sandreas.sandberg@arm.com PYBIND11_NOINLINE void add_object(const char *name, object &obj, bool overwrite = false) { 59311986Sandreas.sandberg@arm.com if (!overwrite && hasattr(*this, name)) 59411986Sandreas.sandberg@arm.com pybind11_fail("Error during initialization: multiple incompatible definitions with name \"" + 59511986Sandreas.sandberg@arm.com std::string(name) + "\""); 59611986Sandreas.sandberg@arm.com 59711986Sandreas.sandberg@arm.com obj.inc_ref(); // PyModule_AddObject() steals a reference 59811986Sandreas.sandberg@arm.com PyModule_AddObject(ptr(), name, obj.ptr()); 59911986Sandreas.sandberg@arm.com } 60011986Sandreas.sandberg@arm.com}; 60111986Sandreas.sandberg@arm.com 60211986Sandreas.sandberg@arm.comNAMESPACE_BEGIN(detail) 60311986Sandreas.sandberg@arm.comextern "C" inline PyObject *get_dict(PyObject *op, void *) { 60411986Sandreas.sandberg@arm.com PyObject *&dict = *_PyObject_GetDictPtr(op); 60511986Sandreas.sandberg@arm.com if (!dict) { 60611986Sandreas.sandberg@arm.com dict = PyDict_New(); 60711986Sandreas.sandberg@arm.com } 60811986Sandreas.sandberg@arm.com Py_XINCREF(dict); 60911986Sandreas.sandberg@arm.com return dict; 61011986Sandreas.sandberg@arm.com} 61111986Sandreas.sandberg@arm.com 61211986Sandreas.sandberg@arm.comextern "C" inline int set_dict(PyObject *op, PyObject *new_dict, void *) { 61311986Sandreas.sandberg@arm.com if (!PyDict_Check(new_dict)) { 61411986Sandreas.sandberg@arm.com PyErr_Format(PyExc_TypeError, "__dict__ must be set to a dictionary, not a '%.200s'", 61511986Sandreas.sandberg@arm.com Py_TYPE(new_dict)->tp_name); 61611986Sandreas.sandberg@arm.com return -1; 61711986Sandreas.sandberg@arm.com } 61811986Sandreas.sandberg@arm.com PyObject *&dict = *_PyObject_GetDictPtr(op); 61911986Sandreas.sandberg@arm.com Py_INCREF(new_dict); 62011986Sandreas.sandberg@arm.com Py_CLEAR(dict); 62111986Sandreas.sandberg@arm.com dict = new_dict; 62211986Sandreas.sandberg@arm.com return 0; 62311986Sandreas.sandberg@arm.com} 62411986Sandreas.sandberg@arm.com 62511986Sandreas.sandberg@arm.comstatic PyGetSetDef generic_getset[] = { 62611986Sandreas.sandberg@arm.com {const_cast<char*>("__dict__"), get_dict, set_dict, nullptr, nullptr}, 62711986Sandreas.sandberg@arm.com {nullptr, nullptr, nullptr, nullptr, nullptr} 62811986Sandreas.sandberg@arm.com}; 62911986Sandreas.sandberg@arm.com 63011986Sandreas.sandberg@arm.com/// Generic support for creating new Python heap types 63111986Sandreas.sandberg@arm.comclass generic_type : public object { 63211986Sandreas.sandberg@arm.com template <typename...> friend class class_; 63311986Sandreas.sandberg@arm.compublic: 63411986Sandreas.sandberg@arm.com PYBIND11_OBJECT_DEFAULT(generic_type, object, PyType_Check) 63511986Sandreas.sandberg@arm.comprotected: 63611986Sandreas.sandberg@arm.com void initialize(type_record *rec) { 63711986Sandreas.sandberg@arm.com auto &internals = get_internals(); 63811986Sandreas.sandberg@arm.com auto tindex = std::type_index(*(rec->type)); 63911986Sandreas.sandberg@arm.com 64011986Sandreas.sandberg@arm.com if (get_type_info(*(rec->type))) 64111986Sandreas.sandberg@arm.com pybind11_fail("generic_type: type \"" + std::string(rec->name) + 64211986Sandreas.sandberg@arm.com "\" is already registered!"); 64311986Sandreas.sandberg@arm.com 64411986Sandreas.sandberg@arm.com auto name = reinterpret_steal<object>(PYBIND11_FROM_STRING(rec->name)); 64511986Sandreas.sandberg@arm.com object scope_module; 64611986Sandreas.sandberg@arm.com if (rec->scope) { 64711986Sandreas.sandberg@arm.com if (hasattr(rec->scope, rec->name)) 64811986Sandreas.sandberg@arm.com pybind11_fail("generic_type: cannot initialize type \"" + std::string(rec->name) + 64911986Sandreas.sandberg@arm.com "\": an object with that name is already defined"); 65011986Sandreas.sandberg@arm.com 65111986Sandreas.sandberg@arm.com if (hasattr(rec->scope, "__module__")) { 65211986Sandreas.sandberg@arm.com scope_module = rec->scope.attr("__module__"); 65311986Sandreas.sandberg@arm.com } else if (hasattr(rec->scope, "__name__")) { 65411986Sandreas.sandberg@arm.com scope_module = rec->scope.attr("__name__"); 65511986Sandreas.sandberg@arm.com } 65611986Sandreas.sandberg@arm.com } 65711986Sandreas.sandberg@arm.com 65811986Sandreas.sandberg@arm.com#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 65911986Sandreas.sandberg@arm.com /* Qualified names for Python >= 3.3 */ 66011986Sandreas.sandberg@arm.com object scope_qualname; 66111986Sandreas.sandberg@arm.com if (rec->scope && hasattr(rec->scope, "__qualname__")) 66211986Sandreas.sandberg@arm.com scope_qualname = rec->scope.attr("__qualname__"); 66311986Sandreas.sandberg@arm.com object ht_qualname; 66411986Sandreas.sandberg@arm.com if (scope_qualname) { 66511986Sandreas.sandberg@arm.com ht_qualname = reinterpret_steal<object>(PyUnicode_FromFormat( 66611986Sandreas.sandberg@arm.com "%U.%U", scope_qualname.ptr(), name.ptr())); 66711986Sandreas.sandberg@arm.com } else { 66811986Sandreas.sandberg@arm.com ht_qualname = name; 66911986Sandreas.sandberg@arm.com } 67011986Sandreas.sandberg@arm.com#endif 67111986Sandreas.sandberg@arm.com 67211986Sandreas.sandberg@arm.com size_t num_bases = rec->bases.size(); 67311986Sandreas.sandberg@arm.com auto bases = tuple(rec->bases); 67411986Sandreas.sandberg@arm.com 67511986Sandreas.sandberg@arm.com std::string full_name = (scope_module ? ((std::string) pybind11::str(scope_module) + "." + rec->name) 67611986Sandreas.sandberg@arm.com : std::string(rec->name)); 67711986Sandreas.sandberg@arm.com 67811986Sandreas.sandberg@arm.com char *tp_doc = nullptr; 67911986Sandreas.sandberg@arm.com if (rec->doc && options::show_user_defined_docstrings()) { 68011986Sandreas.sandberg@arm.com /* Allocate memory for docstring (using PyObject_MALLOC, since 68111986Sandreas.sandberg@arm.com Python will free this later on) */ 68211986Sandreas.sandberg@arm.com size_t size = strlen(rec->doc) + 1; 68311986Sandreas.sandberg@arm.com tp_doc = (char *) PyObject_MALLOC(size); 68411986Sandreas.sandberg@arm.com memcpy((void *) tp_doc, rec->doc, size); 68511986Sandreas.sandberg@arm.com } 68611986Sandreas.sandberg@arm.com 68711986Sandreas.sandberg@arm.com /* Danger zone: from now (and until PyType_Ready), make sure to 68811986Sandreas.sandberg@arm.com issue no Python C API calls which could potentially invoke the 68911986Sandreas.sandberg@arm.com garbage collector (the GC will call type_traverse(), which will in 69011986Sandreas.sandberg@arm.com turn find the newly constructed type in an invalid state) */ 69111986Sandreas.sandberg@arm.com 69211986Sandreas.sandberg@arm.com auto type_holder = reinterpret_steal<object>(PyType_Type.tp_alloc(&PyType_Type, 0)); 69311986Sandreas.sandberg@arm.com auto type = (PyHeapTypeObject*) type_holder.ptr(); 69411986Sandreas.sandberg@arm.com 69511986Sandreas.sandberg@arm.com if (!type_holder || !name) 69611986Sandreas.sandberg@arm.com pybind11_fail(std::string(rec->name) + ": Unable to create type object!"); 69711986Sandreas.sandberg@arm.com 69811986Sandreas.sandberg@arm.com /* Register supplemental type information in C++ dict */ 69911986Sandreas.sandberg@arm.com detail::type_info *tinfo = new detail::type_info(); 70011986Sandreas.sandberg@arm.com tinfo->type = (PyTypeObject *) type; 70111986Sandreas.sandberg@arm.com tinfo->type_size = rec->type_size; 70211986Sandreas.sandberg@arm.com tinfo->init_holder = rec->init_holder; 70311986Sandreas.sandberg@arm.com tinfo->direct_conversions = &internals.direct_conversions[tindex]; 70411986Sandreas.sandberg@arm.com internals.registered_types_cpp[tindex] = tinfo; 70511986Sandreas.sandberg@arm.com internals.registered_types_py[type] = tinfo; 70611986Sandreas.sandberg@arm.com 70711986Sandreas.sandberg@arm.com /* Basic type attributes */ 70811986Sandreas.sandberg@arm.com type->ht_type.tp_name = strdup(full_name.c_str()); 70911986Sandreas.sandberg@arm.com type->ht_type.tp_basicsize = (ssize_t) rec->instance_size; 71011986Sandreas.sandberg@arm.com 71111986Sandreas.sandberg@arm.com if (num_bases > 0) { 71211986Sandreas.sandberg@arm.com type->ht_type.tp_base = (PyTypeObject *) ((object) bases[0]).inc_ref().ptr(); 71311986Sandreas.sandberg@arm.com type->ht_type.tp_bases = bases.release().ptr(); 71411986Sandreas.sandberg@arm.com rec->multiple_inheritance |= num_bases > 1; 71511986Sandreas.sandberg@arm.com } 71611986Sandreas.sandberg@arm.com 71711986Sandreas.sandberg@arm.com type->ht_name = name.release().ptr(); 71811986Sandreas.sandberg@arm.com 71911986Sandreas.sandberg@arm.com#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 72011986Sandreas.sandberg@arm.com type->ht_qualname = ht_qualname.release().ptr(); 72111986Sandreas.sandberg@arm.com#endif 72211986Sandreas.sandberg@arm.com 72311986Sandreas.sandberg@arm.com /* Supported protocols */ 72411986Sandreas.sandberg@arm.com type->ht_type.tp_as_number = &type->as_number; 72511986Sandreas.sandberg@arm.com type->ht_type.tp_as_sequence = &type->as_sequence; 72611986Sandreas.sandberg@arm.com type->ht_type.tp_as_mapping = &type->as_mapping; 72711986Sandreas.sandberg@arm.com 72811986Sandreas.sandberg@arm.com /* Supported elementary operations */ 72911986Sandreas.sandberg@arm.com type->ht_type.tp_init = (initproc) init; 73011986Sandreas.sandberg@arm.com type->ht_type.tp_new = (newfunc) new_instance; 73111986Sandreas.sandberg@arm.com type->ht_type.tp_dealloc = rec->dealloc; 73211986Sandreas.sandberg@arm.com 73311986Sandreas.sandberg@arm.com /* Support weak references (needed for the keep_alive feature) */ 73411986Sandreas.sandberg@arm.com type->ht_type.tp_weaklistoffset = offsetof(instance_essentials<void>, weakrefs); 73511986Sandreas.sandberg@arm.com 73611986Sandreas.sandberg@arm.com /* Flags */ 73711986Sandreas.sandberg@arm.com type->ht_type.tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; 73811986Sandreas.sandberg@arm.com#if PY_MAJOR_VERSION < 3 73911986Sandreas.sandberg@arm.com type->ht_type.tp_flags |= Py_TPFLAGS_CHECKTYPES; 74011986Sandreas.sandberg@arm.com#endif 74111986Sandreas.sandberg@arm.com type->ht_type.tp_flags &= ~Py_TPFLAGS_HAVE_GC; 74211986Sandreas.sandberg@arm.com 74311986Sandreas.sandberg@arm.com /* Support dynamic attributes */ 74411986Sandreas.sandberg@arm.com if (rec->dynamic_attr) { 74511986Sandreas.sandberg@arm.com type->ht_type.tp_flags |= Py_TPFLAGS_HAVE_GC; 74611986Sandreas.sandberg@arm.com type->ht_type.tp_dictoffset = type->ht_type.tp_basicsize; // place the dict at the end 74711986Sandreas.sandberg@arm.com type->ht_type.tp_basicsize += sizeof(PyObject *); // and allocate enough space for it 74811986Sandreas.sandberg@arm.com type->ht_type.tp_getset = generic_getset; 74911986Sandreas.sandberg@arm.com type->ht_type.tp_traverse = traverse; 75011986Sandreas.sandberg@arm.com type->ht_type.tp_clear = clear; 75111986Sandreas.sandberg@arm.com } 75211986Sandreas.sandberg@arm.com 75311986Sandreas.sandberg@arm.com type->ht_type.tp_doc = tp_doc; 75411986Sandreas.sandberg@arm.com 75511986Sandreas.sandberg@arm.com if (PyType_Ready(&type->ht_type) < 0) 75611986Sandreas.sandberg@arm.com pybind11_fail(std::string(rec->name) + ": PyType_Ready failed (" + 75711986Sandreas.sandberg@arm.com detail::error_string() + ")!"); 75811986Sandreas.sandberg@arm.com 75911986Sandreas.sandberg@arm.com m_ptr = type_holder.ptr(); 76011986Sandreas.sandberg@arm.com 76111986Sandreas.sandberg@arm.com if (scope_module) // Needed by pydoc 76211986Sandreas.sandberg@arm.com attr("__module__") = scope_module; 76311986Sandreas.sandberg@arm.com 76411986Sandreas.sandberg@arm.com /* Register type with the parent scope */ 76511986Sandreas.sandberg@arm.com if (rec->scope) 76611986Sandreas.sandberg@arm.com rec->scope.attr(handle(type->ht_name)) = *this; 76711986Sandreas.sandberg@arm.com 76811986Sandreas.sandberg@arm.com if (rec->multiple_inheritance) 76911986Sandreas.sandberg@arm.com mark_parents_nonsimple(&type->ht_type); 77011986Sandreas.sandberg@arm.com 77111986Sandreas.sandberg@arm.com type_holder.release(); 77211986Sandreas.sandberg@arm.com } 77311986Sandreas.sandberg@arm.com 77411986Sandreas.sandberg@arm.com /// Helper function which tags all parents of a type using mult. inheritance 77511986Sandreas.sandberg@arm.com void mark_parents_nonsimple(PyTypeObject *value) { 77611986Sandreas.sandberg@arm.com auto t = reinterpret_borrow<tuple>(value->tp_bases); 77711986Sandreas.sandberg@arm.com for (handle h : t) { 77811986Sandreas.sandberg@arm.com auto tinfo2 = get_type_info((PyTypeObject *) h.ptr()); 77911986Sandreas.sandberg@arm.com if (tinfo2) 78011986Sandreas.sandberg@arm.com tinfo2->simple_type = false; 78111986Sandreas.sandberg@arm.com mark_parents_nonsimple((PyTypeObject *) h.ptr()); 78211986Sandreas.sandberg@arm.com } 78311986Sandreas.sandberg@arm.com } 78411986Sandreas.sandberg@arm.com 78511986Sandreas.sandberg@arm.com /// Allocate a metaclass on demand (for static properties) 78611986Sandreas.sandberg@arm.com handle metaclass() { 78711986Sandreas.sandberg@arm.com auto &ht_type = ((PyHeapTypeObject *) m_ptr)->ht_type; 78811986Sandreas.sandberg@arm.com auto &ob_type = PYBIND11_OB_TYPE(ht_type); 78911986Sandreas.sandberg@arm.com 79011986Sandreas.sandberg@arm.com if (ob_type == &PyType_Type) { 79111986Sandreas.sandberg@arm.com std::string name_ = std::string(ht_type.tp_name) + "__Meta"; 79211986Sandreas.sandberg@arm.com#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 79311986Sandreas.sandberg@arm.com auto ht_qualname = reinterpret_steal<object>(PyUnicode_FromFormat("%U__Meta", attr("__qualname__").ptr())); 79411986Sandreas.sandberg@arm.com#endif 79511986Sandreas.sandberg@arm.com auto name = reinterpret_steal<object>(PYBIND11_FROM_STRING(name_.c_str())); 79611986Sandreas.sandberg@arm.com auto type_holder = reinterpret_steal<object>(PyType_Type.tp_alloc(&PyType_Type, 0)); 79711986Sandreas.sandberg@arm.com if (!type_holder || !name) 79811986Sandreas.sandberg@arm.com pybind11_fail("generic_type::metaclass(): unable to create type object!"); 79911986Sandreas.sandberg@arm.com 80011986Sandreas.sandberg@arm.com auto type = (PyHeapTypeObject*) type_holder.ptr(); 80111986Sandreas.sandberg@arm.com type->ht_name = name.release().ptr(); 80211986Sandreas.sandberg@arm.com 80311986Sandreas.sandberg@arm.com#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 80411986Sandreas.sandberg@arm.com /* Qualified names for Python >= 3.3 */ 80511986Sandreas.sandberg@arm.com type->ht_qualname = ht_qualname.release().ptr(); 80611986Sandreas.sandberg@arm.com#endif 80711986Sandreas.sandberg@arm.com type->ht_type.tp_name = strdup(name_.c_str()); 80811986Sandreas.sandberg@arm.com type->ht_type.tp_base = ob_type; 80911986Sandreas.sandberg@arm.com type->ht_type.tp_flags |= (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE) & 81011986Sandreas.sandberg@arm.com ~Py_TPFLAGS_HAVE_GC; 81111986Sandreas.sandberg@arm.com 81211986Sandreas.sandberg@arm.com if (PyType_Ready(&type->ht_type) < 0) 81311986Sandreas.sandberg@arm.com pybind11_fail("generic_type::metaclass(): PyType_Ready failed!"); 81411986Sandreas.sandberg@arm.com 81511986Sandreas.sandberg@arm.com ob_type = (PyTypeObject *) type_holder.release().ptr(); 81611986Sandreas.sandberg@arm.com } 81711986Sandreas.sandberg@arm.com return handle((PyObject *) ob_type); 81811986Sandreas.sandberg@arm.com } 81911986Sandreas.sandberg@arm.com 82011986Sandreas.sandberg@arm.com static int init(void *self, PyObject *, PyObject *) { 82111986Sandreas.sandberg@arm.com std::string msg = std::string(Py_TYPE(self)->tp_name) + ": No constructor defined!"; 82211986Sandreas.sandberg@arm.com PyErr_SetString(PyExc_TypeError, msg.c_str()); 82311986Sandreas.sandberg@arm.com return -1; 82411986Sandreas.sandberg@arm.com } 82511986Sandreas.sandberg@arm.com 82611986Sandreas.sandberg@arm.com static PyObject *new_instance(PyTypeObject *type, PyObject *, PyObject *) { 82711986Sandreas.sandberg@arm.com instance<void> *self = (instance<void> *) PyType_GenericAlloc((PyTypeObject *) type, 0); 82811986Sandreas.sandberg@arm.com auto tinfo = detail::get_type_info(type); 82911986Sandreas.sandberg@arm.com self->value = ::operator new(tinfo->type_size); 83011986Sandreas.sandberg@arm.com self->owned = true; 83111986Sandreas.sandberg@arm.com self->holder_constructed = false; 83211986Sandreas.sandberg@arm.com detail::get_internals().registered_instances.emplace(self->value, (PyObject *) self); 83311986Sandreas.sandberg@arm.com return (PyObject *) self; 83411986Sandreas.sandberg@arm.com } 83511986Sandreas.sandberg@arm.com 83611986Sandreas.sandberg@arm.com static void dealloc(instance<void> *self) { 83711986Sandreas.sandberg@arm.com if (self->value) { 83811986Sandreas.sandberg@arm.com auto instance_type = Py_TYPE(self); 83911986Sandreas.sandberg@arm.com auto ®istered_instances = detail::get_internals().registered_instances; 84011986Sandreas.sandberg@arm.com auto range = registered_instances.equal_range(self->value); 84111986Sandreas.sandberg@arm.com bool found = false; 84211986Sandreas.sandberg@arm.com for (auto it = range.first; it != range.second; ++it) { 84311986Sandreas.sandberg@arm.com if (instance_type == Py_TYPE(it->second)) { 84411986Sandreas.sandberg@arm.com registered_instances.erase(it); 84511986Sandreas.sandberg@arm.com found = true; 84611986Sandreas.sandberg@arm.com break; 84711986Sandreas.sandberg@arm.com } 84811986Sandreas.sandberg@arm.com } 84911986Sandreas.sandberg@arm.com if (!found) 85011986Sandreas.sandberg@arm.com pybind11_fail("generic_type::dealloc(): Tried to deallocate unregistered instance!"); 85111986Sandreas.sandberg@arm.com 85211986Sandreas.sandberg@arm.com if (self->weakrefs) 85311986Sandreas.sandberg@arm.com PyObject_ClearWeakRefs((PyObject *) self); 85411986Sandreas.sandberg@arm.com 85511986Sandreas.sandberg@arm.com PyObject **dict_ptr = _PyObject_GetDictPtr((PyObject *) self); 85611986Sandreas.sandberg@arm.com if (dict_ptr) { 85711986Sandreas.sandberg@arm.com Py_CLEAR(*dict_ptr); 85811986Sandreas.sandberg@arm.com } 85911986Sandreas.sandberg@arm.com } 86011986Sandreas.sandberg@arm.com Py_TYPE(self)->tp_free((PyObject*) self); 86111986Sandreas.sandberg@arm.com } 86211986Sandreas.sandberg@arm.com 86311986Sandreas.sandberg@arm.com static int traverse(PyObject *op, visitproc visit, void *arg) { 86411986Sandreas.sandberg@arm.com PyObject *&dict = *_PyObject_GetDictPtr(op); 86511986Sandreas.sandberg@arm.com Py_VISIT(dict); 86611986Sandreas.sandberg@arm.com return 0; 86711986Sandreas.sandberg@arm.com } 86811986Sandreas.sandberg@arm.com 86911986Sandreas.sandberg@arm.com static int clear(PyObject *op) { 87011986Sandreas.sandberg@arm.com PyObject *&dict = *_PyObject_GetDictPtr(op); 87111986Sandreas.sandberg@arm.com Py_CLEAR(dict); 87211986Sandreas.sandberg@arm.com return 0; 87311986Sandreas.sandberg@arm.com } 87411986Sandreas.sandberg@arm.com 87511986Sandreas.sandberg@arm.com void install_buffer_funcs( 87611986Sandreas.sandberg@arm.com buffer_info *(*get_buffer)(PyObject *, void *), 87711986Sandreas.sandberg@arm.com void *get_buffer_data) { 87811986Sandreas.sandberg@arm.com PyHeapTypeObject *type = (PyHeapTypeObject*) m_ptr; 87911986Sandreas.sandberg@arm.com type->ht_type.tp_as_buffer = &type->as_buffer; 88011986Sandreas.sandberg@arm.com#if PY_MAJOR_VERSION < 3 88111986Sandreas.sandberg@arm.com type->ht_type.tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER; 88211986Sandreas.sandberg@arm.com#endif 88311986Sandreas.sandberg@arm.com type->as_buffer.bf_getbuffer = getbuffer; 88411986Sandreas.sandberg@arm.com type->as_buffer.bf_releasebuffer = releasebuffer; 88511986Sandreas.sandberg@arm.com auto tinfo = detail::get_type_info(&type->ht_type); 88611986Sandreas.sandberg@arm.com tinfo->get_buffer = get_buffer; 88711986Sandreas.sandberg@arm.com tinfo->get_buffer_data = get_buffer_data; 88811986Sandreas.sandberg@arm.com } 88911986Sandreas.sandberg@arm.com 89011986Sandreas.sandberg@arm.com static int getbuffer(PyObject *obj, Py_buffer *view, int flags) { 89111986Sandreas.sandberg@arm.com auto tinfo = detail::get_type_info(Py_TYPE(obj)); 89211986Sandreas.sandberg@arm.com if (view == nullptr || obj == nullptr || !tinfo || !tinfo->get_buffer) { 89311986Sandreas.sandberg@arm.com PyErr_SetString(PyExc_BufferError, "generic_type::getbuffer(): Internal error"); 89411986Sandreas.sandberg@arm.com return -1; 89511986Sandreas.sandberg@arm.com } 89611986Sandreas.sandberg@arm.com memset(view, 0, sizeof(Py_buffer)); 89711986Sandreas.sandberg@arm.com buffer_info *info = tinfo->get_buffer(obj, tinfo->get_buffer_data); 89811986Sandreas.sandberg@arm.com view->obj = obj; 89911986Sandreas.sandberg@arm.com view->ndim = 1; 90011986Sandreas.sandberg@arm.com view->internal = info; 90111986Sandreas.sandberg@arm.com view->buf = info->ptr; 90211986Sandreas.sandberg@arm.com view->itemsize = (ssize_t) info->itemsize; 90311986Sandreas.sandberg@arm.com view->len = view->itemsize; 90411986Sandreas.sandberg@arm.com for (auto s : info->shape) 90511986Sandreas.sandberg@arm.com view->len *= s; 90611986Sandreas.sandberg@arm.com if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) 90711986Sandreas.sandberg@arm.com view->format = const_cast<char *>(info->format.c_str()); 90811986Sandreas.sandberg@arm.com if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) { 90911986Sandreas.sandberg@arm.com view->ndim = (int) info->ndim; 91011986Sandreas.sandberg@arm.com view->strides = (ssize_t *) &info->strides[0]; 91111986Sandreas.sandberg@arm.com view->shape = (ssize_t *) &info->shape[0]; 91211986Sandreas.sandberg@arm.com } 91311986Sandreas.sandberg@arm.com Py_INCREF(view->obj); 91411986Sandreas.sandberg@arm.com return 0; 91511986Sandreas.sandberg@arm.com } 91611986Sandreas.sandberg@arm.com 91711986Sandreas.sandberg@arm.com static void releasebuffer(PyObject *, Py_buffer *view) { delete (buffer_info *) view->internal; } 91811986Sandreas.sandberg@arm.com}; 91911986Sandreas.sandberg@arm.com 92011986Sandreas.sandberg@arm.comNAMESPACE_END(detail) 92111986Sandreas.sandberg@arm.com 92211986Sandreas.sandberg@arm.comtemplate <typename type_, typename... options> 92311986Sandreas.sandberg@arm.comclass class_ : public detail::generic_type { 92411986Sandreas.sandberg@arm.com template <typename T> using is_holder = detail::is_holder_type<type_, T>; 92511986Sandreas.sandberg@arm.com template <typename T> using is_subtype = detail::bool_constant<std::is_base_of<type_, T>::value && !std::is_same<T, type_>::value>; 92611986Sandreas.sandberg@arm.com template <typename T> using is_base = detail::bool_constant<std::is_base_of<T, type_>::value && !std::is_same<T, type_>::value>; 92711986Sandreas.sandberg@arm.com template <typename T> using is_valid_class_option = 92811986Sandreas.sandberg@arm.com detail::bool_constant< 92911986Sandreas.sandberg@arm.com is_holder<T>::value || 93011986Sandreas.sandberg@arm.com is_subtype<T>::value || 93111986Sandreas.sandberg@arm.com is_base<T>::value 93211986Sandreas.sandberg@arm.com >; 93311986Sandreas.sandberg@arm.com 93411986Sandreas.sandberg@arm.compublic: 93511986Sandreas.sandberg@arm.com using type = type_; 93611986Sandreas.sandberg@arm.com using type_alias = detail::first_of_t<is_subtype, void, options...>; 93711986Sandreas.sandberg@arm.com constexpr static bool has_alias = !std::is_void<type_alias>::value; 93811986Sandreas.sandberg@arm.com using holder_type = detail::first_of_t<is_holder, std::unique_ptr<type>, options...>; 93911986Sandreas.sandberg@arm.com using instance_type = detail::instance<type, holder_type>; 94011986Sandreas.sandberg@arm.com 94111986Sandreas.sandberg@arm.com static_assert(detail::all_of_t<is_valid_class_option, options...>::value, 94211986Sandreas.sandberg@arm.com "Unknown/invalid class_ template parameters provided"); 94311986Sandreas.sandberg@arm.com 94411986Sandreas.sandberg@arm.com PYBIND11_OBJECT(class_, generic_type, PyType_Check) 94511986Sandreas.sandberg@arm.com 94611986Sandreas.sandberg@arm.com template <typename... Extra> 94711986Sandreas.sandberg@arm.com class_(handle scope, const char *name, const Extra &... extra) { 94811986Sandreas.sandberg@arm.com detail::type_record record; 94911986Sandreas.sandberg@arm.com record.scope = scope; 95011986Sandreas.sandberg@arm.com record.name = name; 95111986Sandreas.sandberg@arm.com record.type = &typeid(type); 95211986Sandreas.sandberg@arm.com record.type_size = sizeof(detail::conditional_t<has_alias, type_alias, type>); 95311986Sandreas.sandberg@arm.com record.instance_size = sizeof(instance_type); 95411986Sandreas.sandberg@arm.com record.init_holder = init_holder; 95511986Sandreas.sandberg@arm.com record.dealloc = dealloc; 95611986Sandreas.sandberg@arm.com 95711986Sandreas.sandberg@arm.com /* Register base classes specified via template arguments to class_, if any */ 95811986Sandreas.sandberg@arm.com bool unused[] = { (add_base<options>(record), false)..., false }; 95911986Sandreas.sandberg@arm.com (void) unused; 96011986Sandreas.sandberg@arm.com 96111986Sandreas.sandberg@arm.com /* Process optional arguments, if any */ 96211986Sandreas.sandberg@arm.com detail::process_attributes<Extra...>::init(extra..., &record); 96311986Sandreas.sandberg@arm.com 96411986Sandreas.sandberg@arm.com detail::generic_type::initialize(&record); 96511986Sandreas.sandberg@arm.com 96611986Sandreas.sandberg@arm.com if (has_alias) { 96711986Sandreas.sandberg@arm.com auto &instances = pybind11::detail::get_internals().registered_types_cpp; 96811986Sandreas.sandberg@arm.com instances[std::type_index(typeid(type_alias))] = instances[std::type_index(typeid(type))]; 96911986Sandreas.sandberg@arm.com } 97011986Sandreas.sandberg@arm.com } 97111986Sandreas.sandberg@arm.com 97211986Sandreas.sandberg@arm.com template <typename Base, detail::enable_if_t<is_base<Base>::value, int> = 0> 97311986Sandreas.sandberg@arm.com static void add_base(detail::type_record &rec) { 97411986Sandreas.sandberg@arm.com rec.add_base(&typeid(Base), [](void *src) -> void * { 97511986Sandreas.sandberg@arm.com return static_cast<Base *>(reinterpret_cast<type *>(src)); 97611986Sandreas.sandberg@arm.com }); 97711986Sandreas.sandberg@arm.com } 97811986Sandreas.sandberg@arm.com 97911986Sandreas.sandberg@arm.com template <typename Base, detail::enable_if_t<!is_base<Base>::value, int> = 0> 98011986Sandreas.sandberg@arm.com static void add_base(detail::type_record &) { } 98111986Sandreas.sandberg@arm.com 98211986Sandreas.sandberg@arm.com template <typename Func, typename... Extra> 98311986Sandreas.sandberg@arm.com class_ &def(const char *name_, Func&& f, const Extra&... extra) { 98411986Sandreas.sandberg@arm.com cpp_function cf(std::forward<Func>(f), name(name_), is_method(*this), 98511986Sandreas.sandberg@arm.com sibling(getattr(*this, name_, none())), extra...); 98611986Sandreas.sandberg@arm.com attr(cf.name()) = cf; 98711986Sandreas.sandberg@arm.com return *this; 98811986Sandreas.sandberg@arm.com } 98911986Sandreas.sandberg@arm.com 99011986Sandreas.sandberg@arm.com template <typename Func, typename... Extra> class_ & 99111986Sandreas.sandberg@arm.com def_static(const char *name_, Func f, const Extra&... extra) { 99211986Sandreas.sandberg@arm.com cpp_function cf(std::forward<Func>(f), name(name_), scope(*this), 99311986Sandreas.sandberg@arm.com sibling(getattr(*this, name_, none())), extra...); 99411986Sandreas.sandberg@arm.com attr(cf.name()) = cf; 99511986Sandreas.sandberg@arm.com return *this; 99611986Sandreas.sandberg@arm.com } 99711986Sandreas.sandberg@arm.com 99811986Sandreas.sandberg@arm.com template <detail::op_id id, detail::op_type ot, typename L, typename R, typename... Extra> 99911986Sandreas.sandberg@arm.com class_ &def(const detail::op_<id, ot, L, R> &op, const Extra&... extra) { 100011986Sandreas.sandberg@arm.com op.execute(*this, extra...); 100111986Sandreas.sandberg@arm.com return *this; 100211986Sandreas.sandberg@arm.com } 100311986Sandreas.sandberg@arm.com 100411986Sandreas.sandberg@arm.com template <detail::op_id id, detail::op_type ot, typename L, typename R, typename... Extra> 100511986Sandreas.sandberg@arm.com class_ & def_cast(const detail::op_<id, ot, L, R> &op, const Extra&... extra) { 100611986Sandreas.sandberg@arm.com op.execute_cast(*this, extra...); 100711986Sandreas.sandberg@arm.com return *this; 100811986Sandreas.sandberg@arm.com } 100911986Sandreas.sandberg@arm.com 101011986Sandreas.sandberg@arm.com template <typename... Args, typename... Extra> 101111986Sandreas.sandberg@arm.com class_ &def(const detail::init<Args...> &init, const Extra&... extra) { 101211986Sandreas.sandberg@arm.com init.execute(*this, extra...); 101311986Sandreas.sandberg@arm.com return *this; 101411986Sandreas.sandberg@arm.com } 101511986Sandreas.sandberg@arm.com 101611986Sandreas.sandberg@arm.com template <typename... Args, typename... Extra> 101711986Sandreas.sandberg@arm.com class_ &def(const detail::init_alias<Args...> &init, const Extra&... extra) { 101811986Sandreas.sandberg@arm.com init.execute(*this, extra...); 101911986Sandreas.sandberg@arm.com return *this; 102011986Sandreas.sandberg@arm.com } 102111986Sandreas.sandberg@arm.com 102211986Sandreas.sandberg@arm.com template <typename Func> class_& def_buffer(Func &&func) { 102311986Sandreas.sandberg@arm.com struct capture { Func func; }; 102411986Sandreas.sandberg@arm.com capture *ptr = new capture { std::forward<Func>(func) }; 102511986Sandreas.sandberg@arm.com install_buffer_funcs([](PyObject *obj, void *ptr) -> buffer_info* { 102611986Sandreas.sandberg@arm.com detail::type_caster<type> caster; 102711986Sandreas.sandberg@arm.com if (!caster.load(obj, false)) 102811986Sandreas.sandberg@arm.com return nullptr; 102911986Sandreas.sandberg@arm.com return new buffer_info(((capture *) ptr)->func(caster)); 103011986Sandreas.sandberg@arm.com }, ptr); 103111986Sandreas.sandberg@arm.com return *this; 103211986Sandreas.sandberg@arm.com } 103311986Sandreas.sandberg@arm.com 103411986Sandreas.sandberg@arm.com template <typename C, typename D, typename... Extra> 103511986Sandreas.sandberg@arm.com class_ &def_readwrite(const char *name, D C::*pm, const Extra&... extra) { 103611986Sandreas.sandberg@arm.com cpp_function fget([pm](const C &c) -> const D &{ return c.*pm; }, is_method(*this)), 103711986Sandreas.sandberg@arm.com fset([pm](C &c, const D &value) { c.*pm = value; }, is_method(*this)); 103811986Sandreas.sandberg@arm.com def_property(name, fget, fset, return_value_policy::reference_internal, extra...); 103911986Sandreas.sandberg@arm.com return *this; 104011986Sandreas.sandberg@arm.com } 104111986Sandreas.sandberg@arm.com 104211986Sandreas.sandberg@arm.com template <typename C, typename D, typename... Extra> 104311986Sandreas.sandberg@arm.com class_ &def_readonly(const char *name, const D C::*pm, const Extra& ...extra) { 104411986Sandreas.sandberg@arm.com cpp_function fget([pm](const C &c) -> const D &{ return c.*pm; }, is_method(*this)); 104511986Sandreas.sandberg@arm.com def_property_readonly(name, fget, return_value_policy::reference_internal, extra...); 104611986Sandreas.sandberg@arm.com return *this; 104711986Sandreas.sandberg@arm.com } 104811986Sandreas.sandberg@arm.com 104911986Sandreas.sandberg@arm.com template <typename D, typename... Extra> 105011986Sandreas.sandberg@arm.com class_ &def_readwrite_static(const char *name, D *pm, const Extra& ...extra) { 105111986Sandreas.sandberg@arm.com cpp_function fget([pm](object) -> const D &{ return *pm; }, scope(*this)), 105211986Sandreas.sandberg@arm.com fset([pm](object, const D &value) { *pm = value; }, scope(*this)); 105311986Sandreas.sandberg@arm.com def_property_static(name, fget, fset, return_value_policy::reference, extra...); 105411986Sandreas.sandberg@arm.com return *this; 105511986Sandreas.sandberg@arm.com } 105611986Sandreas.sandberg@arm.com 105711986Sandreas.sandberg@arm.com template <typename D, typename... Extra> 105811986Sandreas.sandberg@arm.com class_ &def_readonly_static(const char *name, const D *pm, const Extra& ...extra) { 105911986Sandreas.sandberg@arm.com cpp_function fget([pm](object) -> const D &{ return *pm; }, scope(*this)); 106011986Sandreas.sandberg@arm.com def_property_readonly_static(name, fget, return_value_policy::reference, extra...); 106111986Sandreas.sandberg@arm.com return *this; 106211986Sandreas.sandberg@arm.com } 106311986Sandreas.sandberg@arm.com 106411986Sandreas.sandberg@arm.com /// Uses return_value_policy::reference_internal by default 106511986Sandreas.sandberg@arm.com template <typename Getter, typename... Extra> 106611986Sandreas.sandberg@arm.com class_ &def_property_readonly(const char *name, const Getter &fget, const Extra& ...extra) { 106711986Sandreas.sandberg@arm.com return def_property_readonly(name, cpp_function(fget), return_value_policy::reference_internal, extra...); 106811986Sandreas.sandberg@arm.com } 106911986Sandreas.sandberg@arm.com 107011986Sandreas.sandberg@arm.com /// Uses cpp_function's return_value_policy by default 107111986Sandreas.sandberg@arm.com template <typename... Extra> 107211986Sandreas.sandberg@arm.com class_ &def_property_readonly(const char *name, const cpp_function &fget, const Extra& ...extra) { 107311986Sandreas.sandberg@arm.com return def_property(name, fget, cpp_function(), extra...); 107411986Sandreas.sandberg@arm.com } 107511986Sandreas.sandberg@arm.com 107611986Sandreas.sandberg@arm.com /// Uses return_value_policy::reference by default 107711986Sandreas.sandberg@arm.com template <typename Getter, typename... Extra> 107811986Sandreas.sandberg@arm.com class_ &def_property_readonly_static(const char *name, const Getter &fget, const Extra& ...extra) { 107911986Sandreas.sandberg@arm.com return def_property_readonly_static(name, cpp_function(fget), return_value_policy::reference, extra...); 108011986Sandreas.sandberg@arm.com } 108111986Sandreas.sandberg@arm.com 108211986Sandreas.sandberg@arm.com /// Uses cpp_function's return_value_policy by default 108311986Sandreas.sandberg@arm.com template <typename... Extra> 108411986Sandreas.sandberg@arm.com class_ &def_property_readonly_static(const char *name, const cpp_function &fget, const Extra& ...extra) { 108511986Sandreas.sandberg@arm.com return def_property_static(name, fget, cpp_function(), extra...); 108611986Sandreas.sandberg@arm.com } 108711986Sandreas.sandberg@arm.com 108811986Sandreas.sandberg@arm.com /// Uses return_value_policy::reference_internal by default 108911986Sandreas.sandberg@arm.com template <typename Getter, typename... Extra> 109011986Sandreas.sandberg@arm.com class_ &def_property(const char *name, const Getter &fget, const cpp_function &fset, const Extra& ...extra) { 109111986Sandreas.sandberg@arm.com return def_property(name, cpp_function(fget), fset, return_value_policy::reference_internal, extra...); 109211986Sandreas.sandberg@arm.com } 109311986Sandreas.sandberg@arm.com 109411986Sandreas.sandberg@arm.com /// Uses cpp_function's return_value_policy by default 109511986Sandreas.sandberg@arm.com template <typename... Extra> 109611986Sandreas.sandberg@arm.com class_ &def_property(const char *name, const cpp_function &fget, const cpp_function &fset, const Extra& ...extra) { 109711986Sandreas.sandberg@arm.com return def_property_static(name, fget, fset, is_method(*this), extra...); 109811986Sandreas.sandberg@arm.com } 109911986Sandreas.sandberg@arm.com 110011986Sandreas.sandberg@arm.com /// Uses return_value_policy::reference by default 110111986Sandreas.sandberg@arm.com template <typename Getter, typename... Extra> 110211986Sandreas.sandberg@arm.com class_ &def_property_static(const char *name, const Getter &fget, const cpp_function &fset, const Extra& ...extra) { 110311986Sandreas.sandberg@arm.com return def_property_static(name, cpp_function(fget), fset, return_value_policy::reference, extra...); 110411986Sandreas.sandberg@arm.com } 110511986Sandreas.sandberg@arm.com 110611986Sandreas.sandberg@arm.com /// Uses cpp_function's return_value_policy by default 110711986Sandreas.sandberg@arm.com template <typename... Extra> 110811986Sandreas.sandberg@arm.com class_ &def_property_static(const char *name, const cpp_function &fget, const cpp_function &fset, const Extra& ...extra) { 110911986Sandreas.sandberg@arm.com auto rec_fget = get_function_record(fget), rec_fset = get_function_record(fset); 111011986Sandreas.sandberg@arm.com char *doc_prev = rec_fget->doc; /* 'extra' field may include a property-specific documentation string */ 111111986Sandreas.sandberg@arm.com detail::process_attributes<Extra...>::init(extra..., rec_fget); 111211986Sandreas.sandberg@arm.com if (rec_fget->doc && rec_fget->doc != doc_prev) { 111311986Sandreas.sandberg@arm.com free(doc_prev); 111411986Sandreas.sandberg@arm.com rec_fget->doc = strdup(rec_fget->doc); 111511986Sandreas.sandberg@arm.com } 111611986Sandreas.sandberg@arm.com if (rec_fset) { 111711986Sandreas.sandberg@arm.com doc_prev = rec_fset->doc; 111811986Sandreas.sandberg@arm.com detail::process_attributes<Extra...>::init(extra..., rec_fset); 111911986Sandreas.sandberg@arm.com if (rec_fset->doc && rec_fset->doc != doc_prev) { 112011986Sandreas.sandberg@arm.com free(doc_prev); 112111986Sandreas.sandberg@arm.com rec_fset->doc = strdup(rec_fset->doc); 112211986Sandreas.sandberg@arm.com } 112311986Sandreas.sandberg@arm.com } 112411986Sandreas.sandberg@arm.com pybind11::str doc_obj = pybind11::str((rec_fget->doc && pybind11::options::show_user_defined_docstrings()) ? rec_fget->doc : ""); 112511986Sandreas.sandberg@arm.com const auto property = reinterpret_steal<object>( 112611986Sandreas.sandberg@arm.com PyObject_CallFunctionObjArgs((PyObject *) &PyProperty_Type, fget.ptr() ? fget.ptr() : Py_None, 112711986Sandreas.sandberg@arm.com fset.ptr() ? fset.ptr() : Py_None, Py_None, doc_obj.ptr(), nullptr)); 112811986Sandreas.sandberg@arm.com if (rec_fget->is_method && rec_fget->scope) 112911986Sandreas.sandberg@arm.com attr(name) = property; 113011986Sandreas.sandberg@arm.com else 113111986Sandreas.sandberg@arm.com metaclass().attr(name) = property; 113211986Sandreas.sandberg@arm.com return *this; 113311986Sandreas.sandberg@arm.com } 113411986Sandreas.sandberg@arm.com 113511986Sandreas.sandberg@arm.comprivate: 113611986Sandreas.sandberg@arm.com /// Initialize holder object, variant 1: object derives from enable_shared_from_this 113711986Sandreas.sandberg@arm.com template <typename T> 113811986Sandreas.sandberg@arm.com static void init_holder_helper(instance_type *inst, const holder_type * /* unused */, const std::enable_shared_from_this<T> * /* dummy */) { 113911986Sandreas.sandberg@arm.com try { 114011986Sandreas.sandberg@arm.com new (&inst->holder) holder_type(std::static_pointer_cast<typename holder_type::element_type>(inst->value->shared_from_this())); 114111986Sandreas.sandberg@arm.com inst->holder_constructed = true; 114211986Sandreas.sandberg@arm.com } catch (const std::bad_weak_ptr &) { 114311986Sandreas.sandberg@arm.com if (inst->owned) { 114411986Sandreas.sandberg@arm.com new (&inst->holder) holder_type(inst->value); 114511986Sandreas.sandberg@arm.com inst->holder_constructed = true; 114611986Sandreas.sandberg@arm.com } 114711986Sandreas.sandberg@arm.com } 114811986Sandreas.sandberg@arm.com } 114911986Sandreas.sandberg@arm.com 115011986Sandreas.sandberg@arm.com /// Initialize holder object, variant 2: try to construct from existing holder object, if possible 115111986Sandreas.sandberg@arm.com template <typename T = holder_type, 115211986Sandreas.sandberg@arm.com detail::enable_if_t<std::is_copy_constructible<T>::value, int> = 0> 115311986Sandreas.sandberg@arm.com static void init_holder_helper(instance_type *inst, const holder_type *holder_ptr, const void * /* dummy */) { 115411986Sandreas.sandberg@arm.com if (holder_ptr) { 115511986Sandreas.sandberg@arm.com new (&inst->holder) holder_type(*holder_ptr); 115611986Sandreas.sandberg@arm.com inst->holder_constructed = true; 115711986Sandreas.sandberg@arm.com } else if (inst->owned) { 115811986Sandreas.sandberg@arm.com new (&inst->holder) holder_type(inst->value); 115911986Sandreas.sandberg@arm.com inst->holder_constructed = true; 116011986Sandreas.sandberg@arm.com } 116111986Sandreas.sandberg@arm.com } 116211986Sandreas.sandberg@arm.com 116311986Sandreas.sandberg@arm.com /// Initialize holder object, variant 3: holder is not copy constructible (e.g. unique_ptr), always initialize from raw pointer 116411986Sandreas.sandberg@arm.com template <typename T = holder_type, 116511986Sandreas.sandberg@arm.com detail::enable_if_t<!std::is_copy_constructible<T>::value, int> = 0> 116611986Sandreas.sandberg@arm.com static void init_holder_helper(instance_type *inst, const holder_type * /* unused */, const void * /* dummy */) { 116711986Sandreas.sandberg@arm.com if (inst->owned) { 116811986Sandreas.sandberg@arm.com new (&inst->holder) holder_type(inst->value); 116911986Sandreas.sandberg@arm.com inst->holder_constructed = true; 117011986Sandreas.sandberg@arm.com } 117111986Sandreas.sandberg@arm.com } 117211986Sandreas.sandberg@arm.com 117311986Sandreas.sandberg@arm.com /// Initialize holder object of an instance, possibly given a pointer to an existing holder 117411986Sandreas.sandberg@arm.com static void init_holder(PyObject *inst_, const void *holder_ptr) { 117511986Sandreas.sandberg@arm.com auto inst = (instance_type *) inst_; 117611986Sandreas.sandberg@arm.com init_holder_helper(inst, (const holder_type *) holder_ptr, inst->value); 117711986Sandreas.sandberg@arm.com } 117811986Sandreas.sandberg@arm.com 117911986Sandreas.sandberg@arm.com static void dealloc(PyObject *inst_) { 118011986Sandreas.sandberg@arm.com instance_type *inst = (instance_type *) inst_; 118111986Sandreas.sandberg@arm.com if (inst->holder_constructed) 118211986Sandreas.sandberg@arm.com inst->holder.~holder_type(); 118311986Sandreas.sandberg@arm.com else if (inst->owned) 118411986Sandreas.sandberg@arm.com ::operator delete(inst->value); 118511986Sandreas.sandberg@arm.com 118611986Sandreas.sandberg@arm.com generic_type::dealloc((detail::instance<void> *) inst); 118711986Sandreas.sandberg@arm.com } 118811986Sandreas.sandberg@arm.com 118911986Sandreas.sandberg@arm.com static detail::function_record *get_function_record(handle h) { 119011986Sandreas.sandberg@arm.com h = detail::get_function(h); 119111986Sandreas.sandberg@arm.com return h ? (detail::function_record *) reinterpret_borrow<capsule>(PyCFunction_GetSelf(h.ptr())) 119211986Sandreas.sandberg@arm.com : nullptr; 119311986Sandreas.sandberg@arm.com } 119411986Sandreas.sandberg@arm.com}; 119511986Sandreas.sandberg@arm.com 119611986Sandreas.sandberg@arm.com/// Binds C++ enumerations and enumeration classes to Python 119711986Sandreas.sandberg@arm.comtemplate <typename Type> class enum_ : public class_<Type> { 119811986Sandreas.sandberg@arm.compublic: 119911986Sandreas.sandberg@arm.com using class_<Type>::def; 120011986Sandreas.sandberg@arm.com using Scalar = typename std::underlying_type<Type>::type; 120111986Sandreas.sandberg@arm.com template <typename T> using arithmetic_tag = std::is_same<T, arithmetic>; 120211986Sandreas.sandberg@arm.com 120311986Sandreas.sandberg@arm.com template <typename... Extra> 120411986Sandreas.sandberg@arm.com enum_(const handle &scope, const char *name, const Extra&... extra) 120511986Sandreas.sandberg@arm.com : class_<Type>(scope, name, extra...), m_parent(scope) { 120611986Sandreas.sandberg@arm.com 120711986Sandreas.sandberg@arm.com constexpr bool is_arithmetic = 120811986Sandreas.sandberg@arm.com !std::is_same<detail::first_of_t<arithmetic_tag, void, Extra...>, 120911986Sandreas.sandberg@arm.com void>::value; 121011986Sandreas.sandberg@arm.com 121111986Sandreas.sandberg@arm.com auto entries = new std::unordered_map<Scalar, const char *>(); 121211986Sandreas.sandberg@arm.com def("__repr__", [name, entries](Type value) -> std::string { 121311986Sandreas.sandberg@arm.com auto it = entries->find((Scalar) value); 121411986Sandreas.sandberg@arm.com return std::string(name) + "." + 121511986Sandreas.sandberg@arm.com ((it == entries->end()) ? std::string("???") 121611986Sandreas.sandberg@arm.com : std::string(it->second)); 121711986Sandreas.sandberg@arm.com }); 121811986Sandreas.sandberg@arm.com def("__init__", [](Type& value, Scalar i) { value = (Type)i; }); 121911986Sandreas.sandberg@arm.com def("__init__", [](Type& value, Scalar i) { new (&value) Type((Type) i); }); 122011986Sandreas.sandberg@arm.com def("__int__", [](Type value) { return (Scalar) value; }); 122111986Sandreas.sandberg@arm.com def("__eq__", [](const Type &value, Type *value2) { return value2 && value == *value2; }); 122211986Sandreas.sandberg@arm.com def("__ne__", [](const Type &value, Type *value2) { return !value2 || value != *value2; }); 122311986Sandreas.sandberg@arm.com if (is_arithmetic) { 122411986Sandreas.sandberg@arm.com def("__lt__", [](const Type &value, Type *value2) { return value2 && value < *value2; }); 122511986Sandreas.sandberg@arm.com def("__gt__", [](const Type &value, Type *value2) { return value2 && value > *value2; }); 122611986Sandreas.sandberg@arm.com def("__le__", [](const Type &value, Type *value2) { return value2 && value <= *value2; }); 122711986Sandreas.sandberg@arm.com def("__ge__", [](const Type &value, Type *value2) { return value2 && value >= *value2; }); 122811986Sandreas.sandberg@arm.com } 122911986Sandreas.sandberg@arm.com if (std::is_convertible<Type, Scalar>::value) { 123011986Sandreas.sandberg@arm.com // Don't provide comparison with the underlying type if the enum isn't convertible, 123111986Sandreas.sandberg@arm.com // i.e. if Type is a scoped enum, mirroring the C++ behaviour. (NB: we explicitly 123211986Sandreas.sandberg@arm.com // convert Type to Scalar below anyway because this needs to compile). 123311986Sandreas.sandberg@arm.com def("__eq__", [](const Type &value, Scalar value2) { return (Scalar) value == value2; }); 123411986Sandreas.sandberg@arm.com def("__ne__", [](const Type &value, Scalar value2) { return (Scalar) value != value2; }); 123511986Sandreas.sandberg@arm.com if (is_arithmetic) { 123611986Sandreas.sandberg@arm.com def("__lt__", [](const Type &value, Scalar value2) { return (Scalar) value < value2; }); 123711986Sandreas.sandberg@arm.com def("__gt__", [](const Type &value, Scalar value2) { return (Scalar) value > value2; }); 123811986Sandreas.sandberg@arm.com def("__le__", [](const Type &value, Scalar value2) { return (Scalar) value <= value2; }); 123911986Sandreas.sandberg@arm.com def("__ge__", [](const Type &value, Scalar value2) { return (Scalar) value >= value2; }); 124011986Sandreas.sandberg@arm.com def("__invert__", [](const Type &value) { return ~((Scalar) value); }); 124111986Sandreas.sandberg@arm.com def("__and__", [](const Type &value, Scalar value2) { return (Scalar) value & value2; }); 124211986Sandreas.sandberg@arm.com def("__or__", [](const Type &value, Scalar value2) { return (Scalar) value | value2; }); 124311986Sandreas.sandberg@arm.com def("__xor__", [](const Type &value, Scalar value2) { return (Scalar) value ^ value2; }); 124411986Sandreas.sandberg@arm.com def("__rand__", [](const Type &value, Scalar value2) { return (Scalar) value & value2; }); 124511986Sandreas.sandberg@arm.com def("__ror__", [](const Type &value, Scalar value2) { return (Scalar) value | value2; }); 124611986Sandreas.sandberg@arm.com def("__rxor__", [](const Type &value, Scalar value2) { return (Scalar) value ^ value2; }); 124711986Sandreas.sandberg@arm.com def("__and__", [](const Type &value, const Type &value2) { return (Scalar) value & (Scalar) value2; }); 124811986Sandreas.sandberg@arm.com def("__or__", [](const Type &value, const Type &value2) { return (Scalar) value | (Scalar) value2; }); 124911986Sandreas.sandberg@arm.com def("__xor__", [](const Type &value, const Type &value2) { return (Scalar) value ^ (Scalar) value2; }); 125011986Sandreas.sandberg@arm.com } 125111986Sandreas.sandberg@arm.com } 125211986Sandreas.sandberg@arm.com def("__hash__", [](const Type &value) { return (Scalar) value; }); 125311986Sandreas.sandberg@arm.com // Pickling and unpickling -- needed for use with the 'multiprocessing' module 125411986Sandreas.sandberg@arm.com def("__getstate__", [](const Type &value) { return pybind11::make_tuple((Scalar) value); }); 125511986Sandreas.sandberg@arm.com def("__setstate__", [](Type &p, tuple t) { new (&p) Type((Type) t[0].cast<Scalar>()); }); 125611986Sandreas.sandberg@arm.com m_entries = entries; 125711986Sandreas.sandberg@arm.com } 125811986Sandreas.sandberg@arm.com 125911986Sandreas.sandberg@arm.com /// Export enumeration entries into the parent scope 126011986Sandreas.sandberg@arm.com enum_ &export_values() { 126111986Sandreas.sandberg@arm.com PyObject *dict = ((PyTypeObject *) this->m_ptr)->tp_dict; 126211986Sandreas.sandberg@arm.com PyObject *key, *value; 126311986Sandreas.sandberg@arm.com ssize_t pos = 0; 126411986Sandreas.sandberg@arm.com while (PyDict_Next(dict, &pos, &key, &value)) 126511986Sandreas.sandberg@arm.com if (PyObject_IsInstance(value, this->m_ptr)) 126611986Sandreas.sandberg@arm.com m_parent.attr(key) = value; 126711986Sandreas.sandberg@arm.com return *this; 126811986Sandreas.sandberg@arm.com } 126911986Sandreas.sandberg@arm.com 127011986Sandreas.sandberg@arm.com /// Add an enumeration entry 127111986Sandreas.sandberg@arm.com enum_& value(char const* name, Type value) { 127211986Sandreas.sandberg@arm.com this->attr(name) = pybind11::cast(value, return_value_policy::copy); 127311986Sandreas.sandberg@arm.com (*m_entries)[(Scalar) value] = name; 127411986Sandreas.sandberg@arm.com return *this; 127511986Sandreas.sandberg@arm.com } 127611986Sandreas.sandberg@arm.comprivate: 127711986Sandreas.sandberg@arm.com std::unordered_map<Scalar, const char *> *m_entries; 127811986Sandreas.sandberg@arm.com handle m_parent; 127911986Sandreas.sandberg@arm.com}; 128011986Sandreas.sandberg@arm.com 128111986Sandreas.sandberg@arm.comNAMESPACE_BEGIN(detail) 128211986Sandreas.sandberg@arm.comtemplate <typename... Args> struct init { 128311986Sandreas.sandberg@arm.com template <typename Class, typename... Extra, enable_if_t<!Class::has_alias, int> = 0> 128411986Sandreas.sandberg@arm.com static void execute(Class &cl, const Extra&... extra) { 128511986Sandreas.sandberg@arm.com using Base = typename Class::type; 128611986Sandreas.sandberg@arm.com /// Function which calls a specific C++ in-place constructor 128711986Sandreas.sandberg@arm.com cl.def("__init__", [](Base *self_, Args... args) { new (self_) Base(args...); }, extra...); 128811986Sandreas.sandberg@arm.com } 128911986Sandreas.sandberg@arm.com 129011986Sandreas.sandberg@arm.com template <typename Class, typename... Extra, 129111986Sandreas.sandberg@arm.com enable_if_t<Class::has_alias && 129211986Sandreas.sandberg@arm.com std::is_constructible<typename Class::type, Args...>::value, int> = 0> 129311986Sandreas.sandberg@arm.com static void execute(Class &cl, const Extra&... extra) { 129411986Sandreas.sandberg@arm.com using Base = typename Class::type; 129511986Sandreas.sandberg@arm.com using Alias = typename Class::type_alias; 129611986Sandreas.sandberg@arm.com handle cl_type = cl; 129711986Sandreas.sandberg@arm.com cl.def("__init__", [cl_type](handle self_, Args... args) { 129811986Sandreas.sandberg@arm.com if (self_.get_type() == cl_type) 129911986Sandreas.sandberg@arm.com new (self_.cast<Base *>()) Base(args...); 130011986Sandreas.sandberg@arm.com else 130111986Sandreas.sandberg@arm.com new (self_.cast<Alias *>()) Alias(args...); 130211986Sandreas.sandberg@arm.com }, extra...); 130311986Sandreas.sandberg@arm.com } 130411986Sandreas.sandberg@arm.com 130511986Sandreas.sandberg@arm.com template <typename Class, typename... Extra, 130611986Sandreas.sandberg@arm.com enable_if_t<Class::has_alias && 130711986Sandreas.sandberg@arm.com !std::is_constructible<typename Class::type, Args...>::value, int> = 0> 130811986Sandreas.sandberg@arm.com static void execute(Class &cl, const Extra&... extra) { 130911986Sandreas.sandberg@arm.com init_alias<Args...>::execute(cl, extra...); 131011986Sandreas.sandberg@arm.com } 131111986Sandreas.sandberg@arm.com}; 131211986Sandreas.sandberg@arm.comtemplate <typename... Args> struct init_alias { 131311986Sandreas.sandberg@arm.com template <typename Class, typename... Extra, 131411986Sandreas.sandberg@arm.com enable_if_t<Class::has_alias && std::is_constructible<typename Class::type_alias, Args...>::value, int> = 0> 131511986Sandreas.sandberg@arm.com static void execute(Class &cl, const Extra&... extra) { 131611986Sandreas.sandberg@arm.com using Alias = typename Class::type_alias; 131711986Sandreas.sandberg@arm.com cl.def("__init__", [](Alias *self_, Args... args) { new (self_) Alias(args...); }, extra...); 131811986Sandreas.sandberg@arm.com } 131911986Sandreas.sandberg@arm.com}; 132011986Sandreas.sandberg@arm.com 132111986Sandreas.sandberg@arm.com 132211986Sandreas.sandberg@arm.cominline void keep_alive_impl(handle nurse, handle patient) { 132311986Sandreas.sandberg@arm.com /* Clever approach based on weak references taken from Boost.Python */ 132411986Sandreas.sandberg@arm.com if (!nurse || !patient) 132511986Sandreas.sandberg@arm.com pybind11_fail("Could not activate keep_alive!"); 132611986Sandreas.sandberg@arm.com 132711986Sandreas.sandberg@arm.com if (patient.is_none() || nurse.is_none()) 132811986Sandreas.sandberg@arm.com return; /* Nothing to keep alive or nothing to be kept alive by */ 132911986Sandreas.sandberg@arm.com 133011986Sandreas.sandberg@arm.com cpp_function disable_lifesupport( 133111986Sandreas.sandberg@arm.com [patient](handle weakref) { patient.dec_ref(); weakref.dec_ref(); }); 133211986Sandreas.sandberg@arm.com 133311986Sandreas.sandberg@arm.com weakref wr(nurse, disable_lifesupport); 133411986Sandreas.sandberg@arm.com 133511986Sandreas.sandberg@arm.com patient.inc_ref(); /* reference patient and leak the weak reference */ 133611986Sandreas.sandberg@arm.com (void) wr.release(); 133711986Sandreas.sandberg@arm.com} 133811986Sandreas.sandberg@arm.com 133911986Sandreas.sandberg@arm.comPYBIND11_NOINLINE inline void keep_alive_impl(int Nurse, int Patient, handle args, handle ret) { 134011986Sandreas.sandberg@arm.com handle nurse (Nurse > 0 ? PyTuple_GetItem(args.ptr(), Nurse - 1) : ret.ptr()); 134111986Sandreas.sandberg@arm.com handle patient(Patient > 0 ? PyTuple_GetItem(args.ptr(), Patient - 1) : ret.ptr()); 134211986Sandreas.sandberg@arm.com 134311986Sandreas.sandberg@arm.com keep_alive_impl(nurse, patient); 134411986Sandreas.sandberg@arm.com} 134511986Sandreas.sandberg@arm.com 134611986Sandreas.sandberg@arm.comtemplate <typename Iterator, typename Sentinel, bool KeyIterator, return_value_policy Policy> 134711986Sandreas.sandberg@arm.comstruct iterator_state { 134811986Sandreas.sandberg@arm.com Iterator it; 134911986Sandreas.sandberg@arm.com Sentinel end; 135011986Sandreas.sandberg@arm.com bool first; 135111986Sandreas.sandberg@arm.com}; 135211986Sandreas.sandberg@arm.com 135311986Sandreas.sandberg@arm.comNAMESPACE_END(detail) 135411986Sandreas.sandberg@arm.com 135511986Sandreas.sandberg@arm.comtemplate <typename... Args> detail::init<Args...> init() { return detail::init<Args...>(); } 135611986Sandreas.sandberg@arm.comtemplate <typename... Args> detail::init_alias<Args...> init_alias() { return detail::init_alias<Args...>(); } 135711986Sandreas.sandberg@arm.com 135811986Sandreas.sandberg@arm.comtemplate <return_value_policy Policy = return_value_policy::reference_internal, 135911986Sandreas.sandberg@arm.com typename Iterator, 136011986Sandreas.sandberg@arm.com typename Sentinel, 136111986Sandreas.sandberg@arm.com typename ValueType = decltype(*std::declval<Iterator>()), 136211986Sandreas.sandberg@arm.com typename... Extra> 136311986Sandreas.sandberg@arm.comiterator make_iterator(Iterator first, Sentinel last, Extra &&... extra) { 136411986Sandreas.sandberg@arm.com typedef detail::iterator_state<Iterator, Sentinel, false, Policy> state; 136511986Sandreas.sandberg@arm.com 136611986Sandreas.sandberg@arm.com if (!detail::get_type_info(typeid(state), false)) { 136711986Sandreas.sandberg@arm.com class_<state>(handle(), "iterator") 136811986Sandreas.sandberg@arm.com .def("__iter__", [](state &s) -> state& { return s; }) 136911986Sandreas.sandberg@arm.com .def("__next__", [](state &s) -> ValueType { 137011986Sandreas.sandberg@arm.com if (!s.first) 137111986Sandreas.sandberg@arm.com ++s.it; 137211986Sandreas.sandberg@arm.com else 137311986Sandreas.sandberg@arm.com s.first = false; 137411986Sandreas.sandberg@arm.com if (s.it == s.end) 137511986Sandreas.sandberg@arm.com throw stop_iteration(); 137611986Sandreas.sandberg@arm.com return *s.it; 137711986Sandreas.sandberg@arm.com }, std::forward<Extra>(extra)..., Policy); 137811986Sandreas.sandberg@arm.com } 137911986Sandreas.sandberg@arm.com 138011986Sandreas.sandberg@arm.com return (iterator) cast(state { first, last, true }); 138111986Sandreas.sandberg@arm.com} 138211986Sandreas.sandberg@arm.com 138311986Sandreas.sandberg@arm.comtemplate <return_value_policy Policy = return_value_policy::reference_internal, 138411986Sandreas.sandberg@arm.com typename Iterator, 138511986Sandreas.sandberg@arm.com typename Sentinel, 138611986Sandreas.sandberg@arm.com typename KeyType = decltype((*std::declval<Iterator>()).first), 138711986Sandreas.sandberg@arm.com typename... Extra> 138811986Sandreas.sandberg@arm.comiterator make_key_iterator(Iterator first, Sentinel last, Extra &&... extra) { 138911986Sandreas.sandberg@arm.com typedef detail::iterator_state<Iterator, Sentinel, true, Policy> state; 139011986Sandreas.sandberg@arm.com 139111986Sandreas.sandberg@arm.com if (!detail::get_type_info(typeid(state), false)) { 139211986Sandreas.sandberg@arm.com class_<state>(handle(), "iterator") 139311986Sandreas.sandberg@arm.com .def("__iter__", [](state &s) -> state& { return s; }) 139411986Sandreas.sandberg@arm.com .def("__next__", [](state &s) -> KeyType { 139511986Sandreas.sandberg@arm.com if (!s.first) 139611986Sandreas.sandberg@arm.com ++s.it; 139711986Sandreas.sandberg@arm.com else 139811986Sandreas.sandberg@arm.com s.first = false; 139911986Sandreas.sandberg@arm.com if (s.it == s.end) 140011986Sandreas.sandberg@arm.com throw stop_iteration(); 140111986Sandreas.sandberg@arm.com return (*s.it).first; 140211986Sandreas.sandberg@arm.com }, std::forward<Extra>(extra)..., Policy); 140311986Sandreas.sandberg@arm.com } 140411986Sandreas.sandberg@arm.com 140511986Sandreas.sandberg@arm.com return (iterator) cast(state { first, last, true }); 140611986Sandreas.sandberg@arm.com} 140711986Sandreas.sandberg@arm.com 140811986Sandreas.sandberg@arm.comtemplate <return_value_policy Policy = return_value_policy::reference_internal, 140911986Sandreas.sandberg@arm.com typename Type, typename... Extra> iterator make_iterator(Type &value, Extra&&... extra) { 141011986Sandreas.sandberg@arm.com return make_iterator<Policy>(std::begin(value), std::end(value), extra...); 141111986Sandreas.sandberg@arm.com} 141211986Sandreas.sandberg@arm.com 141311986Sandreas.sandberg@arm.comtemplate <return_value_policy Policy = return_value_policy::reference_internal, 141411986Sandreas.sandberg@arm.com typename Type, typename... Extra> iterator make_key_iterator(Type &value, Extra&&... extra) { 141511986Sandreas.sandberg@arm.com return make_key_iterator<Policy>(std::begin(value), std::end(value), extra...); 141611986Sandreas.sandberg@arm.com} 141711986Sandreas.sandberg@arm.com 141811986Sandreas.sandberg@arm.comtemplate <typename InputType, typename OutputType> void implicitly_convertible() { 141911986Sandreas.sandberg@arm.com auto implicit_caster = [](PyObject *obj, PyTypeObject *type) -> PyObject * { 142011986Sandreas.sandberg@arm.com if (!detail::type_caster<InputType>().load(obj, false)) 142111986Sandreas.sandberg@arm.com return nullptr; 142211986Sandreas.sandberg@arm.com tuple args(1); 142311986Sandreas.sandberg@arm.com args[0] = obj; 142411986Sandreas.sandberg@arm.com PyObject *result = PyObject_Call((PyObject *) type, args.ptr(), nullptr); 142511986Sandreas.sandberg@arm.com if (result == nullptr) 142611986Sandreas.sandberg@arm.com PyErr_Clear(); 142711986Sandreas.sandberg@arm.com return result; 142811986Sandreas.sandberg@arm.com }; 142911986Sandreas.sandberg@arm.com 143011986Sandreas.sandberg@arm.com if (auto tinfo = detail::get_type_info(typeid(OutputType))) 143111986Sandreas.sandberg@arm.com tinfo->implicit_conversions.push_back(implicit_caster); 143211986Sandreas.sandberg@arm.com else 143311986Sandreas.sandberg@arm.com pybind11_fail("implicitly_convertible: Unable to find type " + type_id<OutputType>()); 143411986Sandreas.sandberg@arm.com} 143511986Sandreas.sandberg@arm.com 143611986Sandreas.sandberg@arm.comtemplate <typename ExceptionTranslator> 143711986Sandreas.sandberg@arm.comvoid register_exception_translator(ExceptionTranslator&& translator) { 143811986Sandreas.sandberg@arm.com detail::get_internals().registered_exception_translators.push_front( 143911986Sandreas.sandberg@arm.com std::forward<ExceptionTranslator>(translator)); 144011986Sandreas.sandberg@arm.com} 144111986Sandreas.sandberg@arm.com 144211986Sandreas.sandberg@arm.com/* Wrapper to generate a new Python exception type. 144311986Sandreas.sandberg@arm.com * 144411986Sandreas.sandberg@arm.com * This should only be used with PyErr_SetString for now. 144511986Sandreas.sandberg@arm.com * It is not (yet) possible to use as a py::base. 144611986Sandreas.sandberg@arm.com * Template type argument is reserved for future use. 144711986Sandreas.sandberg@arm.com */ 144811986Sandreas.sandberg@arm.comtemplate <typename type> 144911986Sandreas.sandberg@arm.comclass exception : public object { 145011986Sandreas.sandberg@arm.compublic: 145111986Sandreas.sandberg@arm.com exception(handle scope, const char *name, PyObject *base = PyExc_Exception) { 145211986Sandreas.sandberg@arm.com std::string full_name = scope.attr("__name__").cast<std::string>() + 145311986Sandreas.sandberg@arm.com std::string(".") + name; 145411986Sandreas.sandberg@arm.com m_ptr = PyErr_NewException((char *) full_name.c_str(), base, NULL); 145511986Sandreas.sandberg@arm.com if (hasattr(scope, name)) 145611986Sandreas.sandberg@arm.com pybind11_fail("Error during initialization: multiple incompatible " 145711986Sandreas.sandberg@arm.com "definitions with name \"" + std::string(name) + "\""); 145811986Sandreas.sandberg@arm.com scope.attr(name) = *this; 145911986Sandreas.sandberg@arm.com } 146011986Sandreas.sandberg@arm.com 146111986Sandreas.sandberg@arm.com // Sets the current python exception to this exception object with the given message 146211986Sandreas.sandberg@arm.com void operator()(const char *message) { 146311986Sandreas.sandberg@arm.com PyErr_SetString(m_ptr, message); 146411986Sandreas.sandberg@arm.com } 146511986Sandreas.sandberg@arm.com}; 146611986Sandreas.sandberg@arm.com 146711986Sandreas.sandberg@arm.com/** Registers a Python exception in `m` of the given `name` and installs an exception translator to 146811986Sandreas.sandberg@arm.com * translate the C++ exception to the created Python exception using the exceptions what() method. 146911986Sandreas.sandberg@arm.com * This is intended for simple exception translations; for more complex translation, register the 147011986Sandreas.sandberg@arm.com * exception object and translator directly. 147111986Sandreas.sandberg@arm.com */ 147211986Sandreas.sandberg@arm.comtemplate <typename CppException> 147311986Sandreas.sandberg@arm.comexception<CppException> ®ister_exception(handle scope, 147411986Sandreas.sandberg@arm.com const char *name, 147511986Sandreas.sandberg@arm.com PyObject *base = PyExc_Exception) { 147611986Sandreas.sandberg@arm.com static exception<CppException> ex(scope, name, base); 147711986Sandreas.sandberg@arm.com register_exception_translator([](std::exception_ptr p) { 147811986Sandreas.sandberg@arm.com if (!p) return; 147911986Sandreas.sandberg@arm.com try { 148011986Sandreas.sandberg@arm.com std::rethrow_exception(p); 148111986Sandreas.sandberg@arm.com } catch (const CppException &e) { 148211986Sandreas.sandberg@arm.com ex(e.what()); 148311986Sandreas.sandberg@arm.com } 148411986Sandreas.sandberg@arm.com }); 148511986Sandreas.sandberg@arm.com return ex; 148611986Sandreas.sandberg@arm.com} 148711986Sandreas.sandberg@arm.com 148811986Sandreas.sandberg@arm.comNAMESPACE_BEGIN(detail) 148911986Sandreas.sandberg@arm.comPYBIND11_NOINLINE inline void print(tuple args, dict kwargs) { 149011986Sandreas.sandberg@arm.com auto strings = tuple(args.size()); 149111986Sandreas.sandberg@arm.com for (size_t i = 0; i < args.size(); ++i) { 149211986Sandreas.sandberg@arm.com strings[i] = str(args[i]); 149311986Sandreas.sandberg@arm.com } 149411986Sandreas.sandberg@arm.com auto sep = kwargs.contains("sep") ? kwargs["sep"] : cast(" "); 149511986Sandreas.sandberg@arm.com auto line = sep.attr("join")(strings); 149611986Sandreas.sandberg@arm.com 149711986Sandreas.sandberg@arm.com object file; 149811986Sandreas.sandberg@arm.com if (kwargs.contains("file")) { 149911986Sandreas.sandberg@arm.com file = kwargs["file"].cast<object>(); 150011986Sandreas.sandberg@arm.com } else { 150111986Sandreas.sandberg@arm.com try { 150211986Sandreas.sandberg@arm.com file = module::import("sys").attr("stdout"); 150311986Sandreas.sandberg@arm.com } catch (const error_already_set &) { 150411986Sandreas.sandberg@arm.com /* If print() is called from code that is executed as 150511986Sandreas.sandberg@arm.com part of garbage collection during interpreter shutdown, 150611986Sandreas.sandberg@arm.com importing 'sys' can fail. Give up rather than crashing the 150711986Sandreas.sandberg@arm.com interpreter in this case. */ 150811986Sandreas.sandberg@arm.com return; 150911986Sandreas.sandberg@arm.com } 151011986Sandreas.sandberg@arm.com } 151111986Sandreas.sandberg@arm.com 151211986Sandreas.sandberg@arm.com auto write = file.attr("write"); 151311986Sandreas.sandberg@arm.com write(line); 151411986Sandreas.sandberg@arm.com write(kwargs.contains("end") ? kwargs["end"] : cast("\n")); 151511986Sandreas.sandberg@arm.com 151611986Sandreas.sandberg@arm.com if (kwargs.contains("flush") && kwargs["flush"].cast<bool>()) 151711986Sandreas.sandberg@arm.com file.attr("flush")(); 151811986Sandreas.sandberg@arm.com} 151911986Sandreas.sandberg@arm.comNAMESPACE_END(detail) 152011986Sandreas.sandberg@arm.com 152111986Sandreas.sandberg@arm.comtemplate <return_value_policy policy = return_value_policy::automatic_reference, typename... Args> 152211986Sandreas.sandberg@arm.comvoid print(Args &&...args) { 152311986Sandreas.sandberg@arm.com auto c = detail::collect_arguments<policy>(std::forward<Args>(args)...); 152411986Sandreas.sandberg@arm.com detail::print(c.args(), c.kwargs()); 152511986Sandreas.sandberg@arm.com} 152611986Sandreas.sandberg@arm.com 152711986Sandreas.sandberg@arm.com#if defined(WITH_THREAD) 152811986Sandreas.sandberg@arm.com 152911986Sandreas.sandberg@arm.com/* The functions below essentially reproduce the PyGILState_* API using a RAII 153011986Sandreas.sandberg@arm.com * pattern, but there are a few important differences: 153111986Sandreas.sandberg@arm.com * 153211986Sandreas.sandberg@arm.com * 1. When acquiring the GIL from an non-main thread during the finalization 153311986Sandreas.sandberg@arm.com * phase, the GILState API blindly terminates the calling thread, which 153411986Sandreas.sandberg@arm.com * is often not what is wanted. This API does not do this. 153511986Sandreas.sandberg@arm.com * 153611986Sandreas.sandberg@arm.com * 2. The gil_scoped_release function can optionally cut the relationship 153711986Sandreas.sandberg@arm.com * of a PyThreadState and its associated thread, which allows moving it to 153811986Sandreas.sandberg@arm.com * another thread (this is a fairly rare/advanced use case). 153911986Sandreas.sandberg@arm.com * 154011986Sandreas.sandberg@arm.com * 3. The reference count of an acquired thread state can be controlled. This 154111986Sandreas.sandberg@arm.com * can be handy to prevent cases where callbacks issued from an external 154211986Sandreas.sandberg@arm.com * thread would otherwise constantly construct and destroy thread state data 154311986Sandreas.sandberg@arm.com * structures. 154411986Sandreas.sandberg@arm.com * 154511986Sandreas.sandberg@arm.com * See the Python bindings of NanoGUI (http://github.com/wjakob/nanogui) for an 154611986Sandreas.sandberg@arm.com * example which uses features 2 and 3 to migrate the Python thread of 154711986Sandreas.sandberg@arm.com * execution to another thread (to run the event loop on the original thread, 154811986Sandreas.sandberg@arm.com * in this case). 154911986Sandreas.sandberg@arm.com */ 155011986Sandreas.sandberg@arm.com 155111986Sandreas.sandberg@arm.comclass gil_scoped_acquire { 155211986Sandreas.sandberg@arm.compublic: 155311986Sandreas.sandberg@arm.com PYBIND11_NOINLINE gil_scoped_acquire() { 155411986Sandreas.sandberg@arm.com auto const &internals = detail::get_internals(); 155511986Sandreas.sandberg@arm.com tstate = (PyThreadState *) PyThread_get_key_value(internals.tstate); 155611986Sandreas.sandberg@arm.com 155711986Sandreas.sandberg@arm.com if (!tstate) { 155811986Sandreas.sandberg@arm.com tstate = PyThreadState_New(internals.istate); 155911986Sandreas.sandberg@arm.com #if !defined(NDEBUG) 156011986Sandreas.sandberg@arm.com if (!tstate) 156111986Sandreas.sandberg@arm.com pybind11_fail("scoped_acquire: could not create thread state!"); 156211986Sandreas.sandberg@arm.com #endif 156311986Sandreas.sandberg@arm.com tstate->gilstate_counter = 0; 156411986Sandreas.sandberg@arm.com #if PY_MAJOR_VERSION < 3 156511986Sandreas.sandberg@arm.com PyThread_delete_key_value(internals.tstate); 156611986Sandreas.sandberg@arm.com #endif 156711986Sandreas.sandberg@arm.com PyThread_set_key_value(internals.tstate, tstate); 156811986Sandreas.sandberg@arm.com } else { 156911986Sandreas.sandberg@arm.com release = detail::get_thread_state_unchecked() != tstate; 157011986Sandreas.sandberg@arm.com } 157111986Sandreas.sandberg@arm.com 157211986Sandreas.sandberg@arm.com if (release) { 157311986Sandreas.sandberg@arm.com /* Work around an annoying assertion in PyThreadState_Swap */ 157411986Sandreas.sandberg@arm.com #if defined(Py_DEBUG) 157511986Sandreas.sandberg@arm.com PyInterpreterState *interp = tstate->interp; 157611986Sandreas.sandberg@arm.com tstate->interp = nullptr; 157711986Sandreas.sandberg@arm.com #endif 157811986Sandreas.sandberg@arm.com PyEval_AcquireThread(tstate); 157911986Sandreas.sandberg@arm.com #if defined(Py_DEBUG) 158011986Sandreas.sandberg@arm.com tstate->interp = interp; 158111986Sandreas.sandberg@arm.com #endif 158211986Sandreas.sandberg@arm.com } 158311986Sandreas.sandberg@arm.com 158411986Sandreas.sandberg@arm.com inc_ref(); 158511986Sandreas.sandberg@arm.com } 158611986Sandreas.sandberg@arm.com 158711986Sandreas.sandberg@arm.com void inc_ref() { 158811986Sandreas.sandberg@arm.com ++tstate->gilstate_counter; 158911986Sandreas.sandberg@arm.com } 159011986Sandreas.sandberg@arm.com 159111986Sandreas.sandberg@arm.com PYBIND11_NOINLINE void dec_ref() { 159211986Sandreas.sandberg@arm.com --tstate->gilstate_counter; 159311986Sandreas.sandberg@arm.com #if !defined(NDEBUG) 159411986Sandreas.sandberg@arm.com if (detail::get_thread_state_unchecked() != tstate) 159511986Sandreas.sandberg@arm.com pybind11_fail("scoped_acquire::dec_ref(): thread state must be current!"); 159611986Sandreas.sandberg@arm.com if (tstate->gilstate_counter < 0) 159711986Sandreas.sandberg@arm.com pybind11_fail("scoped_acquire::dec_ref(): reference count underflow!"); 159811986Sandreas.sandberg@arm.com #endif 159911986Sandreas.sandberg@arm.com if (tstate->gilstate_counter == 0) { 160011986Sandreas.sandberg@arm.com #if !defined(NDEBUG) 160111986Sandreas.sandberg@arm.com if (!release) 160211986Sandreas.sandberg@arm.com pybind11_fail("scoped_acquire::dec_ref(): internal error!"); 160311986Sandreas.sandberg@arm.com #endif 160411986Sandreas.sandberg@arm.com PyThreadState_Clear(tstate); 160511986Sandreas.sandberg@arm.com PyThreadState_DeleteCurrent(); 160611986Sandreas.sandberg@arm.com PyThread_delete_key_value(detail::get_internals().tstate); 160711986Sandreas.sandberg@arm.com release = false; 160811986Sandreas.sandberg@arm.com } 160911986Sandreas.sandberg@arm.com } 161011986Sandreas.sandberg@arm.com 161111986Sandreas.sandberg@arm.com PYBIND11_NOINLINE ~gil_scoped_acquire() { 161211986Sandreas.sandberg@arm.com dec_ref(); 161311986Sandreas.sandberg@arm.com if (release) 161411986Sandreas.sandberg@arm.com PyEval_SaveThread(); 161511986Sandreas.sandberg@arm.com } 161611986Sandreas.sandberg@arm.comprivate: 161711986Sandreas.sandberg@arm.com PyThreadState *tstate = nullptr; 161811986Sandreas.sandberg@arm.com bool release = true; 161911986Sandreas.sandberg@arm.com}; 162011986Sandreas.sandberg@arm.com 162111986Sandreas.sandberg@arm.comclass gil_scoped_release { 162211986Sandreas.sandberg@arm.compublic: 162311986Sandreas.sandberg@arm.com explicit gil_scoped_release(bool disassoc = false) : disassoc(disassoc) { 162411986Sandreas.sandberg@arm.com tstate = PyEval_SaveThread(); 162511986Sandreas.sandberg@arm.com if (disassoc) { 162611986Sandreas.sandberg@arm.com auto key = detail::get_internals().tstate; 162711986Sandreas.sandberg@arm.com #if PY_MAJOR_VERSION < 3 162811986Sandreas.sandberg@arm.com PyThread_delete_key_value(key); 162911986Sandreas.sandberg@arm.com #else 163011986Sandreas.sandberg@arm.com PyThread_set_key_value(key, nullptr); 163111986Sandreas.sandberg@arm.com #endif 163211986Sandreas.sandberg@arm.com } 163311986Sandreas.sandberg@arm.com } 163411986Sandreas.sandberg@arm.com ~gil_scoped_release() { 163511986Sandreas.sandberg@arm.com if (!tstate) 163611986Sandreas.sandberg@arm.com return; 163711986Sandreas.sandberg@arm.com PyEval_RestoreThread(tstate); 163811986Sandreas.sandberg@arm.com if (disassoc) { 163911986Sandreas.sandberg@arm.com auto key = detail::get_internals().tstate; 164011986Sandreas.sandberg@arm.com #if PY_MAJOR_VERSION < 3 164111986Sandreas.sandberg@arm.com PyThread_delete_key_value(key); 164211986Sandreas.sandberg@arm.com #endif 164311986Sandreas.sandberg@arm.com PyThread_set_key_value(key, tstate); 164411986Sandreas.sandberg@arm.com } 164511986Sandreas.sandberg@arm.com } 164611986Sandreas.sandberg@arm.comprivate: 164711986Sandreas.sandberg@arm.com PyThreadState *tstate; 164811986Sandreas.sandberg@arm.com bool disassoc; 164911986Sandreas.sandberg@arm.com}; 165011986Sandreas.sandberg@arm.com#else 165111986Sandreas.sandberg@arm.comclass gil_scoped_acquire { }; 165211986Sandreas.sandberg@arm.comclass gil_scoped_release { }; 165311986Sandreas.sandberg@arm.com#endif 165411986Sandreas.sandberg@arm.com 165511986Sandreas.sandberg@arm.comerror_already_set::~error_already_set() { 165611986Sandreas.sandberg@arm.com if (value) { 165711986Sandreas.sandberg@arm.com gil_scoped_acquire gil; 165811986Sandreas.sandberg@arm.com PyErr_Restore(type, value, trace); 165911986Sandreas.sandberg@arm.com PyErr_Clear(); 166011986Sandreas.sandberg@arm.com } 166111986Sandreas.sandberg@arm.com} 166211986Sandreas.sandberg@arm.com 166311986Sandreas.sandberg@arm.cominline function get_type_overload(const void *this_ptr, const detail::type_info *this_type, const char *name) { 166411986Sandreas.sandberg@arm.com handle py_object = detail::get_object_handle(this_ptr, this_type); 166511986Sandreas.sandberg@arm.com if (!py_object) 166611986Sandreas.sandberg@arm.com return function(); 166711986Sandreas.sandberg@arm.com handle type = py_object.get_type(); 166811986Sandreas.sandberg@arm.com auto key = std::make_pair(type.ptr(), name); 166911986Sandreas.sandberg@arm.com 167011986Sandreas.sandberg@arm.com /* Cache functions that aren't overloaded in Python to avoid 167111986Sandreas.sandberg@arm.com many costly Python dictionary lookups below */ 167211986Sandreas.sandberg@arm.com auto &cache = detail::get_internals().inactive_overload_cache; 167311986Sandreas.sandberg@arm.com if (cache.find(key) != cache.end()) 167411986Sandreas.sandberg@arm.com return function(); 167511986Sandreas.sandberg@arm.com 167611986Sandreas.sandberg@arm.com function overload = getattr(py_object, name, function()); 167711986Sandreas.sandberg@arm.com if (overload.is_cpp_function()) { 167811986Sandreas.sandberg@arm.com cache.insert(key); 167911986Sandreas.sandberg@arm.com return function(); 168011986Sandreas.sandberg@arm.com } 168111986Sandreas.sandberg@arm.com 168211986Sandreas.sandberg@arm.com /* Don't call dispatch code if invoked from overridden function */ 168311986Sandreas.sandberg@arm.com PyFrameObject *frame = PyThreadState_Get()->frame; 168411986Sandreas.sandberg@arm.com if (frame && (std::string) str(frame->f_code->co_name) == name && 168511986Sandreas.sandberg@arm.com frame->f_code->co_argcount > 0) { 168611986Sandreas.sandberg@arm.com PyFrame_FastToLocals(frame); 168711986Sandreas.sandberg@arm.com PyObject *self_caller = PyDict_GetItem( 168811986Sandreas.sandberg@arm.com frame->f_locals, PyTuple_GET_ITEM(frame->f_code->co_varnames, 0)); 168911986Sandreas.sandberg@arm.com if (self_caller == py_object.ptr()) 169011986Sandreas.sandberg@arm.com return function(); 169111986Sandreas.sandberg@arm.com } 169211986Sandreas.sandberg@arm.com return overload; 169311986Sandreas.sandberg@arm.com} 169411986Sandreas.sandberg@arm.com 169511986Sandreas.sandberg@arm.comtemplate <class T> function get_overload(const T *this_ptr, const char *name) { 169611986Sandreas.sandberg@arm.com auto tinfo = detail::get_type_info(typeid(T)); 169711986Sandreas.sandberg@arm.com return tinfo ? get_type_overload(this_ptr, tinfo, name) : function(); 169811986Sandreas.sandberg@arm.com} 169911986Sandreas.sandberg@arm.com 170011986Sandreas.sandberg@arm.com#define PYBIND11_OVERLOAD_INT(ret_type, cname, name, ...) { \ 170111986Sandreas.sandberg@arm.com pybind11::gil_scoped_acquire gil; \ 170211986Sandreas.sandberg@arm.com pybind11::function overload = pybind11::get_overload(static_cast<const cname *>(this), name); \ 170311986Sandreas.sandberg@arm.com if (overload) { \ 170411986Sandreas.sandberg@arm.com auto o = overload(__VA_ARGS__); \ 170511986Sandreas.sandberg@arm.com if (pybind11::detail::cast_is_temporary_value_reference<ret_type>::value) { \ 170611986Sandreas.sandberg@arm.com static pybind11::detail::overload_caster_t<ret_type> caster; \ 170711986Sandreas.sandberg@arm.com return pybind11::detail::cast_ref<ret_type>(std::move(o), caster); \ 170811986Sandreas.sandberg@arm.com } \ 170911986Sandreas.sandberg@arm.com else return pybind11::detail::cast_safe<ret_type>(std::move(o)); \ 171011986Sandreas.sandberg@arm.com } \ 171111986Sandreas.sandberg@arm.com } 171211986Sandreas.sandberg@arm.com 171311986Sandreas.sandberg@arm.com#define PYBIND11_OVERLOAD_NAME(ret_type, cname, name, fn, ...) \ 171411986Sandreas.sandberg@arm.com PYBIND11_OVERLOAD_INT(ret_type, cname, name, __VA_ARGS__) \ 171511986Sandreas.sandberg@arm.com return cname::fn(__VA_ARGS__) 171611986Sandreas.sandberg@arm.com 171711986Sandreas.sandberg@arm.com#define PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, name, fn, ...) \ 171811986Sandreas.sandberg@arm.com PYBIND11_OVERLOAD_INT(ret_type, cname, name, __VA_ARGS__) \ 171911986Sandreas.sandberg@arm.com pybind11::pybind11_fail("Tried to call pure virtual function \"" #cname "::" name "\""); 172011986Sandreas.sandberg@arm.com 172111986Sandreas.sandberg@arm.com#define PYBIND11_OVERLOAD(ret_type, cname, fn, ...) \ 172211986Sandreas.sandberg@arm.com PYBIND11_OVERLOAD_NAME(ret_type, cname, #fn, fn, __VA_ARGS__) 172311986Sandreas.sandberg@arm.com 172411986Sandreas.sandberg@arm.com#define PYBIND11_OVERLOAD_PURE(ret_type, cname, fn, ...) \ 172511986Sandreas.sandberg@arm.com PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, #fn, fn, __VA_ARGS__) 172611986Sandreas.sandberg@arm.com 172711986Sandreas.sandberg@arm.comNAMESPACE_END(pybind11) 172811986Sandreas.sandberg@arm.com 172911986Sandreas.sandberg@arm.com#if defined(_MSC_VER) 173011986Sandreas.sandberg@arm.com# pragma warning(pop) 173111986Sandreas.sandberg@arm.com#elif defined(__INTEL_COMPILER) 173211986Sandreas.sandberg@arm.com/* Leave ignored warnings on */ 173311986Sandreas.sandberg@arm.com#elif defined(__GNUG__) && !defined(__clang__) 173411986Sandreas.sandberg@arm.com# pragma GCC diagnostic pop 173511986Sandreas.sandberg@arm.com#endif 1736