summaryrefslogtreecommitdiffstats
path: root/include/jau/int_math.hpp
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2022-04-28 16:36:19 +0200
committerSven Gothel <[email protected]>2022-04-28 16:36:19 +0200
commit3f6cb97dc0d58e3b9121f535f90d550dd4e8e4e6 (patch)
tree3f70ba0cc61446202427ca721f741b5fc0d8c6a0 /include/jau/int_math.hpp
parentba9884f976668c352f7fde7481fe4a2483017b92 (diff)
int_math.hpp: Refine sign(), invert_sign(), abs() and digits10() template funcs: Better type and signed/unsigned variant for invert_sign() and abs()
Diffstat (limited to 'include/jau/int_math.hpp')
-rw-r--r--include/jau/int_math.hpp63
1 files changed, 45 insertions, 18 deletions
diff --git a/include/jau/int_math.hpp b/include/jau/int_math.hpp
index 1d0e926..be20d16 100644
--- a/include/jau/int_math.hpp
+++ b/include/jau/int_math.hpp
@@ -39,6 +39,8 @@ namespace jau {
// *************************************************
*/
+ // Remember: constexpr specifier used in a function or static data member (since C++17) declaration implies inline.
+
/**
* Returns the value of the sign function.
* <pre>
@@ -47,28 +49,30 @@ namespace jau {
* 1 for x > 0
* </pre>
* Implementation is type safe.
- * @tparam T an integral number type
- * @param x the integral number
+ * @tparam T an arithmetic number type
+ * @param x the arithmetic number
* @return function result
*/
- template <typename T>
+ template <typename T,
+ std::enable_if_t< std::is_arithmetic_v<T>, bool> = true>
constexpr snsize_t sign(const T x) noexcept
{
return (T(0) < x) - (x < T(0));
}
/**
- * Safely inverts the sign of an integral number.
- * <p>
+ * Safely inverts the sign of an arithmetic number.
+ *
* Implementation takes special care to have T_MIN, i.e. std::numeric_limits<T>::min(),
* converted to T_MAX, i.e. std::numeric_limits<T>::max().<br>
* This is necessary since <code>T_MAX < | -T_MIN |</code> and the result would
* not fit in the return type T otherwise.
- * </p>
+ *
* Hence for the extreme minimum case:
* <pre>
* jau::invert_sign<int32_t>(INT32_MIN) = | INT32_MIN | - 1 = INT32_MAX
* </pre>
+ *
* Otherwise with x < 0:
* <pre>
* jau::invert_sign<int32_t>(x) = | x | = -x
@@ -77,31 +81,52 @@ namespace jau {
* <pre>
* jau::invert_sign<int32_t>(x) = -x
* </pre>
- * @tparam T
- * @param x
- * @return
+ *
+ * @tparam T an arithmetic number type
+ * @param x the arithmetic number
+ * @return function result
*/
- template <typename T>
+ template <typename T,
+ std::enable_if_t< std::is_arithmetic_v<T> &&
+ !std::is_unsigned_v<T>, bool> = true>
constexpr T invert_sign(const T x) noexcept
{
return std::numeric_limits<T>::min() == x ? std::numeric_limits<T>::max() : -x;
}
+ template <typename T,
+ std::enable_if_t< std::is_arithmetic_v<T> &&
+ std::is_unsigned_v<T>, bool> = true>
+ constexpr T invert_sign(const T x) noexcept
+ {
+ return x;
+ }
+
/**
- * Returns the absolute value of an integral number
- * <p>
+ * Returns the absolute value of an arithmetic number
+ *
* Implementation uses jau::invert_sign() to have a safe absolute value conversion, if required.
- * </p>
- * @tparam T an integral number type
- * @param x the integral number
+ *
+ * @tparam T an arithmetic number type
+ * @param x the arithmetic number
* @return function result
*/
- template <typename T>
+ template <typename T,
+ std::enable_if_t< std::is_arithmetic_v<T> &&
+ !std::is_unsigned_v<T>, bool> = true>
constexpr T abs(const T x) noexcept
{
return sign(x) < 0 ? invert_sign<T>( x ) : x;
}
+ template <typename T,
+ std::enable_if_t< std::is_arithmetic_v<T> &&
+ std::is_unsigned_v<T>, bool> = true>
+ constexpr T abs(const T x) noexcept
+ {
+ return x;
+ }
+
/**
* Returns the number of decimal digits of the given integral value number using std::log10<T>().<br>
* If sign_is_digit == true (default), treats a potential negative sign as a digit.
@@ -120,7 +145,8 @@ namespace jau {
* @param sign_is_digit if true and value is negative, adds one to result for sign. Defaults to true.
* @return digit count
*/
- template<typename T>
+ template <typename T,
+ std::enable_if_t< std::is_integral_v<T>, bool> = true>
constexpr nsize_t digits10(const T x, const snsize_t x_sign, const bool sign_is_digit=true) noexcept
{
if( x_sign == 0 ) {
@@ -147,7 +173,8 @@ namespace jau {
* @param sign_is_digit if true and value is negative, adds one to result for sign. Defaults to true.
* @return digit count
*/
- template<typename T>
+ template <typename T,
+ std::enable_if_t< std::is_integral_v<T>, bool> = true>
constexpr nsize_t digits10(const T x, const bool sign_is_digit=true) noexcept
{
return digits10<T>(x, jau::sign<T>(x), sign_is_digit);