diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2017-05-16 10:11:20 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2017-05-16 14:13:25 +0200 |
commit | a6f29aae36e5b07d877d7ea833b6d06b49b5574a (patch) | |
tree | 34525744d5b2361bf779038515d77d3d7e078cdb | |
parent | 8ce3c3b202d6393199f24e00ac1ece715a8bf150 (diff) |
Blind fix for MSVC 2017 warning C4018: '>=': signed/unsigned mismatch
...and get rid of the arbitrary, bogus 'long' strong_int ctor parameter
type
Change-Id: If71f4d3993e984b4089b74ff96dce75c68a6cf77
Reviewed-on: https://gerrit.libreoffice.org/37665
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Tested-by: Stephan Bergmann <sbergman@redhat.com>
-rw-r--r-- | include/o3tl/strong_int.hxx | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/include/o3tl/strong_int.hxx b/include/o3tl/strong_int.hxx index ce5466e45167..8a9d91dbfb8c 100644 --- a/include/o3tl/strong_int.hxx +++ b/include/o3tl/strong_int.hxx @@ -23,10 +23,52 @@ #include <sal/config.h> #include <limits> #include <cassert> +#include <type_traits> namespace o3tl { +#if HAVE_CXX14_CONSTEXPR + +namespace detail { + +template<typename T1, typename T2> constexpr +typename std::enable_if< + std::is_signed<T1>::value && std::is_signed<T2>::value, bool>::type +isInRange(T2 value) { + return value >= std::numeric_limits<T1>::min() + && value <= std::numeric_limits<T1>::max(); +} + +template<typename T1, typename T2> constexpr +typename std::enable_if< + std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool>::type +isInRange(T2 value) { + return value + <= static_cast<typename std::make_unsigned<T1>::type>( + std::numeric_limits<T1>::max()); +} + +template<typename T1, typename T2> constexpr +typename std::enable_if< + std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool>::type +isInRange(T2 value) { + return value >= 0 + && (static_cast<typename std::make_unsigned<T2>::type>(value) + <= std::numeric_limits<T1>::max()); +} + +template<typename T1, typename T2> constexpr +typename std::enable_if< + std::is_unsigned<T1>::value && std::is_unsigned<T2>::value, bool>::type +isInRange(T2 value) { + return value <= std::numeric_limits<T1>::max(); +} + +} + +#endif + /// /// Wrap up an integer type so that we prevent accidental conversion to other integer types. /// @@ -42,12 +84,14 @@ template <typename UNDERLYING_TYPE, typename PHANTOM_TYPE> struct strong_int { public: - explicit constexpr strong_int(long value) : m_value(value) + template<typename T> explicit constexpr strong_int( + T value, + typename std::enable_if<std::is_integral<T>::value, int>::type = 0): + m_value(value) { #if HAVE_CXX14_CONSTEXPR // catch attempts to pass in out-of-range values early - assert(value >= std::numeric_limits<UNDERLYING_TYPE>::min() - && value <= std::numeric_limits<UNDERLYING_TYPE>::max() + assert(detail::isInRange<UNDERLYING_TYPE>(value) && "out of range"); #endif } |