Work-In-Progress

This commit is contained in:
John Wellbelove 2022-10-11 06:56:58 +01:00
parent 94117cd56b
commit 17edf62869
7 changed files with 338 additions and 646 deletions

View File

@ -68,8 +68,8 @@ namespace etl
ETL_CONSTEXPR typename etl::enable_if<etl::is_signed<T>::value, TReturn>::type
absolute_unsigned(T value)
{
return (value == etl::integral_limits<T>::min) ? etl::integral_limits<TReturn>::max / 2U
: (value < T(0)) ? TReturn(-value) : TReturn(value);
return (value == etl::integral_limits<T>::min) ? (etl::integral_limits<TReturn>::max / 2U) + 1U
: (value < T(0)) ? TReturn(-value) : TReturn(value);
}
//***************************************************************************

View File

@ -58,7 +58,19 @@ namespace etl
{
TDestination destination;
#if defined(__has_builtin)
#if __has_builtin(__builtin_memcpy)
#define ETL_USE_BUILTIN_MEMCPY
#endif
#endif
#if defined(ETL_USE_BUILTIN_MEMCPY)
__builtin_memcpy(&destination, &source, sizeof(TDestination));
#else
memcpy(&destination, &source, sizeof(TDestination));
#endif
#undef ETL_USE_BUILTIN_MEMCPY
return destination;
}

View File

@ -256,6 +256,7 @@ namespace etl
typedef uint_least32_t type;
};
#if ETL_USING_64BIT_TYPES
//*************************************************************************
// Greater than 32 bits.
//*************************************************************************
@ -264,6 +265,7 @@ namespace etl
{
typedef uint_least64_t type;
};
#endif
//*************************************************************************
// Determine the type to hold the number of bits based on the index.
@ -298,6 +300,7 @@ namespace etl
typedef int_least32_t type;
};
#if ETL_USING_64BIT_TYPES
//*************************************************************************
// Greater than 32 bits.
//*************************************************************************
@ -306,6 +309,7 @@ namespace etl
{
typedef int_least64_t type;
};
#endif
}
//***************************************************************************

View File

@ -235,19 +235,20 @@ SOFTWARE.
// The macros below are dependent on the profile.
// C++11
#if ETL_USING_CPP11 && !defined(ETL_FORCE_NO_ADVANCED_CPP)
#define ETL_CONSTEXPR constexpr
#define ETL_CONSTANT constexpr
#define ETL_DELETE = delete
#define ETL_EXPLICIT explicit
#define ETL_OVERRIDE override
#define ETL_FINAL final
#define ETL_NORETURN [[noreturn]]
#define ETL_MOVE(x) etl::move(x)
#define ETL_CONSTEXPR constexpr
#define ETL_CONSTANT constexpr
#define ETL_STATIC_CONSTANT constexpr
#define ETL_DELETE = delete
#define ETL_EXPLICIT explicit
#define ETL_OVERRIDE override
#define ETL_FINAL final
#define ETL_NORETURN [[noreturn]]
#define ETL_MOVE(x) etl::move(x)
#define ETL_ENUM_CLASS(name) enum class name
#define ETL_ENUM_CLASS_TYPE(name, type) enum class name : type
#if ETL_USING_EXCEPTIONS
#define ETL_NOEXCEPT noexcept
#define ETL_NOEXCEPT noexcept
#define ETL_NOEXCEPT_EXPR(expression) noexcept(expression)
#else
#define ETL_NOEXCEPT
@ -255,7 +256,8 @@ SOFTWARE.
#endif
#else
#define ETL_CONSTEXPR
#define ETL_CONSTANT const
#define ETL_CONSTANT const
#define ETL_STATIC_CONSTANT static const
#define ETL_DELETE
#define ETL_EXPLICIT
#define ETL_OVERRIDE
@ -271,8 +273,8 @@ SOFTWARE.
//*************************************
// C++14
#if ETL_USING_CPP14 && !defined(ETL_FORCE_NO_ADVANCED_CPP)
#define ETL_CONSTEXPR14 constexpr
#define ETL_DEPRECATED [[deprecated]]
#define ETL_CONSTEXPR14 constexpr
#define ETL_DEPRECATED [[deprecated]]
#define ETL_DEPRECATED_REASON(reason) [[deprecated(reason)]]
#else
#define ETL_CONSTEXPR14
@ -301,11 +303,11 @@ SOFTWARE.
//*************************************
// C++20
#if ETL_USING_CPP20 && !defined(ETL_FORCE_NO_ADVANCED_CPP)
#define ETL_LIKELY [[likely]]
#define ETL_UNLIKELY [[unlikely]]
#define ETL_CONSTEXPR20 constexpr
#define ETL_CONSTEVAL consteval
#define ETL_CONSTINIT constinit
#define ETL_LIKELY [[likely]]
#define ETL_UNLIKELY [[unlikely]]
#define ETL_CONSTEXPR20 constexpr
#define ETL_CONSTEVAL consteval
#define ETL_CONSTINIT constinit
#define ETL_NO_UNIQUE_ADDRESS [[no_unique_address]]
#else
#define ETL_LIKELY

View File

@ -226,6 +226,7 @@ namespace etl
typedef uint_least32_t type;
};
#if ETL_USING_64BIT_TYPES
//*************************************************************************
// Greater than 32 bits.
//*************************************************************************
@ -234,6 +235,7 @@ namespace etl
{
typedef uint_least64_t type;
};
#endif
//*************************************************************************
// Determine the type to hold the number of bits based on the index.
@ -268,6 +270,7 @@ namespace etl
typedef int_least32_t type;
};
#if ETL_USING_64BIT_TYPES
//*************************************************************************
// Greater than 32 bits.
//*************************************************************************
@ -276,6 +279,7 @@ namespace etl
{
typedef int_least64_t type;
};
#endif
}
//***************************************************************************

View File

