diff options
Diffstat (limited to 'ext/pybind11/include/pybind11/common.h')
-rw-r--r-- | ext/pybind11/include/pybind11/common.h | 219 |
1 files changed, 171 insertions, 48 deletions
diff --git a/ext/pybind11/include/pybind11/common.h b/ext/pybind11/include/pybind11/common.h index f7a383007..ac2be7aef 100644 --- a/ext/pybind11/include/pybind11/common.h +++ b/ext/pybind11/include/pybind11/common.h @@ -28,6 +28,33 @@ # endif #endif +// Compiler version assertions +#if defined(__INTEL_COMPILER) +# if __INTEL_COMPILER < 1500 +# error pybind11 requires Intel C++ compiler v15 or newer +# endif +#elif defined(__clang__) && !defined(__apple_build_version__) +# if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 3) +# error pybind11 requires clang 3.3 or newer +# endif +#elif defined(__clang__) +// Apple changes clang version macros to its Xcode version; the first Xcode release based on +// (upstream) clang 3.3 was Xcode 5: +# if __clang_major__ < 5 +# error pybind11 requires Xcode/clang 5.0 or newer +# endif +#elif defined(__GNUG__) +# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8) +# error pybind11 requires gcc 4.8 or newer +# endif +#elif defined(_MSC_VER) +// Pybind hits various compiler bugs in 2015u2 and earlier, and also makes use of some stl features +// (e.g. std::negation) added in 2015u3: +# if _MSC_FULL_VER < 190024210 +# error pybind11 requires MSVC 2015 update 3 or newer +# endif +#endif + #if !defined(PYBIND11_EXPORT) # if defined(WIN32) || defined(_WIN32) # define PYBIND11_EXPORT __declspec(dllexport) @@ -52,16 +79,18 @@ # define PYBIND11_DEPRECATED(reason) __declspec(deprecated) #endif -#define PYBIND11_VERSION_MAJOR 1 -#define PYBIND11_VERSION_MINOR 9 -#define PYBIND11_VERSION_PATCH dev0 +#define PYBIND11_VERSION_MAJOR 2 +#define PYBIND11_VERSION_MINOR 1 +#define PYBIND11_VERSION_PATCH 1 /// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode #if defined(_MSC_VER) -# define HAVE_ROUND +# if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 4) +# define HAVE_ROUND 1 +# endif # pragma warning(push) # pragma warning(disable: 4510 4610 4512 4005) -# if _DEBUG +# if defined(_DEBUG) # define PYBIND11_DEBUG_MARKER # undef _DEBUG # endif @@ -111,6 +140,7 @@ #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_BYTES_SIZE PyBytes_Size #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) @@ -119,7 +149,6 @@ #define PYBIND11_SLICE_OBJECT PyObject #define PYBIND11_FROM_STRING PyUnicode_FromString #define PYBIND11_STR_TYPE ::pybind11::str -#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() #else @@ -129,6 +158,7 @@ #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_BYTES_SIZE PyString_Size #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)) @@ -137,9 +167,12 @@ #define PYBIND11_SLICE_OBJECT PySliceObject #define PYBIND11_FROM_STRING PyString_FromString #define PYBIND11_STR_TYPE ::pybind11::bytes -#define PYBIND11_OB_TYPE(ht_type) (ht_type).ob_type #define PYBIND11_PLUGIN_IMPL(name) \ - extern "C" PYBIND11_EXPORT PyObject *init##name() + static PyObject *pybind11_init_wrapper(); \ + extern "C" PYBIND11_EXPORT void init##name() { \ + (void)pybind11_init_wrapper(); \ + } \ + PyObject *pybind11_init_wrapper() #endif #if PY_VERSION_HEX >= 0x03050000 && PY_VERSION_HEX < 0x03050200 @@ -155,6 +188,19 @@ extern "C" { #define PYBIND11_INTERNALS_ID "__pybind11_" \ PYBIND11_TOSTRING(PYBIND11_VERSION_MAJOR) "_" PYBIND11_TOSTRING(PYBIND11_VERSION_MINOR) "__" +/** \rst + This macro creates the entry point that will be invoked when the Python interpreter + imports a plugin library. Please create a `module` in the function body and return + the pointer to its underlying Python object at the end. + + .. code-block:: cpp + + PYBIND11_PLUGIN(example) { + pybind11::module m("example", "pybind11 example plugin"); + /// Set up bindings here + return m.ptr(); + } +\endrst */ #define PYBIND11_PLUGIN(name) \ static PyObject *pybind11_init(); \ PYBIND11_PLUGIN_IMPL(name) { \ @@ -172,6 +218,10 @@ extern "C" { } \ try { \ return pybind11_init(); \ + } catch (pybind11::error_already_set &e) { \ + e.clear(); \ + PyErr_SetString(PyExc_ImportError, e.what()); \ + return nullptr; \ } catch (const std::exception &e) { \ PyErr_SetString(PyExc_ImportError, e.what()); \ return nullptr; \ @@ -327,7 +377,7 @@ struct overload_hash { } }; -/// Internal data struture used to track registered instances and types +/// Internal data structure used to track registered instances and types struct internals { 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 @@ -336,17 +386,34 @@ struct internals { std::unordered_map<std::type_index, std::vector<bool (*)(PyObject *, void *&)>> direct_conversions; std::forward_list<void (*) (std::exception_ptr)> registered_exception_translators; std::unordered_map<std::string, void *> shared_data; // Custom data to be shared across extensions + PyTypeObject *static_property_type; + PyTypeObject *default_metaclass; + std::unordered_map<size_t, PyObject *> bases; // one base type per `instance_size` (very few) #if defined(WITH_THREAD) decltype(PyThread_create_key()) tstate = 0; // Usually an int but a long on Cygwin64 with Python 3.x PyInterpreterState *istate = nullptr; #endif + + /// Return the appropriate base type for the given instance size + PyObject *get_base(size_t instance_size); }; /// Return a reference to the current 'internals' information inline internals &get_internals(); -/// Index sequence for convenient template metaprogramming involving tuples +/// from __cpp_future__ import (convenient aliases from C++14/17) #ifdef PYBIND11_CPP14 +using std::enable_if_t; +using std::conditional_t; +using std::remove_cv_t; +#else +template <bool B, typename T = void> using enable_if_t = typename std::enable_if<B, T>::type; +template <bool B, typename T, typename F> using conditional_t = typename std::conditional<B, T, F>::type; +template <typename T> using remove_cv_t = typename std::remove_cv<T>::type; +#endif + +/// Index sequences +#if defined(PYBIND11_CPP14) || defined(_MSC_VER) using std::index_sequence; using std::make_index_sequence; #else @@ -356,6 +423,35 @@ template<size_t ...S> struct make_index_sequence_impl <0, S...> { typedef index_ template<size_t N> using make_index_sequence = typename make_index_sequence_impl<N>::type; #endif +/// Backports of std::bool_constant and std::negation to accomodate older compilers +template <bool B> using bool_constant = std::integral_constant<bool, B>; +template <typename T> struct negation : bool_constant<!T::value> { }; + +template <typename...> struct void_t_impl { using type = void; }; +template <typename... Ts> using void_t = typename void_t_impl<Ts...>::type; + +/// Compile-time all/any/none of that check the boolean value of all template types +#ifdef __cpp_fold_expressions +template <class... Ts> using all_of = bool_constant<(Ts::value && ...)>; +template <class... Ts> using any_of = bool_constant<(Ts::value || ...)>; +#elif !defined(_MSC_VER) +template <bool...> struct bools {}; +template <class... Ts> using all_of = std::is_same< + bools<Ts::value..., true>, + bools<true, Ts::value...>>; +template <class... Ts> using any_of = negation<all_of<negation<Ts>...>>; +#else +// MSVC has trouble with the above, but supports std::conjunction, which we can use instead (albeit +// at a slight loss of compilation efficiency). +template <class... Ts> using all_of = std::conjunction<Ts...>; +template <class... Ts> using any_of = std::disjunction<Ts...>; +#endif +template <class... Ts> using none_of = negation<any_of<Ts...>>; + +template <class T, template<class> class... Predicates> using satisfies_all_of = all_of<Predicates<T>...>; +template <class T, template<class> class... Predicates> using satisfies_any_of = any_of<Predicates<T>...>; +template <class T, template<class> class... Predicates> using satisfies_none_of = none_of<Predicates<T>...>; + /// 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...); }; @@ -377,34 +473,34 @@ struct void_type { }; /// Helper template which holds a list of types template <typename...> struct type_list { }; -/// from __cpp_future__ import (convenient aliases from C++14/17) -template <bool B> using bool_constant = std::integral_constant<bool, B>; -template <class T> using negation = bool_constant<!T::value>; -template <bool B, typename T = void> using enable_if_t = typename std::enable_if<B, T>::type; -template <bool B, typename T, typename F> using conditional_t = typename std::conditional<B, T, F>::type; - /// Compile-time integer sum +#ifdef __cpp_fold_expressions +template <typename... Ts> constexpr size_t constexpr_sum(Ts... ns) { return (0 + ... + size_t{ns}); } +#else constexpr size_t constexpr_sum() { return 0; } template <typename T, typename... Ts> constexpr size_t constexpr_sum(T n, Ts... ns) { return size_t{n} + constexpr_sum(ns...); } - -// Counts the number of types in the template parameter pack matching the predicate -#if !defined(_MSC_VER) -template <template<typename> class Predicate, typename... Ts> -using count_t = std::integral_constant<size_t, constexpr_sum(Predicate<Ts>::value...)>; -#else -// MSVC workaround (2015 Update 3 has issues with some member type aliases and constexpr) -template <template<typename> class Predicate, typename... Ts> struct count_t; -template <template<typename> class Predicate> struct count_t<Predicate> : std::integral_constant<size_t, 0> {}; -template <template<typename> class Predicate, class T, class... Ts> -struct count_t<Predicate, T, Ts...> : std::integral_constant<size_t, Predicate<T>::value + count_t<Predicate, Ts...>::value> {}; #endif -/// Return true if all/any Ts satify Predicate<T> +NAMESPACE_BEGIN(constexpr_impl) +/// Implementation details for constexpr functions +constexpr int first(int i) { return i; } +template <typename T, typename... Ts> +constexpr int first(int i, T v, Ts... vs) { return v ? i : first(i + 1, vs...); } + +constexpr int last(int /*i*/, int result) { return result; } +template <typename T, typename... Ts> +constexpr int last(int i, int result, T v, Ts... vs) { return last(i + 1, v ? i : result, vs...); } +NAMESPACE_END(constexpr_impl) + +/// Return the index of the first type in Ts which satisfies Predicate<T>. Returns sizeof...(Ts) if +/// none match. template <template<typename> class Predicate, typename... Ts> -using all_of_t = bool_constant<(count_t<Predicate, Ts...>::value == sizeof...(Ts))>; +constexpr int constexpr_first() { return constexpr_impl::first(0, Predicate<Ts>::value...); } + +/// Return the index of the last type in Ts which satisfies Predicate<T>, or -1 if none match. template <template<typename> class Predicate, typename... Ts> -using any_of_t = bool_constant<(count_t<Predicate, Ts...>::value > 0)>; +constexpr int constexpr_last() { return constexpr_impl::last(0, -1, Predicate<Ts>::value...); } // Extracts the first type from the template parameter pack matching the predicate, or Default if none match. template <template<class> class Predicate, class Default, class... Ts> struct first_of; @@ -435,9 +531,9 @@ struct is_template_base_of_impl { /// `is_template_base_of<Base, T>` is true if `struct T : Base<U> {}` where U can be anything template <template<typename...> class Base, typename T> #if !defined(_MSC_VER) -using is_template_base_of = decltype(is_template_base_of_impl<Base>::check((T*)nullptr)); +using is_template_base_of = decltype(is_template_base_of_impl<Base>::check((remove_cv_t<T>*)nullptr)); #else // MSVC2015 has trouble with decltype in template aliases -struct is_template_base_of : decltype(is_template_base_of_impl<Base>::check((T*)nullptr)) { }; +struct is_template_base_of : decltype(is_template_base_of_impl<Base>::check((remove_cv_t<T>*)nullptr)) { }; #endif /// Check if T is std::shared_ptr<U> where U can be anything @@ -498,6 +594,9 @@ public: /// Give the error back to Python void restore() { PyErr_Restore(type, value, trace); type = value = trace = nullptr; } + /// Clear the held Python error state (the C++ `what()` message remains intact) + void clear() { restore(); PyErr_Clear(); } + private: PyObject *type, *value, *trace; }; @@ -506,7 +605,8 @@ private: class builtin_exception : public std::runtime_error { public: using std::runtime_error::runtime_error; - virtual void set_error() const = 0; /// Set the error using the Python C API + /// Set the error using the Python C API + virtual void set_error() const = 0; }; #define PYBIND11_RUNTIME_EXCEPTION(name, type) \ @@ -527,21 +627,49 @@ PYBIND11_RUNTIME_EXCEPTION(reference_cast_error, PyExc_RuntimeError) /// Used in [[noreturn]] PYBIND11_NOINLINE inline void pybind11_fail(const char *reason) { throw std::runtime_error(reason); } [[noreturn]] PYBIND11_NOINLINE inline void pybind11_fail(const std::string &reason) { throw std::runtime_error(reason); } -/// Format strings for basic number types -#define PYBIND11_DECL_FMT(t, v) template<> struct format_descriptor<t> \ - { static constexpr const char* value = v; /* for backwards compatibility */ \ - static std::string format() { return value; } } - template <typename T, typename SFINAE = void> struct format_descriptor { }; -template <typename T> struct format_descriptor<T, detail::enable_if_t<std::is_integral<T>::value>> { - static constexpr const char c = "bBhHiIqQ"[detail::log2(sizeof(T))*2 + std::is_unsigned<T>::value]; +NAMESPACE_BEGIN(detail) +// Returns the index of the given type in the type char array below, and in the list in numpy.h +// The order here is: bool; 8 ints ((signed,unsigned)x(8,16,32,64)bits); float,double,long double; +// complex float,double,long double. Note that the long double types only participate when long +// double is actually longer than double (it isn't under MSVC). +// NB: not only the string below but also complex.h and numpy.h rely on this order. +template <typename T, typename SFINAE = void> struct is_fmt_numeric { static constexpr bool value = false; }; +template <typename T> struct is_fmt_numeric<T, enable_if_t<std::is_arithmetic<T>::value>> { + static constexpr bool value = true; + static constexpr int index = std::is_same<T, bool>::value ? 0 : 1 + ( + std::is_integral<T>::value ? detail::log2(sizeof(T))*2 + std::is_unsigned<T>::value : 8 + ( + std::is_same<T, double>::value ? 1 : std::is_same<T, long double>::value ? 2 : 0)); +}; +NAMESPACE_END(detail) + +template <typename T> struct format_descriptor<T, detail::enable_if_t<detail::is_fmt_numeric<T>::value>> { + static constexpr const char c = "?bBhHiIqQfdgFDG"[detail::is_fmt_numeric<T>::index]; static constexpr const char value[2] = { c, '\0' }; static std::string format() { return std::string(1, c); } }; template <typename T> constexpr const char format_descriptor< - T, detail::enable_if_t<std::is_integral<T>::value>>::value[2]; + T, detail::enable_if_t<detail::is_fmt_numeric<T>::value>>::value[2]; + +NAMESPACE_BEGIN(detail) + +template <typename T, typename SFINAE = void> struct compare_buffer_info { + static bool compare(const buffer_info& b) { + return b.format == format_descriptor<T>::format() && b.itemsize == sizeof(T); + } +}; + +template <typename T> struct compare_buffer_info<T, detail::enable_if_t<std::is_integral<T>::value>> { + static bool compare(const buffer_info& b) { + return b.itemsize == sizeof(T) && (b.format == format_descriptor<T>::value || + ((sizeof(T) == sizeof(long)) && b.format == (std::is_unsigned<T>::value ? "L" : "l")) || + ((sizeof(T) == sizeof(size_t)) && b.format == (std::is_unsigned<T>::value ? "N" : "n"))); + } +}; + +NAMESPACE_END(detail) /// RAII wrapper that temporarily clears any Python error state struct error_scope { @@ -550,16 +678,11 @@ struct error_scope { ~error_scope() { PyErr_Restore(type, value, trace); } }; -PYBIND11_DECL_FMT(float, "f"); -PYBIND11_DECL_FMT(double, "d"); -PYBIND11_DECL_FMT(bool, "?"); - /// Dummy destructor wrapper that can be used to expose classes with a private destructor struct nodelete { template <typename T> void operator()(T*) { } }; -// overload_cast requires variable templates: C++14 or MSVC 2015 Update 2 -#if defined(PYBIND11_CPP14) || ( \ - defined(_MSC_FULL_VER) &&_MSC_FULL_VER >= 190023918) +// overload_cast requires variable templates: C++14 or MSVC +#if defined(PYBIND11_CPP14) || defined(_MSC_VER) #define PYBIND11_OVERLOAD_CAST 1 NAMESPACE_BEGIN(detail) |