summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2017-05-16 10:11:20 +0200
committerStephan Bergmann <sbergman@redhat.com>2017-05-16 14:13:25 +0200
commita6f29aae36e5b07d877d7ea833b6d06b49b5574a (patch)
tree34525744d5b2361bf779038515d77d3d7e078cdb /include
parent8ce3c3b202d6393199f24e00ac1ece715a8bf150 (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>
Diffstat (limited to 'include')
-rw-r--r--include/o3tl/strong_int.hxx50
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
}