common.h 12.1 KB
Newer Older
Wenzel Jakob's avatar
Wenzel Jakob committed
1
/*
2
    pybind11/common.h -- Basic macros
Wenzel Jakob's avatar
Wenzel Jakob committed
3

4
    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
Wenzel Jakob's avatar
Wenzel Jakob committed
5
6
7
8
9

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/

10
#pragma once
Wenzel Jakob's avatar
Wenzel Jakob committed
11
12

#if !defined(NAMESPACE_BEGIN)
13
#  define NAMESPACE_BEGIN(name) namespace name {
Wenzel Jakob's avatar
Wenzel Jakob committed
14
15
#endif
#if !defined(NAMESPACE_END)
16
#  define NAMESPACE_END(name) }
Wenzel Jakob's avatar
Wenzel Jakob committed
17
18
#endif

19
#if !defined(PYBIND11_EXPORT)
20
21
22
23
24
#  if defined(WIN32) || defined(_WIN32)
#    define PYBIND11_EXPORT __declspec(dllexport)
#  else
#    define PYBIND11_EXPORT __attribute__ ((visibility("default")))
#  endif
Wenzel Jakob's avatar
Wenzel Jakob committed
25
#endif
26

27
#if defined(_MSC_VER)
28
#  define PYBIND11_NOINLINE __declspec(noinline)
29
#else
30
#  define PYBIND11_NOINLINE __attribute__ ((noinline))
31
32
#endif

33
#define PYBIND11_VERSION_MAJOR 1
34
#define PYBIND11_VERSION_MINOR 6
35

Wenzel Jakob's avatar
Wenzel Jakob committed
36
37
/// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode
#if defined(_MSC_VER)
38
39
40
41
#  define HAVE_ROUND
#  pragma warning(push)
#  pragma warning(disable: 4510 4610 4512 4005)
#  if _DEBUG
42
#    define PYBIND11_DEBUG_MARKER
43
44
#    undef _DEBUG
#  endif
Wenzel Jakob's avatar
Wenzel Jakob committed
45
#endif
46

Wenzel Jakob's avatar
Wenzel Jakob committed
47
#include <Python.h>
48
#include <frameobject.h>
49

50
#ifdef isalnum
51
52
53
54
55
56
57
#  undef isalnum
#  undef isalpha
#  undef islower
#  undef isspace
#  undef isupper
#  undef tolower
#  undef toupper
58
#endif
59

Wenzel Jakob's avatar
Wenzel Jakob committed
60
#if defined(_MSC_VER)
61
#  if defined(PYBIND11_DEBUG_MARKER)
62
#    define _DEBUG
63
64
#    undef PYBIND11_DEBUG_MARKER
#  endif
65
#  pragma warning(pop)
Wenzel Jakob's avatar
Wenzel Jakob committed
66
67
#endif

68
69
70
71
72
73
#include <vector>
#include <string>
#include <stdexcept>
#include <unordered_set>
#include <unordered_map>
#include <memory>
74
#include <typeindex>
75

76
#if PY_MAJOR_VERSION >= 3 /// Compatibility macros for various Python versions
Wenzel Jakob's avatar
Wenzel Jakob committed
77
#define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyInstanceMethod_New(ptr)
78
79
80
81
82
83
84
85
#define PYBIND11_BYTES_CHECK PyBytes_Check
#define PYBIND11_BYTES_FROM_STRING PyBytes_FromString
#define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyBytes_FromStringAndSize
#define PYBIND11_BYTES_AS_STRING_AND_SIZE PyBytes_AsStringAndSize
#define PYBIND11_BYTES_AS_STRING PyBytes_AsString
#define PYBIND11_LONG_CHECK(o) PyLong_Check(o)
#define PYBIND11_LONG_AS_LONGLONG(o) PyLong_AsLongLong(o)
#define PYBIND11_LONG_AS_UNSIGNED_LONGLONG(o) PyLong_AsUnsignedLongLong(o)
86
#define PYBIND11_BYTES_NAME "bytes"
87
88
#define PYBIND11_STRING_NAME "str"
#define PYBIND11_SLICE_OBJECT PyObject
89
90
91
92
#define PYBIND11_FROM_STRING PyUnicode_FromString
#define PYBIND11_OB_TYPE(ht_type) (ht_type).ob_base.ob_base.ob_type
#define PYBIND11_PLUGIN_IMPL(name) \
    extern "C" PYBIND11_EXPORT PyObject *PyInit_##name()
93
#else
Wenzel Jakob's avatar
Wenzel Jakob committed
94
#define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyMethod_New(ptr, nullptr, class_)
95
96
97
98
99
100
101
102
#define PYBIND11_BYTES_CHECK PyString_Check
#define PYBIND11_BYTES_FROM_STRING PyString_FromString
#define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyString_FromStringAndSize
#define PYBIND11_BYTES_AS_STRING_AND_SIZE PyString_AsStringAndSize
#define PYBIND11_BYTES_AS_STRING PyString_AsString
#define PYBIND11_LONG_CHECK(o) (PyInt_Check(o) || PyLong_Check(o))
#define PYBIND11_LONG_AS_LONGLONG(o) (PyInt_Check(o) ? (long long) PyLong_AsLong(o) : PyLong_AsLongLong(o))
#define PYBIND11_LONG_AS_UNSIGNED_LONGLONG(o) (PyInt_Check(o) ? (unsigned long long) PyLong_AsUnsignedLong(o) : PyLong_AsUnsignedLongLong(o))
103
#define PYBIND11_BYTES_NAME "str"
104
105
#define PYBIND11_STRING_NAME "unicode"
#define PYBIND11_SLICE_OBJECT PySliceObject
106
107
108
109
#define PYBIND11_FROM_STRING PyString_FromString
#define PYBIND11_OB_TYPE(ht_type) (ht_type).ob_type
#define PYBIND11_PLUGIN_IMPL(name) \
    extern "C" PYBIND11_EXPORT PyObject *init##name()
110
#endif
111

112
#define PYBIND11_TRY_NEXT_OVERLOAD ((PyObject *) 1) // special failure return code
113
114
115
116
#define PYBIND11_STRINGIFY(x) #x
#define PYBIND11_TOSTRING(x) PYBIND11_STRINGIFY(x)
#define PYBIND11_INTERNALS_ID "__pybind11_" \
    PYBIND11_TOSTRING(PYBIND11_VERSION_MAJOR) "_" PYBIND11_TOSTRING(PYBIND11_VERSION_MINOR) "__"
117
118
119
120
121
122
123
124
125
126
127
128
129
130

#define PYBIND11_PLUGIN(name) \
    static PyObject *pybind11_init(); \
    PYBIND11_PLUGIN_IMPL(name) { \
        try { \
            return pybind11_init(); \
        } catch (const std::exception &e) { \
            PyErr_SetString(PyExc_ImportError, e.what()); \
            return nullptr; \
        } \
    } \
    PyObject *pybind11_init()


131
NAMESPACE_BEGIN(pybind11)
Wenzel Jakob's avatar
Wenzel Jakob committed
132
133
134
135
136
137
138
139

typedef Py_ssize_t ssize_t;

/// Approach used to cast a previously unknown C++ instance into a Python object
enum class return_value_policy : int {
    /** Automatic: copy objects returned as values and take ownership of objects
        returned as pointers */
    automatic = 0,
