// Copyright (C) 2026 Kiyotsugu Arai // SPDX-License-Identifier: LGPL-3.0-or-later // error.hpp // // 状態管理システム関連のエラー処理 // // このファイルでは、数値状態管理システムに関連するエラー処理機能の追加インターフェースを提供します。 // common.hppで定義された例外クラスと状態エラー処理機能を利用して、より特化したエラー処理を実装します。 // // 主な機能: // - 特殊なエラー検出ユーティリティ // - 追加のエラー処理ポリシー #ifndef CALX_ERROR_HPP #define CALX_ERROR_HPP #include #include #include #include #include namespace calx { // エラー処理ユーティリティ // ゼロ除算チェック template inline void check_division_by_zero(T divisor, const std::string& message = "Division by zero") { if (divisor == T(0)) { const auto& options = global_state_error_options(); switch (options.divide_by_zero_error_mode) { case StateErrorMode::Exception: throw DivideByZeroError(message); case StateErrorMode::ReturnSpecial: case StateErrorMode::Silent: // 特殊値は呼び出し側で処理 break; } } } // NaNチェック template inline void check_nan(const T& value, const std::string& message = "Operation resulted in NaN") { if (std::isnan(value)) { const auto& options = global_state_error_options(); switch (options.nan_error_mode) { case StateErrorMode::Exception: throw NaNError(message); case StateErrorMode::ReturnSpecial: case StateErrorMode::Silent: // 特殊値は呼び出し側で処理 break; } } } // 無限大チェック template inline void check_infinity(const T& value, const std::string& message = "Operation resulted in infinity") { if (std::isinf(value)) { const auto& options = global_state_error_options(); switch (options.infinity_error_mode) { case StateErrorMode::Exception: throw InfinityError(message, value > 0); case StateErrorMode::ReturnSpecial: case StateErrorMode::Silent: // 特殊値は呼び出し側で処理 break; } } } // オーバーフローチェック inline void check_overflow(bool overflow_condition, const std::string& message = "Numeric overflow") { if (overflow_condition) { const auto& options = global_state_error_options(); switch (options.overflow_error_mode) { case StateErrorMode::Exception: throw OverflowError(message); case StateErrorMode::ReturnSpecial: case StateErrorMode::Silent: // 特殊値は呼び出し側で処理 break; } } } // アンダーフローチェック inline void check_underflow(bool underflow_condition, const std::string& message = "Numeric underflow") { if (underflow_condition) { const auto& options = global_state_error_options(); switch (options.underflow_error_mode) { case StateErrorMode::Exception: throw UnderflowError(message); case StateErrorMode::ReturnSpecial: case StateErrorMode::Silent: // 特殊値は呼び出し側で処理 break; } } } // 発散チェック inline void check_divergence(bool divergence_condition, DivergenceDetail detail = DivergenceDetail::Diverging, const std::string& message = "Algorithm diverged") { if (divergence_condition) { const auto& options = global_state_error_options(); switch (options.divergence_error_mode) { case StateErrorMode::Exception: throw DivergenceStateError(message, detail); case StateErrorMode::ReturnSpecial: case StateErrorMode::Silent: // 特殊値は呼び出し側で処理 break; } } } // エラー原因と状態を結合したチェック inline void check_error_and_state(NumericError error, NumericState state, const std::string& message = "Numeric error occurred") { const auto& options = global_state_error_options(); // エラー原因に基づくチェック if (error != NumericError::None) { switch (error) { case NumericError::DivideByZero: if (options.divide_by_zero_error_mode == StateErrorMode::Exception) { throw DivideByZeroError(message); } break; case NumericError::NaNPropagation: case NumericError::ExplicitNaN: if (options.nan_error_mode == StateErrorMode::Exception) { throw NaNError(message); } break; case NumericError::ConversionError: case NumericError::OutOfRangeInput: if (options.overflow_error_mode == StateErrorMode::Exception) { throw OverflowError(message); } break; case NumericError::DivergenceError: if (options.divergence_error_mode == StateErrorMode::Exception) { throw DivergenceStateError(message); } break; default: // その他のエラーは特に処理しない break; } } // 状態に基づくチェック if (NumericStateTraits::isNaN(state) && options.nan_error_mode == StateErrorMode::Exception) { throw NaNError(message); } if (NumericStateTraits::isInfinite(state)) { if (options.infinity_error_mode == StateErrorMode::Exception) { bool is_positive = (state == NumericState::PositiveInfinity); throw InfinityError(message, is_positive); } } if (state == NumericState::Overflow && options.overflow_error_mode == StateErrorMode::Exception) { throw OverflowError(message); } if (state == NumericState::Underflow && options.underflow_error_mode == StateErrorMode::Exception) { throw UnderflowError(message); } if (NumericStateTraits::isDivergent(state) && options.divergence_error_mode == StateErrorMode::Exception) { throw DivergenceStateError(message); } } // 追加: 状態とエラーの一貫性を検証するユーティリティ inline void validate_state_and_error(NumericState& state, NumericError& error) { // エラーがあるのに状態が正常な場合、エラーに対応する状態を設定 if (error != NumericError::None && state == NumericState::Normal) { state = NumericStateTraits::errorToState(error); } // 状態が特殊なのにエラーがない場合、状態に対応するデフォルトのエラーを設定 if (NumericStateTraits::requiresErrorCode(state) && error == NumericError::None) { error = NumericStateTraits::stateToDefaultError(state); } } // 追加: 状態とエラーを一貫して設定するヘルパー inline void set_state_and_error(NumericState& state_dest, NumericError& error_dest, NumericState state_src, NumericError error_src) { state_dest = state_src; error_dest = error_src; validate_state_and_error(state_dest, error_dest); } } // namespace calx #endif // CALX_ERROR_HPP