summaryrefslogtreecommitdiff
path: root/zen/int64.h
diff options
context:
space:
mode:
Diffstat (limited to 'zen/int64.h')
-rw-r--r--zen/int64.h25
1 files changed, 10 insertions, 15 deletions
diff --git a/zen/int64.h b/zen/int64.h
index 31c278ca..a5140ffd 100644
--- a/zen/int64.h
+++ b/zen/int64.h
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) ZenJu (zhnmju123 AT gmx DOT de) - All Rights Reserved *
// **************************************************************************
#ifndef FFS_LARGE_64_BIT_INTEGER_H_INCLUDED
@@ -14,6 +14,7 @@
#include <ostream>
#include "assert_static.h"
#include "type_tools.h"
+#include "type_traits.h"
#ifdef FFS_WIN
#include "win.h"
@@ -46,18 +47,15 @@ void checkRange(U value)
class Int64
{
- struct DummyClass { operator int() { return 0; } };
public:
//safe implicit conversions
Int64() : value(0) {}
Int64(const Int64& rhs) : value(rhs.value) {}
- Int64(int rhs) : value(rhs) {} //ambiguity intentional for types other than these
- Int64(long rhs) : value(rhs) {}
- Int64(SelectIf<IsSameType<std::int64_t, long>::result, DummyClass, std::int64_t>::Result rhs) :
- value(rhs) {} //-> std::int64_t equals long int on x64 Linux! Still we want implicit behavior for all other systems!
+ template <class T>
+ Int64(T rhs, typename EnableIf<IsSignedInt<T>::result && sizeof(T) <= sizeof(std::int64_t)>::Result* = NULL) : value(static_cast<std::int64_t>(rhs)) {}
- //unsafe explicit but checked conversion from arbitrary integer type
- template <class T> explicit Int64(T rhs) : value(static_cast<std::int64_t>(rhs)) { checkRange<std::int64_t>(rhs); }
+ //unsafe explicit but checked conversion for all other integer types
+ template <class T> explicit Int64(T rhs, typename EnableIf<!(IsSignedInt<T>::result && sizeof(T) <= sizeof(std::int64_t))>::Result* = NULL) : value(static_cast<std::int64_t>(rhs)) { checkRange<std::int64_t>(rhs); }
Int64& operator=(const Int64& rhs) { value = rhs.value; return *this; }
@@ -126,18 +124,15 @@ inline Int64 operator>>(const Int64& lhs, int rhs) { return Int64(lhs) >>= rhs;
class UInt64
{
- struct DummyClass { operator size_t() { return 0U; } };
public:
//safe implicit conversions
UInt64() : value(0) {}
UInt64(const UInt64& rhs) : value(rhs.value) {}
- UInt64(unsigned int rhs) : value(rhs) {} //ambiguity intentional for types other than these
- UInt64(unsigned long rhs) : value(rhs) {}
- UInt64(SelectIf<IsSameType<std::uint64_t, unsigned long>::result, DummyClass, std::uint64_t>::Result rhs) :
- value(rhs) {} //-> std::uint64_t equals unsigned long int on x64 Linux! Still we want implicit behavior for all other systems!
+ template <class T>
+ UInt64(T rhs, typename EnableIf<IsUnsignedInt<T>::result && sizeof(T) <= sizeof(std::uint64_t)>::Result* = NULL) : value(static_cast<std::uint64_t>(rhs)) {}
- //unsafe explicit but checked conversion from arbitrary integer type
- template <class T> explicit UInt64(T rhs) : value(static_cast<std::uint64_t>(rhs)) { checkRange<std::uint64_t>(rhs); }
+ //unsafe explicit but checked conversion for all other integer types
+ template <class T> explicit UInt64(T rhs, typename EnableIf<!(IsUnsignedInt<T>::result && sizeof(T) <= sizeof(std::uint64_t))>::Result* = NULL) : value(static_cast<std::uint64_t>(rhs)) { checkRange<std::uint64_t>(rhs); }
UInt64& operator=(const UInt64& rhs) { value = rhs.value; return *this; }
bgstack15