File indexing completed on 2025-02-16 05:12:15

0001 /*
0002     pybind11/complex.h: Complex number support
0003 
0004     Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
0005 
0006     All rights reserved. Use of this source code is governed by a
0007     BSD-style license that can be found in the LICENSE file.
0008 */
0009 
0010 #pragma once
0011 
0012 #include "pybind11.h"
0013 #include <complex>
0014 
0015 /// glibc defines I as a macro which breaks things, e.g., boost template names
0016 #ifdef I
0017 #  undef I
0018 #endif
0019 
0020 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
0021 
0022 template <typename T> struct format_descriptor<std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>> {
0023     static constexpr const char c = format_descriptor<T>::c;
0024     static constexpr const char value[3] = { 'Z', c, '\0' };
0025     static std::string format() { return std::string(value); }
0026 };
0027 
0028 #ifndef PYBIND11_CPP17
0029 
0030 template <typename T> constexpr const char format_descriptor<
0031     std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>>::value[3];
0032 
0033 #endif
0034 
0035 PYBIND11_NAMESPACE_BEGIN(detail)
0036 
0037 template <typename T> struct is_fmt_numeric<std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>> {
0038     static constexpr bool value = true;
0039     static constexpr int index = is_fmt_numeric<T>::index + 3;
0040 };
0041 
0042 template <typename T> class type_caster<std::complex<T>> {
0043 public:
0044     bool load(handle src, bool convert) {
0045         if (!src)
0046             return false;
0047         if (!convert && !PyComplex_Check(src.ptr()))
0048             return false;
0049         Py_complex result = PyComplex_AsCComplex(src.ptr());
0050         if (result.real == -1.0 && PyErr_Occurred()) {
0051             PyErr_Clear();
0052             return false;
0053         }
0054         value = std::complex<T>((T) result.real, (T) result.imag);
0055         return true;
0056     }
0057 
0058     static handle cast(const std::complex<T> &src, return_value_policy /* policy */, handle /* parent */) {
0059         return PyComplex_FromDoubles((double) src.real(), (double) src.imag());
0060     }
0061 
0062     PYBIND11_TYPE_CASTER(std::complex<T>, const_name("complex"));
0063 };
0064 PYBIND11_NAMESPACE_END(detail)
0065 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)