blob: 05750c6535e1a767a1bda32a1d154837ee1f2c01 [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 Jakoba2f6fde2015-10-01 16:46:03 +020030#include <unordered_set>
Wenzel Jakob38bd7112015-07-05 20:05:44 +020031#include <unordered_map>
Wenzel Jakob38bd7112015-07-05 20:05:44 +020032#include <memory>
33
34/// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode
35#if defined(_MSC_VER)
36#define HAVE_ROUND
37#pragma warning(push)
Wenzel Jakob57082212015-09-04 23:42:12 +020038#pragma warning(disable: 4510 4610 4512 4005)
Wenzel Jakob38bd7112015-07-05 20:05:44 +020039#if _DEBUG
40#define _DEBUG_MARKER
41#undef _DEBUG
42#endif
43#endif
44#include <Python.h>
Wenzel Jakob96c10532015-10-01 16:42:15 +020045#include <frameobject.h>
Wenzel Jakob281aa0e2015-07-30 15:29:00 +020046#ifdef isalnum
47#undef isalnum
48#undef isalpha
49#undef islower
50#undef isspace
51#undef isupper
52#undef tolower
53#undef toupper
54#endif
Wenzel Jakob38bd7112015-07-05 20:05:44 +020055#if defined(_MSC_VER)
56#if defined(_DEBUG_MARKER)
57#define _DEBUG
58#undef _DEBUG_MARKER
59#endif
60#pragma warning(pop)
61#endif
62
Wenzel Jakob57082212015-09-04 23:42:12 +020063#if PY_MAJOR_VERSION >= 3
64#define PYTHON_PLUGIN(name) \
65 extern "C" PYTHON_EXPORT PyObject *PyInit_##name()
66#else
67#define PYTHON_PLUGIN(name) \
68 extern "C" PYTHON_EXPORT PyObject *init##name()
69#endif
70
Wenzel Jakob38bd7112015-07-05 20:05:44 +020071NAMESPACE_BEGIN(pybind)
72
73typedef Py_ssize_t ssize_t;
74
75/// Approach used to cast a previously unknown C++ instance into a Python object
76enum class return_value_policy : int {
77 /** Automatic: copy objects returned as values and take ownership of objects
78 returned as pointers */
79 automatic = 0,
80 /** Reference the object and take ownership. Python will call the
81 destructor and delete operator when the reference count reaches zero */
82 take_ownership,
83 /** Reference the object, but do not take ownership (dangerous when C++ code
84 deletes it and Python still has a nonzero reference count) */
85 reference,
86 /** Reference the object, but do not take ownership. The object is considered
87 be owned by the C++ instance whose method or property returned it. The
88 Python object will increase the reference count of this 'parent' by 1 */
89 reference_internal,
90 /// Create a new copy of the returned object, which will be owned by Python
91 copy
92};
93
94/// Format strings for basic number types
95template <typename type> struct format_descriptor { };
Wenzel Jakob281aa0e2015-07-30 15:29:00 +020096#define PYBIND_DECL_FMT(t, n) template<> struct format_descriptor<t> { static std::string value() { return n; }; };
97PYBIND_DECL_FMT(int8_t, "b"); PYBIND_DECL_FMT(uint8_t, "B"); PYBIND_DECL_FMT(int16_t, "h"); PYBIND_DECL_FMT(uint16_t, "H");
98PYBIND_DECL_FMT(int32_t, "i"); PYBIND_DECL_FMT(uint32_t, "I"); PYBIND_DECL_FMT(int64_t, "q"); PYBIND_DECL_FMT(uint64_t, "Q");
99PYBIND_DECL_FMT(float, "f"); PYBIND_DECL_FMT(double, "d"); PYBIND_DECL_FMT(bool, "?");
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200100
101/// Information record describing a Python buffer object
102struct buffer_info {
103 void *ptr;
Wenzel Jakobd4258ba2015-07-26 16:33:49 +0200104 size_t itemsize, count;
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200105 std::string format; // for dense contents, this should be set to format_descriptor<T>::value
106 int ndim;
107 std::vector<size_t> shape;
108 std::vector<size_t> strides;
109
Wenzel Jakobd4258ba2015-07-26 16:33:49 +0200110 buffer_info(void *ptr, size_t itemsize, const std::string &format, int ndim,
111 const std::vector<size_t> &shape, const std::vector<size_t> &strides)
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200112 : ptr(ptr), itemsize(itemsize), format(format), ndim(ndim),
Wenzel Jakobd4258ba2015-07-26 16:33:49 +0200113 shape(shape), strides(strides) {
114 count = 1; for (int i=0; i<ndim; ++i) count *= shape[i];
115 }
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200116};
117
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200118NAMESPACE_BEGIN(detail)
119
Wenzel Jakob96c10532015-10-01 16:42:15 +0200120inline std::string error_string();
121
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200122/// PyObject wrapper around generic types
123template <typename type, typename holder_type = std::unique_ptr<type>> struct instance {
124 PyObject_HEAD
125 type *value;
126 PyObject *parent;
127 bool owned : 1;
128 bool constructed : 1;
129 holder_type holder;
130};
131
132/// Additional type information which does not fit into the PyTypeObjet
133struct type_info {
134 PyTypeObject *type;
135 size_t type_size;
136 void (*init_holder)(PyObject *);
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200137 std::vector<PyObject *(*)(PyObject *, PyTypeObject *)> implicit_conversions;
Wenzel Jakob43398a82015-07-28 16:12:20 +0200138 buffer_info *(*get_buffer)(PyObject *, void *) = nullptr;
139 void *get_buffer_data = nullptr;
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200140};
141
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +0200142struct overload_hash {
143 inline std::size_t operator()(const std::pair<const PyObject *, const char *>& v) const {
144 size_t value = std::hash<const void *>()(v.first);
145 value ^= std::hash<const void *>()(v.second) + 0x9e3779b9 + (value<<6) + (value>>2);
146 return value;
147 }
148};
149
Wenzel Jakob43398a82015-07-28 16:12:20 +0200150/// Internal data struture used to track registered instances and types
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200151struct internals {
Wenzel Jakobf5fae922015-08-24 15:31:24 +0200152 std::unordered_map<const std::type_info *, type_info> registered_types;
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +0200153 std::unordered_map<const void *, PyObject *> registered_instances;
154 std::unordered_set<std::pair<const PyObject *, const char *>, overload_hash> inactive_overload_cache;
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200155};
156
Wenzel Jakobd4258ba2015-07-26 16:33:49 +0200157/// Return a reference to the current 'internals' information
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200158inline internals &get_internals();
159
Wenzel Jakobd4258ba2015-07-26 16:33:49 +0200160/// Index sequence for convenient template metaprogramming involving tuples
161template<size_t ...> struct index_sequence { };
162template<size_t N, size_t ...S> struct make_index_sequence : make_index_sequence <N - 1, N - 1, S...> { };
163template<size_t ...S> struct make_index_sequence <0, S...> { typedef index_sequence<S...> type; };
164
165/// Strip the class from a method type
166template <typename T> struct remove_class {};
167template <typename C, typename R, typename... A> struct remove_class<R (C::*)(A...)> { typedef R type(A...); };
168template <typename C, typename R, typename... A> struct remove_class<R (C::*)(A...) const> { typedef R type(A...); };
169
170/// Helper template to strip away type modifiers
171template <typename T> struct decay { typedef T type; };
172template <typename T> struct decay<const T> { typedef typename decay<T>::type type; };
173template <typename T> struct decay<T*> { typedef typename decay<T>::type type; };
174template <typename T> struct decay<T&> { typedef typename decay<T>::type type; };
175template <typename T> struct decay<T&&> { typedef typename decay<T>::type type; };
176template <typename T, size_t N> struct decay<const T[N]> { typedef typename decay<T>::type type; };
177template <typename T, size_t N> struct decay<T[N]> { typedef typename decay<T>::type type; };
178
179/// Helper type to replace 'void' in some expressions
180struct void_type { };
Wenzel Jakob281aa0e2015-07-30 15:29:00 +0200181
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +0200182/// to_string variant which also accepts strings
183template <typename T> inline typename std::enable_if<!std::is_enum<T>::value, std::string>::type
184to_string(const T &value) { return std::to_string(value); }
185template <> inline std::string to_string(const std::string &value) { return value; }
186template <typename T> inline typename std::enable_if<std::is_enum<T>::value, std::string>::type
187to_string(T value) { return std::to_string((int) value); }
188
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200189NAMESPACE_END(detail)
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +0200190
191// C++ bindings of core Python exceptions
192struct stop_iteration : public std::runtime_error { public: stop_iteration(const std::string &w="") : std::runtime_error(w) {} };
193struct index_error : public std::runtime_error { public: index_error(const std::string &w="") : std::runtime_error(w) {} };
194struct error_already_set : public std::runtime_error { public: error_already_set() : std::runtime_error(detail::error_string()) {} };
195/// Thrown when pybind::cast or handle::call fail due to a type casting error
196struct cast_error : public std::runtime_error { public: cast_error(const std::string &w = "") : std::runtime_error(w) {} };
197
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200198NAMESPACE_END(pybind)