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
21PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
22
23template <typename T>
24struct 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
32template <typename T>
33constexpr 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
39PYBIND11_NAMESPACE_BEGIN(detail)
40
41template <typename T>
42struct 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
47template <typename T>
48class type_caster<std::complex<T>> {
49public:
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};
73PYBIND11_NAMESPACE_END(detail)
74PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
75