diff options
author | Sven Gothel <[email protected]> | 2020-12-02 22:05:32 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2020-12-02 22:05:32 +0100 |
commit | c7bf17933016e6cd0f8d9bb54ae7a662911058d4 (patch) | |
tree | 36028ab6a7b0cb0c20fd6139a4d22f705bb196f3 | |
parent | ab78639c0dc59a087088e8581f2363e7f74daf5b (diff) |
basic_algos.hpp: Add constexpr noexcept template functions: sign(T), abs(T) and digits10(T)
Since above functions utilze nsize_t and snsize_t,
their definition is also moved to basic_algos.hpp from basic_types.hpp.
-rw-r--r-- | include/jau/basic_algos.hpp | 97 | ||||
-rw-r--r-- | include/jau/basic_types.hpp | 31 |
2 files changed, 98 insertions, 30 deletions
diff --git a/include/jau/basic_algos.hpp b/include/jau/basic_algos.hpp index 1121eda..39603ab 100644 --- a/include/jau/basic_algos.hpp +++ b/include/jau/basic_algos.hpp @@ -27,8 +27,105 @@ #define JAU_BASIC_ALGOS_HPP_ #include <mutex> +#include <cmath> namespace jau { + /** + // ************************************************* + // ************************************************* + // ************************************************* + */ + + /** + * Natural 'size_t' alternative using 'unsigned int' as its natural sized type. + * <p> + * The leading 'n' stands for natural. + * </p> + * <p> + * This is a compromise to indicate intend, + * but to avoid handling a multiple sized 'size_t' footprint where not desired. + * </p> + */ + typedef unsigned int nsize_t; + + /** + * Natural 'ssize_t' alternative using 'signed int' as its natural sized type. + * <p> + * The leading 'n' stands for natural. + * </p> + * <p> + * This is a compromise to indicate intend, + * but to avoid handling a multiple sized 'ssize_t' footprint where not desired. + * </p> + */ + typedef signed int snsize_t; + + /** + // ************************************************* + // ************************************************* + // ************************************************* + */ + + /** + * Returns the value of the sign function. + * <pre> + * -1 for x < 0 + * 0 for x = 0 + * 1 for x > 0 + * </pre> + * Implementation is type safe. + * @tparam T an integral number type + * @param x the integral number + * @return function result + */ + template <typename T> + constexpr snsize_t sign(T x) noexcept + { + return (T(0) < x) - (x < T(0)); + } + + /** + * Returns the absolute value of an integral number + * @tparam T an integral number type + * @param x the integral number + * @return function result + */ + template <typename T> + constexpr T abs(T x) noexcept + { + return sign(x) < 0 ? -x : x; + } + + /** + * Returns the number of decimal digits of the given integral value number using std::log10<T>(). + * <pre> + * x < 0: 2 + floor( log10( -x ) ) ) + * x = 0: 1 + * x > 0: 1 + (int)( log10( x ) ) ) + * </p> + * @tparam T an integral integer type + * @param x the integral integer + * @return digit count + */ + template<typename T> + constexpr nsize_t digits10(T x) noexcept + { + const snsize_t x_sign = jau::sign<T>(x); + if( x_sign == 0 ) { + return 1; + } + if( x_sign < 0 ) { + return 2 + static_cast<nsize_t>( std::floor<T>( std::log10<T>( -x ) ) ); + } else { + return 1 + static_cast<nsize_t>( std::log10<T>( x ) ); + } + } + + /** + // ************************************************* + // ************************************************* + // ************************************************* + */ /** * Custom for_each template, using indices instead of iterators, diff --git a/include/jau/basic_types.hpp b/include/jau/basic_types.hpp index b1b0d87..3e6d53d 100644 --- a/include/jau/basic_types.hpp +++ b/include/jau/basic_types.hpp @@ -37,6 +37,7 @@ extern "C" { #include <byteswap.h> } +#include <jau/basic_algos.hpp> #include <jau/packed_attribute.hpp> namespace jau { @@ -52,36 +53,6 @@ namespace jau { // ************************************************* */ - /** - * Natural 'size_t' alternative using 'unsigned int' as its natural sized type. - * <p> - * The leading 'n' stands for natural. - * </p> - * <p> - * This is a compromise to indicate intend, - * but to avoid handling a multiple sized 'size_t' footprint where not desired. - * </p> - */ - typedef unsigned int nsize_t; - - /** - * Natural 'ssize_t' alternative using 'signed int' as its natural sized type. - * <p> - * The leading 'n' stands for natural. - * </p> - * <p> - * This is a compromise to indicate intend, - * but to avoid handling a multiple sized 'ssize_t' footprint where not desired. - * </p> - */ - typedef signed int snsize_t; - - /** - // ************************************************* - // ************************************************* - // ************************************************* - */ - #define E_FILE_LINE __FILE__,__LINE__ class RuntimeException : public std::exception { |