//! Helper macros for validated type implementations.
//!
//! This module provides composable macro helpers to reduce boilerplate when implementing
//! traits for validated wrapper types. These macros are used internally by the library
//! and are not part of the public API.

/// Generates standard arithmetic operator implementations (Add, Sub, Mul, Div) for a validated type.
///
/// This macro creates all four variants for each operator:
/// - `T op T`
/// - `&T op T`
/// - `T op &T`
/// - `&T op &T`
///
/// # Usage
///
/// ```ignore
/// impl_arithmetic_ops!(RealValidated, RealPolicy, RawReal);
/// ```
#[macro_export]
macro_rules! impl_arithmetic_ops {
    ($struct_name:ident, $policy_type:ident, $raw_type:ident) => {
        // Uses internal helper macros from validated.rs
        $crate::__impl_validated_arithmetic_op!(
            $struct_name, $policy_type, Add, add, 
            "Addition failed during validation", {}
        );
        $crate::__impl_validated_arithmetic_op!(
            $struct_name, $policy_type, Sub, sub, 
            "Subtraction failed during validation", {}
        );
        $crate::__impl_validated_arithmetic_op!(
            $struct_name, $policy_type, Mul, mul, 
            "Multiplication failed during validation", {}
        );
        $crate::__impl_validated_arithmetic_op!(
            $struct_name, $policy_type, Div, div, 
            "Division failed during validation",
            { |rhs: &$struct_name<_>| debug_assert!(!rhs.is_zero(), "Division by zero") }
        );
    };
}

/// Generates Zero and One trait implementations for a validated type.
///
/// # Usage
///
/// ```ignore
/// impl_numeric_identity_traits!(RealValidated);
/// ```
#[macro_export]
macro_rules! impl_numeric_identity_traits {
    ($struct_name:ident) => {
        impl<K: $crate::kernels::NumKernel> num::Zero for $struct_name<K> {
            fn zero() -> Self {
                Self::new(K::$raw_type::zero())
            }
            fn is_zero(&self) -> bool {
                self.value.is_zero()
            }
        }
        
        impl<K: $crate::kernels::NumKernel> num::One for $struct_name<K> {
            fn one() -> Self {
                Self::new(K::$raw_type::one())
            }
        }
    };
}

/// Generates assignment operator implementations (AddAssign, SubAssign, MulAssign, DivAssign).
///
/// Creates both variants:
/// - `T op= T`
/// - `T op= &T`
///
/// # Usage
///
/// ```ignore
/// impl_arithmetic_assign_ops!(RealValidated, RealPolicy, RawReal);
/// ```
#[macro_export]
macro_rules! impl_arithmetic_assign_ops {
    ($struct_name:ident, $policy_type:ident, $raw_type:ident) => {
        $crate::__impl_validated_arithmetic_op_assign!(
            $struct_name, $policy_type, AddAssign, add_assign, 
            "AddAssign failed during validation", {}
        );
        $crate::__impl_validated_arithmetic_op_assign!(
            $struct_name, $policy_type, SubAssign, sub_assign, 
            "SubAssign failed during validation", {}
        );
        $crate::__impl_validated_arithmetic_op_assign!(
            $struct_name, $policy_type, MulAssign, mul_assign, 
            "MulAssign failed during validation", {}
        );
        $crate::__impl_validated_arithmetic_op_assign!(
            $struct_name, $policy_type, DivAssign, div_assign, 
            "DivAssign failed during validation",
            { |rhs: &$struct_name<_>| debug_assert!(!rhs.is_zero(), "Division by zero") }
        );
    };
}