Wenzel Jakob's avatar
Wenzel Jakob committed
140

141
142
143
    /** Automatic variant 2: copy objects returned as values and reference objects
        returned as pointers */
    automatic_reference,
Wenzel Jakob's avatar
Wenzel Jakob committed
144

Wenzel Jakob's avatar
Wenzel Jakob committed
145
146
147
    /** Reference the object and take ownership. Python will call the
        destructor and delete operator when the reference count reaches zero */
    take_ownership,
Wenzel Jakob's avatar
Wenzel Jakob committed
148

Wenzel Jakob's avatar
Wenzel Jakob committed
149
150
151
    /** Reference the object, but do not take ownership (dangerous when C++ code
        deletes it and Python still has a nonzero reference count) */
    reference,
Wenzel Jakob's avatar
Wenzel Jakob committed
152

Wenzel Jakob's avatar
Wenzel Jakob committed
153
154
155
156
    /** Reference the object, but do not take ownership. The object is considered
        be owned by the C++ instance whose method or property returned it. The
        Python object will increase the reference count of this 'parent' by 1 */
    reference_internal,
Wenzel Jakob's avatar
Wenzel Jakob committed
157

Wenzel Jakob's avatar
Wenzel Jakob committed
158
159
160
161
162
163
    /// Create a new copy of the returned object, which will be owned by Python
    copy
};