@ -9,83 +9,16 @@
#include "optional.h"
#include "string_utilities.h"
#include "iterator.h"
#include "exception.h"
#include "error_handler.h"
#include "bit.h"
#include "smallest.h"
#include "absolute.h"
namespace etl
{
//***************************************************************************
///
//***************************************************************************
class to_arithmetic_exception : public etl::exception
{
public:
to_arithmetic_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
: exception(reason_, file_name_, line_number_)
{
}
};
//***************************************************************************
///
//***************************************************************************
class to_arithmetic_signed_to_unsigned : public to_arithmetic_exception
{
public:
to_arithmetic_signed_to_unsigned(string_type file_name_, numeric_type line_number_)
: to_arithmetic_exception(ETL_ERROR_TEXT("to arithmetic:signed to unsigned", ETL_TO_ARITHMETIC_FILE_ID"A"), file_name_, line_number_)
{
}
};
//***************************************************************************
///
//***************************************************************************
class to_arithmetic_invalid_format : public to_arithmetic_exception
{
public:
to_arithmetic_invalid_format(string_type file_name_, numeric_type line_number_)
: to_arithmetic_exception(ETL_ERROR_TEXT("to arithmetic:invalid format", ETL_TO_ARITHMETIC_FILE_ID"B"), file_name_, line_number_)
{
}
};
//***************************************************************************
///
//***************************************************************************
class to_arithmetic_invalid_radix : public to_arithmetic_exception
{
public:
to_arithmetic_invalid_radix(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_)
{
}
};
//***************************************************************************
///
//***************************************************************************
class to_arithmetic_overflow : public to_arithmetic_exception
{
public:
to_arithmetic_overflow(string_type file_name_, numeric_type line_number_)
: to_arithmetic_exception(ETL_ERROR_TEXT("to arithmetic:overflow", ETL_TO_ARITHMETIC_FILE_ID"D"), file_name_, line_number_)
{
}
};
namespace private_to_arithmetic
{
//static ETL_CONSTANT char binary_length = 2;
//static ETL_CONSTANT char octal_length = 8;
//static ETL_CONSTANT char decimal_length = 10;
static ETL_CONSTANT char Numeric_Length = 16;
static ETL_CONSTANT int valid_length = 28;
static ETL_CONSTANT int Valid_Length = 28;
//***********************************************************************
///
@ -159,15 +92,14 @@ namespace etl
case etl::radix::hex:
{
for (int i = 0; i < 16; ++i)
if ((c >= '0') && (c <= '9'))
{
if (c == numeric_chars[i])
{
return i;
}
return c - '0';
}
else
{
return (c - 'a') + 10;
}
return 0;
break;
}
@ -178,23 +110,6 @@ namespace etl
}
}
}
private:
//*******************************************
//ETL_NODISCARD
//ETL_CONSTEXPR14
//static int get_length(etl::radix::value_type radix)
//{
// switch (radix)
// {
// case etl::radix::binary: { return binary_length; }
// case etl::radix::octal: { return octal_length; }
// case etl::radix::decimal: { return decimal_length; }
// case etl::radix::hex: { return hex_length; }
// default: { ETL_ASSERT_FAIL_AND_RETURN_VALUE(ETL_ERROR(etl::to_arithmetic_invalid_radix), 0) }
// }
//}
};
//*******************************************
@ -233,13 +148,9 @@ namespace etl
typedef wchar_t value_type;
typedef const value_type* string_type;
#if ETL_USING_CPP14
constexpr string_type valid_chars = L"+-.,eE0123456789abcdefABCDEF";
#else
static const string_type valid_chars = L"+-.,eE0123456789abcdefABCDEF";
#endif
ETL_STATIC_CONSTANT string_type valid_chars = L"+-.,eE0123456789abcdefABCDEF";
for (int i = 0; i < valid_length; ++i)
for (int i = 0; i < Valid_Length; ++i)
{
if (c == valid_chars[i])
{
@ -259,13 +170,9 @@ namespace etl
typedef char16_t value_type;
typedef const value_type* string_type;
#if ETL_USING_CPP14
constexpr string_type valid_chars = u"+-.,eE0123456789abcdefABCDEF";
#else
static const string_type valid_chars = u"+-.,eE0123456789abcdefABCDEF";
#endif
ETL_STATIC_CONSTANT string_type valid_chars = u"+-.,eE0123456789abcdefABCDEF";
for (int i = 0; i < valid_length; ++i)
for (int i = 0; i < Valid_Length; ++i)
{
if (c == valid_chars[i])
{
@ -285,13 +192,9 @@ namespace etl
typedef char32_t value_type;
typedef const value_type* string_type;
#if ETL_USING_CPP14
constexpr string_type valid_chars = U"+-.,eE0123456789abcdefABCDEF";
#else
static const string_type valid_chars = U"+-.,eE0123456789abcdefABCDEF";
#endif
ETL_STATIC_CONSTANT string_type valid_chars = U"+-.,eE0123456789abcdefABCDEF";
for (int i = 0; i < valid_length; ++i)
for (int i = 0; i < Valid_Length; ++i)
{
if (c == valid_chars[i])
{
@ -302,36 +205,6 @@ namespace etl
return valid_character_set::unknown_char;
}
//***************************************************************************
///
//***************************************************************************
template <typename TValue>
ETL_NODISCARD
ETL_CONSTEXPR14
typename etl::enable_if<etl::is_integral<TValue>::value && etl::is_unsigned<TValue>::value, TValue>::type
accumulate_value(TValue value, char digit, etl::radix::value_type radix, bool is_negative)
{
value *= radix;
value += digit;
return value;
}
//***************************************************************************
///
//***************************************************************************
template <typename TValue>
ETL_NODISCARD
ETL_CONSTEXPR14
typename etl::enable_if<etl::is_integral<TValue>::value && etl::is_signed<TValue>::value, TValue>::type
accumulate_value(TValue value, char digit, etl::radix::value_type radix, bool is_negative)
{
value *= radix;
is_negative ? value -= digit : value += digit;
return value;
}
//***************************************************************************
///
//***************************************************************************
@ -339,7 +212,7 @@ namespace etl
ETL_NODISCARD
ETL_CONSTEXPR14
typename etl::enable_if<etl::is_floating_point<TValue>::value, TValue>::type
accumulate_value(TValue value, char digit, bool is_negative)
accumulate_floating_point_value(TValue value, char digit, bool is_negative)
{
value *= etl::radix::decimal;
is_negative ? value -= digit : value += digit;
@ -348,82 +221,25 @@ namespace etl
}
//*******************************************
template <typename TIterator>
template <typename TChar>
ETL_NODISCARD
ETL_CONSTEXPR14
bool check_has_negative_prefix(TIterator& itr)
bool check_and_remove_sign_prefix(etl::basic_string_view<TChar>& view)
{
// Check for prefix.
const char c = convert(*itr);
const char c = convert(view[0]);
const bool has_positive_prefix = (c == valid_character_set::positive_char);
const bool has_negative_prefix = (c == valid_character_set::negative_char);
// Step over the prefix, if present.
if (has_positive_prefix || has_negative_prefix)
{
++itr;
view.remove_prefix(1);
}
return has_negative_prefix;
}
//***************************************************************************
///
//***************************************************************************
//template <typename TValue>
//struct to_integral_implementation
//{
// //*********************************
// ETL_NODISCARD
// ETL_CONSTEXPR14
// to_integral_implementation(etl::radix::value_type radix_, bool is_negative_)
// : value(0)
// , is_negative(is_negative_)
// , valid_value(false)
// , radix(radix_)
// {
// }
// //*********************************
// ETL_NODISCARD
// ETL_CONSTEXPR14
// bool add(char c)
// {
// bool is_valid = valid_character_set::is_valid(c, radix);
//
// if (is_valid)
// {
// value = accumulate_value(value, valid_character_set::digit_value(c, radix), radix, is_negative);
// valid_value = true;
// }
// return is_valid;
// }
// //*********************************
// ETL_NODISCARD
// ETL_CONSTEXPR14
// bool has_value() const
// {
// return (valid_value == true);
// }
// //*********************************
// ETL_NODISCARD
// ETL_CONSTEXPR14
// TValue get_value() const
// {
// return value;
// }
//private:
// TValue value;
// bool is_negative;
// bool valid_value;
// etl::radix::value_type radix;
//};
//***************************************************************************
///
//***************************************************************************
@ -449,7 +265,7 @@ namespace etl
if (is_valid)
{
value = accumulate_value(value, valid_character_set::digit_value(c, etl::radix::decimal), is_negative);
value = accumulate_floating_point_value(value, valid_character_set::digit_value(c, etl::radix::decimal), is_negative);
valid_value = true;
}
@ -479,230 +295,6 @@ namespace etl
bool valid_value;
};
//***************************************************************************
/// Text to integral from view and radix value type.
// For unsigned 32 int.
//***************************************************************************
//template <typename TChar>
//ETL_NODISCARD
//ETL_CONSTEXPR14
//etl::optional<uint32_t> to_arithmetic_uint32_t(const etl::basic_string_view<TChar>& view, const etl::radix::value_type radix)
//{
// using namespace etl::private_to_arithmetic;
// etl::optional<uint32_t> result;
// bool is_negative = false;
//
// if (!view.empty())
// {
// ETL_ASSERT(!check_has_negative_prefix(view), ETL_ERROR(etl::to_arithmetic_signed_to_unsigned));
// to_integral_implementation<uint32_t> implementation(radix, is_negative);
// bool parsing = true;
// etl::basic_string_view<TChar>::const_iterator itr = view.begin();
// while (parsing)
// {
// parsing = implementation.add(convert(*itr));
// if (parsing)
// {
// ++itr;
// if (itr == view.end())
// {
// ETL_ASSERT(implementation.has_value(), ETL_ERROR(etl::to_arithmetic_invalid_format));
// result = implementation.get_value();
// parsing = false;
// }
// }
// else
// {
// ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_invalid_format));
// }
// }
// }
// else
// {
// ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_invalid_format));
// }
// return result;
//}
//***************************************************************************
/// Text to integral from view and radix value type.
// For signed 32 int.
//***************************************************************************
// template <typename TChar>
// ETL_NODISCARD
// ETL_CONSTEXPR14
// etl::optional<int32_t> to_arithmetic_int32_t(const etl::basic_string_view<TChar>& view, const etl::radix::value_type radix)
// {
// using namespace etl::private_to_arithmetic;
//
// etl::optional<int32_t> result;
// bool is_negative = false;
//
// if (!view.empty())
// {
// is_negative = check_has_negative_prefix(view);
// }
//
// if (!view.empty())
// {
// to_integral_implementation<int32_t> implementation(radix, is_negative);
//
// bool parsing = true;
//
// etl::basic_string_view<TChar>::const_iterator itr = view.begin();
//
// while (parsing)
// {
// parsing = implementation.add(convert(*itr));
//
// if (parsing)
// {
// ++itr;
//
// if (itr == view.end())
// {
// ETL_ASSERT(implementation.has_value(), ETL_ERROR(etl::to_arithmetic_invalid_format));
//
// result = implementation.get_value();
// parsing = false;
// }
// }
// else
// {
// ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_invalid_format));
// }
// }
// }
// else
// {
// ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_invalid_format));
// }
//
// return result;
// }
//
//#if ETL_USING_64BIT_TYPES
// //***************************************************************************
// /// Text to integral from view and radix value type.
// // For unsigned 64 int.
// //***************************************************************************
// template <typename TChar>
// ETL_NODISCARD
// ETL_CONSTEXPR14
// etl::optional<uint64_t> to_arithmetic_uint64_t(const etl::basic_string_view<TChar>& view, const etl::radix::value_type radix)
// {
// using namespace etl::private_to_arithmetic;
//
// etl::optional<uint64_t> result;
// bool is_negative = false;
//
// if (!view.empty())
// {
// ETL_ASSERT(!check_has_negative_prefix(view), ETL_ERROR(etl::to_arithmetic_signed_to_unsigned));
//
// to_integral_implementation<uint64_t> implementation(radix, is_negative);
//
// bool parsing = true;
//
// etl::basic_string_view<TChar>::const_iterator itr = view.begin();
//
// while (parsing)
// {
// parsing = implementation.add(convert(*itr));
//
// if (parsing)
// {
// ++itr;
//
// if (itr == view.end())
// {
// ETL_ASSERT(implementation.has_value(), ETL_ERROR(etl::to_arithmetic_invalid_format));
//
// result = implementation.get_value();
// parsing = false;
// }
// }
// else
// {
// ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_invalid_format));
// }
// }
// }
// else
// {
// ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_invalid_format));
// }
//
// return result;
// }
//
// //***************************************************************************
// /// Text to integral from view and radix value type.
// // For signed 64 int.
// //***************************************************************************
// template <typename TChar>
// ETL_NODISCARD
// ETL_CONSTEXPR14
// etl::optional<int64_t> to_arithmetic_int64_t(const etl::basic_string_view<TChar>& view, const etl::radix::value_type radix)
// {
// using namespace etl::private_to_arithmetic;
//
// etl::optional<int64_t> result;
// bool is_negative = false;
//
// if (!view.empty())
// {
// is_negative = check_has_negative_prefix(view);
// }
//
// if (!view.empty())
// {
// to_integral_implementation<int64_t> implementation(radix, is_negative);
//
// bool parsing = true;
//
// etl::basic_string_view<TChar>::const_iterator itr = view.begin();
//
// while (parsing)
// {
// parsing = implementation.add(convert(*itr));
//
// if (parsing)
// {
// ++itr;
//
// if (itr == view.end())
// {
// ETL_ASSERT(implementation.has_value(), ETL_ERROR(etl::to_arithmetic_invalid_format));
//
// result = implementation.get_value();
// parsing = false;
// }
// }
// else
// {
// ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_invalid_format));
// }
// }
// }
// else
// {
// ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_invalid_format));
// }
//
// return result;
// }
//#endif
//***************************************************************************
///
//***************************************************************************
@ -725,52 +317,53 @@ namespace etl
//*********************************
ETL_NODISCARD
ETL_CONSTEXPR14
integral_accumulator(etl::radix::value_type radix_)
: is_negative(false)
, valid_value(false)
, first_char(true)
integral_accumulator(etl::radix::value_type radix_, TValue maximum_)
: radix(radix_)
, maximum(maximum_)
, value(0)
, radix(radix_)
, value_is_valid(false)
{
}
//*********************************
ETL_NODISCARD
ETL_CONSTEXPR14
bool add(char c)
bool add(const char c)
{
bool has_positive_prefix = false;
bool has_negative_prefix = false;
value_is_valid = false;
if (first_char)
if (valid_character_set::is_valid(c, radix))
{
has_positive_prefix = (c == valid_character_set::positive_char);
has_negative_prefix = (c == valid_character_set::negative_char);
TValue old_value = value;
value *= radix;
if (has_positive_prefix || has_negative_prefix)
// No multipication overflow?
if ((value / radix) == old_value)
{
is_negative = has_negative_prefix;
first_char = false;
const char digit = valid_character_set::digit_value(c, radix);
return true;
// No addition overflow?
if ((maximum - digit) >= value)
{
value += digit;
value_is_valid = true;
}
else
{
int i = 0;
}
}
else
{
int i = 0; // <<<<<<<< Test to catch this.
}
}
const bool is_valid = valid_character_set::is_valid(c, radix);
ETL_ASSERT_AND_RETURN_VALUE(is_valid,
ETL_ERROR(etl::to_arithmetic_invalid_format),
false);
if (is_valid)
else
{
value = accumulate_value(value, valid_character_set::digit_value(c, radix), radix, is_negative);
valid_value = true;
int i = 0;
}
first_char = false;
return is_valid;
return value_is_valid;
}
//*********************************
@ -778,9 +371,8 @@ namespace etl
ETL_CONSTEXPR14
bool has_value() const
{
return (valid_value == true);
return value_is_valid;
}
//*********************************
ETL_NODISCARD
ETL_CONSTEXPR14
@ -791,85 +383,52 @@ namespace etl
private:
bool is_negative;
bool valid_value;
bool first_char;
TValue value;
etl::radix::value_type radix;
TValue maximum;
TValue value;
bool value_is_valid;
};
//***************************************************************************
// Define intermediate type.
// Define an intermediate type that is larger than TValue.
//***************************************************************************
#if ETL_USING_64BIT_TYPES
template <typename TValue>
struct intermediate
{
ETL_STATIC_ASSERT(etl::integral_limits<TValue>::bits <= 64U, "Types greater than 64bits not supported");
typedef typename etl::conditional<etl::integral_limits<TValue>::bits <= 32U,
typename etl::conditional<etl::is_unsigned<TValue>::value,
uint32_t,
int32_t>::type,
typename etl::conditional<etl::is_unsigned<TValue>::value,
uint64_t,
int64_t>::type>::type type;
typedef typename etl::smallest_uint_for_bits<etl::integral_limits<TValue>::bits>::type type;
};
#else
template <typename TValue>
struct intermediate
{
ETL_STATIC_ASSERT(etl::integral_limits<TValue>::bits <= 32U, "Types greater than 32bits not supported");
typedef typename etl::conditional<etl::is_unsigned<TValue>::value,
uint32_t,
int32_t>::type type;
};
#endif
//***************************************************************************
/// Text to integral from view and radix value type.
///\tparam TIntermediate One of int32t, uint32_t, int64_t or uint64_t.
//***************************************************************************
template <typename TIntermediate, typename TChar>
template <typename TChar, typename TIntermediate>
ETL_NODISCARD
ETL_CONSTEXPR14
etl::optional<TIntermediate> to_arithmetic_integral(const etl::basic_string_view<TChar>& view,
const etl::radix::value_type radix)
const etl::radix::value_type radix,
const TIntermediate maximum)
{
ETL_ASSERT_AND_RETURN_VALUE(is_valid_radix(radix), ETL_ERROR(etl::to_arithmetic_invalid_radix), false);
etl::optional<TIntermediate> intermediate_result;
etl::basic_string_view<TChar>::const_iterator itr = view.begin();
etl::basic_string_view<TChar>::const_iterator itr = view.begin();
const etl::basic_string_view<TChar>::const_iterator itr_end = view.end();
if (itr == itr_end)
{
ETL_ASSERT_FAIL_AND_RETURN_VALUE(ETL_ERROR(etl::to_arithmetic_invalid_format), false);
}
else
if (itr != itr_end)
{
const char first_char = convert(*itr);
ETL_ASSERT(!((first_char == valid_character_set::negative_char) && etl::is_unsigned<TIntermediate>::value), ETL_ERROR(etl::to_arithmetic_signed_to_unsigned));
integral_accumulator<TIntermediate> accumulator(radix);
integral_accumulator<TIntermediate> accumulator(radix, maximum);
while ((itr != itr_end) && accumulator.add(convert(*itr)))
{
// Keep looping until done or an error occurs.
++itr;
}
}
if (accumulator.has_value())
{
intermediate_result = accumulator.get_value();
}
else
{
ETL_ASSERT_FAIL_AND_RETURN_VALUE(ETL_ERROR(etl::to_arithmetic_invalid_format), false);
}
}
return intermediate_result;
@ -883,20 +442,38 @@ namespace etl
ETL_NODISCARD
ETL_CONSTEXPR14
typename etl::enable_if<etl::is_integral<TValue>::value, etl::optional<TValue> >::type
to_arithmetic(const 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;
etl::optional<TValue> result;
typedef typename intermediate<TValue>::type intermediate_type;
etl::optional<intermediate_type> intermediate_result;
intermediate_result = to_arithmetic_integral<intermediate_type, TChar>(view, radix);
// Is this a negative number?
const bool is_negative = check_and_remove_sign_prefix(view);
if (intermediate_result.has_value())
// Make sure we're not trying to put a negative value into an unsigned type.
if (!(is_negative && etl::is_unsigned<TValue>::value))
{
result = intermediate_result.value();
const bool is_decimal = (radix == etl::radix::decimal);
// What's the maximum absolute value for the type value we're trying to convert to?
//const intermediate_type maximum = (is_negative || non_decimal) ? etl::absolute_unsigned(etl::integral_limits<TValue>::min)
// : etl::integral_limits<TValue>::max;
const intermediate_type maximum = is_negative ? etl::absolute_unsigned(etl::integral_limits<TValue>::min)
: is_decimal ? etl::integral_limits<TValue>::max
: etl::integral_limits<typename etl::make_unsigned<TValue>::type>::max;
// Do the conversion.
etl::optional<intermediate_type> intermediate_result = to_arithmetic_integral<TChar>(view, radix, maximum);
// Was it successful?
if (intermediate_result.has_value())
{
// Convert from the intermediate type to the desired type.
result = is_negative ? TValue(0) - intermediate_result.value() : etl::bit_cast<TValue>(intermediate_result.value());
}
}
return result;
@ -1009,7 +586,7 @@ namespace etl
if (!view.empty())
{
is_negative = check_has_negative_prefix(view);
is_negative = check_and_remove_sign_prefix(view);
}
if (!view.empty())

View File

@ -48,37 +48,37 @@ namespace
//*************************************************************************
TEST(test_invalid_radixes)
{
const std::string text("128");
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 0), etl::to_arithmetic_invalid_radix);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 1), etl::to_arithmetic_invalid_radix);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 3), etl::to_arithmetic_invalid_radix);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 4), etl::to_arithmetic_invalid_radix);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 5), etl::to_arithmetic_invalid_radix);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 6), etl::to_arithmetic_invalid_radix);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 7), etl::to_arithmetic_invalid_radix);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 9), etl::to_arithmetic_invalid_radix);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 11), etl::to_arithmetic_invalid_radix);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 12), etl::to_arithmetic_invalid_radix);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 13), etl::to_arithmetic_invalid_radix);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 14), etl::to_arithmetic_invalid_radix);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 15), etl::to_arithmetic_invalid_radix);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 17), etl::to_arithmetic_invalid_radix);
//const std::string text("128");
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 0), etl::to_arithmetic_invalid_radix);
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 1), etl::to_arithmetic_invalid_radix);
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 3), etl::to_arithmetic_invalid_radix);
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 4), etl::to_arithmetic_invalid_radix);
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 5), etl::to_arithmetic_invalid_radix);
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 6), etl::to_arithmetic_invalid_radix);
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 7), etl::to_arithmetic_invalid_radix);
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 9), etl::to_arithmetic_invalid_radix);
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 11), etl::to_arithmetic_invalid_radix);
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 12), etl::to_arithmetic_invalid_radix);
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 13), etl::to_arithmetic_invalid_radix);
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 14), etl::to_arithmetic_invalid_radix);
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 15), etl::to_arithmetic_invalid_radix);
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text.c_str(), text.size(), 17), etl::to_arithmetic_invalid_radix);
}
//*************************************************************************
TEST(test_invalid_binary_numerics)
{
const std::string text1(" 101");
const std::string text2("101 ");
const std::string text3("121");
const std::string text4("");
const std::string text5("-101");
//const std::string text1(" 101");
//const std::string text2("101 ");
//const std::string text3("121");
//const std::string text4("");
//const std::string text5("-101");
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text1.c_str(), text1.size(), etl::bin), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text2.c_str(), text2.size(), etl::bin), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text3.c_str(), text3.size(), etl::bin), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text4.c_str(), text4.size(), etl::bin), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<uint8_t>(text5.c_str(), text5.size(), etl::bin), etl::to_arithmetic_signed_to_unsigned);
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text1.c_str(), text1.size(), etl::bin));
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text2.c_str(), text2.size(), etl::bin));
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text3.c_str(), text3.size(), etl::bin));
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text4.c_str(), text4.size(), etl::bin));
//CHECK_THROW((void)etl::to_arithmetic<uint8_t>(text5.c_str(), text5.size(), etl::bin), etl::to_arithmetic_signed_to_unsigned);
}
//*************************************************************************
@ -90,7 +90,7 @@ namespace
const std::string value4("1010");
const std::string value5("01010011");
const std::string value6("10101100");
const std::string value7("-01010011");
const std::string value7("-01010100");
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()));
@ -98,65 +98,65 @@ namespace
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()));
CHECK_EQUAL(int(-83), int(etl::to_arithmetic<int8_t>(value7.c_str(), value7.size(), etl::bin).value()));
CHECK_EQUAL(int(-84), int(etl::to_arithmetic<int8_t>(value7.c_str(), value7.size(), etl::bin).value()));
}
//*************************************************************************
TEST(test_big_binary_numerics)
{
const std::string value1("1000000000000000000000000000000000000000000000000000000000000000");
const std::string value2("0111111111111111111111111111111111111111111111111111111111111111");
const std::string value3("1111111111111111111111111111111111111111111111111111111111111111");
//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());
//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 std::string text1(" 127");
const std::string text2("127 ");
const std::string text3("187");
const std::string text4("-187");
//const std::string text1(" 127");
//const std::string text2("127 ");
//const std::string text3("187");
//const std::string text4("-187");
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text1.c_str(), text1.size(), etl::oct), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text2.c_str(), text2.size(), etl::oct), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text3.c_str(), text3.size(), etl::oct), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<uint8_t>(text4.c_str(), text4.size(), etl::oct), etl::to_arithmetic_signed_to_unsigned);
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text1.c_str(), text1.size(), etl::oct));
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text2.c_str(), text2.size(), etl::oct));
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text3.c_str(), text3.size(), etl::oct));
//CHECK_THROW((void)etl::to_arithmetic<uint8_t>(text4.c_str(), text4.size(), etl::oct), etl::to_arithmetic_signed_to_unsigned);
}
//*************************************************************************
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");
const std::string value7("-123");
//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");
//const std::string value7("-123");
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()));
CHECK_EQUAL(int(-83), int(etl::to_arithmetic<int8_t>(value7.c_str(), value7.size(), etl::oct).value()));
//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()));
//CHECK_EQUAL(int(-83), int(etl::to_arithmetic<int8_t>(value7.c_str(), value7.size(), etl::oct).value()));
}
//*************************************************************************
TEST(test_big_octal_numerics)
{
const std::string value1("1000000000000000000000");
const std::string value2("0777777777777777777777");
const std::string value3("1777777777777777777777");
//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());
//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());
}
//*************************************************************************
@ -173,16 +173,16 @@ namespace
const std::string text9("-");
const std::string text10("");
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text1.c_str(), text1.size(), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text2.c_str(), text2.size(), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text3.c_str(), text3.size(), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text4.c_str(), text4.size(), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text5.c_str(), text5.size(), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text6.c_str(), text6.size(), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text7.c_str(), text7.size(), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text8.c_str(), text8.size(), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text9.c_str(), text9.size(), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text10.c_str(), text10.size(), etl::dec), etl::to_arithmetic_invalid_format);
CHECK(!etl::to_arithmetic<int8_t>(text1.c_str(), text1.size(), etl::dec));
CHECK(!etl::to_arithmetic<int8_t>(text2.c_str(), text2.size(), etl::dec));
CHECK(!etl::to_arithmetic<int8_t>(text3.c_str(), text3.size(), etl::dec));
CHECK(!etl::to_arithmetic<int8_t>(text4.c_str(), text4.size(), etl::dec));
CHECK(!etl::to_arithmetic<int8_t>(text5.c_str(), text5.size(), etl::dec));
CHECK(!etl::to_arithmetic<int8_t>(text6.c_str(), text6.size(), etl::dec));
CHECK(!etl::to_arithmetic<int8_t>(text7.c_str(), text7.size(), etl::dec));
CHECK(!etl::to_arithmetic<int8_t>(text8.c_str(), text8.size(), etl::dec));
CHECK(!etl::to_arithmetic<int8_t>(text9.c_str(), text9.size(), etl::dec));
CHECK(!etl::to_arithmetic<int8_t>(text10.c_str(), text10.size(), etl::dec));
}
//*************************************************************************
@ -200,70 +200,163 @@ namespace
CHECK_EQUAL(int(5), int(etl::to_arithmetic<int8_t>(text3.c_str(), text3.size(), etl::dec).value()));
CHECK_EQUAL(int(10), int(etl::to_arithmetic<int8_t>(text4.c_str(), text4.size(), etl::dec).value()));
CHECK_EQUAL(int(83), int(etl::to_arithmetic<int8_t>(text5.c_str(), text5.size(), etl::dec).value()));
CHECK_EQUAL(int(83), int(etl::to_arithmetic<uint8_t>(text5.c_str(), text5.size(), etl::dec).value()));
CHECK_EQUAL(int(-84), int(etl::to_arithmetic<int8_t>(text6.c_str(), text6.size(), etl::dec).value()));
}
//*************************************************************************
TEST(test_big_decimal_numerics)
TEST(test_maximum_decimal_numerics)
{
const std::string text1("-9223372036854775808");
const std::string text2("9223372036854775807");
const std::string text3("-1");
const std::string int8_max("127");
const std::string int8_min("-128");
CHECK_EQUAL(-9223372036854775808LL, etl::to_arithmetic<int64_t>(text1.c_str(), text1.size(), etl::dec).value());
CHECK_EQUAL(9223372036854775807LL, etl::to_arithmetic<int64_t>(text2.c_str(), text2.size(), etl::dec).value());
CHECK_EQUAL(-1LL, etl::to_arithmetic<int64_t>(text3.c_str(), text3.size(), etl::dec).value());
const std::string uint8_max("255");
const std::string uint8_min("0");
const std::string int16_max("32767");
const std::string int16_min("-32768");
const std::string uint16_max("65535");
const std::string uint16_min("0");
const std::string int32_max("2147483647");
const std::string int32_min("-2147483648");
const std::string uint32_max("4294967295");
const std::string uint32_min("0");
const std::string int64_max("9223372036854775807");
const std::string int64_min("-9223372036854775808");
const std::string uint64_max("18446744073709551615");
const std::string uint64_min("0");
CHECK_EQUAL( 127, etl::to_arithmetic<int8_t>(int8_max.c_str(), int8_max.size(), etl::dec));
CHECK_EQUAL(-128, etl::to_arithmetic<int8_t>(int8_min.c_str(), int8_min.size(), etl::dec));
CHECK_EQUAL(255, etl::to_arithmetic<uint8_t>(uint8_max.c_str(), uint8_max.size(), etl::dec));
CHECK_EQUAL( 0, etl::to_arithmetic<uint8_t>(uint8_min.c_str(), uint8_min.size(), etl::dec));
CHECK_EQUAL( 32767, etl::to_arithmetic<int16_t>(int16_max.c_str(), int16_max.size(), etl::dec));
CHECK_EQUAL(-32768, etl::to_arithmetic<int16_t>(int16_min.c_str(), int16_min.size(), etl::dec));
CHECK_EQUAL(65535, etl::to_arithmetic<uint16_t>(uint16_max.c_str(), uint16_max.size(), etl::dec));
CHECK_EQUAL( 0, etl::to_arithmetic<uint16_t>(uint16_min.c_str(), uint16_min.size(), etl::dec));
CHECK_EQUAL( 2147483647LL, etl::to_arithmetic<int32_t>(int32_max.c_str(), int32_max.size(), etl::dec));
CHECK_EQUAL(-2147483648LL, etl::to_arithmetic<int32_t>(int32_min.c_str(), int32_min.size(), etl::dec));
CHECK_EQUAL(4294967295ULL, etl::to_arithmetic<uint32_t>(uint32_max.c_str(), uint32_max.size(), etl::dec));
CHECK_EQUAL( 0ULL, etl::to_arithmetic<uint32_t>(uint32_min.c_str(), uint32_min.size(), etl::dec));
CHECK_EQUAL( 9223372036854775807LL, etl::to_arithmetic<int64_t>(int64_max.c_str(), int64_max.size(), etl::dec));
CHECK_EQUAL(-9223372036854775808LL, etl::to_arithmetic<int64_t>(int64_min.c_str(), int64_min.size(), etl::dec));
CHECK_EQUAL(18446744073709551615ULL, etl::to_arithmetic<uint64_t>(uint64_max.c_str(), uint64_max.size(), etl::dec));
CHECK_EQUAL( 0ULL, etl::to_arithmetic<uint64_t>(uint64_min.c_str(), uint64_min.size(), etl::dec));
}
//*************************************************************************
TEST(test_decimal_overflow)
{
const std::string int8_overflow_max("128");
const std::string int8_overflow_min("-129");
const std::string uint8_overflow_max("256");
const std::string uint8_overflow_min("-1");
const std::string int16_overflow_max("32768");
const std::string int16_overflow_min("-32769");
const std::string uint16_overflow_max("65536");
const std::string uint16_overflow_min("-1");
const std::string int32_overflow_max("2147483648");
const std::string int32_overflow_min("-2147483649");
const std::string uint32_overflow_max("4294967296");
const std::string uint32_overflow_min("-1");
const std::string int64_overflow_max("9223372036854775808");
const std::string int64_overflow_min("-9223372036854775809");
const std::string uint64_overflow_max("18446744073709551616");
const std::string uint64_overflow_min("-1");
CHECK(!etl::to_arithmetic<int8_t>(int8_overflow_max.c_str(), int8_overflow_max.size(), etl::dec));
CHECK(!etl::to_arithmetic<int8_t>(int8_overflow_min.c_str(), int8_overflow_min.size(), etl::dec));
CHECK(!etl::to_arithmetic<uint8_t>(uint8_overflow_max.c_str(), uint8_overflow_max.size(), etl::dec));
CHECK(!etl::to_arithmetic<uint8_t>(uint8_overflow_min.c_str(), uint8_overflow_min.size(), etl::dec));
CHECK(!etl::to_arithmetic<int16_t>(int16_overflow_max.c_str(), int16_overflow_max.size(), etl::dec));
CHECK(!etl::to_arithmetic<int16_t>(int16_overflow_min.c_str(), int16_overflow_min.size(), etl::dec));
CHECK(!etl::to_arithmetic<uint16_t>(uint16_overflow_max.c_str(), uint16_overflow_max.size(), etl::dec));
CHECK(!etl::to_arithmetic<uint16_t>(uint16_overflow_min.c_str(), uint16_overflow_min.size(), etl::dec));
CHECK(!etl::to_arithmetic<int32_t>(int32_overflow_max.c_str(), int32_overflow_max.size(), etl::dec));
CHECK(!etl::to_arithmetic<int32_t>(int32_overflow_min.c_str(), int32_overflow_min.size(), etl::dec));
CHECK(!etl::to_arithmetic<uint32_t>(uint32_overflow_max.c_str(), uint32_overflow_max.size(), etl::dec));
CHECK(!etl::to_arithmetic<uint32_t>(uint32_overflow_min.c_str(), uint32_overflow_min.size(), etl::dec));
CHECK(!etl::to_arithmetic<int64_t>(int64_overflow_max.c_str(), int64_overflow_max.size(), etl::dec));
CHECK(!etl::to_arithmetic<int64_t>(int64_overflow_min.c_str(), int64_overflow_min.size(), etl::dec));
CHECK(!etl::to_arithmetic<uint64_t>(uint64_overflow_max.c_str(), uint64_overflow_max.size(), etl::dec));
CHECK(!etl::to_arithmetic<uint64_t>(uint64_overflow_min.c_str(), uint64_overflow_min.size(), etl::dec));
}
//*************************************************************************
TEST(test_invalid_hex_numerics)
{
const std::string text1(" 1Af");
const std::string text2("1Af ");
const std::string text3("1Gf");
const std::string text4("-1Af");
//const std::string text1(" 1Af");
//const std::string text2("1Af ");
//const std::string text3("1Gf");
//const std::string text4("-1Af");
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text1.c_str(), text1.size(), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text2.c_str(), text2.size(), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<int8_t>(text3.c_str(), text3.size(), etl::dec), etl::to_arithmetic_invalid_format);
CHECK_THROW((void)etl::to_arithmetic<uint8_t>(text4.c_str(), text4.size(), etl::dec), etl::to_arithmetic_signed_to_unsigned);
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text1.c_str(), text1.size(), etl::dec));
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text2.c_str(), text2.size(), etl::dec));
//CHECK_THROW((void)etl::to_arithmetic<int8_t>(text3.c_str(), text3.size(), etl::dec));
//CHECK_THROW((void)etl::to_arithmetic<uint8_t>(text4.c_str(), text4.size(), etl::dec), etl::to_arithmetic_signed_to_unsigned);
}
//*************************************************************************
TEST(test_valid_hex_numerics)
{
const std::string text1("0");
const std::string text2("1");
const std::string text3("5");
const std::string text4("a");
const std::string text5("53");
const std::string text6("Ac");
const std::string text7("-53");
//const std::string text1("0");
//const std::string text2("1");
//const std::string text3("5");
//const std::string text4("a");
//const std::string text5("53");
//const std::string text6("Ac");
//const std::string text7("-53");
CHECK_EQUAL(int(0), int(etl::to_arithmetic<int8_t>(text1.c_str(), text1.size(), etl::hex).value()));
CHECK_EQUAL(int(1), int(etl::to_arithmetic<int8_t>(text2.c_str(), text2.size(), etl::hex).value()));
CHECK_EQUAL(int(5), int(etl::to_arithmetic<int8_t>(text3.c_str(), text3.size(), etl::hex).value()));
CHECK_EQUAL(int(10), int(etl::to_arithmetic<int8_t>(text4.c_str(), text4.size(), etl::hex).value()));
CHECK_EQUAL(int(83), int(etl::to_arithmetic<int8_t>(text5.c_str(), text5.size(), etl::hex).value()));
CHECK_EQUAL(int(-84), int(etl::to_arithmetic<int8_t>(text6.c_str(), text6.size(), etl::hex).value()));
CHECK_EQUAL(int(-83), int(etl::to_arithmetic<int8_t>(text7.c_str(), text7.size(), etl::hex).value()));
//CHECK_EQUAL(int(0), int(etl::to_arithmetic<int8_t>(text1.c_str(), text1.size(), etl::hex).value()));
//CHECK_EQUAL(int(1), int(etl::to_arithmetic<int8_t>(text2.c_str(), text2.size(), etl::hex).value()));
//CHECK_EQUAL(int(5), int(etl::to_arithmetic<int8_t>(text3.c_str(), text3.size(), etl::hex).value()));
//CHECK_EQUAL(int(10), int(etl::to_arithmetic<int8_t>(text4.c_str(), text4.size(), etl::hex).value()));
//CHECK_EQUAL(int(83), int(etl::to_arithmetic<int8_t>(text5.c_str(), text5.size(), etl::hex).value()));
//CHECK_EQUAL(int(-84), int(etl::to_arithmetic<int8_t>(text6.c_str(), text6.size(), etl::hex).value()));
//CHECK_EQUAL(int(-83), int(etl::to_arithmetic<int8_t>(text7.c_str(), text7.size(), etl::hex).value()));
}
//*************************************************************************
TEST(test_big_hex_numerics)
{
const std::string text1("8000000000000000");
const std::string text2("7FFFFFFFFFFFFFFF");
const std::string text3("FFFFFFFFFFFFFFFF");
//const std::string text1("8000000000000000");
//const std::string text2("7FFFFFFFFFFFFFFF");
//const std::string text3("FFFFFFFFFFFFFFFF");
CHECK_EQUAL(uint64_t(0x8000000000000000ULL), etl::to_arithmetic<uint64_t>(text1.c_str(), text1.size(), etl::hex).value());
CHECK_EQUAL(uint64_t(0x7FFFFFFFFFFFFFFFULL), etl::to_arithmetic<uint64_t>(text2.c_str(), text2.size(), etl::hex).value());
CHECK_EQUAL(uint64_t(0xFFFFFFFFFFFFFFFFULL), etl::to_arithmetic<uint64_t>(text3.c_str(), text3.size(), etl::hex).value());
//CHECK_EQUAL(uint64_t(0x8000000000000000ULL), etl::to_arithmetic<uint64_t>(text1.c_str(), text1.size(), etl::hex).value());
//CHECK_EQUAL(uint64_t(0x7FFFFFFFFFFFFFFFULL), etl::to_arithmetic<uint64_t>(text2.c_str(), text2.size(), etl::hex).value());
//CHECK_EQUAL(uint64_t(0xFFFFFFFFFFFFFFFFULL), etl::to_arithmetic<uint64_t>(text3.c_str(), text3.size(), etl::hex).value());
}
//*************************************************************************
//TEST(test_valid_float)
//{
TEST(test_valid_float)
{
// const std::string text1("-123.456789");
// float f1 = strtof(text1.c_str(), nullptr);
@ -275,22 +368,22 @@ namespace
// float f3 = etl::to_arithmetic<float>(text2.c_str(), text2.size()).value();
// CHECK_EQUAL(f1, f3);
//}
}
//*************************************************************************
//TEST(test_valid_double)
//{
TEST(test_valid_double)
{
// const std::string text1("-123.45678901234567");
// double f1 = strtod(text1.c_str(), nullptr);
// double f2 = etl::to_arithmetic<double>(text1.c_str(), text1.size()).value();
// CHECK_EQUAL(f1, f2);
//}
}
//*************************************************************************
//TEST(test_constexpr_integral)
//{
TEST(test_constexpr_integral)
{
// constexpr const char* text{ "123" };
// constexpr etl::string_view view(text, 3);
@ -298,7 +391,7 @@ namespace
// constexpr int i = opt.value();
// CHECK_EQUAL(123, i);
//}
}
//*************************************************************************
TEST(test_constexpr_floating_point)