Run Code
|
API
|
Code Wall
|
Misc
|
Feedback
|
Login
|
Theme
|
Privacy
|
Patreon
narrow_cast
#include <iostream> #include <limits> using namespace std; #if defined(_MSC_VER) && _MSC_VER < 1900 // const expression are supported from VS 2015 #define CONST_EXPPR #else #define CONST_EXPPR constexpr #endif /* * Helper template which returns common minimum and maximum values for integer types */ template<typename DestinationType, typename SourceType, bool commonSignes, bool DestSourceEqual> struct HelperCommonLimits { static CONST_EXPPR SourceType max() { return static_cast<SourceType>(std::numeric_limits<DestinationType>::max()); } static CONST_EXPPR SourceType min() { return static_cast<SourceType>(std::numeric_limits<DestinationType>::min()); } }; template<typename DestinationType, typename SourceType> struct HelperCommonLimits<DestinationType, SourceType, false, false> { static CONST_EXPPR SourceType max() { return static_cast<SourceType>(std::numeric_limits<DestinationType>::max()); } static CONST_EXPPR SourceType min() { return 0; } }; template<typename DestinationType, typename SourceType> struct HelperCommonLimits<DestinationType, SourceType, false, true> { static CONST_EXPPR SourceType max() { return static_cast<SourceType>(std::numeric_limits<typename std::make_signed<DestinationType>::type>::max()); } static CONST_EXPPR SourceType min() { return 0; } }; /* * Helper template used to detect if size on destination type is bigger. * If signs are same than simple casting is enough. * if sings are different zero minimum is applied */ template<typename DestinationType, typename SourceType, bool singedToUnsigned, bool DestIsBigger> struct HelperNorrowCast { static CONST_EXPPR DestinationType Cast(SourceType arg) { using HelperType = HelperCommonLimits<DestinationType, SourceType, std::is_signed<SourceType>::value == std::is_signed<DestinationType>::value, (sizeof(DestinationType) == sizeof(SourceType))>; return static_cast<DestinationType>( HelperType::min() >= arg ? HelperType::min() : HelperType::max() <= arg ? HelperType::max() : arg); } }; template<typename DestinationType, typename SourceType> struct HelperNorrowCast<DestinationType, SourceType, false, true> { static CONST_EXPPR DestinationType Cast(SourceType arg) { return static_cast<DestinationType>(arg); } }; template<typename DestinationType, typename SourceType> struct HelperNorrowCast<DestinationType, SourceType, true, true> { static CONST_EXPPR DestinationType Cast(SourceType arg) { return static_cast<DestinationType>(arg >= 0 ? arg : 0); } }; /** * Used to do integer casting in such way that if argument value exceeds destination type range * result value is returns respectively maximum or minimum values of result type. */ template<typename DestinationType, typename SourceType> CONST_EXPPR DestinationType narrow_cast(SourceType arg) { static_assert(std::is_integral<DestinationType>::value, "Only integer types are supported"); static_assert(std::is_integral<SourceType>::value, "Only integer types are supported"); return HelperNorrowCast<DestinationType, SourceType, std::is_signed<SourceType>::value && std::is_unsigned<DestinationType>::value, (sizeof(DestinationType) > sizeof(SourceType))>::Cast(arg); } #define EXPECT_EQ(x, y) if (x != y) cout << "Failed test for " << #x << " : " << __LINE__ \ << "\nexpected: " << y \ << "\n actual: " << x << endl; else int main() { cout << std::numeric_limits<int32_t>::min() << endl; // to smaller type signed to signed EXPECT_EQ(narrow_cast<short>(100000), 32767); EXPECT_EQ(narrow_cast<short>(-100000), -32768); EXPECT_EQ(narrow_cast<short>(0), 0); EXPECT_EQ(narrow_cast<short>(-1), -1); // to smaller type unsigned to unsigned EXPECT_EQ(narrow_cast<unsigned short>(100000u), 65535u); EXPECT_EQ(narrow_cast<unsigned short>(60000u), 60000u); EXPECT_EQ(narrow_cast<unsigned short>(0u), 0u); EXPECT_EQ(narrow_cast<unsigned short>(1u), 1u); // to smaller type signed to signed to unsigned EXPECT_EQ(narrow_cast<unsigned short>(100000), 65535); EXPECT_EQ(narrow_cast<unsigned short>(-100000), 0); EXPECT_EQ(narrow_cast<unsigned short>(0), 0); EXPECT_EQ(narrow_cast<unsigned short>(-1), 0); // to smaller type unsigned to signed EXPECT_EQ(narrow_cast<short>(100000u), 32767); EXPECT_EQ(narrow_cast<short>(60000u), 32767); EXPECT_EQ(narrow_cast<short>(0u), 0); EXPECT_EQ(narrow_cast<short>(1u), 1); // to same size type signed to signed //// EXPECT_EQ(narrow_cast<int>(0x7fffffff), 0x7fffffff); EXPECT_EQ((narrow_cast<int, int>(-2147483648)), -2147483648); EXPECT_EQ(narrow_cast<int>(0), 0); EXPECT_EQ(narrow_cast<int>(-1), -1); // to same size type unsigned to unsigned EXPECT_EQ(narrow_cast<unsigned int>(0xffffffffu), 0xffffffffu); EXPECT_EQ(narrow_cast<unsigned int>(60000u), 60000u); EXPECT_EQ(narrow_cast<unsigned int>(0u), 0u); EXPECT_EQ(narrow_cast<unsigned int>(1u), 1u); // to same size type signed to signed to unsigned EXPECT_EQ((narrow_cast<unsigned int>(0x7fffffff)), 0x7fffffffu); EXPECT_EQ((narrow_cast<unsigned int, int>(-2147483648)), 0u); EXPECT_EQ((narrow_cast<unsigned int>(0)), 0u); EXPECT_EQ((narrow_cast<unsigned int>(-1)), 0u); // to same size type unsigned to signed EXPECT_EQ(narrow_cast<int>(0xffffffffu), 0x7fffffff); EXPECT_EQ(narrow_cast<int>(0x7fffffffu), 0x7fffffff); EXPECT_EQ(narrow_cast<int>(0x80000000u), 0x7fffffff); EXPECT_EQ(narrow_cast<int>(0u), 0); EXPECT_EQ(narrow_cast<int>(1u), 1); // to bigger size type signed to signed //// EXPECT_EQ(narrow_cast<int64_t>(0x7fffffff), 0x7fffffffll); EXPECT_EQ(narrow_cast<int64_t>(int32_t(-2147483648)), -2147483648ll); EXPECT_EQ(narrow_cast<int64_t>(0), 0); EXPECT_EQ(narrow_cast<int64_t>(-1), -1ll); // to bigger size type unsigned to unsigned EXPECT_EQ(narrow_cast<uint64_t>(0xffffffffu), 0xffffffffull); EXPECT_EQ(narrow_cast<uint64_t>(60000u), 60000ull); EXPECT_EQ(narrow_cast<uint64_t>(0u), 0ull); EXPECT_EQ(narrow_cast<uint64_t>(1u), 1ull); // to bigger size type signed to signed to unsigned EXPECT_EQ(narrow_cast<uint64_t>(0x7fffffff), 0x7fffffffull); EXPECT_EQ(narrow_cast<uint64_t>(int32_t(-2147483648)), 0ull); EXPECT_EQ(narrow_cast<uint64_t>(0), 0ull); EXPECT_EQ(narrow_cast<uint64_t>(-1), 0ull); // to bigger size type unsigned to signed EXPECT_EQ(narrow_cast<int64_t>(0xffffffffu), 0xffffffffll); EXPECT_EQ(narrow_cast<int64_t>(0x7fffffffu), 0x7fffffffll); EXPECT_EQ(narrow_cast<int64_t>(0x80000000u), 0x80000000ll); EXPECT_EQ(narrow_cast<int64_t>(0u), 0ll); EXPECT_EQ(narrow_cast<int64_t>(1u), 1ll); return 0; }
run
|
edit
|
history
|
help
0
xxx
Computing factorial of an integer with recursion and iteration [EDIT]
VC++
VS2013 hello world includes
Triangle N5
CIS-2207 Week1 Assignment1 Company Devisions
-1 Girene Kadar Ortalama
Hello World
MSVC alias template
seh exception