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