diff --git a/include/gcem_incl/is_finite.hpp b/include/gcem_incl/is_finite.hpp index ff39a46..6326abe 100644 --- a/include/gcem_incl/is_finite.hpp +++ b/include/gcem_incl/is_finite.hpp @@ -25,8 +25,12 @@ #ifndef _gcem_is_finite_HPP #define _gcem_is_finite_HPP -namespace internal -{ +/** + * Compile-time check if a float is not NaN-valued or +/-Inf + * + * @param x floating point value. + * @return true if \c x is not NaN-valued or +/-Inf, false otherwise. + */ template constexpr @@ -37,42 +41,68 @@ noexcept return (!is_nan(x)) && (!is_inf(x)); } -template +/** + * Compile-time check if a float is not NaN-valued or +/-Inf + * + * @param x floating point value. + * @return true if \c x is not NaN-valued or +/-Inf, false otherwise. + */ + +template constexpr bool -any_finite(const T1 x, const T2 y) +any_finite(const T x) noexcept { - return( is_finite(x) || is_finite(y) ); + return is_finite(x); } -template +/** + * Compile-time check if any float in a sequence is not NaN-valued or +/-Inf + * + * @param args... floating point values. + * @return true if any float in a sequence is not NaN-valued or +/-Inf, false otherwise. + */ + +template constexpr bool -all_finite(const T1 x, const T2 y) +any_finite(const T x, const Args... args) noexcept { - return( is_finite(x) && is_finite(y) ); + return is_finite(x) || any_finite(args...); } -template +/** + * Compile-time check if a float is not NaN-valued or +/-Inf + * + * @param x floating point value. + * @return true if \c x is not NaN-valued or +/-Inf, false otherwise. + */ + +template constexpr bool -any_finite(const T1 x, const T2 y, const T3 z) +all_finite(const T x) noexcept { - return( is_finite(x) || is_finite(y) || is_finite(z) ); + return is_finite(x); } -template +/** + * Compile-time check if all floats in a sequence are not NaN-valued or +/-Inf + * + * @param args... floating point values. + * @return true if all floats in a sequence are not NaN-valued or +/-Inf, false otherwise. + */ + +template constexpr bool -all_finite(const T1 x, const T2 y, const T3 z) +all_finite(const T x, const Args... args) noexcept { - return( is_finite(x) && is_finite(y) && is_finite(z) ); -} - + return is_finite(x) && all_finite(args...); } #endif diff --git a/include/gcem_incl/is_inf.hpp b/include/gcem_incl/is_inf.hpp index 703e6a1..91bab0e 100644 --- a/include/gcem_incl/is_inf.hpp +++ b/include/gcem_incl/is_inf.hpp @@ -25,8 +25,12 @@ #ifndef _gcem_is_inf_HPP #define _gcem_is_inf_HPP -namespace internal -{ +/** + * Compile-time check if a float is -Inf + * + * @param x floating point value. + * @return true if \c x is -Inf, false otherwise. + */ template constexpr @@ -37,44 +41,79 @@ noexcept return x == - GCLIM::infinity(); } -template +/** + * Compile-time check if a float is -Inf + * + * @param x floating point value. + * @return true if \c x is -Inf, false otherwise. + */ + +template constexpr bool -any_neginf(const T1 x, const T2 y) +any_neginf(const T x) noexcept { - return( is_neginf(x) || is_neginf(y) ); + return is_neginf(x); } -template +/** + * Compile-time check if any float in a sequence is -Inf + * + * @param args... floating point values. + * @return true if any float in a sequence is -Inf, false otherwise. + */ + +template constexpr bool -all_neginf(const T1 x, const T2 y) +any_neginf(const T x, const Args... args) noexcept { - return( is_neginf(x) && is_neginf(y) ); + return is_neginf(x) || is_neginf(args...); } -template +/** + * Compile-time check if a float is -Inf + * + * @param x floating point value. + * @return true if \c x is -Inf, false otherwise. + */ + +template constexpr bool -any_neginf(const T1 x, const T2 y, const T3 z) +all_neginf(const T x) noexcept { - return( is_neginf(x) || is_neginf(y) || is_neginf(z) ); + return is_neginf(x); } -template +/** + * Compile-time check if all floats in a sequence are -Inf + * + * @param args... floating point values. + * @return true if all floats in a sequence are -Inf, false otherwise. + */ + +template constexpr bool -all_neginf(const T1 x, const T2 y, const T3 z) +all_neginf(const T x, const Args... args) noexcept { - return( is_neginf(x) && is_neginf(y) && is_neginf(z) ); + return is_neginf(x) && all_neginf(args...); } // +/** + * Compile-time check if a float is +Inf + * + * @param x floating point value. + * @return true if \c x is +Inf, false otherwise. + */ + template constexpr bool @@ -84,89 +123,151 @@ noexcept return x == GCLIM::infinity(); } -template +/** + * Compile-time check if a float is +Inf + * + * @param x floating point value. + * @return true if \c x is +Inf, false otherwise. + */ + +template constexpr bool -any_posinf(const T1 x, const T2 y) +any_posinf(const T x) noexcept { - return( is_posinf(x) || is_posinf(y) ); + return is_posinf(x); } -template +/** + * Compile-time check if any float in a sequence is +Inf + * + * @param args... floating point values. + * @return true if any float in a sequence is +Inf, false otherwise. + */ + +template constexpr bool -all_posinf(const T1 x, const T2 y) +any_posinf(const T x, const Args... args) noexcept { - return( is_posinf(x) && is_posinf(y) ); + return is_posinf(x) || any_posinf(args...); } -template +/** + * Compile-time check if a float is +Inf + * + * @param x floating point value. + * @return true if \c x is +Inf, false otherwise. + */ + +template constexpr bool -any_posinf(const T1 x, const T2 y, const T3 z) +all_posinf(const T x) noexcept { - return( is_posinf(x) || is_posinf(y) || is_posinf(z) ); + return is_posinf(x); } -template +/** + * Compile-time check if all floats in a sequence are +Inf + * + * @param args... floating point values. + * @return true if all floats in a sequence are +Inf, false otherwise. + */ + + +template constexpr bool -all_posinf(const T1 x, const T2 y, const T3 z) +all_posinf(const T x, const Args... args) noexcept { - return( is_posinf(x) && is_posinf(y) && is_posinf(z) ); + return is_posinf(x) && all_posinf(args...); } // +/** + * Compile-time check if a float is +/-Inf + * + * @param x floating point value. + * @return true if \c x is +/-Inf, false otherwise. + */ + template constexpr bool is_inf(const T x) noexcept { - return( is_neginf(x) || is_posinf(x) ); + return is_neginf(x) || is_posinf(x); } -template +/** + * Compile-time check if a float is +/-Inf + * + * @param x floating point value. + * @return true if \c x is +/-Inf, false otherwise. + */ + +template constexpr bool -any_inf(const T1 x, const T2 y) +any_inf(const T x) noexcept { - return( is_inf(x) || is_inf(y) ); + return is_inf(x); } -template +/** + * Compile-time check if any float in a sequence is +/-Inf + * + * @param args... floating point values. + * @return true if any float in a sequence is +/-Inf, false otherwise. + */ + +template constexpr bool -all_inf(const T1 x, const T2 y) +any_inf(const T x, const Args... args) noexcept { - return( is_inf(x) && is_inf(y) ); + return is_inf(x) || any_inf(args...); } -template +/** + * Compile-time check if a float is +/-Inf + * + * @param x floating point value. + * @return true if \c x is +/-Inf, false otherwise. + */ + +template constexpr bool -any_inf(const T1 x, const T2 y, const T3 z) +all_inf(const T x) noexcept { - return( is_inf(x) || is_inf(y) || is_inf(z) ); + return is_inf(x); } -template +/** + * Compile-time check if all floats in a sequence are +/-Inf + * + * @param args... floating point values. + * @return true if all floats in a sequence are +/-Inf, false otherwise. + */ + +template constexpr bool -all_inf(const T1 x, const T2 y, const T3 z) +all_inf(const T x, const Args... args) noexcept { - return( is_inf(x) && is_inf(y) && is_inf(z) ); -} - + return is_inf(x) && all_inf(args...); } #endif diff --git a/include/gcem_incl/is_nan.hpp b/include/gcem_incl/is_nan.hpp index 2fb1ed5..8798c4d 100644 --- a/include/gcem_incl/is_nan.hpp +++ b/include/gcem_incl/is_nan.hpp @@ -25,11 +25,15 @@ #ifndef _gcem_is_nan_HPP #define _gcem_is_nan_HPP -namespace internal -{ - // future: consider using __builtin_isnan(__x) +/** + * Compile-time check if a float is NaN-valued + * + * @param x floating point value. + * @return true if \c x is NaN-valued, false otherwise. + */ + template constexpr bool @@ -39,42 +43,68 @@ noexcept return x != x; } -template +/** + * Compile-time check if a float is NaN-valued + * + * @param x floating point value. + * @return true if \c x is NaN-valued, false otherwise. + */ + +template constexpr bool -any_nan(const T1 x, const T2 y) +any_nan(const T x) noexcept { - return( is_nan(x) || is_nan(y) ); + return is_nan(x); } -template +/** + * Compile-time check if any float in a sequence is NaN-valued + * + * @param args... floating point values. + * @return true if any float in a sequence is NaN-valued, false otherwise. + */ + +template constexpr bool -all_nan(const T1 x, const T2 y) +any_nan(const T x, const Args... args) noexcept { - return( is_nan(x) && is_nan(y) ); + return is_nan(x) || any_nan(args...); } -template +/** + * Compile-time check if a float is NaN-valued + * + * @param x floating point value. + * @return true if \c x is NaN-valued, false otherwise. + */ + +template constexpr bool -any_nan(const T1 x, const T2 y, const T3 z) +all_nan(const T x) noexcept { - return( is_nan(x) || is_nan(y) || is_nan(z) ); + returnis_nan(x); } -template +/** + * Compile-time check if all floats in a sequence are NaN-valued + * + * @param args... floating point values. + * @return true if all floats in a sequence are NaN-valued, false otherwise. + */ + +template constexpr bool -all_nan(const T1 x, const T2 y, const T3 z) +all_nan(const T x, const Args... args) noexcept { - return( is_nan(x) && is_nan(y) && is_nan(z) ); -} - + return is_nan(x) && all_nan(args...); } #endif diff --git a/include/gcem_incl/max.hpp b/include/gcem_incl/max.hpp index 1e34c93..ec57fbb 100644 --- a/include/gcem_incl/max.hpp +++ b/include/gcem_incl/max.hpp @@ -38,4 +38,21 @@ noexcept return( y < x ? x : y ); } +/** + * Compile-time maximum function from parametr pack + * + * @param args... a real-valued input. + * @return Computes the maximum between all \c args... in the pack, where \c args... have the same type (e.g., \c int, \c double, etc.) + */ + +template +constexpr +common_t +max(const T x, const Args... args) +noexcept +{ + const auto y = max(args...); + return( y < x ? x : y ); +} + #endif diff --git a/include/gcem_incl/min.hpp b/include/gcem_incl/min.hpp index a41f6eb..2c6ee25 100644 --- a/include/gcem_incl/min.hpp +++ b/include/gcem_incl/min.hpp @@ -38,4 +38,21 @@ noexcept return( y > x ? x : y ); } +/** + * Compile-time minimum function from parametr pack + * + * @param args... a real-valued input. + * @return Computes the minimum between all \c args... in the pack, where \c args... have the same type (e.g., \c int, \c double, etc.) + */ + +template +constexpr +common_t +min(const T x, const Args... args) +noexcept +{ + const auto y = min(args...); + return( x < y ? x : y ); +} + #endif