Refactored to_arithmetic

This commit is contained in:
John Wellbelove 2022-09-19 18:50:17 +01:00
parent 3d412e6e7d
commit ee7f9469dc
2 changed files with 308 additions and 130 deletions

View File

@ -53,6 +53,19 @@ namespace etl
}
};
//***************************************************************************
///
//***************************************************************************
class to_arithmetic_radix_not_supported : public to_arithmetic_exception
{
public:
to_arithmetic_radix_not_supported(string_type file_name_, numeric_type line_number_)
: to_arithmetic_exception(ETL_ERROR_TEXT("to arithmetic:radix not supported", ETL_TO_ARITHMETIC_FILE_ID"C"), file_name_, line_number_)
{
}
};
namespace private_to_arithmetic
{
template <typename TChar>
@ -103,20 +116,6 @@ namespace etl
static ETL_CONSTANT char decimal_length = 10;
static ETL_CONSTANT char hex_length = 16 + 6;
//*******************************
template <typename TChar>
bool has_valid_characters(etl::basic_string_view<TChar> view, etl::basic_string_view<TChar> valid_characters)
{
if (valid_characters.empty())
{
return false;
}
size_t position = view.find_first_not_of(valid_characters);
return position == etl::basic_string_view<TChar>::npos;
}
//*******************************
template <typename TChar>
char get_digit_value(TChar c)
@ -134,49 +133,44 @@ namespace etl
return 0;
}
//*******************************
template <typename TChar>
struct processed_string
{
etl::basic_string_view<TChar> view;
bool is_negative;
bool is_valid;
};
//***************************************************************************
///
//***************************************************************************
template <typename TChar>
processed_string<TChar> preprocess_string(etl::basic_string_view<TChar> view, const etl::radix::value_type radix)
ETL_CONSTEXPR14 bool is_valid_numeric_character(const TChar c,
const etl::basic_string_view<TChar>& valid_characters)
{
using namespace etl::private_to_arithmetic;
view = etl::trim_view_whitespace(view);
etl::basic_string_view<TChar> itr = etl::find(valid_characters.begin(), valid_characters.end(), c);
const bool has_positive_prefix = (view[0] == character_set<TChar>::positive_char);
const bool has_negative_prefix = (view[0] == character_set<TChar>::negative_char);
// Remove positive or negative prefixes.
if (has_positive_prefix || has_negative_prefix)
{
view.remove_prefix(1);
}
etl::basic_string_view<TChar> valid_characters;
return (itr != valid_characters.end());
}
//***************************************************************************
///
//***************************************************************************
template <typename T>
ETL_CONSTEXPR14 T accumulate_value(T value, const char digit, const bool is_negative, int shift, const etl::radix::value_type radix)
{
switch (radix)
{
case etl::radix::binary: { valid_characters = etl::basic_string_view<TChar>(character_set<TChar>::numeric_chars, binary_length); break; }
case etl::radix::octal: { valid_characters = etl::basic_string_view<TChar>(character_set<TChar>::numeric_chars, octal_length); break; }
case etl::radix::decimal: { valid_characters = etl::basic_string_view<TChar>(character_set<TChar>::numeric_chars, decimal_length); break; }
case etl::radix::hex: { valid_characters = etl::basic_string_view<TChar>(character_set<TChar>::numeric_chars, hex_length); break; }
default: { break; } // No conversion available.
case etl::radix::decimal:
{
value *= radix;
is_negative ? value -= digit : value += digit;
break;
}
default: // Binary, octal or hex.
{
value <<= shift;
value = value | digit;
break;
}
}
const bool has_valid_prefix = !has_negative_prefix || (radix == etl::radix::decimal);
const bool is_valid = has_valid_prefix && has_valid_characters(view, valid_characters);
return processed_string<TChar>{ view, has_negative_prefix, is_valid };
return value;
}
}
@ -185,65 +179,72 @@ namespace etl
//***************************************************************************
template <typename T, typename TChar>
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
to_integer(etl::basic_string_view<TChar> view, const etl::radix::value_type radix)
to_arithmetic(etl::basic_string_view<TChar> view, const etl::radix::value_type radix)
{
using namespace etl::private_to_arithmetic;
processed_string<TChar> data = preprocess_string(view, radix);
etl::optional<T> result;
// String input was not in a valid format.
if (!data.is_valid)
bool finished_parsing = false;
etl::basic_string_view<TChar> valid_characters;
switch (radix)
{
ETL_ASSERT_FAIL_AND_RETURN_VALUE(ETL_ERROR(etl::to_arithmetic_invalid_format), result);
case etl::radix::binary: { valid_characters = etl::basic_string_view<TChar>(character_set<TChar>::numeric_chars, binary_length); break; }
case etl::radix::octal: { valid_characters = etl::basic_string_view<TChar>(character_set<TChar>::numeric_chars, octal_length); break; }
case etl::radix::decimal: { valid_characters = etl::basic_string_view<TChar>(character_set<TChar>::numeric_chars, decimal_length); break; }
case etl::radix::hex: { valid_characters = etl::basic_string_view<TChar>(character_set<TChar>::numeric_chars, hex_length); break; }
default: { ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_radix_not_supported)); finished_parsing = false; break; }
}
// Can't convert signed to unsigned.
if (data.is_negative && etl::is_unsigned<T>::value)
{
ETL_ASSERT_FAIL_AND_RETURN_VALUE(ETL_ERROR(etl::to_arithmetic_signed_to_unsigned), result);
}
if (data.is_valid)
if (!finished_parsing)
{
T value = 0;
switch (radix)
// Only used for binary, octal and hex.
int shift = (radix == etl::radix::binary) ? 1 : (radix == etl::radix::octal) ? 3 : 4;
etl::basic_string_view<TChar>::const_iterator itr = view.begin();
// Search for a prefix.
const bool has_positive_prefix = (*itr == character_set<TChar>::positive_char);
const bool has_negative_prefix = (*itr == character_set<TChar>::negative_char);
if (has_positive_prefix || has_negative_prefix)
{
case etl::radix::decimal:
{
for (etl::basic_string_view<TChar>::const_iterator itr = data.view.begin(); itr != data.view.end(); ++itr)
{
value *= radix;
char digit = get_digit_value(*itr);
data.is_negative ? value -= digit : value += digit;
}
break;
}
default:
{
int shift = (radix == etl::radix::binary) ? 1 : (radix == etl::radix::octal) ? 3 : 4;
for (etl::basic_string_view<TChar>::const_iterator itr = data.view.begin(); itr != data.view.end(); ++itr)
{
value <<= shift;
char digit = get_digit_value(*itr);
value = value | digit;
}
break;
}
++itr;
}
result = value;
// Negative prefix is only allowed with decimals.
if (has_negative_prefix && (radix != etl::radix::decimal))
{
ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_invalid_format));
finished_parsing = true;
}
// Parse the numeric part.
while (!finished_parsing)
{
if (is_valid_numeric_character(*itr, valid_characters))
{
value = accumulate_value(value, get_digit_value(*itr), has_negative_prefix, shift, radix);
++itr;
if (itr == view.end())
{
result = value;
finished_parsing = true;
}
}
else
{
// Character was not a valid numeric, so fail.
ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_invalid_format));
finished_parsing = true;
}
}
}
return result;
@ -254,9 +255,9 @@ namespace etl
//***************************************************************************
template <typename T, typename TChar>
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
to_integer(const etl::basic_string_view<TChar>& view)
to_arithmetic(const etl::basic_string_view<TChar>& view)
{
return etl::to_integer<T, TChar>(view, etl::radix::decimal);
return etl::to_arithmetic<T, TChar>(view, etl::radix::decimal);
}
//***************************************************************************
@ -264,9 +265,9 @@ namespace etl
//***************************************************************************
template <typename T, typename TChar>
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
to_integer(const etl::basic_string_view<TChar>& view, const etl::basic_format_spec<etl::ibasic_string<TChar> >& spec)
to_arithmetic(const etl::basic_string_view<TChar>& view, const etl::basic_format_spec<etl::ibasic_string<TChar> >& spec)
{
return etl::to_integer<T, TChar>(view, spec.get_base());
return etl::to_arithmetic<T, TChar>(view, spec.get_base());
}
//***************************************************************************
@ -274,9 +275,9 @@ namespace etl
//***************************************************************************
template <typename T, typename TChar>
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
to_integer(const TChar* cp, size_t length, const etl::radix::value_type radix)
to_arithmetic(const TChar* cp, size_t length, const etl::radix::value_type radix)
{
return etl::to_integer<T, TChar>(etl::basic_string_view<TChar>(cp, length), radix);
return etl::to_arithmetic<T, TChar>(etl::basic_string_view<TChar>(cp, length), radix);
}
//***************************************************************************
@ -284,9 +285,9 @@ namespace etl
//***************************************************************************
template <typename T, typename TChar>
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
to_integer(const TChar* cp, size_t length)
to_arithmetic(const TChar* cp, size_t length)
{
return etl::to_integer<T, TChar>(etl::basic_string_view<TChar>(cp, length), etl::radix::decimal);;
return etl::to_arithmetic<T, TChar>(etl::basic_string_view<TChar>(cp, length), etl::radix::decimal);;
}
//***************************************************************************
@ -294,9 +295,9 @@ namespace etl
//***************************************************************************
template <typename T, typename TChar>
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
to_integer(const TChar* cp, size_t length, const typename etl::private_basic_format_spec::base_spec& spec)
to_arithmetic(const TChar* cp, size_t length, const typename etl::private_basic_format_spec::base_spec& spec)
{
return etl::to_integer<T, TChar>(etl::basic_string_view<TChar>(cp, length), spec.base);;
return etl::to_arithmetic<T, TChar>(etl::basic_string_view<TChar>(cp, length), spec.base);;
}
//***************************************************************************
@ -304,9 +305,9 @@ namespace etl
//***************************************************************************
template <typename T, typename TChar>
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
to_integer(const etl::ibasic_string<TChar>& str, const etl::radix::value_type radix)
to_arithmetic(const etl::ibasic_string<TChar>& str, const etl::radix::value_type radix)
{
return etl::to_integer<T, TChar>(etl::basic_string_view<TChar>(str), radix);;
return etl::to_arithmetic<T, TChar>(etl::basic_string_view<TChar>(str), radix);;
}
//***************************************************************************
@ -314,9 +315,9 @@ namespace etl
//***************************************************************************
template <typename T, typename TChar>
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
to_integer(const etl::ibasic_string<TChar>& str)
to_arithmetic(const etl::ibasic_string<TChar>& str)
{
return etl::to_integer<T, TChar>(etl::basic_string_view<TChar>(str), radix);;
return etl::to_arithmetic<T, TChar>(etl::basic_string_view<TChar>(str), radix);;
}
//***************************************************************************
@ -324,22 +325,15 @@ namespace etl
//***************************************************************************
template <typename T, typename TChar>
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
to_integer(const etl::ibasic_string<TChar>& str, const etl::basic_format_spec<etl::ibasic_string<TChar> >& spec)
to_arithmetic(const etl::ibasic_string<TChar>& str, const etl::basic_format_spec<etl::ibasic_string<TChar> >& spec)
{
return etl::to_integer<T, TChar>(etl::basic_string_view<TChar>(str), spec);;
return etl::to_arithmetic<T, TChar>(etl::basic_string_view<TChar>(str), spec);;
}
template <typename T, typename TChar>
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
to_arithmetic(etl::basic_string_view<TChar> view, const etl::radix::value_type radix)
{
return to_integer<T>(view, radix);
}
template <typename T, typename TChar>
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_floating_point<T>::value, etl::optional<T> >::type
to_arithmetic(etl::basic_string_view<TChar> view, const etl::radix::value_type radix)
{
return to_floating_point<T>(view, radix);
}
//template <typename T, typename TChar>
//ETL_CONSTEXPR14 typename etl::enable_if<etl::is_floating_point<T>::value, etl::optional<T> >::type
// to_arithmetic(etl::basic_string_view<TChar> view, const etl::radix::value_type radix)
//{
// return to_floating_point<T>(view, radix);
//}
}