/// Format strings for basic number types
template <typename type> struct format_descriptor { };
164
#define PYBIND11_DECL_FMT(t, n) template<> struct format_descriptor<t> { static std::string value() { return n; }; }
165
166
167
PYBIND11_DECL_FMT(int8_t,  "b"); PYBIND11_DECL_FMT(uint8_t,  "B"); PYBIND11_DECL_FMT(int16_t, "h"); PYBIND11_DECL_FMT(uint16_t, "H");
PYBIND11_DECL_FMT(int32_t, "i"); PYBIND11_DECL_FMT(uint32_t, "I"); PYBIND11_DECL_FMT(int64_t, "q"); PYBIND11_DECL_FMT(uint64_t, "Q");
PYBIND11_DECL_FMT(float,   "f"); PYBIND11_DECL_FMT(double,   "d"); PYBIND11_DECL_FMT(bool,    "?");
Wenzel Jakob's avatar
Wenzel Jakob committed
168
169
170

/// Information record describing a Python buffer object
struct buffer_info {
171
172
173
174
175
176
177
    void *ptr;                   // Pointer to the underlying storage
    size_t itemsize;             // Size of individual items in bytes
    size_t size;                 // Total number of entries
    std::string format;          // For homogeneous buffers, this should be set to format_descriptor<T>::value
    int ndim;                    // Number of dimensions
    std::vector<size_t> shape;   // Shape of the tensor (1 entry per dimension)
    std::vector<size_t> strides; // Number of entries between adjacent entries (for each per dimension)
Wenzel Jakob's avatar
Wenzel Jakob committed
178

Wenzel Jakob's avatar
Wenzel Jakob committed
179
180
    buffer_info(void *ptr, size_t itemsize, const std::string &format, int ndim,
                const std::vector<size_t> &shape, const std::vector<size_t> &strides)
181
182
183
        : ptr(ptr), itemsize(itemsize), size(1), format(format),
          ndim(ndim), shape(shape), strides(strides) {
        for (int i=0; i<ndim; ++i) size *= shape[i];
Wenzel Jakob's avatar
Wenzel Jakob committed
184
    }
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200

    buffer_info(Py_buffer *view)
        : ptr(view->buf), itemsize(view->itemsize), size(1), format(view->format),
          ndim(view->ndim), shape(view->ndim), strides(view->ndim), view(view) {
        for (int i = 0; i < view->ndim; ++i) {
            shape[i] = (size_t) view->shape[i];
            strides[i] = (size_t) view->strides[i];
            size *= shape[i];
        }
    }

    ~buffer_info() {
        if (view) { PyBuffer_Release(view); delete view; }
    }
private:
    Py_buffer *view = nullptr;
Wenzel Jakob's avatar
Wenzel Jakob committed
201
202
203
204
};

NAMESPACE_BEGIN(detail)

205
206
inline std::string error_string();

207
208
/// Core part of the 'instance' type which POD (needed to be able to use 'offsetof')
template <typename type> struct instance_essentials {
Wenzel Jakob's avatar
Wenzel Jakob committed
209
210
211
    PyObject_HEAD
    type *value;
    PyObject *parent;
212
    PyObject *weakrefs;
Wenzel Jakob's avatar
Wenzel Jakob committed
213
214
    bool owned : 1;
    bool constructed : 1;
215
216
217
218
};

/// PyObject wrapper around generic types, includes a special holder type that is responsible for lifetime management
template <typename type, typename holder_type = std::unique_ptr<type>> struct instance : instance_essentials<type> {
Wenzel Jakob's avatar
Wenzel Jakob committed
219
220
221
    holder_type holder;
};

222
223
224
225
226
227
228
229
struct overload_hash {
    inline std::size_t operator()(const std::pair<const PyObject *, const char *>& v) const {
        size_t value = std::hash<const void *>()(v.first);
        value ^= std::hash<const void *>()(v.second)  + 0x9e3779b9 + (value<<6) + (value>>2);
        return value;
    }
};

Wenzel Jakob's avatar
Wenzel Jakob committed
230
/// Internal data struture used to track registered instances and types
Wenzel Jakob's avatar
Wenzel Jakob committed
231
struct internals {
232
233
234
    std::unordered_map<std::type_index, void*> registered_types_cpp; // std::type_index -> type_info
    std::unordered_map<const void *, void*> registered_types_py;     // PyTypeObject* -> type_info
    std::unordered_map<const void *, void*> registered_instances;    // void * -> PyObject*
235
    std::unordered_set<std::pair<const PyObject *, const char *>, overload_hash> inactive_overload_cache;
Wenzel Jakob's avatar
Wenzel Jakob committed
236
237
};

