blob: 3a95210b597566f557033ce7a1efd4829edefbba [file] [log] [blame]
Wenzel Jakob38bd7112015-07-05 20:05:44 +02001/*
2 pybind/common.h -- Basic macros
3
4 Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
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 Jakobbd4a5292015-07-11 17:41:48 +020010#pragma once
Wenzel Jakob38bd7112015-07-05 20:05:44 +020011
12#if !defined(NAMESPACE_BEGIN)
13#define NAMESPACE_BEGIN(name) namespace name {
14#endif
15#if !defined(NAMESPACE_END)
16#define NAMESPACE_END(name) }
17#endif
18
19#if !defined(PYTHON_EXPORT)
20#if defined(WIN32)
21#define PYTHON_EXPORT __declspec(dllexport)
22#else
23#define PYTHON_EXPORT __attribute__ ((visibility("default")))
24#endif
25#endif
26
Wenzel Jakob38bd7112015-07-05 20:05:44 +020027#include <vector>
28#include <string>
29#include <stdexcept>
Wenzel Jakob38bd7112015-07-05 20:05:44 +020030#include <unordered_map>
Wenzel Jakob38bd7112015-07-05 20:05:44 +020031#include <memory>
32
33/// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode
34#if defined(_MSC_VER)
35#define HAVE_ROUND
36#pragma warning(push)
Wenzel Jakob57082212015-09-04 23:42:12 +020037#pragma warning(disable: 4510 4610 4512 4005)
Wenzel Jakob38bd7112015-07-05 20:05:44 +020038#if _DEBUG
39#define _DEBUG_MARKER
40#undef _DEBUG
41#endif
42#endif
43#include <Python.h>
Wenzel Jakob96c10532015-10-01 16:42:15 +020044#include <frameobject.h>
Wenzel Jakob281aa0e2015-07-30 15:29:00 +020045#ifdef isalnum
46#undef isalnum
47#undef isalpha
48#undef islower
49#undef isspace
50#undef isupper
51#undef tolower
52#undef toupper
53#endif
Wenzel Jakob38bd7112015-07-05 20:05:44 +020054#if defined(_MSC_VER)
55#if defined(_DEBUG_MARKER)
56#define _DEBUG
57#undef _DEBUG_MARKER
58#endif
59#pragma warning(pop)
60#endif
61
Wenzel Jakob57082212015-09-04 23:42:12 +020062#if PY_MAJOR_VERSION >= 3
63#define PYTHON_PLUGIN(name) \
64 extern "C" PYTHON_EXPORT PyObject *PyInit_##name()
65#else
66#define PYTHON_PLUGIN(name) \
67 extern "C" PYTHON_EXPORT PyObject *init##name()
68#endif
69
Wenzel Jakob38bd7112015-07-05 20:05:44 +020070NAMESPACE_BEGIN(pybind)
71
72typedef Py_ssize_t ssize_t;
73
74/// Approach used to cast a previously unknown C++ instance into a Python object
75enum class return_value_policy : int {
76 /** Automatic: copy objects returned as values and take ownership of objects
77 returned as pointers */
78 automatic = 0,
79 /** Reference the object and take ownership. Python will call the
80 destructor and delete operator when the reference count reaches zero */
81 take_ownership,
82 /** Reference the object, but do not take ownership (dangerous when C++ code
83 deletes it and Python still has a nonzero reference count) */
84 reference,
85 /** Reference the object, but do not take ownership. The object is considered
86 be owned by the C++ instance whose method or property returned it. The
87 Python object will increase the reference count of this 'parent' by 1 */
88 reference_internal,
89 /// Create a new copy of the returned object, which will be owned by Python
90 copy
91};
92
93/// Format strings for basic number types
94template <typename type> struct format_descriptor { };
Wenzel Jakob281aa0e2015-07-30 15:29:00 +020095#define PYBIND_DECL_FMT(t, n) template<> struct format_descriptor<t> { static std::string value() { return n; }; };
96PYBIND_DECL_FMT(int8_t, "b"); PYBIND_DECL_FMT(uint8_t, "B"); PYBIND_DECL_FMT(int16_t, "h"); PYBIND_DECL_FMT(uint16_t, "H");
97PYBIND_DECL_FMT(int32_t, "i"); PYBIND_DECL_FMT(uint32_t, "I"); PYBIND_DECL_FMT(int64_t, "q"); PYBIND_DECL_FMT(uint64_t, "Q");
98PYBIND_DECL_FMT(float, "f"); PYBIND_DECL_FMT(double, "d"); PYBIND_DECL_FMT(bool, "?");
Wenzel Jakob38bd7112015-07-05 20:05:44 +020099
100/// Information record describing a Python buffer object
101struct buffer_info {
102 void *ptr;
Wenzel Jakobd4258ba2015-07-26 16:33:49 +0200103 size_t itemsize, count;
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200104 std::string format; // for dense contents, this should be set to format_descriptor<T>::value
105 int ndim;
106 std::vector<size_t> shape;
107 std::vector<size_t> strides;
108
Wenzel Jakobd4258ba2015-07-26 16:33:49 +0200109 buffer_info(void *ptr, size_t itemsize, const std::string &format, int ndim,
110 const std::vector<size_t> &shape, const std::vector<size_t> &strides)
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200111 : ptr(ptr), itemsize(itemsize), format(format), ndim(ndim),
Wenzel Jakobd4258ba2015-07-26 16:33:49 +0200112 shape(shape), strides(strides) {
113 count = 1; for (int i=0; i<ndim; ++i) count *= shape[i];
114 }
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200115};
116
117// C++ bindings of core Python exceptions
118struct stop_iteration : public std::runtime_error { public: stop_iteration(const std::string &w="") : std::runtime_error(w) {} };
119struct index_error : public std::runtime_error { public: index_error(const std::string &w="") : std::runtime_error(w) {} };
120struct error_already_set : public std::exception { public: error_already_set() {} };
121/// Thrown when pybind::cast or handle::call fail due to a type casting error
122struct cast_error : public std::runtime_error { public: cast_error(const std::string &w = "") : std::runtime_error(w) {} };
123
124NAMESPACE_BEGIN(detail)
125
Wenzel Jakob96c10532015-10-01 16:42:15 +0200126inline std::string error_string();
127
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200128/// PyObject wrapper around generic types
129template <typename type, typename holder_type = std::unique_ptr<type>> struct instance {
130 PyObject_HEAD
131 type *value;
132 PyObject *parent;
133 bool owned : 1;
134 bool constructed : 1;
135 holder_type holder;
136};
137
138/// Additional type information which does not fit into the PyTypeObjet
139struct type_info {
140 PyTypeObject *type;
141 size_t type_size;
142 void (*init_holder)(PyObject *);
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200143 std::vector<PyObject *(*)(PyObject *, PyTypeObject *)> implicit_conversions;
Wenzel Jakob43398a82015-07-28 16:12:20 +0200144 buffer_info *(*get_buffer)(PyObject *, void *) = nullptr;
145 void *get_buffer_data = nullptr;
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200146};
147
Wenzel Jakob43398a82015-07-28 16:12:20 +0200148/// Internal data struture used to track registered instances and types
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200149struct internals {
Wenzel Jakobf5fae922015-08-24 15:31:24 +0200150 std::unordered_map<const std::type_info *, type_info> registered_types;
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200151 std::unordered_map<void *, PyObject *> registered_instances;
152};
153
Wenzel Jakobd4258ba2015-07-26 16:33:49 +0200154/// Return a reference to the current 'internals' information
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200155inline internals &get_internals();
156
Wenzel Jakobd4258ba2015-07-26 16:33:49 +0200157/// Index sequence for convenient template metaprogramming involving tuples
158template<size_t ...> struct index_sequence { };
159template<size_t N, size_t ...S> struct make_index_sequence : make_index_sequence <N - 1, N - 1, S...> { };
160template<size_t ...S> struct make_index_sequence <0, S...> { typedef index_sequence<S...> type; };
161
162/// Strip the class from a method type
163template <typename T> struct remove_class {};
164template <typename C, typename R, typename... A> struct remove_class<R (C::*)(A...)> { typedef R type(A...); };
165template <typename C, typename R, typename... A> struct remove_class<R (C::*)(A...) const> { typedef R type(A...); };
166
167/// Helper template to strip away type modifiers
168template <typename T> struct decay { typedef T type; };
169template <typename T> struct decay<const T> { typedef typename decay<T>::type type; };
170template <typename T> struct decay<T*> { typedef typename decay<T>::type type; };
171template <typename T> struct decay<T&> { typedef typename decay<T>::type type; };
172template <typename T> struct decay<T&&> { typedef typename decay<T>::type type; };
173template <typename T, size_t N> struct decay<const T[N]> { typedef typename decay<T>::type type; };
174template <typename T, size_t N> struct decay<T[N]> { typedef typename decay<T>::type type; };
175
176/// Helper type to replace 'void' in some expressions
177struct void_type { };
Wenzel Jakob281aa0e2015-07-30 15:29:00 +0200178
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200179NAMESPACE_END(detail)
180NAMESPACE_END(pybind)