View File

@ -45,23 +45,207 @@ namespace
SUITE(test_to_arithmetic)
{
TEST(test_to_integer_from_char_pointer_to_decimals)
//*************************************************************************
TEST(test_invalid_radixes)
{
const char* pp = " -128 ";
const char* pn = " -123";
const char* decimal = "128";
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal, strlen(decimal), 0), etl::to_arithmetic_radix_not_supported);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal, strlen(decimal), 1), etl::to_arithmetic_radix_not_supported);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal, strlen(decimal), 3), etl::to_arithmetic_radix_not_supported);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal, strlen(decimal), 4), etl::to_arithmetic_radix_not_supported);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal, strlen(decimal), 5), etl::to_arithmetic_radix_not_supported);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal, strlen(decimal), 6), etl::to_arithmetic_radix_not_supported);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal, strlen(decimal), 7), etl::to_arithmetic_radix_not_supported);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal, strlen(decimal), 9), etl::to_arithmetic_radix_not_supported);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal, strlen(decimal), 11), etl::to_arithmetic_radix_not_supported);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal, strlen(decimal), 12), etl::to_arithmetic_radix_not_supported);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal, strlen(decimal), 13), etl::to_arithmetic_radix_not_supported);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal, strlen(decimal), 14), etl::to_arithmetic_radix_not_supported);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal, strlen(decimal), 15), etl::to_arithmetic_radix_not_supported);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal, strlen(decimal), 17), etl::to_arithmetic_radix_not_supported);
}
const std::string huge_n("8000000000000001");
const std::string huge_p("7FFFFFFFFFFFFFFF");
//*************************************************************************
TEST(test_invalid_binary_numerics)
{
const char* decimal1 = " 101";
const char* decimal2 = "101 ";
const char* decimal3 = "121";
const char* decimal4 = "-101";
//CHECK_EQUAL(int(-128), etl::to_integer<int8_t>(pp, strlen(pp), etl::dec).value());
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal1, strlen(decimal1), etl::bin), etl::to_arithmetic_invalid_format);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal2, strlen(decimal2), etl::bin), etl::to_arithmetic_invalid_format);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal3, strlen(decimal3), etl::bin), etl::to_arithmetic_invalid_format);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal4, strlen(decimal4), etl::bin), etl::to_arithmetic_invalid_format);
}
CHECK_EQUAL(std::numeric_limits<int64_t>::min(), etl::to_integer<int64_t>(huge_n.c_str(), huge_n.size(), etl::hex).value());
CHECK_EQUAL(std::numeric_limits<int64_t>::max(), etl::to_integer<int64_t>(huge_p.c_str(), huge_p.size(), etl::hex).value());
//*************************************************************************
TEST(test_valid_binary_numerics)
{
const std::string value1("0");
const std::string value2("1");
const std::string value3("0101");
const std::string value4("1010");
const std::string value5("01010011");
const std::string value6("10101100");
//CHECK_EQUAL(123, etl::to_integer<char>(pp, 3, etl::dec));
//CHECK_EQUAL(123, etl::to_integer<char>(pp, 3, etl::radix::decimal));
//CHECK_EQUAL(123, etl::to_integer<char>(pp, 3, etl::radix(etl::radix::decimal)));
//CHECK_EQUAL(123, etl::to_integer<char>(pp, 3, 10));
CHECK_EQUAL(int(0), int(etl::to_arithmetic<int8_t>(value1.c_str(), value1.size(), etl::bin).value()));
CHECK_EQUAL(int(1), int(etl::to_arithmetic<int8_t>(value2.c_str(), value2.size(), etl::bin).value()));
CHECK_EQUAL(int(5), int(etl::to_arithmetic<int8_t>(value3.c_str(), value3.size(), etl::bin).value()));
CHECK_EQUAL(int(10), int(etl::to_arithmetic<int8_t>(value4.c_str(), value4.size(), etl::bin).value()));
CHECK_EQUAL(int(83), int(etl::to_arithmetic<int8_t>(value5.c_str(), value5.size(), etl::bin).value()));
CHECK_EQUAL(int(-84), int(etl::to_arithmetic<int8_t>(value6.c_str(), value6.size(), etl::bin).value()));
}
//*************************************************************************
TEST(test_big_binary_numerics)
{
const std::string value1("1000000000000000000000000000000000000000000000000000000000000000");
const std::string value2("0111111111111111111111111111111111111111111111111111111111111111");
const std::string value3("1111111111111111111111111111111111111111111111111111111111111111");
CHECK_EQUAL(uint64_t(0x8000000000000000ULL), etl::to_arithmetic<uint64_t>(value1.c_str(), value1.size(), etl::bin).value());
CHECK_EQUAL(uint64_t(0x7FFFFFFFFFFFFFFFULL), etl::to_arithmetic<uint64_t>(value2.c_str(), value2.size(), etl::bin).value());
CHECK_EQUAL(uint64_t(0xFFFFFFFFFFFFFFFFULL), etl::to_arithmetic<uint64_t>(value3.c_str(), value3.size(), etl::bin).value());
}
//*************************************************************************
TEST(test_invalid_octal_numerics)
{
const char* decimal1 = " 127";
const char* decimal2 = "127 ";
const char* decimal3 = "187";
const char* decimal4 = "-127";
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal1, strlen(decimal1), etl::oct), etl::to_arithmetic_invalid_format);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal2, strlen(decimal2), etl::oct), etl::to_arithmetic_invalid_format);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal3, strlen(decimal3), etl::oct), etl::to_arithmetic_invalid_format);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal4, strlen(decimal4), etl::oct), etl::to_arithmetic_invalid_format);
}
//*************************************************************************
TEST(test_valid_octal_numerics)
{
const std::string value1("0");
const std::string value2("1");
const std::string value3("5");
const std::string value4("12");
const std::string value5("123");
const std::string value6("254");
CHECK_EQUAL(int(0), int(etl::to_arithmetic<int8_t>(value1.c_str(), value1.size(), etl::oct).value()));
CHECK_EQUAL(int(1), int(etl::to_arithmetic<int8_t>(value2.c_str(), value2.size(), etl::oct).value()));
CHECK_EQUAL(int(5), int(etl::to_arithmetic<int8_t>(value3.c_str(), value3.size(), etl::oct).value()));
CHECK_EQUAL(int(10), int(etl::to_arithmetic<int8_t>(value4.c_str(), value4.size(), etl::oct).value()));
CHECK_EQUAL(int(83), int(etl::to_arithmetic<int8_t>(value5.c_str(), value5.size(), etl::oct).value()));
CHECK_EQUAL(int(-84), int(etl::to_arithmetic<int8_t>(value6.c_str(), value6.size(), etl::oct).value()));
}
//*************************************************************************
TEST(test_big_octal_numerics)
{
const std::string value1("1000000000000000000000");
const std::string value2("0777777777777777777777");
const std::string value3("1777777777777777777777");
CHECK_EQUAL(uint64_t(0x8000000000000000ULL), etl::to_arithmetic<uint64_t>(value1.c_str(), value1.size(), etl::oct).value());
CHECK_EQUAL(uint64_t(0x7FFFFFFFFFFFFFFFULL), etl::to_arithmetic<uint64_t>(value2.c_str(), value2.size(), etl::oct).value());
CHECK_EQUAL(uint64_t(0xFFFFFFFFFFFFFFFFULL), etl::to_arithmetic<uint64_t>(value3.c_str(), value3.size(), etl::oct).value());
}
//*************************************************************************
TEST(test_invalid_decimal_numerics)
{
const char* decimal1 = " 128";
const char* decimal2 = "128 ";
const char* decimal3 = "1A8";
const char* decimal4 = "++128";
const char* decimal5 = "-+128";
const char* decimal6 = "+-128";
const char* decimal7 = "--128";
const char* decimal8 = "-127";
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal1, strlen(decimal1), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal2, strlen(decimal2), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal3, strlen(decimal3), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal4, strlen(decimal4), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal5, strlen(decimal5), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal6, strlen(decimal6), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal7, strlen(decimal7), etl::dec), etl::to_arithmetic_invalid_format);
}
//*************************************************************************
TEST(test_valid_decimal_numerics)
{
const std::string value1("0");
const std::string value2("1");
const std::string value3("5");
const std::string value4("+10");
const std::string value5("83");
const std::string value6("-84");
CHECK_EQUAL(int(0), int(etl::to_arithmetic<int8_t>(value1.c_str(), value1.size(), etl::dec).value()));
CHECK_EQUAL(int(1), int(etl::to_arithmetic<int8_t>(value2.c_str(), value2.size(), etl::dec).value()));
CHECK_EQUAL(int(5), int(etl::to_arithmetic<int8_t>(value3.c_str(), value3.size(), etl::dec).value()));
CHECK_EQUAL(int(10), int(etl::to_arithmetic<int8_t>(value4.c_str(), value4.size(), etl::dec).value()));
CHECK_EQUAL(int(83), int(etl::to_arithmetic<int8_t>(value5.c_str(), value5.size(), etl::dec).value()));
CHECK_EQUAL(int(-84), int(etl::to_arithmetic<int8_t>(value6.c_str(), value6.size(), etl::dec).value()));
}
//*************************************************************************
TEST(test_big_decimal_numerics)
{
const std::string value1("-9223372036854775808");
const std::string value2("9223372036854775807");
const std::string value3("-1");
CHECK_EQUAL(int64_t(0x8000000000000000ULL), etl::to_arithmetic<int64_t>(value1.c_str(), value1.size(), etl::dec).value());
CHECK_EQUAL(int64_t(0x7FFFFFFFFFFFFFFFULL), etl::to_arithmetic<int64_t>(value2.c_str(), value2.size(), etl::dec).value());
CHECK_EQUAL(int64_t(0xFFFFFFFFFFFFFFFFULL), etl::to_arithmetic<int64_t>(value3.c_str(), value3.size(), etl::dec).value());
}
//*************************************************************************
TEST(test_invalid_hex_numerics)
{
const char* decimal1 = " 1Af";
const char* decimal2 = "1Af ";
const char* decimal3 = "1Gf";
const char* decimal4 = "-1Af";
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal1, strlen(decimal1), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal2, strlen(decimal2), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal3, strlen(decimal3), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW(etl::to_arithmetic<int8_t>(decimal4, strlen(decimal4), etl::dec), etl::to_arithmetic_invalid_format);
}
//*************************************************************************
TEST(test_valid_hex_numerics)
{
const std::string value1("0");
const std::string value2("1");
const std::string value3("5");
const std::string value4("a");
const std::string value5("53");
const std::string value6("Ac");
CHECK_EQUAL(int(0), int(etl::to_arithmetic<int8_t>(value1.c_str(), value1.size(), etl::hex).value()));
CHECK_EQUAL(int(1), int(etl::to_arithmetic<int8_t>(value2.c_str(), value2.size(), etl::hex).value()));
CHECK_EQUAL(int(5), int(etl::to_arithmetic<int8_t>(value3.c_str(), value3.size(), etl::hex).value()));
CHECK_EQUAL(int(10), int(etl::to_arithmetic<int8_t>(value4.c_str(), value4.size(), etl::hex).value()));
CHECK_EQUAL(int(83), int(etl::to_arithmetic<int8_t>(value5.c_str(), value5.size(), etl::hex).value()));
CHECK_EQUAL(int(-84), int(etl::to_arithmetic<int8_t>(value6.c_str(), value6.size(), etl::hex).value()));
}
//*************************************************************************
TEST(test_big_hex_numerics)
{
const std::string value1("8000000000000000");
const std::string value2("7FFFFFFFFFFFFFFF");
const std::string value3("FFFFFFFFFFFFFFFF");
CHECK_EQUAL(uint64_t(0x8000000000000000ULL), etl::to_arithmetic<uint64_t>(value1.c_str(), value1.size(), etl::hex).value());
CHECK_EQUAL(uint64_t(0x7FFFFFFFFFFFFFFFULL), etl::to_arithmetic<uint64_t>(value2.c_str(), value2.size(), etl::hex).value());
CHECK_EQUAL(uint64_t(0xFFFFFFFFFFFFFFFFULL), etl::to_arithmetic<uint64_t>(value3.c_str(), value3.size(), etl::hex).value());
}
}
}