diff --git a/hash/sha1.cpp b/hash/sha1.cpp index 7042bd07..8f0903bf 100644 --- a/hash/sha1.cpp +++ b/hash/sha1.cpp @@ -225,25 +225,25 @@ SHA1::digest (void) const { CHECK_EQ (state, FINISHED); return { { - size_cast ((H[0] >> 24u) & 0xFF), - size_cast ((H[0] >> 16u) & 0xFF), - size_cast ((H[0] >> 8u) & 0xFF), - size_cast ((H[0] ) & 0xFF), - size_cast ((H[1] >> 24u) & 0xFF), - size_cast ((H[1] >> 16u) & 0xFF), - size_cast ((H[1] >> 8u) & 0xFF), - size_cast ((H[1] ) & 0xFF), - size_cast ((H[2] >> 24u) & 0xFF), - size_cast ((H[2] >> 16u) & 0xFF), - size_cast ((H[2] >> 8u) & 0xFF), - size_cast ((H[2] ) & 0xFF), - size_cast ((H[3] >> 24u) & 0xFF), - size_cast ((H[3] >> 16u) & 0xFF), - size_cast ((H[3] >> 8u) & 0xFF), - size_cast ((H[3] ) & 0xFF), - size_cast ((H[4] >> 24u) & 0xFF), - size_cast ((H[4] >> 16u) & 0xFF), - size_cast ((H[4] >> 8u) & 0xFF), - size_cast ((H[4] ) & 0xFF) + trunc_cast ((H[0] >> 24u) & 0xFF), + trunc_cast ((H[0] >> 16u) & 0xFF), + trunc_cast ((H[0] >> 8u) & 0xFF), + trunc_cast ((H[0] ) & 0xFF), + trunc_cast ((H[1] >> 24u) & 0xFF), + trunc_cast ((H[1] >> 16u) & 0xFF), + trunc_cast ((H[1] >> 8u) & 0xFF), + trunc_cast ((H[1] ) & 0xFF), + trunc_cast ((H[2] >> 24u) & 0xFF), + trunc_cast ((H[2] >> 16u) & 0xFF), + trunc_cast ((H[2] >> 8u) & 0xFF), + trunc_cast ((H[2] ) & 0xFF), + trunc_cast ((H[3] >> 24u) & 0xFF), + trunc_cast ((H[3] >> 16u) & 0xFF), + trunc_cast ((H[3] >> 8u) & 0xFF), + trunc_cast ((H[3] ) & 0xFF), + trunc_cast ((H[4] >> 24u) & 0xFF), + trunc_cast ((H[4] >> 16u) & 0xFF), + trunc_cast ((H[4] >> 8u) & 0xFF), + trunc_cast ((H[4] ) & 0xFF) } }; } diff --git a/types/casts.hpp b/types/casts.hpp index 0b904622..8fab11b4 100644 --- a/types/casts.hpp +++ b/types/casts.hpp @@ -56,6 +56,7 @@ namespace detail { { return v; } } + /// Safely cast a numeric type to its (un)signed counterpart, aborting if the /// dynamically checked result is not representable. May be optimised out if /// NDEBUG is defined. @@ -65,60 +66,29 @@ sign_cast (const V v) { return detail::_sign_cast(v); } -//----------------------------------------------------------------------------- -namespace detail { - // Same sign, no possibility of truncation with larger target type - template - T - _trunc_cast (const typename std::enable_if= sizeof (V) && - std::is_signed::value == std::is_signed::value, V>::type v) - { return v; } +///---------------------------------------------------------------------------- +/// assert if the value cannot be cast loslessly from U to T, else return the +/// converted value.Note: this is only a debug-time check and is compiled out +/// in optimised builds. +template +T +trunc_cast (U u) +{ + auto t = static_cast (u); + if (u == u) + CHECK_EQ (t, u); + else + CHECK_NEQ (t, t); - template - T - _trunc_cast (const typename std::enable_if::value == std::is_signed::value && - std::is_integral::value, V>::type v) { - CHECK_LE (v, std::numeric_limits::max ()); - CHECK_GE (v, std::numeric_limits::lowest ()); - - return static_cast (v); - } - - - template - T - _trunc_cast (const typename std::enable_if::value == std::is_signed::value && - std::is_floating_point::value, V>::type v) { - CHECK_LE (v, std::numeric_limits::max ()); - CHECK_GE (v, std::numeric_limits::lowest ()); - CHECK_EQ (remainder (v, 1), 0.0); - - return static_cast (v); - } + return t; } -template -T -trunc_cast (V v) - { return detail::_trunc_cast (v); } - - -//----------------------------------------------------------------------------- -template -T -size_cast (const V v) { - CHECK_LE (std::numeric_limits::lowest (), v); - CHECK_GE (std::numeric_limits::max (), v); - - return static_cast (v); -} - - -//----------------------------------------------------------------------------- +///---------------------------------------------------------------------------- +/// assert if the value is not a pointer to a subclass of T, else return the +/// converted value. Note: this is only a debug-time check and is compiled out +/// in optimised builds. template T* known_cast (V *v) { @@ -127,6 +97,7 @@ known_cast (V *v) { } +//----------------------------------------------------------------------------- template T& known_cast (V &v) {