1 | /* |
2 | pybind11/complex.h: Complex number support |
3 | |
4 | Copyright (c) 2016 Wenzel Jakob <[email protected]> |
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 | |
10 | #pragma once |
11 | |
12 | #include "pybind11.h" |
13 | |
14 | #include <complex> |
15 | |
16 | /// glibc defines I as a macro which breaks things, e.g., boost template names |
17 | #ifdef I |
18 | # undef I |
19 | #endif |
20 | |
21 | PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) |
22 | |
23 | template <typename T> |
24 | struct format_descriptor<std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>> { |
25 | static constexpr const char c = format_descriptor<T>::c; |
26 | static constexpr const char value[3] = {'Z', c, '\0'}; |
27 | static std::string format() { return std::string(value); } |
28 | }; |
29 | |
30 | #ifndef PYBIND11_CPP17 |
31 | |
32 | template <typename T> |
33 | constexpr const char |
34 | format_descriptor<std::complex<T>, |
35 | detail::enable_if_t<std::is_floating_point<T>::value>>::value[3]; |
36 | |
37 | #endif |
38 | |
39 | PYBIND11_NAMESPACE_BEGIN(detail) |
40 | |
41 | template <typename T> |
42 | struct is_fmt_numeric<std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>> { |
43 | static constexpr bool value = true; |
44 | static constexpr int index = is_fmt_numeric<T>::index + 3; |
45 | }; |
46 | |
47 | template <typename T> |
48 | class type_caster<std::complex<T>> { |
49 | public: |
50 | bool load(handle src, bool convert) { |
51 | if (!src) { |
52 | return false; |
53 | } |
54 | if (!convert && !PyComplex_Check(src.ptr())) { |
55 | return false; |
56 | } |
57 | Py_complex result = PyComplex_AsCComplex(src.ptr()); |
58 | if (result.real == -1.0 && PyErr_Occurred()) { |
59 | PyErr_Clear(); |
60 | return false; |
61 | } |
62 | value = std::complex<T>((T) result.real, (T) result.imag); |
63 | return true; |
64 | } |
65 | |
66 | static handle |
67 | cast(const std::complex<T> &src, return_value_policy /* policy */, handle /* parent */) { |
68 | return PyComplex_FromDoubles((double) src.real(), (double) src.imag()); |
69 | } |
70 | |
71 | PYBIND11_TYPE_CASTER(std::complex<T>, const_name("complex" )); |
72 | }; |
73 | PYBIND11_NAMESPACE_END(detail) |
74 | PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) |
75 | |