/*
    pybind11/complex.h: Complex number support

    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/

#pragma once

#include "pybind11.h"

#include <complex>

/// glibc defines I as a macro which breaks things, e.g., boost template names
#ifdef I
#    undef I
#endif

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

template <typename T>
struct format_descriptor<std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>> {
    static constexpr const char c = format_descriptor<T>::c;
    static constexpr const char value[3] = {'Z', c, '\0'};
    static std::string format() { return std::string(value); }
};

#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L

template <typename T>
constexpr const char
    format_descriptor<std::complex<T>,
                      detail::enable_if_t<std::is_floating_point<T>::value>>::value[3];

#endif

PYBIND11_NAMESPACE_BEGIN(detail)

template <typename T>
struct is_fmt_numeric<std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>> {
    static constexpr bool value = true;
    static constexpr int index = is_fmt_numeric<T>::index + 3;
};

template <typename T>
class type_caster<std::complex<T>> {
public:
    bool load(handle src, bool convert) {
        if (!src) {
            return false;
        }
        if (!convert
            && !(PyComplex_Check(src.ptr()) || PyFloat_Check(src.ptr())
                 || PYBIND11_LONG_CHECK(src.ptr()))) {
            return false;
        }
        handle src_or_index = src;
        // PyPy: 7.3.7's 3.8 does not implement PyLong_*'s __index__ calls.
        // The same logic is used in numeric_caster for ints and floats
#if defined(PYPY_VERSION)
        object index;
        if (PYBIND11_INDEX_CHECK(src.ptr())) {
            index = reinterpret_steal<object>(PyNumber_Index(src.ptr()));
            if (!index) {
                PyErr_Clear();
                if (!convert)
                    return false;
            } else {
                src_or_index = index;
            }
        }
#endif
        Py_complex result = PyComplex_AsCComplex(src_or_index.ptr());
        if (result.real == -1.0 && PyErr_Occurred()) {
            PyErr_Clear();
            return false;
        }
        value = std::complex<T>((T) result.real, (T) result.imag);
        return true;
    }

    static handle
    cast(const std::complex<T> &src, return_value_policy /* policy */, handle /* parent */) {
        return PyComplex_FromDoubles((double) src.real(), (double) src.imag());
    }

    // `complex` does not satisfy `typing.SupportsComplex` in typeshed for Python <= 3.10.
    // Keep it explicit so generated stubs targeting those versions accept complex values.
    PYBIND11_TYPE_CASTER(
        std::complex<T>,
        io_name("complex | typing.SupportsComplex | typing.SupportsFloat | typing.SupportsIndex",
                "complex"));
};
PYBIND11_NAMESPACE_END(detail)
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
