Work-In-Progress

This commit is contained in:
John Wellbelove 2022-10-03 11:54:26 +01:00
parent 1e53bbbbb8
commit dd89aa10fd
2 changed files with 161 additions and 142 deletions

View File

@ -191,88 +191,85 @@ namespace etl
struct character_set;
//*******************************************
template <>
struct character_set<char>
static char convert(char c)
{
ETL_NODISCARD
ETL_CONSTEXPR14
static char lookup(char c)
{
return to_lower(c);
}
};
return to_lower(c);
}
//*******************************************
template <>
struct character_set<wchar_t>
ETL_NODISCARD
ETL_CONSTEXPR14
static char convert(wchar_t c)
{
typedef wchar_t value_type;
typedef const value_type* string_type;
static ETL_CONSTANT string_type valid_chars = L"+-.,eE0123456789abcdefABCDEF";
ETL_NODISCARD
ETL_CONSTEXPR14
static char lookup(wchar_t c)
#if ETL_USING_CPP14
constexpr string_type valid_chars = L"+-.,eE0123456789abcdefABCDEF";
#else
static const string_type valid_chars = L"+-.,eE0123456789abcdefABCDEF";
#endif
for (int i = 0; i < valid_length; ++i)
{
for (int i = 0; i < valid_length; ++i)
if (c == valid_chars[i])
{
if (c == valid_chars[i])
{
return to_lower(valid_character_set::valid_chars[i]);
}
return to_lower(valid_character_set::valid_chars[i]);
}
return valid_character_set::unknown_char;
}
};
return valid_character_set::unknown_char;
}
//*******************************************
template <>
struct character_set<char16_t>
ETL_NODISCARD
ETL_CONSTEXPR14
static char convert(char16_t c)
{
typedef char16_t value_type;
typedef const value_type* string_type;
static ETL_CONSTANT string_type valid_chars = u"+-.,eE0123456789abcdefABCDEF";
ETL_NODISCARD
ETL_CONSTEXPR14
static char lookup(char16_t c)
#if ETL_USING_CPP14
constexpr string_type valid_chars = u"+-.,eE0123456789abcdefABCDEF";
#else
static const string_type valid_chars = u"+-.,eE0123456789abcdefABCDEF";
#endif
for (int i = 0; i < valid_length; ++i)
{
for (int i = 0; i < valid_length; ++i)
if (c == valid_chars[i])
{
if (c == valid_chars[i])
{
return to_lower(valid_character_set::valid_chars[i]);
}
return to_lower(valid_character_set::valid_chars[i]);
}
return valid_character_set::unknown_char;
}
};
return valid_character_set::unknown_char;
}
//*******************************************
template <>
struct character_set<char32_t>
ETL_NODISCARD
ETL_CONSTEXPR14
static char convert(char32_t c)
{
typedef char32_t value_type;
typedef const value_type* string_type;
static ETL_CONSTANT string_type valid_chars = U"+-.,eE0123456789abcdefABCDEF";
#if ETL_USING_CPP14
constexpr string_type valid_chars = U"+-.,eE0123456789abcdefABCDEF";
#else
static const string_type valid_chars = U"+-.,eE0123456789abcdefABCDEF";
#endif
ETL_NODISCARD
ETL_CONSTEXPR14
static char lookup(wchar_t c)
for (int i = 0; i < valid_length; ++i)
{
for (int i = 0; i < valid_length; ++i)
if (c == valid_chars[i])
{
if (c == valid_chars[i])
{
return to_lower(valid_character_set::valid_chars[i]);
}
return to_lower(valid_character_set::valid_chars[i]);
}
return valid_character_set::unknown_char;
}
};
return valid_character_set::unknown_char;
}
//***************************************************************************
///
@ -304,12 +301,29 @@ namespace etl
return value;
}
//***************************************************************************
///
//***************************************************************************
template <typename TValue>
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)
{
value *= etl::radix::decimal;
is_negative ? value -= digit : value += digit;
return value;
}
//*******************************************
template <typename TChar>
ETL_NODISCARD
ETL_CONSTEXPR14
bool check_has_negative_prefix(etl::basic_string_view<TChar>& view)
{
// Check for prefix.
const char c = character_set<TChar>::lookup(view[0]);
const char c = character_set<TChar>::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);
@ -356,12 +370,16 @@ namespace etl
}
//*********************************
ETL_NODISCARD
ETL_CONSTEXPR14
bool has_value() const
{
return (valid_value == true);
}
//*********************************
ETL_NODISCARD
ETL_CONSTEXPR14
TValue get_value() const
{
return value;
@ -374,6 +392,61 @@ namespace etl
bool valid_value;
etl::radix::value_type radix;
};
//***************************************************************************
///
//***************************************************************************
template <typename TValue>
struct to_float_implementation
{
//*********************************
ETL_NODISCARD
ETL_CONSTEXPR14
to_float_implementation(bool is_negative_)
: value(0)
, is_negative(is_negative_)
, valid_value(false)
{
}
//*********************************
ETL_NODISCARD
ETL_CONSTEXPR14
bool add(char c)
{
bool is_valid = valid_character_set::is_valid(c, etl::radix::decimal);
if (is_valid)
{
value = accumulate_value(value, valid_character_set::digit_value(c, etl::radix::decimal), 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;
};
//***************************************************************************
/// Text to integral from view and radix value type.
@ -401,7 +474,7 @@ namespace etl
while (parsing)
{
parsing = implementation.add(character_set<TChar>::lookup(*itr));
parsing = implementation.add(character_set<TChar>::convert(*itr));
if (parsing)
{
@ -458,7 +531,7 @@ namespace etl
while (parsing)
{
parsing = implementation.add(character_set<TChar>::lookup(*itr));
parsing = implementation.add(character_set<TChar>::convert(*itr));
if (parsing)
{
@ -513,7 +586,7 @@ namespace etl
while (parsing)
{
parsing = implementation.add(character_set<TChar>::lookup(*itr));
parsing = implementation.add(character_set<TChar>::convert(*itr));
if (parsing)
{
@ -570,7 +643,7 @@ namespace etl
while (parsing)
{
parsing = implementation.add(character_set<TChar>::lookup(*itr));
parsing = implementation.add(character_set<TChar>::convert(*itr));
if (parsing)
{
@ -800,81 +873,27 @@ namespace etl
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);
bool is_negative = false;
if (parsing)
if (!view.empty())
{
// 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;
is_negative = check_has_negative_prefix(view);
}
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 (!view.empty())
{
bool parsing = true;
if (parsing)
{
value = intergal_value + fractional_value;
result = value;
// Integral part.
// Fractional part.
// Exponetial part.
}
}

View File

@ -262,20 +262,20 @@ namespace
}
//*************************************************************************
//TEST(test_valid_float)
//{
// const std::string text1("-123.456789");
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();
float f1 = strtof(text1.c_str(), nullptr);
float f2 = etl::to_arithmetic<float>(text1.c_str(), text1.size()).value();
// CHECK_EQUAL(f1, f2);
CHECK_EQUAL(f1, f2);
// const std::string text2("-1.23456789e2");
// float f3 = etl::to_arithmetic<float>(text2.c_str(), text2.size()).value();
const std::string text2("-1.23456789e2");
float f3 = etl::to_arithmetic<float>(text2.c_str(), text2.size()).value();
// CHECK_EQUAL(f1, f3);
//}
CHECK_EQUAL(f1, f3);
}
//*************************************************************************
//TEST(test_valid_double)
@ -289,16 +289,16 @@ namespace
//}
//*************************************************************************
//TEST(test_constexpr_integral)
//{
// constexpr const char* text{ "123" };
// constexpr etl::string_view view(text, 3);
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();
constexpr etl::optional<int> opt = etl::to_arithmetic<int>(view, etl::radix::decimal);
constexpr int i = opt.value();
// CHECK_EQUAL(123, i);
//}
CHECK_EQUAL(123, i);
}
//*************************************************************************
TEST(test_constexpr_floating_point)