Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 1 | /* |
Wenzel Jakob | 8f4eb00 | 2015-10-15 18:13:33 +0200 | [diff] [blame] | 2 | pybind11/common.h -- Basic macros |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 3 | |
Wenzel Jakob | 8cb6cb3 | 2016-04-17 20:21:41 +0200 | [diff] [blame] | 4 | Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch> |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 5 | |
| 6 | All rights reserved. Use of this source code is governed by a |
| 7 | BSD-style license that can be found in the LICENSE file. |
| 8 | */ |
| 9 | |
Wenzel Jakob | bd4a529 | 2015-07-11 17:41:48 +0200 | [diff] [blame] | 10 | #pragma once |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 11 | |
| 12 | #if !defined(NAMESPACE_BEGIN) |
Wenzel Jakob | 53b2654 | 2016-01-17 22:36:43 +0100 | [diff] [blame] | 13 | # define NAMESPACE_BEGIN(name) namespace name { |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 14 | #endif |
| 15 | #if !defined(NAMESPACE_END) |
Wenzel Jakob | 53b2654 | 2016-01-17 22:36:43 +0100 | [diff] [blame] | 16 | # define NAMESPACE_END(name) } |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 17 | #endif |
| 18 | |
Wenzel Jakob | b1b7140 | 2015-10-18 16:48:30 +0200 | [diff] [blame] | 19 | #if !defined(PYBIND11_EXPORT) |
Wenzel Jakob | 53b2654 | 2016-01-17 22:36:43 +0100 | [diff] [blame] | 20 | # if defined(WIN32) || defined(_WIN32) |
| 21 | # define PYBIND11_EXPORT __declspec(dllexport) |
| 22 | # else |
| 23 | # define PYBIND11_EXPORT __attribute__ ((visibility("default"))) |
| 24 | # endif |
Wenzel Jakob | 0fb8528 | 2015-10-19 23:50:51 +0200 | [diff] [blame] | 25 | #endif |
| 26 | |
Wenzel Jakob | 53b2654 | 2016-01-17 22:36:43 +0100 | [diff] [blame] | 27 | #if defined(_MSC_VER) |
| 28 | # define PYBIND11_NOINLINE __declspec(noinline) |
| 29 | #else |
| 30 | # define PYBIND11_NOINLINE __attribute__ ((noinline)) |
| 31 | #endif |
| 32 | |
Wenzel Jakob | 1ae77fe | 2016-01-17 22:36:43 +0100 | [diff] [blame] | 33 | #define PYBIND11_VERSION_MAJOR 1 |
Wenzel Jakob | f85c529 | 2016-06-14 15:24:47 +0200 | [diff] [blame] | 34 | #define PYBIND11_VERSION_MINOR 9 |
Wenzel Jakob | a720a60 | 2016-07-12 18:02:13 +0200 | [diff] [blame] | 35 | #define PYBIND11_VERSION_PATCH dev0 |
Wenzel Jakob | 1ae77fe | 2016-01-17 22:36:43 +0100 | [diff] [blame] | 36 | |
Wenzel Jakob | 53b2654 | 2016-01-17 22:36:43 +0100 | [diff] [blame] | 37 | /// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode |
| 38 | #if defined(_MSC_VER) |
| 39 | # define HAVE_ROUND |
| 40 | # pragma warning(push) |
| 41 | # pragma warning(disable: 4510 4610 4512 4005) |
| 42 | # if _DEBUG |
Wenzel Jakob | 8cb6cb3 | 2016-04-17 20:21:41 +0200 | [diff] [blame] | 43 | # define PYBIND11_DEBUG_MARKER |
Wenzel Jakob | 53b2654 | 2016-01-17 22:36:43 +0100 | [diff] [blame] | 44 | # undef _DEBUG |
| 45 | # endif |
| 46 | #endif |
| 47 | |
| 48 | #include <Python.h> |
| 49 | #include <frameobject.h> |
Wenzel Jakob | 39e97e6 | 2016-04-25 03:26:15 +0200 | [diff] [blame] | 50 | #include <pythread.h> |
Wenzel Jakob | 53b2654 | 2016-01-17 22:36:43 +0100 | [diff] [blame] | 51 | |
Wenzel Jakob | a771e36 | 2016-07-19 17:47:59 +0200 | [diff] [blame] | 52 | #if defined(_WIN32) && (defined(min) || defined(max)) |
| 53 | # error Macro clash with min and max -- define NOMINMAX when compiling your program on Windows |
| 54 | #endif |
| 55 | |
| 56 | #if defined(isalnum) |
Wenzel Jakob | 53b2654 | 2016-01-17 22:36:43 +0100 | [diff] [blame] | 57 | # undef isalnum |
| 58 | # undef isalpha |
| 59 | # undef islower |
| 60 | # undef isspace |
| 61 | # undef isupper |
| 62 | # undef tolower |
| 63 | # undef toupper |
| 64 | #endif |
| 65 | |
| 66 | #if defined(_MSC_VER) |
Wenzel Jakob | 8cb6cb3 | 2016-04-17 20:21:41 +0200 | [diff] [blame] | 67 | # if defined(PYBIND11_DEBUG_MARKER) |
Wenzel Jakob | 53b2654 | 2016-01-17 22:36:43 +0100 | [diff] [blame] | 68 | # define _DEBUG |
Wenzel Jakob | 8cb6cb3 | 2016-04-17 20:21:41 +0200 | [diff] [blame] | 69 | # undef PYBIND11_DEBUG_MARKER |
| 70 | # endif |
Wenzel Jakob | 53b2654 | 2016-01-17 22:36:43 +0100 | [diff] [blame] | 71 | # pragma warning(pop) |
| 72 | #endif |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 73 | |
Pim Schellart | 5a7d17f | 2016-06-17 17:35:59 -0400 | [diff] [blame] | 74 | #include <forward_list> |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 75 | #include <vector> |
| 76 | #include <string> |
| 77 | #include <stdexcept> |
Wenzel Jakob | a2f6fde | 2015-10-01 16:46:03 +0200 | [diff] [blame] | 78 | #include <unordered_set> |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 79 | #include <unordered_map> |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 80 | #include <memory> |
Wenzel Jakob | b6cf75d | 2016-01-29 11:39:32 +0100 | [diff] [blame] | 81 | #include <typeindex> |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 82 | |
Wenzel Jakob | 27e8e10 | 2016-01-17 22:36:37 +0100 | [diff] [blame] | 83 | #if PY_MAJOR_VERSION >= 3 /// Compatibility macros for various Python versions |
Wenzel Jakob | 48548ea | 2016-01-17 22:36:44 +0100 | [diff] [blame] | 84 | #define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyInstanceMethod_New(ptr) |
Wenzel Jakob | 27e8e10 | 2016-01-17 22:36:37 +0100 | [diff] [blame] | 85 | #define PYBIND11_BYTES_CHECK PyBytes_Check |
| 86 | #define PYBIND11_BYTES_FROM_STRING PyBytes_FromString |
| 87 | #define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyBytes_FromStringAndSize |
| 88 | #define PYBIND11_BYTES_AS_STRING_AND_SIZE PyBytes_AsStringAndSize |
| 89 | #define PYBIND11_BYTES_AS_STRING PyBytes_AsString |
Wenzel Jakob | 5612a0c | 2016-05-01 00:32:18 +0200 | [diff] [blame] | 90 | #define PYBIND11_BYTES_CHECK PyBytes_Check |
Wenzel Jakob | 27e8e10 | 2016-01-17 22:36:37 +0100 | [diff] [blame] | 91 | #define PYBIND11_LONG_CHECK(o) PyLong_Check(o) |
| 92 | #define PYBIND11_LONG_AS_LONGLONG(o) PyLong_AsLongLong(o) |
| 93 | #define PYBIND11_LONG_AS_UNSIGNED_LONGLONG(o) PyLong_AsUnsignedLongLong(o) |
Wenzel Jakob | 56e9f49 | 2016-01-17 22:36:38 +0100 | [diff] [blame] | 94 | #define PYBIND11_BYTES_NAME "bytes" |
Wenzel Jakob | 27e8e10 | 2016-01-17 22:36:37 +0100 | [diff] [blame] | 95 | #define PYBIND11_STRING_NAME "str" |
| 96 | #define PYBIND11_SLICE_OBJECT PyObject |
Wenzel Jakob | d561cb0 | 2016-01-17 22:36:41 +0100 | [diff] [blame] | 97 | #define PYBIND11_FROM_STRING PyUnicode_FromString |
Ivan Smirnov | 1cdd171 | 2016-08-13 12:39:16 +0100 | [diff] [blame] | 98 | #define PYBIND11_STR_TYPE ::pybind11::str |
Wenzel Jakob | d561cb0 | 2016-01-17 22:36:41 +0100 | [diff] [blame] | 99 | #define PYBIND11_OB_TYPE(ht_type) (ht_type).ob_base.ob_base.ob_type |
| 100 | #define PYBIND11_PLUGIN_IMPL(name) \ |
| 101 | extern "C" PYBIND11_EXPORT PyObject *PyInit_##name() |
Wenzel Jakob | 27e8e10 | 2016-01-17 22:36:37 +0100 | [diff] [blame] | 102 | #else |
Wenzel Jakob | 48548ea | 2016-01-17 22:36:44 +0100 | [diff] [blame] | 103 | #define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyMethod_New(ptr, nullptr, class_) |
Wenzel Jakob | 27e8e10 | 2016-01-17 22:36:37 +0100 | [diff] [blame] | 104 | #define PYBIND11_BYTES_CHECK PyString_Check |
| 105 | #define PYBIND11_BYTES_FROM_STRING PyString_FromString |
| 106 | #define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyString_FromStringAndSize |
| 107 | #define PYBIND11_BYTES_AS_STRING_AND_SIZE PyString_AsStringAndSize |
| 108 | #define PYBIND11_BYTES_AS_STRING PyString_AsString |
Wenzel Jakob | 5612a0c | 2016-05-01 00:32:18 +0200 | [diff] [blame] | 109 | #define PYBIND11_BYTES_CHECK PyString_Check |
Wenzel Jakob | 27e8e10 | 2016-01-17 22:36:37 +0100 | [diff] [blame] | 110 | #define PYBIND11_LONG_CHECK(o) (PyInt_Check(o) || PyLong_Check(o)) |
| 111 | #define PYBIND11_LONG_AS_LONGLONG(o) (PyInt_Check(o) ? (long long) PyLong_AsLong(o) : PyLong_AsLongLong(o)) |
| 112 | #define PYBIND11_LONG_AS_UNSIGNED_LONGLONG(o) (PyInt_Check(o) ? (unsigned long long) PyLong_AsUnsignedLong(o) : PyLong_AsUnsignedLongLong(o)) |
Wenzel Jakob | 56e9f49 | 2016-01-17 22:36:38 +0100 | [diff] [blame] | 113 | #define PYBIND11_BYTES_NAME "str" |
Wenzel Jakob | 27e8e10 | 2016-01-17 22:36:37 +0100 | [diff] [blame] | 114 | #define PYBIND11_STRING_NAME "unicode" |
| 115 | #define PYBIND11_SLICE_OBJECT PySliceObject |
Wenzel Jakob | d561cb0 | 2016-01-17 22:36:41 +0100 | [diff] [blame] | 116 | #define PYBIND11_FROM_STRING PyString_FromString |
Ivan Smirnov | 1cdd171 | 2016-08-13 12:39:16 +0100 | [diff] [blame] | 117 | #define PYBIND11_STR_TYPE ::pybind11::bytes |
Wenzel Jakob | d561cb0 | 2016-01-17 22:36:41 +0100 | [diff] [blame] | 118 | #define PYBIND11_OB_TYPE(ht_type) (ht_type).ob_type |
| 119 | #define PYBIND11_PLUGIN_IMPL(name) \ |
| 120 | extern "C" PYBIND11_EXPORT PyObject *init##name() |
Wenzel Jakob | 27e8e10 | 2016-01-17 22:36:37 +0100 | [diff] [blame] | 121 | #endif |
Wenzel Jakob | 5708221 | 2015-09-04 23:42:12 +0200 | [diff] [blame] | 122 | |
Wenzel Jakob | fbafdea | 2016-04-25 15:02:43 +0200 | [diff] [blame] | 123 | #if PY_VERSION_HEX >= 0x03050000 && PY_VERSION_HEX < 0x03050200 |
| 124 | extern "C" { |
| 125 | struct _Py_atomic_address { void *value; }; |
| 126 | PyAPI_DATA(_Py_atomic_address) _PyThreadState_Current; |
Ivan Smirnov | 3ae5bd7 | 2016-06-17 22:29:10 +0100 | [diff] [blame] | 127 | } |
Wenzel Jakob | fbafdea | 2016-04-25 15:02:43 +0200 | [diff] [blame] | 128 | #endif |
| 129 | |
Wenzel Jakob | d561cb0 | 2016-01-17 22:36:41 +0100 | [diff] [blame] | 130 | #define PYBIND11_TRY_NEXT_OVERLOAD ((PyObject *) 1) // special failure return code |
Wenzel Jakob | 77586fd | 2016-03-06 13:38:18 +0100 | [diff] [blame] | 131 | #define PYBIND11_STRINGIFY(x) #x |
| 132 | #define PYBIND11_TOSTRING(x) PYBIND11_STRINGIFY(x) |
| 133 | #define PYBIND11_INTERNALS_ID "__pybind11_" \ |
| 134 | PYBIND11_TOSTRING(PYBIND11_VERSION_MAJOR) "_" PYBIND11_TOSTRING(PYBIND11_VERSION_MINOR) "__" |
Wenzel Jakob | d561cb0 | 2016-01-17 22:36:41 +0100 | [diff] [blame] | 135 | |
| 136 | #define PYBIND11_PLUGIN(name) \ |
| 137 | static PyObject *pybind11_init(); \ |
| 138 | PYBIND11_PLUGIN_IMPL(name) { \ |
| 139 | try { \ |
| 140 | return pybind11_init(); \ |
| 141 | } catch (const std::exception &e) { \ |
| 142 | PyErr_SetString(PyExc_ImportError, e.what()); \ |
| 143 | return nullptr; \ |
| 144 | } \ |
| 145 | } \ |
| 146 | PyObject *pybind11_init() |
| 147 | |
Wenzel Jakob | 8f4eb00 | 2015-10-15 18:13:33 +0200 | [diff] [blame] | 148 | NAMESPACE_BEGIN(pybind11) |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 149 | |
| 150 | typedef Py_ssize_t ssize_t; |
| 151 | |
| 152 | /// Approach used to cast a previously unknown C++ instance into a Python object |
Wenzel Jakob | 178c8a8 | 2016-05-10 15:59:01 +0100 | [diff] [blame] | 153 | enum class return_value_policy : uint8_t { |
Wenzel Jakob | f7b5874 | 2016-04-25 23:04:27 +0200 | [diff] [blame] | 154 | /** This is the default return value policy, which falls back to the policy |
| 155 | return_value_policy::take_ownership when the return value is a pointer. |
| 156 | Otherwise, it uses return_value::move or return_value::copy for rvalue |
| 157 | and lvalue references, respectively. See below for a description of what |
| 158 | all of these different policies do. */ |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 159 | automatic = 0, |
Wenzel Jakob | 7d0162a | 2016-04-25 03:24:46 +0200 | [diff] [blame] | 160 | |
Wenzel Jakob | f7b5874 | 2016-04-25 23:04:27 +0200 | [diff] [blame] | 161 | /** As above, but use policy return_value_policy::reference when the return |
Wenzel Jakob | 37e1f61 | 2016-06-22 14:29:13 +0200 | [diff] [blame] | 162 | value is a pointer. This is the default conversion policy for function |
| 163 | arguments when calling Python functions manually from C++ code (i.e. via |
| 164 | handle::operator()). You probably won't need to use this. */ |
Wenzel Jakob | 8bd31c7 | 2016-04-14 14:26:13 +0200 | [diff] [blame] | 165 | automatic_reference, |
Wenzel Jakob | 7d0162a | 2016-04-25 03:24:46 +0200 | [diff] [blame] | 166 | |
Wenzel Jakob | f7b5874 | 2016-04-25 23:04:27 +0200 | [diff] [blame] | 167 | /** Reference an existing object (i.e. do not create a new copy) and take |
| 168 | ownership. Python will call the destructor and delete operator when the |
| 169 | object’s reference count reaches zero. Undefined behavior ensues when |
| 170 | the C++ side does the same.. */ |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 171 | take_ownership, |
Wenzel Jakob | 7d0162a | 2016-04-25 03:24:46 +0200 | [diff] [blame] | 172 | |
Wenzel Jakob | f7b5874 | 2016-04-25 23:04:27 +0200 | [diff] [blame] | 173 | /** Create a new copy of the returned object, which will be owned by |
| 174 | Python. This policy is comparably safe because the lifetimes of the two |
| 175 | instances are decoupled. */ |
| 176 | copy, |
| 177 | |
| 178 | /** Use std::move to move the return value contents into a new instance |
| 179 | that will be owned by Python. This policy is comparably safe because the |
| 180 | lifetimes of the two instances (move source and destination) are |
| 181 | decoupled. */ |
| 182 | move, |
| 183 | |
| 184 | /** Reference an existing object, but do not take ownership. The C++ side |
| 185 | is responsible for managing the object’s lifetime and deallocating it |
| 186 | when it is no longer used. Warning: undefined behavior will ensue when |
Wenzel Jakob | e84f557 | 2016-04-26 23:19:19 +0200 | [diff] [blame] | 187 | the C++ side deletes an object that is still referenced and used by |
| 188 | Python. */ |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 189 | reference, |
Wenzel Jakob | 7d0162a | 2016-04-25 03:24:46 +0200 | [diff] [blame] | 190 | |
Wenzel Jakob | e84f557 | 2016-04-26 23:19:19 +0200 | [diff] [blame] | 191 | /** This policy only applies to methods and properties. It references the |
| 192 | object without taking ownership similar to the above |
| 193 | return_value_policy::reference policy. In contrast to that policy, the |
| 194 | function or property’s implicit this argument (called the parent) is |
| 195 | considered to be the the owner of the return value (the child). |
| 196 | pybind11 then couples the lifetime of the parent to the child via a |
| 197 | reference relationship that ensures that the parent cannot be garbage |
| 198 | collected while Python is still using the child. More advanced |
| 199 | variations of this scheme are also possible using combinations of |
| 200 | return_value_policy::reference and the keep_alive call policy */ |
Wenzel Jakob | f7b5874 | 2016-04-25 23:04:27 +0200 | [diff] [blame] | 201 | reference_internal |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 202 | }; |
| 203 | |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 204 | /// Information record describing a Python buffer object |
| 205 | struct buffer_info { |
Wenzel Jakob | e45b290 | 2016-01-17 22:36:41 +0100 | [diff] [blame] | 206 | void *ptr; // Pointer to the underlying storage |
| 207 | size_t itemsize; // Size of individual items in bytes |
| 208 | size_t size; // Total number of entries |
Ivan Smirnov | 5e71e17 | 2016-06-26 12:42:34 +0100 | [diff] [blame] | 209 | std::string format; // For homogeneous buffers, this should be set to format_descriptor<T>::format() |
Wenzel Jakob | 0a07805 | 2016-05-29 13:40:40 +0200 | [diff] [blame] | 210 | size_t ndim; // Number of dimensions |
Wenzel Jakob | e45b290 | 2016-01-17 22:36:41 +0100 | [diff] [blame] | 211 | std::vector<size_t> shape; // Shape of the tensor (1 entry per dimension) |
| 212 | std::vector<size_t> strides; // Number of entries between adjacent entries (for each per dimension) |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 213 | |
Johan Mabille | a63d93b | 2016-05-11 11:25:15 +0200 | [diff] [blame] | 214 | buffer_info() : ptr(nullptr), view(nullptr) {} |
Ivan Smirnov | 98ba98c | 2016-07-24 20:29:44 +0100 | [diff] [blame] | 215 | |
Wenzel Jakob | 0a07805 | 2016-05-29 13:40:40 +0200 | [diff] [blame] | 216 | buffer_info(void *ptr, size_t itemsize, const std::string &format, size_t ndim, |
Wenzel Jakob | d4258ba | 2015-07-26 16:33:49 +0200 | [diff] [blame] | 217 | const std::vector<size_t> &shape, const std::vector<size_t> &strides) |
Wenzel Jakob | d33361a | 2016-01-17 22:36:40 +0100 | [diff] [blame] | 218 | : ptr(ptr), itemsize(itemsize), size(1), format(format), |
| 219 | ndim(ndim), shape(shape), strides(strides) { |
Wenzel Jakob | 0a07805 | 2016-05-29 13:40:40 +0200 | [diff] [blame] | 220 | for (size_t i = 0; i < ndim; ++i) |
| 221 | size *= shape[i]; |
Wenzel Jakob | d4258ba | 2015-07-26 16:33:49 +0200 | [diff] [blame] | 222 | } |
Wenzel Jakob | d33361a | 2016-01-17 22:36:40 +0100 | [diff] [blame] | 223 | |
Ivan Smirnov | 98ba98c | 2016-07-24 20:29:44 +0100 | [diff] [blame] | 224 | buffer_info(void *ptr, size_t itemsize, const std::string &format, size_t size) |
| 225 | : buffer_info(ptr, itemsize, format, 1, std::vector<size_t> { size }, |
| 226 | std::vector<size_t> { itemsize }) { } |
| 227 | |
Wenzel Jakob | d33361a | 2016-01-17 22:36:40 +0100 | [diff] [blame] | 228 | buffer_info(Py_buffer *view) |
Wenzel Jakob | 0a07805 | 2016-05-29 13:40:40 +0200 | [diff] [blame] | 229 | : ptr(view->buf), itemsize((size_t) view->itemsize), size(1), format(view->format), |
| 230 | ndim((size_t) view->ndim), shape((size_t) view->ndim), strides((size_t) view->ndim), view(view) { |
| 231 | for (size_t i = 0; i < (size_t) view->ndim; ++i) { |
Wenzel Jakob | d33361a | 2016-01-17 22:36:40 +0100 | [diff] [blame] | 232 | shape[i] = (size_t) view->shape[i]; |
| 233 | strides[i] = (size_t) view->strides[i]; |
| 234 | size *= shape[i]; |
| 235 | } |
| 236 | } |
| 237 | |
| 238 | ~buffer_info() { |
| 239 | if (view) { PyBuffer_Release(view); delete view; } |
| 240 | } |
Ivan Smirnov | a7e62e1 | 2016-06-19 14:37:55 +0100 | [diff] [blame] | 241 | |
Wenzel Jakob | d33361a | 2016-01-17 22:36:40 +0100 | [diff] [blame] | 242 | private: |
| 243 | Py_buffer *view = nullptr; |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 244 | }; |
| 245 | |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 246 | NAMESPACE_BEGIN(detail) |
| 247 | |
Wenzel Jakob | e611823 | 2016-05-05 21:54:24 +0200 | [diff] [blame] | 248 | inline static constexpr int log2(size_t n, int k = 0) { return (n <= 1) ? k : log2(n >> 1, k + 1); } |
Wenzel Jakob | 876eeab | 2016-05-04 22:22:48 +0200 | [diff] [blame] | 249 | |
Wenzel Jakob | 96c1053 | 2015-10-01 16:42:15 +0200 | [diff] [blame] | 250 | inline std::string error_string(); |
| 251 | |
Wenzel Jakob | 88d1d04 | 2016-01-20 01:26:42 +0100 | [diff] [blame] | 252 | /// Core part of the 'instance' type which POD (needed to be able to use 'offsetof') |
| 253 | template <typename type> struct instance_essentials { |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 254 | PyObject_HEAD |
| 255 | type *value; |
Wenzel Jakob | 5f218b3 | 2016-01-17 22:36:39 +0100 | [diff] [blame] | 256 | PyObject *weakrefs; |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 257 | bool owned : 1; |
| 258 | bool constructed : 1; |
Wenzel Jakob | 88d1d04 | 2016-01-20 01:26:42 +0100 | [diff] [blame] | 259 | }; |
| 260 | |
| 261 | /// PyObject wrapper around generic types, includes a special holder type that is responsible for lifetime management |
| 262 | template <typename type, typename holder_type = std::unique_ptr<type>> struct instance : instance_essentials<type> { |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 263 | holder_type holder; |
| 264 | }; |
| 265 | |
Wenzel Jakob | a2f6fde | 2015-10-01 16:46:03 +0200 | [diff] [blame] | 266 | struct overload_hash { |
| 267 | inline std::size_t operator()(const std::pair<const PyObject *, const char *>& v) const { |
| 268 | size_t value = std::hash<const void *>()(v.first); |
| 269 | value ^= std::hash<const void *>()(v.second) + 0x9e3779b9 + (value<<6) + (value>>2); |
| 270 | return value; |
| 271 | } |
| 272 | }; |
| 273 | |
Wenzel Jakob | 43398a8 | 2015-07-28 16:12:20 +0200 | [diff] [blame] | 274 | /// Internal data struture used to track registered instances and types |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 275 | struct internals { |
Jason Rhinelander | 1b05ce5 | 2016-08-09 17:57:59 -0400 | [diff] [blame] | 276 | std::unordered_map<std::type_index, void*> registered_types_cpp; // std::type_index -> type_info |
| 277 | std::unordered_map<const void *, void*> registered_types_py; // PyTypeObject* -> type_info |
| 278 | std::unordered_multimap<const void *, void*> registered_instances; // void * -> PyObject* |
Wenzel Jakob | a2f6fde | 2015-10-01 16:46:03 +0200 | [diff] [blame] | 279 | std::unordered_set<std::pair<const PyObject *, const char *>, overload_hash> inactive_overload_cache; |
Pim Schellart | 5a7d17f | 2016-06-17 17:35:59 -0400 | [diff] [blame] | 280 | std::forward_list<void (*) (std::exception_ptr)> registered_exception_translators; |
Wenzel Jakob | 39e97e6 | 2016-04-25 03:26:15 +0200 | [diff] [blame] | 281 | #if defined(WITH_THREAD) |
Boris Schäling | 20ee935 | 2016-05-28 12:26:18 +0200 | [diff] [blame] | 282 | decltype(PyThread_create_key()) tstate = 0; // Usually an int but a long on Cygwin64 with Python 3.x |
Wenzel Jakob | 39e97e6 | 2016-04-25 03:26:15 +0200 | [diff] [blame] | 283 | PyInterpreterState *istate = nullptr; |
| 284 | #endif |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 285 | }; |
| 286 | |
Wenzel Jakob | d4258ba | 2015-07-26 16:33:49 +0200 | [diff] [blame] | 287 | /// Return a reference to the current 'internals' information |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 288 | inline internals &get_internals(); |
| 289 | |
Wenzel Jakob | d4258ba | 2015-07-26 16:33:49 +0200 | [diff] [blame] | 290 | /// Index sequence for convenient template metaprogramming involving tuples |
| 291 | template<size_t ...> struct index_sequence { }; |
| 292 | template<size_t N, size_t ...S> struct make_index_sequence : make_index_sequence <N - 1, N - 1, S...> { }; |
| 293 | template<size_t ...S> struct make_index_sequence <0, S...> { typedef index_sequence<S...> type; }; |
| 294 | |
| 295 | /// Strip the class from a method type |
Wenzel Jakob | ad69634 | 2016-05-03 13:28:40 +0200 | [diff] [blame] | 296 | template <typename T> struct remove_class { }; |
Wenzel Jakob | d4258ba | 2015-07-26 16:33:49 +0200 | [diff] [blame] | 297 | template <typename C, typename R, typename... A> struct remove_class<R (C::*)(A...)> { typedef R type(A...); }; |
| 298 | template <typename C, typename R, typename... A> struct remove_class<R (C::*)(A...) const> { typedef R type(A...); }; |
| 299 | |
| 300 | /// Helper template to strip away type modifiers |
Wenzel Jakob | 4177ed4 | 2016-01-17 22:36:38 +0100 | [diff] [blame] | 301 | template <typename T> struct intrinsic_type { typedef T type; }; |
| 302 | template <typename T> struct intrinsic_type<const T> { typedef typename intrinsic_type<T>::type type; }; |
| 303 | template <typename T> struct intrinsic_type<T*> { typedef typename intrinsic_type<T>::type type; }; |
| 304 | template <typename T> struct intrinsic_type<T&> { typedef typename intrinsic_type<T>::type type; }; |
| 305 | template <typename T> struct intrinsic_type<T&&> { typedef typename intrinsic_type<T>::type type; }; |
| 306 | template <typename T, size_t N> struct intrinsic_type<const T[N]> { typedef typename intrinsic_type<T>::type type; }; |
| 307 | template <typename T, size_t N> struct intrinsic_type<T[N]> { typedef typename intrinsic_type<T>::type type; }; |
Wenzel Jakob | d4258ba | 2015-07-26 16:33:49 +0200 | [diff] [blame] | 308 | |
| 309 | /// Helper type to replace 'void' in some expressions |
| 310 | struct void_type { }; |
Wenzel Jakob | 281aa0e | 2015-07-30 15:29:00 +0200 | [diff] [blame] | 311 | |
Wenzel Jakob | 38bd711 | 2015-07-05 20:05:44 +0200 | [diff] [blame] | 312 | NAMESPACE_END(detail) |
Wenzel Jakob | a2f6fde | 2015-10-01 16:46:03 +0200 | [diff] [blame] | 313 | |
Wenzel Jakob | ad69634 | 2016-05-03 13:28:40 +0200 | [diff] [blame] | 314 | #define PYBIND11_RUNTIME_EXCEPTION(name) \ |
| 315 | class name : public std::runtime_error { public: \ |
| 316 | name(const std::string &w) : std::runtime_error(w) { }; \ |
| 317 | name(const char *s) : std::runtime_error(s) { }; \ |
| 318 | name() : std::runtime_error("") { } \ |
| 319 | }; |
| 320 | |
Wenzel Jakob | a2f6fde | 2015-10-01 16:46:03 +0200 | [diff] [blame] | 321 | // C++ bindings of core Python exceptions |
Wenzel Jakob | ad69634 | 2016-05-03 13:28:40 +0200 | [diff] [blame] | 322 | class error_already_set : public std::runtime_error { public: error_already_set() : std::runtime_error(detail::error_string()) {} }; |
| 323 | PYBIND11_RUNTIME_EXCEPTION(stop_iteration) |
| 324 | PYBIND11_RUNTIME_EXCEPTION(index_error) |
Jason Rhinelander | 5aa85be | 2016-08-11 21:22:05 -0400 | [diff] [blame] | 325 | PYBIND11_RUNTIME_EXCEPTION(key_error) |
Sergey Lyskov | a315c7a | 2016-05-07 18:50:26 -0400 | [diff] [blame] | 326 | PYBIND11_RUNTIME_EXCEPTION(value_error) |
Wenzel Jakob | ad69634 | 2016-05-03 13:28:40 +0200 | [diff] [blame] | 327 | PYBIND11_RUNTIME_EXCEPTION(cast_error) /// Thrown when pybind11::cast or handle::call fail due to a type casting error |
Wenzel Jakob | 0006259 | 2016-07-01 16:07:35 +0200 | [diff] [blame] | 328 | PYBIND11_RUNTIME_EXCEPTION(reference_cast_error) /// Used internally |
Wenzel Jakob | a2f6fde | 2015-10-01 16:46:03 +0200 | [diff] [blame] | 329 | |
Wenzel Jakob | fc92d82 | 2016-04-30 23:55:44 +0200 | [diff] [blame] | 330 | [[noreturn]] PYBIND11_NOINLINE inline void pybind11_fail(const char *reason) { throw std::runtime_error(reason); } |
| 331 | [[noreturn]] PYBIND11_NOINLINE inline void pybind11_fail(const std::string &reason) { throw std::runtime_error(reason); } |
Wenzel Jakob | 678d787 | 2016-01-17 22:36:41 +0100 | [diff] [blame] | 332 | |
Wenzel Jakob | 876eeab | 2016-05-04 22:22:48 +0200 | [diff] [blame] | 333 | /// Format strings for basic number types |
Ivan Smirnov | 42ad328 | 2016-06-19 14:39:41 +0100 | [diff] [blame] | 334 | #define PYBIND11_DECL_FMT(t, v) template<> struct format_descriptor<t> \ |
Ivan Smirnov | 5e71e17 | 2016-06-26 12:42:34 +0100 | [diff] [blame] | 335 | { static constexpr const char* value = v; /* for backwards compatibility */ \ |
Ivan Smirnov | 03fb488 | 2016-08-14 13:45:49 +0100 | [diff] [blame] | 336 | static std::string format() { return value; } } |
Ivan Smirnov | 42ad328 | 2016-06-19 14:39:41 +0100 | [diff] [blame] | 337 | |
Wenzel Jakob | 876eeab | 2016-05-04 22:22:48 +0200 | [diff] [blame] | 338 | template <typename T, typename SFINAE = void> struct format_descriptor { }; |
Ivan Smirnov | 42ad328 | 2016-06-19 14:39:41 +0100 | [diff] [blame] | 339 | |
Wenzel Jakob | 876eeab | 2016-05-04 22:22:48 +0200 | [diff] [blame] | 340 | template <typename T> struct format_descriptor<T, typename std::enable_if<std::is_integral<T>::value>::type> { |
Ivan Smirnov | 5e71e17 | 2016-06-26 12:42:34 +0100 | [diff] [blame] | 341 | static constexpr const char value[2] = |
Wenzel Jakob | 876eeab | 2016-05-04 22:22:48 +0200 | [diff] [blame] | 342 | { "bBhHiIqQ"[detail::log2(sizeof(T))*2 + (std::is_unsigned<T>::value ? 1 : 0)], '\0' }; |
Ivan Smirnov | 03fb488 | 2016-08-14 13:45:49 +0100 | [diff] [blame] | 343 | static std::string format() { return value; } |
Wenzel Jakob | 876eeab | 2016-05-04 22:22:48 +0200 | [diff] [blame] | 344 | }; |
Ivan Smirnov | 42ad328 | 2016-06-19 14:39:41 +0100 | [diff] [blame] | 345 | |
Wenzel Jakob | 876eeab | 2016-05-04 22:22:48 +0200 | [diff] [blame] | 346 | template <typename T> constexpr const char format_descriptor< |
Ivan Smirnov | 5e71e17 | 2016-06-26 12:42:34 +0100 | [diff] [blame] | 347 | T, typename std::enable_if<std::is_integral<T>::value>::type>::value[2]; |
Ivan Smirnov | 42ad328 | 2016-06-19 14:39:41 +0100 | [diff] [blame] | 348 | |
| 349 | PYBIND11_DECL_FMT(float, "f"); |
| 350 | PYBIND11_DECL_FMT(double, "d"); |
| 351 | PYBIND11_DECL_FMT(bool, "?"); |
Wenzel Jakob | 876eeab | 2016-05-04 22:22:48 +0200 | [diff] [blame] | 352 | |
Wenzel Jakob | 5e4e477 | 2016-08-28 02:03:15 +0200 | [diff] [blame^] | 353 | /// Dummy destructor wrapper that can be used to expose classes with a private destructor |
| 354 | struct nodelete { template <typename T> void operator()(T*) { } }; |
Nickolai Belakovski | 6333825 | 2016-08-27 11:57:55 -0700 | [diff] [blame] | 355 | |
Wenzel Jakob | 8f4eb00 | 2015-10-15 18:13:33 +0200 | [diff] [blame] | 356 | NAMESPACE_END(pybind11) |