mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Work-In-Progress
Function parameter radix implementation
This commit is contained in:
parent
8f90d117c1
commit
7e33c6a96b
@ -1,6 +1,7 @@
|
||||
|
||||
#include "platform.h"
|
||||
#include "type_traits.h"
|
||||
#include "integral_limits.h"
|
||||
#include "string_view.h"
|
||||
#include "basic_string.h"
|
||||
#include "format_spec.h"
|
||||
@ -8,7 +9,6 @@
|
||||
#include "optional.h"
|
||||
#include "string_utilities.h"
|
||||
#include "iterator.h"
|
||||
#include "largest.h"
|
||||
#include "exception.h"
|
||||
#include "error_handler.h"
|
||||
|
||||
@ -56,11 +56,11 @@ namespace etl
|
||||
//***************************************************************************
|
||||
///
|
||||
//***************************************************************************
|
||||
class to_arithmetic_radix_not_supported : public to_arithmetic_exception
|
||||
class to_arithmetic_invalid_radix : public to_arithmetic_exception
|
||||
{
|
||||
public:
|
||||
|
||||
to_arithmetic_radix_not_supported(string_type file_name_, numeric_type line_number_)
|
||||
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_)
|
||||
{
|
||||
}
|
||||
@ -68,6 +68,9 @@ namespace etl
|
||||
|
||||
namespace private_to_arithmetic
|
||||
{
|
||||
//***********************************************************************
|
||||
///
|
||||
//***********************************************************************
|
||||
template <typename TChar>
|
||||
struct character_set;
|
||||
|
||||
@ -79,6 +82,8 @@ namespace etl
|
||||
static ETL_CONSTANT string_type numeric_chars = "0123456789abcdefABCDEF";
|
||||
static ETL_CONSTANT value_type positive_char = '+';
|
||||
static ETL_CONSTANT value_type negative_char = '-';
|
||||
static ETL_CONSTANT string_type radix_point = ".,";
|
||||
static ETL_CONSTANT string_type exponential = "eE";
|
||||
};
|
||||
|
||||
template <>
|
||||
@ -89,6 +94,8 @@ namespace etl
|
||||
static ETL_CONSTANT string_type numeric_chars = L"0123456789abcdefABCDEF";
|
||||
static ETL_CONSTANT value_type positive_char = L'+';
|
||||
static ETL_CONSTANT value_type negative_char = L'-';
|
||||
static ETL_CONSTANT string_type radix_point = L".,";
|
||||
static ETL_CONSTANT string_type exponential = L"eE";
|
||||
};
|
||||
|
||||
template <>
|
||||
@ -99,6 +106,8 @@ namespace etl
|
||||
static ETL_CONSTANT string_type numeric_chars = u"0123456789abcdefABCDEF";
|
||||
static ETL_CONSTANT value_type positive_char = u'+';
|
||||
static ETL_CONSTANT value_type negative_char = u'-';
|
||||
static ETL_CONSTANT string_type radix_point = u".,";
|
||||
static ETL_CONSTANT string_type exponential = u"eE";
|
||||
};
|
||||
|
||||
template <>
|
||||
@ -109,6 +118,8 @@ namespace etl
|
||||
static ETL_CONSTANT string_type numeric_chars = U"0123456789abcdefABCDEF";
|
||||
static ETL_CONSTANT value_type positive_char = U'+';
|
||||
static ETL_CONSTANT value_type negative_char = U'-';
|
||||
static ETL_CONSTANT string_type radix_point = U".,";
|
||||
static ETL_CONSTANT string_type exponential = U"eE";
|
||||
};
|
||||
|
||||
static ETL_CONSTANT char binary_length = 2;
|
||||
@ -116,8 +127,12 @@ namespace etl
|
||||
static ETL_CONSTANT char decimal_length = 10;
|
||||
static ETL_CONSTANT char hex_length = 16 + 6;
|
||||
|
||||
//*******************************
|
||||
//***************************************************************************
|
||||
///
|
||||
//***************************************************************************
|
||||
template <typename TChar>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
char get_digit_value(TChar c)
|
||||
{
|
||||
size_t length = etl::strlen(character_set<TChar>::numeric_chars);
|
||||
@ -137,112 +152,236 @@ namespace etl
|
||||
///
|
||||
//***************************************************************************
|
||||
template <typename TChar>
|
||||
ETL_CONSTEXPR14 bool is_valid_numeric_character(const TChar c,
|
||||
const etl::basic_string_view<TChar>& valid_characters)
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
etl::basic_string_view<TChar> get_character_set(const etl::radix::value_type radix)
|
||||
{
|
||||
using namespace etl::private_to_arithmetic;
|
||||
switch (radix)
|
||||
{
|
||||
case etl::radix::binary: { return etl::basic_string_view<TChar>(character_set<TChar>::numeric_chars, binary_length); break; }
|
||||
case etl::radix::octal: { return etl::basic_string_view<TChar>(character_set<TChar>::numeric_chars, octal_length); break; }
|
||||
case etl::radix::decimal: { return etl::basic_string_view<TChar>(character_set<TChar>::numeric_chars, decimal_length); break; }
|
||||
case etl::radix::hex: { return etl::basic_string_view<TChar>(character_set<TChar>::numeric_chars, hex_length); break; }
|
||||
default: { ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_invalid_radix)); return etl::basic_string_view<TChar>(); break; }
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
///
|
||||
//***************************************************************************
|
||||
template <typename TChar>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
bool is_valid_numeric_character(const TChar c,
|
||||
const etl::basic_string_view<TChar>& valid_characters)
|
||||
{
|
||||
etl::basic_string_view<TChar> itr = etl::find(valid_characters.begin(), valid_characters.end(), c);
|
||||
|
||||
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)
|
||||
///
|
||||
//***************************************************************************
|
||||
template <typename TChar>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
bool is_valid_decimal_character(const TChar c)
|
||||
{
|
||||
switch (radix)
|
||||
{
|
||||
case etl::radix::decimal:
|
||||
{
|
||||
value *= radix;
|
||||
is_negative ? value -= digit : value += digit;
|
||||
break;
|
||||
}
|
||||
return (c >= character_set<TChar>::numeric_chars[0]) && (c <= character_set<TChar>::numeric_chars[9]);
|
||||
}
|
||||
|
||||
default: // Binary, octal or hex.
|
||||
//***************************************************************************
|
||||
///
|
||||
//***************************************************************************
|
||||
template <typename TChar>
|
||||
struct view_information
|
||||
{
|
||||
ETL_CONSTEXPR14
|
||||
view_information()
|
||||
: valid_characters()
|
||||
{
|
||||
}
|
||||
|
||||
etl::basic_string_view<TChar> valid_characters;
|
||||
};
|
||||
|
||||
//*********************************
|
||||
struct numeric_information
|
||||
{
|
||||
ETL_CONSTEXPR14
|
||||
numeric_information()
|
||||
: digit(0)
|
||||
, is_negative(false)
|
||||
, radix(0)
|
||||
, radix_point_position(etl::npos)
|
||||
, exponential_position(etl::npos)
|
||||
{
|
||||
}
|
||||
|
||||
char digit;
|
||||
bool is_negative;
|
||||
etl::radix::value_type radix;
|
||||
size_t radix_point_position;
|
||||
size_t exponential_position;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///
|
||||
//***************************************************************************
|
||||
template <typename TChar>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
bool validate_information_from_view(etl::basic_string_view<TChar>& view, etl::radix::value_type radix, view_information<TChar>& view_info, numeric_information& numeric_info)
|
||||
{
|
||||
numeric_info.radix = radix;
|
||||
view_info.valid_characters = get_character_set<TChar>(numeric_info.radix);
|
||||
|
||||
bool is_valid = !view_info.valid_characters.empty();
|
||||
|
||||
if (is_valid)
|
||||
{
|
||||
// Look for a prefix.
|
||||
const bool has_positive_prefix = (view[0] == character_set<TChar>::positive_char);
|
||||
numeric_info.is_negative = (view[0] == character_set<TChar>::negative_char);
|
||||
|
||||
if (has_positive_prefix || numeric_info.is_negative)
|
||||
{
|
||||
value <<= shift;
|
||||
value = value | digit;
|
||||
break;
|
||||
view.remove_prefix(1U);
|
||||
is_valid = (view.begin() != view.end());
|
||||
}
|
||||
}
|
||||
|
||||
if (is_valid)
|
||||
{
|
||||
// Look for a radix point.
|
||||
numeric_info.radix_point_position = view.find_first_of(character_set<TChar>::radix_point);
|
||||
|
||||
// Look for an exponential.
|
||||
numeric_info.exponential_position = view.find_first_of(character_set<TChar>::exponential);
|
||||
}
|
||||
|
||||
ETL_ASSERT(is_valid, ETL_ERROR(etl::to_arithmetic_invalid_format));
|
||||
|
||||
return is_valid;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
///
|
||||
//***************************************************************************
|
||||
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, const numeric_information& info)
|
||||
{
|
||||
value *= info.radix;
|
||||
value += info.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, const numeric_information& info)
|
||||
{
|
||||
value *= info.radix;
|
||||
info.is_negative ? value -= info.digit : value += info.digit;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
///
|
||||
//***************************************************************************
|
||||
template <typename TValue>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
typename etl::enable_if<etl::is_floating_point<TValue>::value, TValue>::type
|
||||
accumulate_integral_part(TValue value, const numeric_information& info)
|
||||
{
|
||||
value *= info.radix;
|
||||
info.is_negative ? value -= info.digit : value += info.digit;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
///
|
||||
//***************************************************************************
|
||||
template <typename TValue>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
typename etl::enable_if<etl::is_floating_point<TValue>::value, TValue>::type
|
||||
accumulate_fractional_part(TValue value, const numeric_information& info)
|
||||
{
|
||||
value /= info.radix;
|
||||
TValue d = TValue(info.digit) / info.radix;
|
||||
info.is_negative ? value -= d : value += d;
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
///
|
||||
/// Text to integral from view and radix value type.
|
||||
//***************************************************************************
|
||||
template <typename T, typename TChar>
|
||||
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
|
||||
template <typename TValue, typename TChar>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
typename etl::enable_if<etl::is_integral<TValue>::value, etl::optional<TValue> >::type
|
||||
to_arithmetic(etl::basic_string_view<TChar> view, const etl::radix::value_type radix)
|
||||
{
|
||||
using namespace etl::private_to_arithmetic;
|
||||
|
||||
etl::optional<T> result;
|
||||
|
||||
bool finished_parsing = false;
|
||||
|
||||
etl::optional<TValue> result;
|
||||
etl::basic_string_view<TChar> valid_characters;
|
||||
view_information<TChar> view_info;
|
||||
numeric_information numeric_info;
|
||||
|
||||
switch (radix)
|
||||
bool parsing = validate_information_from_view<TChar>(view, radix, view_info, numeric_info);
|
||||
|
||||
if (parsing)
|
||||
{
|
||||
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; }
|
||||
}
|
||||
|
||||
if (!finished_parsing)
|
||||
{
|
||||
T value = 0;
|
||||
|
||||
// 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)
|
||||
if (etl::is_unsigned<TValue>::value && numeric_info.is_negative)
|
||||
{
|
||||
++itr;
|
||||
parsing = false;
|
||||
ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_signed_to_unsigned));
|
||||
}
|
||||
|
||||
// Negative prefix is only allowed with decimals.
|
||||
if (has_negative_prefix && (radix != etl::radix::decimal))
|
||||
if (parsing)
|
||||
{
|
||||
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))
|
||||
// Parse the numeric part.
|
||||
TValue value = 0;
|
||||
|
||||
etl::basic_string_view<TChar>::const_iterator itr = view.begin();
|
||||
|
||||
while (parsing)
|
||||
{
|
||||
value = accumulate_value(value, get_digit_value(*itr), has_negative_prefix, shift, radix);
|
||||
|
||||
++itr;
|
||||
|
||||
if (itr == view.end())
|
||||
if (is_valid_numeric_character(*itr, view_info.valid_characters))
|
||||
{
|
||||
result = value;
|
||||
finished_parsing = true;
|
||||
numeric_info.digit = get_digit_value(*itr);
|
||||
value = accumulate_value(value, numeric_info);
|
||||
|
||||
++itr;
|
||||
|
||||
if (itr == view.end())
|
||||
{
|
||||
result = value;
|
||||
parsing = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Character was not a valid numeric, so fail.
|
||||
ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_invalid_format));
|
||||
parsing = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Character was not a valid numeric, so fail.
|
||||
ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_invalid_format));
|
||||
finished_parsing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -251,89 +390,207 @@ namespace etl
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
///
|
||||
/// Text to integral from view and default decimal radix.
|
||||
//***************************************************************************
|
||||
template <typename T, typename TChar>
|
||||
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
|
||||
template <typename TValue, typename TChar>
|
||||
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)
|
||||
{
|
||||
return etl::to_arithmetic<T, TChar>(view, etl::radix::decimal);
|
||||
return etl::to_arithmetic<TValue, TChar>(view, etl::radix::decimal);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
///
|
||||
/// Text to integral from view and radix format spec.
|
||||
//***************************************************************************
|
||||
template <typename T, typename TChar>
|
||||
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
|
||||
template <typename TValue, typename TChar>
|
||||
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::basic_format_spec<etl::ibasic_string<TChar> >& spec)
|
||||
{
|
||||
return etl::to_arithmetic<T, TChar>(view, spec.get_base());
|
||||
return etl::to_arithmetic<TValue, TChar>(view, spec.get_base());
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
///
|
||||
/// Text to integral from pointer, length and radix value type.
|
||||
//***************************************************************************
|
||||
template <typename T, typename TChar>
|
||||
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
|
||||
template <typename TValue, typename TChar>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
typename etl::enable_if<etl::is_integral<TValue>::value, etl::optional<TValue> >::type
|
||||
to_arithmetic(const TChar* cp, size_t length, const etl::radix::value_type radix)
|
||||
{
|
||||
return etl::to_arithmetic<T, TChar>(etl::basic_string_view<TChar>(cp, length), radix);
|
||||
return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(cp, length), radix);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
///
|
||||
/// Text to integral from pointer, length and default decimal radix.
|
||||
//***************************************************************************
|
||||
template <typename T, typename TChar>
|
||||
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
|
||||
template <typename TValue, typename TChar>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<TValue>::value, etl::optional<TValue> >::type
|
||||
to_arithmetic(const TChar* cp, size_t length)
|
||||
{
|
||||
return etl::to_arithmetic<T, TChar>(etl::basic_string_view<TChar>(cp, length), etl::radix::decimal);;
|
||||
return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(cp, length), etl::radix::decimal);;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
///
|
||||
/// Text to integral from pointer, length and radix format spec.
|
||||
//***************************************************************************
|
||||
template <typename T, typename TChar>
|
||||
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
|
||||
template <typename TValue, typename TChar>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<TValue>::value, etl::optional<TValue> >::type
|
||||
to_arithmetic(const TChar* cp, size_t length, const typename etl::private_basic_format_spec::base_spec& spec)
|
||||
{
|
||||
return etl::to_arithmetic<T, TChar>(etl::basic_string_view<TChar>(cp, length), spec.base);;
|
||||
return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(cp, length), spec.base);;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
///
|
||||
/// Text to integral from string and radix value type.
|
||||
//***************************************************************************
|
||||
template <typename T, typename TChar>
|
||||
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
|
||||
template <typename TValue, typename TChar>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<TValue>::value, etl::optional<TValue> >::type
|
||||
to_arithmetic(const etl::ibasic_string<TChar>& str, const etl::radix::value_type radix)
|
||||
{
|
||||
return etl::to_arithmetic<T, TChar>(etl::basic_string_view<TChar>(str), radix);;
|
||||
return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(str), radix);;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
///
|
||||
/// Text to integral from string and default decimal radix.
|
||||
//***************************************************************************
|
||||
template <typename T, typename TChar>
|
||||
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
|
||||
template <typename TValue, typename TChar>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<TValue>::value, etl::optional<TValue> >::type
|
||||
to_arithmetic(const etl::ibasic_string<TChar>& str)
|
||||
{
|
||||
return etl::to_arithmetic<T, TChar>(etl::basic_string_view<TChar>(str), radix);;
|
||||
return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(str), etl::radix::decimal);;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
///
|
||||
/// Text to integral from string and radix format spec.
|
||||
//***************************************************************************
|
||||
template <typename T, typename TChar>
|
||||
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<T>::value, etl::optional<T> >::type
|
||||
template <typename TValue, typename TChar>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<TValue>::value, etl::optional<TValue> >::type
|
||||
to_arithmetic(const etl::ibasic_string<TChar>& str, const etl::basic_format_spec<etl::ibasic_string<TChar> >& spec)
|
||||
{
|
||||
return etl::to_arithmetic<T, TChar>(etl::basic_string_view<TChar>(str), spec);;
|
||||
return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(str), spec);;
|
||||
}
|
||||
|
||||
//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);
|
||||
//}
|
||||
//***************************************************************************
|
||||
/// Floating point from view.
|
||||
//***************************************************************************
|
||||
template <typename TValue, typename TChar>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_floating_point<TValue>::value, etl::optional<TValue> >::type
|
||||
to_arithmetic(etl::basic_string_view<TChar> view)
|
||||
{
|
||||
using namespace etl::private_to_arithmetic;
|
||||
|
||||
etl::optional<TValue> result;
|
||||
etl::basic_string_view<TChar> valid_characters;
|
||||
view_information<TChar> view_info;
|
||||
numeric_information numeric_info;
|
||||
|
||||
bool parsing = validate_information_from_view<TChar>(view, etl::radix::decimal, view_info, numeric_info);
|
||||
|
||||
if (parsing)
|
||||
{
|
||||
// Integral part.
|
||||
etl::basic_string_view<TChar>::const_iterator itr_integral_begin = view.begin();
|
||||
etl::basic_string_view<TChar>::const_iterator itr_integral_end = (numeric_info.radix_point_position == etl::npos)
|
||||
? view.end()
|
||||
: itr_integral_begin + numeric_info.radix_point_position;
|
||||
|
||||
TValue intergal_value = 0;
|
||||
|
||||
while (itr_integral_begin != itr_integral_end)
|
||||
{
|
||||
if (is_valid_decimal_character(*itr_integral_begin))
|
||||
{
|
||||
numeric_info.digit = get_digit_value(*itr_integral_begin);
|
||||
intergal_value = accumulate_integral_part(intergal_value, numeric_info);
|
||||
++itr_integral_begin;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Character was not a valid numeric, so fail.
|
||||
ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_invalid_format));
|
||||
parsing = false;
|
||||
itr_integral_begin = itr_integral_end;
|
||||
}
|
||||
}
|
||||
|
||||
// Fractional part.
|
||||
etl::basic_string_view<TChar>::const_reverse_iterator itr_fractional_end = ETL_OR_STD::reverse_iterator(itr_integral_begin + 1);
|
||||
etl::basic_string_view<TChar>::const_reverse_iterator itr_fractional_begin = (numeric_info.radix_point_position == etl::npos)
|
||||
? itr_fractional_end
|
||||
: (numeric_info.exponential_position == etl::npos)
|
||||
? view.rbegin()
|
||||
: ETL_OR_STD::reverse_iterator(view.begin() + numeric_info.exponential_position);
|
||||
|
||||
TValue fractional_value = 0;
|
||||
|
||||
while (itr_fractional_begin != itr_fractional_end)
|
||||
{
|
||||
if (is_valid_decimal_character(*itr_fractional_begin))
|
||||
{
|
||||
numeric_info.digit = get_digit_value(*itr_fractional_begin);
|
||||
fractional_value = accumulate_fractional_part(fractional_value, numeric_info);
|
||||
++itr_fractional_begin;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Character was not a valid numeric, so fail.
|
||||
ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_invalid_format));
|
||||
parsing = false;
|
||||
itr_fractional_begin = itr_fractional_end;
|
||||
}
|
||||
}
|
||||
|
||||
// Exponetial part.
|
||||
etl::basic_string_view<TChar>::const_iterator itr_exponential_end = view.end();
|
||||
etl::basic_string_view<TChar>::const_iterator itr_exponential_begin = (numeric_info.exponential_position == etl::npos)
|
||||
? view.end()
|
||||
: view.begin() + numeric_info.exponential_position + 1;
|
||||
|
||||
//optional<int> exponential_value = to_arithmetic<int, TChar>(etl::basic_string_view<TChar>(itr_exponential_begin, itr_exponential_end));
|
||||
|
||||
// Combine the integral and fractional parts.
|
||||
TValue value = 0;
|
||||
|
||||
if (parsing)
|
||||
{
|
||||
value = intergal_value + fractional_value;
|
||||
result = value;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Floating point from pointer and length.
|
||||
//***************************************************************************
|
||||
template <typename TValue, typename TChar>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_floating_point<TValue>::value, etl::optional<TValue> >::type
|
||||
to_arithmetic(const TChar* cp, size_t length)
|
||||
{
|
||||
return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(cp, length));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Floating point from string.
|
||||
//***************************************************************************
|
||||
template <typename TValue, typename TChar>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_floating_point<TValue>::value, etl::optional<TValue> >::type
|
||||
to_arithmetic(const etl::ibasic_string<TChar>& str)
|
||||
{
|
||||
return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(str));
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,35 +48,37 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST(test_invalid_radixes)
|
||||
{
|
||||
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 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 char* decimal1 = " 101";
|
||||
const char* decimal2 = "101 ";
|
||||
const char* decimal3 = "121";
|
||||
const char* decimal4 = "-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(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_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);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -88,13 +90,15 @@ namespace
|
||||
const std::string value4("1010");
|
||||
const std::string value5("01010011");
|
||||
const std::string value6("10101100");
|
||||
const std::string value7("-01010011");
|
||||
|
||||
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(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()));
|
||||
CHECK_EQUAL(int(-83), int(etl::to_arithmetic<int8_t>(value7.c_str(), value7.size(), etl::bin).value()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -112,15 +116,15 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST(test_invalid_octal_numerics)
|
||||
{
|
||||
const char* decimal1 = " 127";
|
||||
const char* decimal2 = "127 ";
|
||||
const char* decimal3 = "187";
|
||||
const char* decimal4 = "-127";
|
||||
const std::string text1(" 127");
|
||||
const std::string text2("127 ");
|
||||
const std::string text3("187");
|
||||
const std::string text4("-187");
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -132,13 +136,15 @@ namespace
|
||||
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(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()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -156,96 +162,154 @@ namespace
|
||||
//*************************************************************************
|
||||
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";
|
||||
const std::string text1(" 128");
|
||||
const std::string text2("128 ");
|
||||
const std::string text3("1A8");
|
||||
const std::string text4("++128");
|
||||
const std::string text5("-+128");
|
||||
const std::string text6("+-128");
|
||||
const std::string text7("--128");
|
||||
const std::string text8("+");
|
||||
const std::string text9("-");
|
||||
const std::string text10("");
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
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");
|
||||
const std::string text1("0");
|
||||
const std::string text2("1");
|
||||
const std::string text3("5");
|
||||
const std::string text4("+10");
|
||||
const std::string text5("83");
|
||||
const std::string text6("-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()));
|
||||
CHECK_EQUAL(int(0), int(etl::to_arithmetic<int8_t>(text1.c_str(), text1.size(), etl::dec).value()));
|
||||
CHECK_EQUAL(int(1), int(etl::to_arithmetic<int8_t>(text2.c_str(), text2.size(), etl::dec).value()));
|
||||
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(-84), int(etl::to_arithmetic<int8_t>(text6.c_str(), text6.size(), etl::dec).value()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_big_decimal_numerics)
|
||||
{
|
||||
const std::string value1("-9223372036854775808");
|
||||
const std::string value2("9223372036854775807");
|
||||
const std::string value3("-1");
|
||||
const std::string text1("-9223372036854775808");
|
||||
const std::string text2("9223372036854775807");
|
||||
const std::string text3("-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());
|
||||
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());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_invalid_hex_numerics)
|
||||
{
|
||||
const char* decimal1 = " 1Af";
|
||||
const char* decimal2 = "1Af ";
|
||||
const char* decimal3 = "1Gf";
|
||||
const char* decimal4 = "-1Af";
|
||||
const std::string text1(" 1Af");
|
||||
const std::string text2("1Af ");
|
||||
const std::string text3("1Gf");
|
||||
const std::string text4("-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);
|
||||
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);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
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");
|
||||
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>(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()));
|
||||
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 value1("8000000000000000");
|
||||
const std::string value2("7FFFFFFFFFFFFFFF");
|
||||
const std::string value3("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>(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());
|
||||
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)
|
||||
{
|
||||
const std::string text1("-123.456789");
|
||||
|
||||
float f1 = strtof(text1.c_str(), nullptr);
|
||||
float f2 = etl::to_arithmetic<float>(text1.c_str(), text1.size()).value();
|
||||
|
||||
CHECK_EQUAL(f1, f2);
|
||||
|
||||
const std::string text2("-1.23456789e2");
|
||||
float f3 = etl::to_arithmetic<float>(text2.c_str(), text2.size()).value();
|
||||
|
||||
CHECK_EQUAL(f1, f3);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
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)
|
||||
{
|
||||
constexpr const char* text{ "123" };
|
||||
constexpr etl::string_view view(text, 3);
|
||||
|
||||
constexpr etl::optional<int> opt = etl::to_arithmetic<int>(view, etl::radix::decimal);
|
||||
constexpr int i = opt.value();
|
||||
|
||||
CHECK_EQUAL(123, i);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_constexpr_floating_point)
|
||||
{
|
||||
//constexpr const char* text{ "123.456789" };
|
||||
//constexpr etl::string_view view(text, 3);
|
||||
|
||||
//constexpr etl::optional<double> opt = etl::to_arithmetic<double>(view);
|
||||
//constexpr double i = opt.value();
|
||||
|
||||
//CHECK_EQUAL(123, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user