Browse Source

* Implemented convert_cast

master
bergmann 4 years ago
parent
commit
f088bb428d
10 changed files with 453 additions and 17 deletions
  1. +0
    -1
      CMakeFiles/cmake.check_cache
  2. +4
    -0
      cmake/config.h.in
  3. +6
    -0
      cmake/cppcore-options.cmake
  4. +25
    -0
      include/cppcore/conversion/convert_cast.h
  5. +178
    -0
      include/cppcore/conversion/convert_cast.inl
  6. +31
    -5
      include/cppcore/conversion/string.inl
  7. +6
    -4
      include/cppcore/misc/stream.inl
  8. +9
    -7
      include/cppcore/misc/vector_streambuf.inl
  9. +12
    -0
      src/CMakeLists.txt
  10. +182
    -0
      test/cppcore/conversion/convert_cast_tests.cpp

+ 0
- 1
CMakeFiles/cmake.check_cache View File

@@ -1 +0,0 @@
# This file is generated by cmake for dependency checking of the CMakeCache.txt file

+ 4
- 0
cmake/config.h.in View File

@@ -0,0 +1,4 @@
#pragma once

#cmakedefine CPPCORE_CONVERT_CAST_ABORT
#cmakedefine CPPCORE_CONVERT_CAST_THROW

+ 6
- 0
cmake/cppcore-options.cmake View File

@@ -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 ( )

+ 25
- 0
include/cppcore/conversion/convert_cast.h View File

@@ -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"

+ 178
- 0
include/cppcore/conversion/convert_cast.inl View File

@@ -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); }

}

+ 31
- 5
include/cppcore/conversion/string.inl View File

@@ -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);
}
};


+ 6
- 4
include/cppcore/misc/stream.inl View File

@@ -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);
}
};



+ 9
- 7
include/cppcore/misc/vector_streambuf.inl View File

@@ -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;


+ 12
- 0
src/CMakeLists.txt View File

@@ -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} )


+ 182
- 0
test/cppcore/conversion/convert_cast_tests.cpp View File

@@ -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));
}

Loading…
Cancel
Save