// Copyright (C) 2026 Kiyotsugu Arai
// SPDX-License-Identifier: LGPL-3.0-or-later

// basic_types.hpp
// Basic type definitions and forward declarations
//
// This file provides the basic type definitions used in other header files.
// To avoid circular references, this file does not depend on other header files.

#ifndef SANGI_BASIC_TYPES_HPP
#define SANGI_BASIC_TYPES_HPP

#include <cstdint>
#include <utility> // added for std::pair
#include <stdexcept> // added for exception classes

namespace sangi {

    // Version information
    constexpr int VERSION_MAJOR = 2;
    constexpr int VERSION_MINOR = 0;
    constexpr int VERSION_PATCH = 0;

    /**
     * @brief Enumeration representing numeric state
     * IEEE 754 compliant with extended numeric states
     */
    enum class NumericState : uint16_t {
        // Normal state
        Normal = 0,                     ///< Ordinary valid numeric value

        // Special states
        NaN = 1,                        ///< Not a number
        PositiveInfinity = 100,         ///< +∞
        NegativeInfinity = 101,         ///< -∞
        ComplexInfinity = 102,          ///< Complex infinity
        Overflow = 103,                 ///< Numeric value is too large
        Underflow = 104,                ///< Numeric value is too small (precision lost)
        Interrupted = 105,              ///< Computation was interrupted
        PrecisionLimit = 106,           ///< Issue with the precision of the result

        // Zero-related states
        PositiveZero = 201,      ///< +0
        NegativeZero = 202,      ///< -0

        // Special floating-point states
        Subnormal = 300,         ///< Subnormal number

        // Convergence states
        NotConverged = 400,      ///< Did not converge
        Divergent = 401,         ///< Diverged
        Oscillating = 402,       ///< Oscillating
        SlowConvergence = 403,   ///< Slow convergence
        TruncatedConvergence = 404 ///< Convergence computation was truncated midway
    };

    /**
     * @brief Enumeration representing numeric error causes
     * Indicates the cause of an error in numeric computation
     */
    enum class NumericError : uint16_t {
        None = 0,                       ///< No error
        DivideByZero = 1,               ///< Division by zero
        InfiniteIndeterminate = 2,      ///< ∞/∞, ∞-∞
        ZeroTimesInfinity = 3,          ///< 0×∞
        NegativeSqrt = 4,               ///< Square root of a negative number
        ConversionError = 5,            ///< Conversion outside the representable range
        ExplicitNaN = 6,                ///< NaN set programmatically
        Uninitialized = 7,              ///< Uninitialized variable
        InvalidBitPattern = 8,          ///< NaN bit pattern defined by IEEE 754
        InvalidStringConversion = 9,    ///< Conversion from a string not interpretable as a number
        OutOfRangeInput = 10,           ///< Value exceeding implementation limits
        NaNPropagation = 11,            ///< Propagation from an operation with NaN
        IntegerConversionError = 12,    ///< Conversion from an integer not representable in floating-point
        FunctionDomainError = 13,       ///< Value outside the domain of a math function (e.g. asin(2))
        InvalidBitOperation = 14,       ///< Inappropriate bit operation
        DivergenceError = 15,           ///< Divergence error
        ConditionalConvergenceViolation = 16  ///< Conditional-convergence violation (referenced by convergence_criteria.hpp)
    };

    /**
     * @brief Auxiliary enumeration for divergence details
     */
    enum class DivergenceDetail : uint8_t {
        None = 0,                   ///< Not diverging
        Diverging = 1,              ///< Monotonically increasing/decreasing divergence
        Oscillating = 2,            ///< Oscillating with increasing amplitude
        Chaotic = 3,                ///< Exhibits chaotic behavior
        SlowConvergence = 4,        ///< Converges, but extremely slowly
        TruncatedConvergence = 5,   ///< Convergence process truncated (e.g. maximum iterations reached)
        ConditionalConvergenceViolation = 6,    ///< Conditional convergence does not hold
        AlternatingSeriesDivergence = 7         ///< Alternating series diverges
    };

    // SIMD instruction-set detection
    enum class SimdInstructionSet {
        None,
        SSE2,
        SSE3,
        SSSE3,
        SSE4_1,
        SSE4_2,
        AVX,
        AVX2,
        AVX512,
        NEON
    };

    // Error-handling options for states
    enum class StateErrorMode {
        Exception,     // Throw an exception when an error occurs
        ReturnSpecial, // Return a special value (NaN, infinity, etc.)
        Silent         // Ignore errors (warning only)
    };

    // Forward declarations
    class Int;
    class Float;
    template<typename T> class Matrix;
    template<typename T> class Vector;

    // Forward declaration of the numeric-state traits class
    class NumericStateTraits;

    // Forward declaration of the UInt128 type (UInt128.hpp include removed)
    struct UInt128;

} // namespace sangi

#endif // SANGI_BASIC_TYPES_HPP