| @@ -1 +0,0 @@ | |||
| # This file is generated by cmake for dependency checking of the CMakeCache.txt file | |||
| @@ -0,0 +1,4 @@ | |||
| #pragma once | |||
| #cmakedefine CPPCORE_CONVERT_CAST_ABORT | |||
| #cmakedefine CPPCORE_CONVERT_CAST_THROW | |||
| @@ -9,3 +9,9 @@ Option ( CPPCORE_INSTALL_PACKAGE | |||
| Option ( CPPCORE_USE_GIT_VERSION | |||
| "Read the git tags to get the version of cppcore" | |||
| ON ) | |||
| If ( NOT CPPCORE_CONVERT_CAST ) | |||
| Set ( CPPCORE_CONVERT_CAST throw | |||
| CACHE STRING "Specify how the convert_cast should handle invalid values." ) | |||
| Set_Property ( CACHE CPPCORE_CONVERT_CAST | |||
| PROPERTY STRINGS throw abort ) | |||
| EndIf ( ) | |||
| @@ -0,0 +1,25 @@ | |||
| #pragma once | |||
| namespace cppcore | |||
| { | |||
| /** | |||
| * @brief Convert one type to another type. | |||
| * | |||
| * This method will try to convert the given value to the given type. | |||
| * If a convertion between the two types is unknown, a compiler error is raised. | |||
| * If the value to convert does not fullfill the conversion requirements (like range checks) | |||
| * the program will panic (call to std::abort) or throw an convert_exception (if configured). | |||
| * | |||
| * @tparam T_to Type to convert to. | |||
| * @tparam T_from Type to convert from. | |||
| * | |||
| * @param[in] p_value Value to convert. | |||
| * @return Converted value. | |||
| */ | |||
| template<typename T_to, typename T_from> | |||
| constexpr T_to convert_cast(T_from p_value); | |||
| } | |||
| #include "convert_cast.inl" | |||
| @@ -0,0 +1,178 @@ | |||
| #pragma once | |||
| #ifdef CPPCORE_CONVERT_CAST_ABORT | |||
| # include <iostream> | |||
| #endif | |||
| #include <limits> | |||
| #include <type_traits> | |||
| #include <cppcore/config.h> | |||
| #include <cppcore/misc/exception.h> | |||
| #include <cppcore/misc/type_helper.h> | |||
| #include "convert_cast.h" | |||
| namespace cppcore | |||
| { | |||
| namespace __impl | |||
| { | |||
| template<typename T_to, typename T_from> | |||
| void convert_cast_raise(T_from p_value) | |||
| { | |||
| #if defined(CPPCORE_CONVERT_CAST_THROW) | |||
| using namespace std; | |||
| throw convert_exception("Unable to convert "s | |||
| + type_helper<T_from>::name() | |||
| + "(" + std::to_string(p_value) + ") to " | |||
| + type_helper<T_to>::name()); | |||
| #elif defined(CPPCORE_CONVERT_CAST_ABORT) | |||
| std::cerr | |||
| << "Unable to convert " | |||
| << type_helper<T_from>::name() | |||
| << "(" << p_value << ") to " | |||
| << type_helper<T_to>::name() | |||
| << std::endl; | |||
| std::abort(); | |||
| #endif | |||
| } | |||
| template<typename T_from, typename T_to, typename T_enable = void> | |||
| struct convert_cast_impl | |||
| { | |||
| constexpr T_to operator()(T_from p_value) const | |||
| { static_assert(sizeof(T_from) < 0, "convert_cast is not available for the passed types!"); } | |||
| }; | |||
| /** | |||
| * types are equal => simple static cast | |||
| */ | |||
| template<typename T> | |||
| struct convert_cast_impl<T, T, void> | |||
| { | |||
| constexpr T operator()(T p_value) const | |||
| { return p_value; } | |||
| }; | |||
| /** | |||
| * T_from does fit into T_to => simple static cast | |||
| */ | |||
| template<typename T_from, typename T_to> | |||
| struct convert_cast_impl< | |||
| T_from, | |||
| T_to, | |||
| std::enable_if_t< | |||
| (sizeof(T_from) < sizeof(T_to)) | |||
| && std::disjunction_v< | |||
| std::conjunction< | |||
| std::is_unsigned<std::decay_t<T_from>>, | |||
| std::is_integral<std::decay_t<T_to>> | |||
| >, | |||
| std::conjunction< | |||
| std::is_signed<std::decay_t<T_from>>, | |||
| std::is_signed<std::decay_t<T_to>> | |||
| > | |||
| > | |||
| > | |||
| > | |||
| { | |||
| constexpr T_to operator()(T_from p_value) const | |||
| { return static_cast<T_to>(p_value); } | |||
| }; | |||
| /** | |||
| * T_from does fit into T_to => check range and cast | |||
| */ | |||
| template<typename T_from, typename T_to> | |||
| struct convert_cast_impl< | |||
| T_from, | |||
| T_to, | |||
| std::enable_if_t< | |||
| (sizeof(T_from) > sizeof(T_to)) | |||
| && std::is_signed_v<std::decay_t<T_from>> | |||
| && std::is_signed_v<std::decay_t<T_to>> | |||
| > | |||
| > | |||
| { | |||
| constexpr T_to operator()(T_from p_value) const | |||
| { | |||
| if (p_value < std::numeric_limits<T_to>::min()) | |||
| convert_cast_raise<T_to>(p_value); | |||
| if (p_value > std::numeric_limits<T_to>::max()) | |||
| convert_cast_raise<T_to>(p_value); | |||
| return static_cast<T_to>(p_value); | |||
| } | |||
| }; | |||
| /** | |||
| * T_from does fit into T_to => check range and cast | |||
| */ | |||
| template<typename T_from, typename T_to> | |||
| struct convert_cast_impl< | |||
| T_from, | |||
| T_to, | |||
| std::enable_if_t< | |||
| ( (sizeof(T_from) >= sizeof(T_to)) | |||
| && std::is_unsigned_v<std::decay_t<T_from>> | |||
| && std::is_signed_v<std::decay_t<T_to>>) | |||
| || ( (sizeof(T_from) > sizeof(T_to)) | |||
| && std::is_unsigned_v<std::decay_t<T_from>> | |||
| && std::is_unsigned_v<std::decay_t<T_to>>) | |||
| > | |||
| > | |||
| { | |||
| constexpr T_to operator()(T_from p_value) const | |||
| { | |||
| if (p_value > std::numeric_limits<T_to>::max()) | |||
| convert_cast_raise<T_to>(p_value); | |||
| return static_cast<T_to>(p_value); | |||
| } | |||
| }; | |||
| /** | |||
| * signed to unsigned cast => check lower range and cast | |||
| */ | |||
| template<typename T_from, typename T_to> | |||
| struct convert_cast_impl< | |||
| T_from, | |||
| T_to, | |||
| std::enable_if_t< | |||
| std::is_signed_v <std::decay_t<T_from>> | |||
| && std::is_unsigned_v<std::decay_t<T_to >>>> | |||
| { | |||
| constexpr T_to operator()(T_from p_value) const | |||
| { | |||
| using unsigned_type = std::make_unsigned_t<T_from>; | |||
| if (p_value < 0) | |||
| convert_cast_raise<T_to>(p_value); | |||
| return convert_cast<T_to>(static_cast<unsigned_type>(p_value)); | |||
| } | |||
| }; | |||
| /** | |||
| * enum to integral cast => static cast | |||
| */ | |||
| template<typename T_from, typename T_to> | |||
| struct convert_cast_impl< | |||
| T_from, | |||
| T_to, | |||
| std::enable_if_t< | |||
| std::is_enum_v <std::decay_t<T_from>> | |||
| && std::is_integral_v<std::decay_t<T_to >> | |||
| >> | |||
| { | |||
| constexpr T_to operator()(T_from p_value) const | |||
| { | |||
| using underlying_type = std::underlying_type_t<T_from>; | |||
| return convert_cast<T_to>(static_cast<underlying_type>(p_value)); | |||
| } | |||
| }; | |||
| } | |||
| template<typename T_to, typename T_from> | |||
| constexpr T_to convert_cast(T_from p_value) | |||
| { return __impl::convert_cast_impl<T_from, T_to>()(p_value); } | |||
| } | |||
| @@ -1,10 +1,13 @@ | |||
| #pragma once | |||
| #include <limits> | |||
| #include <cppcore/misc/exception.h> | |||
| #include <cppcore/misc/type_helper.h> | |||
| #include "enum.h" | |||
| #include "string.h" | |||
| #include "convert_cast.h" | |||
| #ifdef _GLIBCXX_VECTOR | |||
| #define CPPCORE_HAS_VECTOR | |||
| @@ -51,7 +54,7 @@ namespace cppcore | |||
| && ( *i == seperator | |||
| || *i == '\0')) | |||
| { | |||
| std::string tmp(s, static_cast<size_t>(i - s)); | |||
| std::string tmp(s, convert_cast<size_t>(i - s)); | |||
| if (!predicate(tmp)) | |||
| return false; | |||
| s = i + 1; | |||
| @@ -362,13 +365,32 @@ namespace cppcore | |||
| }; | |||
| template<typename T> | |||
| struct op_from_string<T, typename std::enable_if_t<std::is_integral_v<T>>> | |||
| struct op_from_string<T, typename std::enable_if_t<std::is_unsigned_v<T> && std::is_integral_v<T>>> | |||
| { | |||
| inline bool operator()(const std::string& s, T& v) const | |||
| inline bool operator()(const std::string& s, T& value) const | |||
| { | |||
| char *e = nullptr; | |||
| const char *c = s.c_str(); | |||
| auto tmp = std::strtoull(c, &e, 0); | |||
| if (tmp > std::numeric_limits<T>::max()) | |||
| return false; | |||
| value = static_cast<T>(tmp); | |||
| return (c != e); | |||
| } | |||
| }; | |||
| template<typename T> | |||
| struct op_from_string<T, typename std::enable_if_t<std::is_signed_v<T> && std::is_integral_v<T>>> | |||
| { | |||
| inline bool operator()(const std::string& s, T& value) const | |||
| { | |||
| char *e = nullptr; | |||
| const char *c = s.c_str(); | |||
| v = static_cast<T>(std::strtoull(c, &e, 0)); | |||
| auto tmp = std::strtoll(c, &e, 0); | |||
| if ( tmp > std::numeric_limits<T>::max() | |||
| || tmp < std::numeric_limits<T>::min()) | |||
| return false; | |||
| value = static_cast<T>(tmp); | |||
| return (c != e); | |||
| } | |||
| }; | |||
| @@ -380,7 +402,11 @@ namespace cppcore | |||
| { | |||
| char *e = nullptr; | |||
| const char *c = s.c_str(); | |||
| value = static_cast<T>(std::strtold(c, &e)); | |||
| auto tmp = std::strtold(c, &e); | |||
| if ( tmp > static_cast<long double>(std::numeric_limits<T>::max()) | |||
| || tmp < static_cast<long double>(std::numeric_limits<T>::min())) | |||
| return false; | |||
| value = static_cast<T>(tmp); | |||
| return (c != e); | |||
| } | |||
| }; | |||
| @@ -1,5 +1,7 @@ | |||
| #pragma once | |||
| #include <cppcore/conversion/convert_cast.h> | |||
| #include "stream.h" | |||
| namespace cppcore | |||
| @@ -123,7 +125,7 @@ namespace cppcore | |||
| { | |||
| auto pos = is.tellg(); | |||
| t.deserialize(is); | |||
| return static_cast<size_t>(is.tellg() - pos); | |||
| return convert_cast<size_t>(is.tellg() - pos); | |||
| } | |||
| }; | |||
| @@ -150,10 +152,10 @@ namespace cppcore | |||
| { | |||
| if (t.size() > std::numeric_limits<uint32_t>::max()) | |||
| throw exception("unable to write data to stream: string is to large"); | |||
| op_stream_write<uint32_t, void>()(os, static_cast<uint32_t>(t.size())); | |||
| op_stream_write<uint32_t, void>()(os, convert_cast<uint32_t>(t.size())); | |||
| if (!os) | |||
| throw exception("unable to write data to stream: invalid stream"); | |||
| os.write(t.data(), static_cast<std::streamsize>(t.size())); | |||
| os.write(t.data(), convert_cast<std::streamsize>(t.size())); | |||
| if (!os) | |||
| throw exception("unable to write data to stream: stream error"); | |||
| return sizeof(uint32_t) + t.size(); | |||
| @@ -167,7 +169,7 @@ namespace cppcore | |||
| { | |||
| auto pos = os.tellp(); | |||
| t.serialize(os); | |||
| return static_cast<size_t>(os.tellp() - pos); | |||
| return convert_cast<size_t>(os.tellp() - pos); | |||
| } | |||
| }; | |||
| @@ -1,5 +1,7 @@ | |||
| #pragma once | |||
| #include <cppcore/conversion/convert_cast.h> | |||
| #include "vector_streambuf.h" | |||
| namespace cppcore | |||
| @@ -18,7 +20,7 @@ namespace cppcore | |||
| ::get() const | |||
| { | |||
| auto vec = _buffer; | |||
| vec.resize(static_cast<size_t>(this->pptr() - this->pbase())); | |||
| vec.resize(convert_cast<size_t>(this->pptr() - this->pbase())); | |||
| return vec; | |||
| } | |||
| @@ -40,7 +42,7 @@ namespace cppcore | |||
| basic_vector_streambuf<T_data, T_char> | |||
| ::extract() | |||
| { | |||
| _buffer.resize(static_cast<size_t>(this->pptr() - this->pbase())); | |||
| _buffer.resize(convert_cast<size_t>(this->pptr() - this->pbase())); | |||
| auto ret = std::move(_buffer); | |||
| this->setp(nullptr, nullptr); | |||
| this->setg(nullptr, nullptr, nullptr); | |||
| @@ -52,11 +54,11 @@ namespace cppcore | |||
| basic_vector_streambuf<T_data, T_char> | |||
| ::underflow() | |||
| { | |||
| auto gpos = static_cast<size_t>(this->gptr() - this->eback()); | |||
| auto gpos = convert_cast<size_t>(this->gptr() - this->eback()); | |||
| this->setg(this->eback(), this->eback() + gpos, this->pptr()); | |||
| if (this->gptr() == this->egptr()) | |||
| return traits_type::eof(); | |||
| auto ret = static_cast<int_type>(*this->gptr()); | |||
| auto ret = convert_cast<int_type>(*this->gptr()); | |||
| return ret; | |||
| } | |||
| @@ -80,15 +82,15 @@ namespace cppcore | |||
| auto beg = reinterpret_cast<char_type*>(&_buffer.front()); | |||
| auto end = beg + _buffer.size(); | |||
| auto ppos = static_cast<int>(this->pptr() - this->pbase()); | |||
| auto gpos = static_cast<size_t>(this->gptr() - this->eback()); | |||
| auto ppos = convert_cast<int>(this->pptr() - this->pbase()); | |||
| auto gpos = convert_cast<size_t>(this->gptr() - this->eback()); | |||
| this->setp(beg, end); | |||
| this->setg(beg, beg + gpos, beg + ppos); | |||
| this->pbump(ppos); | |||
| auto p = this->pptr(); | |||
| assert(this->pbase() <= p && p < this->epptr()); | |||
| *p = static_cast<char_type>(ch); | |||
| *p = convert_cast<char_type>(ch); | |||
| this->pbump(1); | |||
| } | |||
| return ch; | |||
| @@ -6,11 +6,21 @@ Include ( strip_symbols OPTIONAL RESULT_VARIABLE HAS_STRIP_S | |||
| # Interface Library ############################################################################### | |||
| If ( "${CPPCORE_CONVERT_CAST}" STREQUAL "abort" ) | |||
| Set ( CPPCORE_CONVERT_CAST_ABORT 1 ) | |||
| ElseIf ( "${CPPCORE_CONVERT_CAST}" STREQUAL "throw" ) | |||
| Set ( CPPCORE_CONVERT_CAST_THROW 1 ) | |||
| EndIf ( ) | |||
| Set ( CPPCORE_GENERATED_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated ) | |||
| Configure_File ( ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/config.h.in | |||
| ${CPPCORE_GENERATED_INCLUDE_DIR}/cppcore/config.h ) | |||
| Set ( CPPCORE_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../include ) | |||
| Add_Library ( cppcore INTERFACE ) | |||
| Target_Include_Directories ( cppcore | |||
| INTERFACE | |||
| $<BUILD_INTERFACE:${CPPCORE_INCLUDE_DIR}> | |||
| $<BUILD_INTERFACE:${CPPCORE_GENERATED_INCLUDE_DIR}> | |||
| $<INSTALL_INTERFACE:${CPPCORE_INSTALL_DIR_INCLUDE}> ) | |||
| # Install ######################################################################################### | |||
| @@ -24,6 +34,8 @@ If ( CPPCORE_INSTALL_HEADER ) | |||
| DESTINATION ${CPPCORE_INSTALL_DIR_INCLUDE} ) | |||
| Install ( DIRECTORY ${CPPCORE_INCLUDE_DIR}/cppcore | |||
| DESTINATION ${CPPCORE_INSTALL_DIR_INCLUDE} ) | |||
| Install ( DIRECTORY ${CPPCORE_GENERATED_INCLUDE_DIR}/cppcore | |||
| DESTINATION ${CPPCORE_INSTALL_DIR_INCLUDE} ) | |||
| Install ( TARGETS cppcore | |||
| EXPORT cppcore | |||
| DESTINATION ${CPPCORE_INSTALL_DIR_INCLUDE} ) | |||
| @@ -0,0 +1,182 @@ | |||
| #include <gtest/gtest.h> | |||
| #define CPPCORE_CONVERT_CAST_THROW | |||
| #include <cppcore/conversion/convert_cast.h> | |||
| using namespace ::cppcore; | |||
| enum class test_enum | |||
| { | |||
| test0 = 0, | |||
| test1, | |||
| test2, | |||
| test256 = 256, | |||
| }; | |||
| TEST(convert_cast_test, i8) | |||
| { | |||
| EXPECT_THROW(convert_cast<int8_t>(static_cast< int16_t>(128)), convert_exception); | |||
| EXPECT_THROW(convert_cast<int8_t>(static_cast< int32_t>(128)), convert_exception); | |||
| EXPECT_THROW(convert_cast<int8_t>(static_cast< int64_t>(128)), convert_exception); | |||
| EXPECT_THROW(convert_cast<int8_t>(static_cast< uint8_t>(128)), convert_exception); | |||
| EXPECT_THROW(convert_cast<int8_t>(static_cast<uint16_t>(128)), convert_exception); | |||
| EXPECT_THROW(convert_cast<int8_t>(static_cast<uint32_t>(128)), convert_exception); | |||
| EXPECT_THROW(convert_cast<int8_t>(static_cast<uint64_t>(128)), convert_exception); | |||
| EXPECT_EQ (convert_cast<int8_t>(static_cast< int8_t>(1)), static_cast<int8_t>(1)); | |||
| EXPECT_EQ (convert_cast<int8_t>(static_cast< int16_t>(2)), static_cast<int8_t>(2)); | |||
| EXPECT_EQ (convert_cast<int8_t>(static_cast< int32_t>(3)), static_cast<int8_t>(3)); | |||
| EXPECT_EQ (convert_cast<int8_t>(static_cast< int64_t>(4)), static_cast<int8_t>(4)); | |||
| EXPECT_EQ (convert_cast<int8_t>(static_cast< uint8_t>(4)), static_cast<int8_t>(4)); | |||
| EXPECT_EQ (convert_cast<int8_t>(static_cast<uint16_t>(5)), static_cast<int8_t>(5)); | |||
| EXPECT_EQ (convert_cast<int8_t>(static_cast<uint32_t>(6)), static_cast<int8_t>(6)); | |||
| EXPECT_EQ (convert_cast<int8_t>(static_cast<uint64_t>(7)), static_cast<int8_t>(7)); | |||
| } | |||
| TEST(convert_cast_test, u8) | |||
| { | |||
| EXPECT_THROW(convert_cast<uint8_t>(static_cast< int8_t>( -1)), convert_exception); | |||
| EXPECT_THROW(convert_cast<uint8_t>(static_cast< int16_t>(256)), convert_exception); | |||
| EXPECT_THROW(convert_cast<uint8_t>(static_cast< int32_t>( -1)), convert_exception); | |||
| EXPECT_THROW(convert_cast<uint8_t>(static_cast< int64_t>(256)), convert_exception); | |||
| EXPECT_THROW(convert_cast<uint8_t>(static_cast<uint16_t>(256)), convert_exception); | |||
| EXPECT_THROW(convert_cast<uint8_t>(static_cast<uint32_t>(256)), convert_exception); | |||
| EXPECT_THROW(convert_cast<uint8_t>(static_cast<uint64_t>(256)), convert_exception); | |||
| EXPECT_EQ (convert_cast<uint8_t>(static_cast< int8_t>(1)), static_cast<uint8_t>(1)); | |||
| EXPECT_EQ (convert_cast<uint8_t>(static_cast< int16_t>(2)), static_cast<uint8_t>(2)); | |||
| EXPECT_EQ (convert_cast<uint8_t>(static_cast< int32_t>(3)), static_cast<uint8_t>(3)); | |||
| EXPECT_EQ (convert_cast<uint8_t>(static_cast< int64_t>(4)), static_cast<uint8_t>(4)); | |||
| EXPECT_EQ (convert_cast<uint8_t>(static_cast< uint8_t>(4)), static_cast<uint8_t>(4)); | |||
| EXPECT_EQ (convert_cast<uint8_t>(static_cast<uint16_t>(5)), static_cast<uint8_t>(5)); | |||
| EXPECT_EQ (convert_cast<uint8_t>(static_cast<uint32_t>(6)), static_cast<uint8_t>(6)); | |||
| EXPECT_EQ (convert_cast<uint8_t>(static_cast<uint64_t>(7)), static_cast<uint8_t>(7)); | |||
| } | |||
| TEST(convert_cast_test, i16) | |||
| { | |||
| EXPECT_THROW(convert_cast<int16_t>(static_cast< int32_t>(32'768)), convert_exception); | |||
| EXPECT_THROW(convert_cast<int16_t>(static_cast< int64_t>(32'768)), convert_exception); | |||
| EXPECT_THROW(convert_cast<int16_t>(static_cast<uint16_t>(32'768)), convert_exception); | |||
| EXPECT_THROW(convert_cast<int16_t>(static_cast<uint32_t>(32'768)), convert_exception); | |||
| EXPECT_THROW(convert_cast<int16_t>(static_cast<uint64_t>(32'768)), convert_exception); | |||
| EXPECT_EQ (convert_cast<int16_t>(static_cast< int8_t>(1)), static_cast<int16_t>(1)); | |||
| EXPECT_EQ (convert_cast<int16_t>(static_cast< int16_t>(2)), static_cast<int16_t>(2)); | |||
| EXPECT_EQ (convert_cast<int16_t>(static_cast< int32_t>(3)), static_cast<int16_t>(3)); | |||
| EXPECT_EQ (convert_cast<int16_t>(static_cast< int64_t>(4)), static_cast<int16_t>(4)); | |||
| EXPECT_EQ (convert_cast<int16_t>(static_cast< uint8_t>(4)), static_cast<int16_t>(4)); | |||
| EXPECT_EQ (convert_cast<int16_t>(static_cast<uint16_t>(5)), static_cast<int16_t>(5)); | |||
| EXPECT_EQ (convert_cast<int16_t>(static_cast<uint32_t>(6)), static_cast<int16_t>(6)); | |||
| EXPECT_EQ (convert_cast<int16_t>(static_cast<uint64_t>(7)), static_cast<int16_t>(7)); | |||
| } | |||
| TEST(convert_cast_test, u16) | |||
| { | |||
| EXPECT_THROW(convert_cast<uint16_t>(static_cast< int8_t>( -1)), convert_exception); | |||
| EXPECT_THROW(convert_cast<uint16_t>(static_cast< int16_t>( -1)), convert_exception); | |||
| EXPECT_THROW(convert_cast<uint16_t>(static_cast< int32_t>(65'536)), convert_exception); | |||
| EXPECT_THROW(convert_cast<uint16_t>(static_cast< int64_t>(65'536)), convert_exception); | |||
| EXPECT_THROW(convert_cast<uint16_t>(static_cast<uint32_t>(65'536)), convert_exception); | |||
| EXPECT_THROW(convert_cast<uint16_t>(static_cast<uint64_t>(65'536)), convert_exception); | |||
| EXPECT_EQ (convert_cast<uint16_t>(static_cast< int8_t>(1)), static_cast<int16_t>(1)); | |||
| EXPECT_EQ (convert_cast<uint16_t>(static_cast< int16_t>(2)), static_cast<int16_t>(2)); | |||
| EXPECT_EQ (convert_cast<uint16_t>(static_cast< int32_t>(3)), static_cast<int16_t>(3)); | |||
| EXPECT_EQ (convert_cast<uint16_t>(static_cast< int64_t>(4)), static_cast<int16_t>(4)); | |||
| EXPECT_EQ (convert_cast<uint16_t>(static_cast< uint8_t>(4)), static_cast<int16_t>(4)); | |||
| EXPECT_EQ (convert_cast<uint16_t>(static_cast<uint16_t>(5)), static_cast<int16_t>(5)); | |||
| EXPECT_EQ (convert_cast<uint16_t>(static_cast<uint32_t>(6)), static_cast<int16_t>(6)); | |||
| EXPECT_EQ (convert_cast<uint16_t>(static_cast<uint64_t>(7)), static_cast<int16_t>(7)); | |||
| } | |||
| TEST(convert_cast_test, i32) | |||
| { | |||
| EXPECT_THROW(convert_cast<int32_t>(static_cast< int64_t>(2'147'483'648)), convert_exception); | |||
| EXPECT_THROW(convert_cast<int32_t>(static_cast<uint32_t>(2'147'483'648)), convert_exception); | |||
| EXPECT_THROW(convert_cast<int32_t>(static_cast<uint64_t>(2'147'483'648)), convert_exception); | |||
| EXPECT_EQ (convert_cast<int32_t>(static_cast< int8_t>(1)), static_cast<int32_t>(1)); | |||
| EXPECT_EQ (convert_cast<int32_t>(static_cast< int16_t>(2)), static_cast<int32_t>(2)); | |||
| EXPECT_EQ (convert_cast<int32_t>(static_cast< int32_t>(3)), static_cast<int32_t>(3)); | |||
| EXPECT_EQ (convert_cast<int32_t>(static_cast< int64_t>(4)), static_cast<int32_t>(4)); | |||
| EXPECT_EQ (convert_cast<int32_t>(static_cast< uint8_t>(4)), static_cast<int32_t>(4)); | |||
| EXPECT_EQ (convert_cast<int32_t>(static_cast<uint16_t>(5)), static_cast<int32_t>(5)); | |||
| EXPECT_EQ (convert_cast<int32_t>(static_cast<uint32_t>(6)), static_cast<int32_t>(6)); | |||
| EXPECT_EQ (convert_cast<int32_t>(static_cast<uint64_t>(7)), static_cast<int32_t>(7)); | |||
| } | |||
| TEST(convert_cast_test, u32) | |||
| { | |||
| EXPECT_THROW(convert_cast<uint32_t>(static_cast< int8_t>( -1)), convert_exception); | |||
| EXPECT_THROW(convert_cast<uint32_t>(static_cast< int16_t>( -1)), convert_exception); | |||
| EXPECT_THROW(convert_cast<uint32_t>(static_cast< int32_t>( -1)), convert_exception); | |||
| EXPECT_THROW(convert_cast<uint32_t>(static_cast< int64_t>(4'294'967'296)), convert_exception); | |||
| EXPECT_THROW(convert_cast<uint32_t>(static_cast<uint64_t>(4'294'967'296)), convert_exception); | |||
| EXPECT_EQ (convert_cast<uint32_t>(static_cast< int8_t>(1)), static_cast<int32_t>(1)); | |||
| EXPECT_EQ (convert_cast<uint32_t>(static_cast< int16_t>(2)), static_cast<int32_t>(2)); | |||
| EXPECT_EQ (convert_cast<uint32_t>(static_cast< int32_t>(3)), static_cast<int32_t>(3)); | |||
| EXPECT_EQ (convert_cast<uint32_t>(static_cast< int64_t>(4)), static_cast<int32_t>(4)); | |||
| EXPECT_EQ (convert_cast<uint32_t>(static_cast< uint8_t>(4)), static_cast<int32_t>(4)); | |||
| EXPECT_EQ (convert_cast<uint32_t>(static_cast<uint16_t>(5)), static_cast<int32_t>(5)); | |||
| EXPECT_EQ (convert_cast<uint32_t>(static_cast<uint32_t>(6)), static_cast<int32_t>(6)); | |||
| EXPECT_EQ (convert_cast<uint32_t>(static_cast<uint64_t>(7)), static_cast<int32_t>(7)); | |||
| } | |||
| TEST(convert_cast_test, i64) | |||
| { | |||
| EXPECT_THROW(convert_cast<int64_t>(static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) + 1), convert_exception); | |||
| EXPECT_EQ (convert_cast<int64_t>(static_cast< int8_t>(1)), static_cast<int64_t>(1)); | |||
| EXPECT_EQ (convert_cast<int64_t>(static_cast< int16_t>(2)), static_cast<int64_t>(2)); | |||
| EXPECT_EQ (convert_cast<int64_t>(static_cast< int32_t>(3)), static_cast<int64_t>(3)); | |||
| EXPECT_EQ (convert_cast<int64_t>(static_cast< int64_t>(4)), static_cast<int64_t>(4)); | |||
| EXPECT_EQ (convert_cast<int64_t>(static_cast< uint8_t>(4)), static_cast<int64_t>(4)); | |||
| EXPECT_EQ (convert_cast<int64_t>(static_cast<uint16_t>(5)), static_cast<int64_t>(5)); | |||
| EXPECT_EQ (convert_cast<int64_t>(static_cast<uint32_t>(6)), static_cast<int64_t>(6)); | |||
| EXPECT_EQ (convert_cast<int64_t>(static_cast<uint64_t>(7)), static_cast<int64_t>(7)); | |||
| } | |||
| TEST(convert_cast_test, u64) | |||
| { | |||
| EXPECT_THROW(convert_cast<uint64_t>(static_cast< int8_t>( -1)), convert_exception); | |||
| EXPECT_THROW(convert_cast<uint64_t>(static_cast< int16_t>( -1)), convert_exception); | |||
| EXPECT_THROW(convert_cast<uint64_t>(static_cast< int32_t>( -1)), convert_exception); | |||
| EXPECT_EQ (convert_cast<uint64_t>(static_cast< int8_t>(1)), static_cast<int64_t>(1)); | |||
| EXPECT_EQ (convert_cast<uint64_t>(static_cast< int16_t>(2)), static_cast<int64_t>(2)); | |||
| EXPECT_EQ (convert_cast<uint64_t>(static_cast< int32_t>(3)), static_cast<int64_t>(3)); | |||
| EXPECT_EQ (convert_cast<uint64_t>(static_cast< int64_t>(4)), static_cast<int64_t>(4)); | |||
| EXPECT_EQ (convert_cast<uint64_t>(static_cast< uint8_t>(4)), static_cast<int64_t>(4)); | |||
| EXPECT_EQ (convert_cast<uint64_t>(static_cast<uint16_t>(5)), static_cast<int64_t>(5)); | |||
| EXPECT_EQ (convert_cast<uint64_t>(static_cast<uint32_t>(6)), static_cast<int64_t>(6)); | |||
| EXPECT_EQ (convert_cast<uint64_t>(static_cast<uint64_t>(7)), static_cast<int64_t>(7)); | |||
| } | |||
| TEST(convert_cast_test, enum) | |||
| { | |||
| EXPECT_EQ(convert_cast< int8_t>( test_enum::test0), static_cast< int8_t>( 0)); | |||
| EXPECT_EQ(convert_cast<int16_t>( test_enum::test1), static_cast<int16_t>( 1)); | |||
| EXPECT_EQ(convert_cast<int32_t>( test_enum::test2), static_cast<int32_t>( 2)); | |||
| EXPECT_EQ(convert_cast<int64_t>(test_enum::test256), static_cast<int64_t>(256)); | |||
| EXPECT_EQ(convert_cast< uint8_t>( test_enum::test0), static_cast< uint8_t>( 0)); | |||
| EXPECT_EQ(convert_cast<uint16_t>( test_enum::test1), static_cast<uint16_t>( 1)); | |||
| EXPECT_EQ(convert_cast<uint32_t>( test_enum::test2), static_cast<uint32_t>( 2)); | |||
| EXPECT_EQ(convert_cast<uint64_t>(test_enum::test256), static_cast<uint64_t>(256)); | |||
| } | |||