Wenzel Jakob's avatar
Wenzel Jakob committed
238
/// Return a reference to the current 'internals' information
Wenzel Jakob's avatar
Wenzel Jakob committed
239
240
inline internals &get_internals();

Wenzel Jakob's avatar
Wenzel Jakob committed
241
242
243
244
245
246
247
248
249
250
251
/// Index sequence for convenient template metaprogramming involving tuples
template<size_t ...> struct index_sequence  { };
template<size_t N, size_t ...S> struct make_index_sequence : make_index_sequence <N - 1, N - 1, S...> { };
template<size_t ...S> struct make_index_sequence <0, S...> { typedef index_sequence<S...> type; };

/// Strip the class from a method type
template <typename T> struct remove_class {};
template <typename C, typename R, typename... A> struct remove_class<R (C::*)(A...)> { typedef R type(A...); };
template <typename C, typename R, typename... A> struct remove_class<R (C::*)(A...) const> { typedef R type(A...); };

/// Helper template to strip away type modifiers
252
253
254
255
256
257
258
template <typename T> struct intrinsic_type                       { typedef T type; };
template <typename T> struct intrinsic_type<const T>              { typedef typename intrinsic_type<T>::type type; };
template <typename T> struct intrinsic_type<T*>                   { typedef typename intrinsic_type<T>::type type; };
template <typename T> struct intrinsic_type<T&>                   { typedef typename intrinsic_type<T>::type type; };
template <typename T> struct intrinsic_type<T&&>                  { typedef typename intrinsic_type<T>::type type; };
template <typename T, size_t N> struct intrinsic_type<const T[N]> { typedef typename intrinsic_type<T>::type type; };
template <typename T, size_t N> struct intrinsic_type<T[N]>       { typedef typename intrinsic_type<T>::type type; };
Wenzel Jakob's avatar
Wenzel Jakob committed
259

Wenzel Jakob's avatar
Wenzel Jakob committed
260
/** \brief SFINAE helper class to check if a copy constructor is usable (in contrast to
261
262
 * std::is_copy_constructible, this class also checks if the 'new' operator is accessible */
template <typename T>  struct is_copy_constructible {
263
    template <typename T2> static std::true_type test(decltype(new T2(std::declval<typename std::add_lvalue_reference<T2>::type>())) *);
264
265
266
267
    template <typename T2> static std::false_type test(...);
    static const bool value = std::is_same<std::true_type, decltype(test<T>(nullptr))>::value;
};

Wenzel Jakob's avatar
Wenzel Jakob committed
268
269
/// Helper type to replace 'void' in some expressions
struct void_type { };
270

271
272
273
274
275
276
277
/// to_string variant which also accepts strings
template <typename T> inline typename std::enable_if<!std::is_enum<T>::value, std::string>::type
to_string(const T &value) { return std::to_string(value); }
template <> inline std::string to_string(const std::string &value) { return value; }
template <typename T> inline typename std::enable_if<std::is_enum<T>::value, std::string>::type
to_string(T value) { return std::to_string((int) value); }

Wenzel Jakob's avatar
Wenzel Jakob committed
278
NAMESPACE_END(detail)
279
280
281
282
283

// C++ bindings of core Python exceptions
struct stop_iteration    : public std::runtime_error { public: stop_iteration(const std::string &w="") : std::runtime_error(w)   {} };
struct index_error       : public std::runtime_error { public: index_error(const std::string &w="")    : std::runtime_error(w)   {} };
struct error_already_set : public std::runtime_error { public: error_already_set() : std::runtime_error(detail::error_string())  {} };
284
/// Thrown when pybind11::cast or handle::call fail due to a type casting error
285
286
struct cast_error        : public std::runtime_error { public: cast_error(const std::string &w = "") : std::runtime_error(w)     {} };

287
288
289
PYBIND11_NOINLINE inline void pybind11_fail(const char *reason) { throw std::runtime_error(reason); }
PYBIND11_NOINLINE inline void pybind11_fail(const std::string &reason) { throw std::runtime_error(reason); }

290
NAMESPACE_END(pybind11)