Added u8string + utilities

Changed char types to unsigned 'least' types
This commit is contained in:
John Wellbelove 2023-11-14 00:06:57 +00:00
parent f1dd0d4490
commit b6650120f8
28 changed files with 15507 additions and 97 deletions

View File

@ -65,7 +65,6 @@ namespace etl
typedef char state_type;
};
#if ETL_USING_CPP20
template<> struct char_traits_types<char8_t>
{
typedef char8_t char_type;
@ -74,7 +73,6 @@ namespace etl
typedef size_t pos_type;
typedef char state_type;
};
#endif
template<> struct char_traits_types<char16_t>
{

View File

@ -351,25 +351,20 @@ SOFTWARE.
//*************************************
// Determine if the ETL can use char8_t type.
#if ETL_USING_8BIT_TYPES
#if ETL_NO_SMALL_CHAR_SUPPORT
typedef int8_t char8_t;
#define ETL_HAS_CHAR8_T 1
#define ETL_HAS_NATIVE_CHAR8_T 0
#else
#define ETL_HAS_CHAR8_T 1
#define ETL_HAS_NATIVE_CHAR8_T 1
#endif
#else
#define ETL_HAS_CHAR8_T 0
#if ETL_NO_SMALL_CHAR_SUPPORT
typedef uint_least8_t char8_t;
#define ETL_HAS_CHAR8_T 1
#define ETL_HAS_NATIVE_CHAR8_T 0
#else
#define ETL_HAS_CHAR8_T 1
#define ETL_HAS_NATIVE_CHAR8_T 1
#endif
//*************************************
// Define the large character types if necessary.
#if ETL_NO_LARGE_CHAR_SUPPORT
typedef int16_t char16_t;
typedef int32_t char32_t;
typedef uint_least16_t char16_t;
typedef uint_least32_t char32_t;
#define ETL_HAS_NATIVE_CHAR16_T 0
#define ETL_HAS_NATIVE_CHAR32_T 0
#else

View File

@ -77,6 +77,17 @@ namespace etl
}
};
#if ETL_USING_CPP20
template <>
struct whitespace<char8_t>
{
static ETL_CONSTEXPR const char8_t* value()
{
return u8" \t\n\r\f\v";
}
};
#endif
template <>
struct whitespace<wchar_t>
{

View File

@ -802,6 +802,7 @@ namespace etl
typedef etl::basic_string_view<char> string_view;
typedef etl::basic_string_view<wchar_t> wstring_view;
typedef etl::basic_string_view<char8_t> u8string_view;
typedef etl::basic_string_view<char16_t> u16string_view;
typedef etl::basic_string_view<char32_t> u32string_view;
@ -825,6 +826,15 @@ namespace etl
return wstring_view(text, length);
}
//***********************************
template<size_t Array_Size>
ETL_CONSTEXPR14 u8string_view make_string_view(const char8_t(&text)[Array_Size])
{
size_t length = etl::char_traits<char8_t>::length(text, Array_Size - 1U);
return u8string_view(text, length);
}
//***********************************
template<size_t Array_Size>
ETL_CONSTEXPR14 u16string_view make_string_view(const char16_t(&text)[Array_Size])

150
include/etl/to_u8string.h Normal file
View File

@ -0,0 +1,150 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2019 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_TO_U8STRING_INCLUDED
#define ETL_TO_U8STRING_INCLUDED
///\ingroup string
#include "platform.h"
#include "type_traits.h"
#include "u8string.h"
#include "u8format_spec.h"
#include "private/to_string_helper.h"
namespace etl
{
//***************************************************************************
/// Default format spec.
/// !etl::iu8string && !etl::u8string_view
//***************************************************************************
template <typename T>
typename etl::enable_if<!etl::is_same<T, etl::iu8string>::value && !etl::is_same<T, etl::u8string_view>::value, const etl::iu8string&>::type
to_string(const T value, etl::iu8string& str, bool append = false)
{
etl::u8format_spec format;
return private_to_string::to_string(value, str, format, append);
}
//***************************************************************************
/// Supplied format spec.
/// !etl::iu8string && !etl::u8string_view
//***************************************************************************
template <typename T>
typename etl::enable_if<!etl::is_same<T, etl::iu8string>::value && !etl::is_same<T, etl::u8string_view>::value, const etl::iu8string&>::type
to_string(const T value, etl::iu8string& str, const etl::u8format_spec& format, bool append = false)
{
return private_to_string::to_string(value, str, format, append);
}
//***************************************************************************
/// Default format spec.
/// !etl::iu8string && !etl::u8string_view
//***************************************************************************
template <typename T>
typename etl::enable_if<!etl::is_same<T, etl::iu8string>::value && !etl::is_same<T, etl::u8string_view>::value, const etl::iu8string&>::type
to_string(const T value, uint32_t denominator_exponent, etl::iu8string& str, bool append = false)
{
etl::u8format_spec format;
return private_to_string::to_string(value, denominator_exponent, str, format, append);
}
//***************************************************************************
/// Supplied format spec.
/// !etl::u8string_view && !etl::u8string_view
//***************************************************************************
template <typename T>
typename etl::enable_if<!etl::is_same<T, etl::iu8string>::value && !etl::is_same<T, etl::u8string_view>::value, const etl::iu8string&>::type
to_string(const T value, uint32_t denominator_exponent, etl::iu8string& str, const etl::u8format_spec& format, bool append = false)
{
return private_to_string::to_string(value, denominator_exponent, str, format, append);
}
//***************************************************************************
/// Default format spec.
/// etl::iu8string
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<T, etl::iu8string>::value, const etl::iu8string&>::type
to_string(const T& value, etl::iu8string& str, bool append = false)
{
etl::u8format_spec format;
private_to_string::add_string(value, str, format, append);
return str;
}
//***************************************************************************
/// Supplied format spec.
/// etl::iu8string
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<T, etl::iu8string>::value, const etl::iu8string&>::type
to_string(const etl::iu8string& value, T& str, const etl::u8format_spec& format, bool append = false)
{
private_to_string::add_string(value, str, format, append);
return str;
}
//***************************************************************************
/// Default format spec.
/// etl::u8string_view
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<T, etl::u8string_view>::value, const etl::iu8string&>::type
to_string(T value, etl::iu8string& str, bool append = false)
{
etl::u8format_spec format;
private_to_string::add_string_view(value, str, format, append);
return str;
}
//***************************************************************************
/// Supplied format spec.
/// etl::u8string_view
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<T, etl::u8string_view>::value, const etl::iu8string&>::type
to_string(T value, etl::iu8string& str, const etl::u8format_spec& format, bool append = false)
{
private_to_string::add_string_view(value, str, format, append);
return str;
}
}
#endif

View File

@ -0,0 +1,45 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_U8FORMAT_SPEC_INCLUDED
#define ETL_U8FORMAT_SPEC_INCLUDED
///\ingroup string
#include "platform.h"
#include "basic_format_spec.h"
#include "u8string.h"
namespace etl
{
typedef etl::basic_format_spec<etl::iu8string> u8format_spec;
}
#endif

510
include/etl/u8string.h Normal file
View File

@ -0,0 +1,510 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_U8STRING_INCLUDED
#define ETL_U8STRING_INCLUDED
#include "platform.h"
#include "basic_string.h"
#include "string_view.h"
#include "hash.h"
#include "initializer_list.h"
#include <ctype.h>
#include "private/minmax_push.h"
#if ETL_HAS_CHAR8_T
namespace etl
{
#if ETL_USING_CPP11 && ETL_HAS_NATIVE_CHAR8_T
inline namespace literals
{
inline namespace string_literals
{
constexpr etl::u8string_view operator ""_sv(const char8_t* str, size_t length) noexcept
{
return etl::u8string_view{ str, length };
}
}
}
#endif
typedef etl::ibasic_string<char8_t> iu8string;
//***************************************************************************
/// A u8string implementation that uses a fixed size buffer.
///\tparam MAX_SIZE_ The maximum number of elements that can be stored.
///\ingroup u8string
//***************************************************************************
template <size_t MAX_SIZE_>
class u8string : public iu8string
{
public:
typedef iu8string base_type;
typedef iu8string interface_type;
typedef iu8string::value_type value_type;
static ETL_CONSTANT size_t MAX_SIZE = MAX_SIZE_;
//*************************************************************************
/// Constructor.
//*************************************************************************
u8string()
: iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
this->initialise();
}
//*************************************************************************
/// Copy constructor.
///\param other The other u8string.
//*************************************************************************
u8string(const etl::u8string<MAX_SIZE_>& other)
: iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
this->assign(other);
}
//*************************************************************************
/// From other iu8string.
///\param other The other iu8string.
//*************************************************************************
u8string(const etl::iu8string& other)
: iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
this->assign(other);
}
//*************************************************************************
/// From other u8string, position, length.
///\param other The other u8string.
///\param position The position of the first character.
///\param length The number of characters. Default = npos.
//*************************************************************************
u8string(const etl::iu8string& other, size_t position, size_t length = npos)
: iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
ETL_ASSERT(position < other.size(), ETL_ERROR(string_out_of_bounds));
this->assign(other, position, length);
}
//*************************************************************************
/// Constructor, from null terminated text.
///\param text The initial text of the u8string.
//*************************************************************************
ETL_EXPLICIT_STRING_FROM_CHAR u8string(const value_type* text)
: iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
this->assign(text, text + etl::char_traits<value_type>::length(text));
}
//*************************************************************************
/// Constructor, from null terminated text and count.
///\param text The initial text of the u8string.
///\param count The number of characters to copy.
//*************************************************************************
u8string(const value_type* text, size_t count)
: iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
this->assign(text, text + count);
}
//*************************************************************************
/// Constructor, from initial size and value.
///\param initialSize The initial size of the u8string.
///\param value The value to fill the u8string with.
//*************************************************************************
u8string(size_type count, value_type c)
: iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
this->initialise();
this->resize(count, c);
}
//*************************************************************************
/// Constructor, from an iterator range.
///\tparam TIterator The iterator type.
///\param first The iterator to the first element.
///\param last The iterator to the last element + 1.
//*************************************************************************
template <typename TIterator>
u8string(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
: iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
this->assign(first, last);
}
#if ETL_HAS_INITIALIZER_LIST
//*************************************************************************
/// Construct from initializer_list.
//*************************************************************************
u8string(std::initializer_list<value_type> init)
: iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
this->assign(init.begin(), init.end());
}
#endif
//*************************************************************************
/// From string_view.
///\param view The string_view.
//*************************************************************************
explicit u8string(const etl::u8string_view& view)
: iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
this->assign(view.begin(), view.end());
}
//*************************************************************************
/// Returns a sub-u8string.
///\param position The position of the first character. Default = 0.
///\param length The number of characters. Default = npos.
//*************************************************************************
etl::u8string<MAX_SIZE_> substr(size_type position = 0, size_type length_ = npos) const
{
etl::u8string<MAX_SIZE_> new_string;
if (position != this->size())
{
ETL_ASSERT(position < this->size(), ETL_ERROR(string_out_of_bounds));
length_ = etl::min(length_, this->size() - position);
new_string.assign(buffer + position, buffer + position + length_);
}
return new_string;
}
//*************************************************************************
/// Assignment operator.
//*************************************************************************
u8string& operator = (const u8string& rhs)
{
if (&rhs != this)
{
this->assign(rhs);
}
return *this;
}
//*************************************************************************
/// Assignment operator.
//*************************************************************************
u8string& operator = (const iu8string& rhs)
{
if (&rhs != this)
{
this->assign(rhs);
}
return *this;
}
//*************************************************************************
/// Assignment operator.
//*************************************************************************
u8string& operator = (const value_type* text)
{
this->assign(text);
return *this;
}
//*************************************************************************
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
void repair()
#if ETL_HAS_ISTRING_REPAIR
ETL_OVERRIDE
#endif
{
etl::iu8string::repair_buffer(buffer);
}
private:
value_type buffer[MAX_SIZE + 1];
};
template <size_t MAX_SIZE_>
ETL_CONSTANT size_t u8string<MAX_SIZE_>::MAX_SIZE;
//***************************************************************************
/// A u8string implementation that uses a fixed size external buffer.
///\ingroup u8string
//***************************************************************************
class u8string_ext : public iu8string
{
public:
typedef iu8string base_type;
typedef iu8string interface_type;
typedef iu8string::value_type value_type;
typedef iu8string::size_type size_type;
//*************************************************************************
/// Constructor.
//*************************************************************************
u8string_ext(value_type* buffer, size_type buffer_size)
: iu8string(buffer, buffer_size - 1U)
{
this->initialise();
}
//*************************************************************************
/// Copy constructor.
///\param other The other u8string_ext.
//*************************************************************************
u8string_ext(const etl::u8string_ext& other, value_type* buffer, size_type buffer_size)
: iu8string(buffer, buffer_size - 1U)
{
this->assign(other);
}
//*************************************************************************
/// From other iu8string.
///\param other The other iu8string.
//*************************************************************************
u8string_ext(const etl::iu8string& other, value_type* buffer, size_type buffer_size)
: iu8string(buffer, buffer_size - 1U)
{
this->assign(other);
}
//*************************************************************************
/// From other u8string_ext, position, length.
///\param other The other u8string_ext.
///\param position The position of the first character.
///\param length The number of characters. Default = npos.
//*************************************************************************
u8string_ext(const etl::iu8string& other, value_type* buffer, size_type buffer_size, size_type position, size_type length = npos)
: iu8string(buffer, buffer_size - 1U)
{
ETL_ASSERT(position < other.size(), ETL_ERROR(string_out_of_bounds));
this->assign(other, position, length);
}
//*************************************************************************
/// Constructor, from null terminated text.
///\param text The initial text of the u8string_ext.
//*************************************************************************
u8string_ext(const char8_t* text, char8_t* buffer, size_type buffer_size)
: iu8string(buffer, buffer_size - 1U)
{
// Is the initial text at the same address as the buffer?
if (text == buffer)
{
this->current_size = etl::strlen(buffer);
}
else
{
this->assign(text, text + etl::strlen(text));
}
}
//*************************************************************************
/// Constructor, from null terminated text and count.
///\param text The initial text of the u8string_ext.
///\param count The number of characters to copy.
//*************************************************************************
u8string_ext(const value_type* text, size_type count, value_type* buffer, size_type buffer_size)
: iu8string(buffer, buffer_size - 1U)
{
this->assign(text, text + count);
}
//*************************************************************************
/// Constructor, from initial size and value.
///\param initialSize The initial size of the u8string_ext.
///\param value The value to fill the u8string_ext with.
//*************************************************************************
u8string_ext(size_type count, value_type c, value_type* buffer, size_type buffer_size)
: iu8string(buffer, buffer_size - 1U)
{
this->initialise();
this->resize(count, c);
}
//*************************************************************************
/// Constructor, from an iterator range.
///\tparam TIterator The iterator type.
///\param first The iterator to the first element.
///\param last The iterator to the last element + 1.
//*************************************************************************
template <typename TIterator>
u8string_ext(TIterator first, TIterator last, value_type* buffer, size_type buffer_size, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
: iu8string(buffer, buffer_size - 1U)
{
this->assign(first, last);
}
#if ETL_HAS_INITIALIZER_LIST
//*************************************************************************
/// Construct from initializer_list.
//*************************************************************************
u8string_ext(std::initializer_list<value_type> init, value_type* buffer, size_type buffer_size)
: iu8string(buffer, buffer_size - 1U)
{
this->assign(init.begin(), init.end());
}
#endif
//*************************************************************************
/// From string_view.
///\param view The string_view.
//*************************************************************************
explicit u8string_ext(const etl::u8string_view& view, value_type* buffer, size_type buffer_size)
: iu8string(buffer, buffer_size - 1U)
{
this->assign(view.begin(), view.end());
}
//*************************************************************************
/// Assignment operator.
//*************************************************************************
u8string_ext& operator = (const u8string_ext& rhs)
{
if (&rhs != this)
{
this->assign(rhs);
}
return *this;
}
//*************************************************************************
/// Assignment operator.
//*************************************************************************
u8string_ext& operator = (const iu8string& rhs)
{
if (&rhs != this)
{
this->assign(rhs);
}
return *this;
}
//*************************************************************************
/// Assignment operator.
//*************************************************************************
u8string_ext& operator = (const value_type* text)
{
this->assign(text);
return *this;
}
//*************************************************************************
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
void repair()
#if ETL_HAS_ISTRING_REPAIR
ETL_OVERRIDE
#endif
{
}
private:
//*************************************************************************
/// Deleted.
//*************************************************************************
u8string_ext(const u8string_ext& other) ETL_DELETE;
};
//*************************************************************************
/// Hash function.
//*************************************************************************
#if ETL_USING_8BIT_TYPES
template <>
struct hash<etl::iu8string>
{
size_t operator()(const etl::iu8string& text) const
{
return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(text.data()),
reinterpret_cast<const uint8_t*>(text.data() + text.size()));
}
};
template <size_t SIZE>
struct hash<etl::u8string<SIZE> >
{
size_t operator()(const etl::u8string<SIZE>& text) const
{
return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(text.data()),
reinterpret_cast<const uint8_t*>(text.data() + text.size()));
}
};
template <>
struct hash<etl::u8string_ext>
{
size_t operator()(const etl::u8string_ext& text) const
{
return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(text.data()),
reinterpret_cast<const uint8_t*>(text.data() + text.size()));
}
};
#endif
//***************************************************************************
/// Make u8string from u8string literal or array
//***************************************************************************
template<size_t Array_Size>
etl::u8string<Array_Size - 1U> make_string(const char(&text)[Array_Size])
{
return etl::u8string<Array_Size - 1U>(text, etl::strlen(text, Array_Size - 1));
}
//***************************************************************************
/// Make u8string with max capacity from u8string literal or array
//***************************************************************************
template<size_t MAX_SIZE, size_t SIZE>
etl::u8string<MAX_SIZE> make_string_with_capacity(const char(&text)[SIZE])
{
return etl::u8string<MAX_SIZE>(text, etl::strlen(text, SIZE));
}
}
#endif
#include "private/minmax_pop.h"
#endif

View File

@ -0,0 +1,48 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_U8STRING_STREAM_INCLUDED
#define ETL_U8STRING_STREAM_INCLUDED
///\ingroup string
#include "platform.h"
#include "u8string.h"
#include "u8format_spec.h"
#include "to_u8string.h"
#include "string_view.h"
#include "basic_string_stream.h"
namespace etl
{
typedef etl::basic_string_stream<etl::u8format_spec, etl::iu8string, etl::u8string_view> u8string_stream;
}
#endif

View File

@ -225,18 +225,23 @@ add_executable(etl_tests
test_string_char.cpp
test_string_char_external_buffer.cpp
test_string_stream.cpp
test_string_stream_u8.cpp
test_string_stream_u16.cpp
test_string_stream_u32.cpp
test_string_stream_wchar_t.cpp
test_string_u8.cpp
test_string_u8_external_buffer.cpp
test_string_u16.cpp
test_string_u16_external_buffer.cpp
test_string_u32.cpp
test_string_u32_external_buffer.cpp
test_string_utilities.cpp
test_string_utilities_std.cpp
test_string_utilities_std_u8.cpp
test_string_utilities_std_u16.cpp
test_string_utilities_std_u32.cpp
test_string_utilities_std_wchar_t.cpp
test_string_utilities_u8.cpp
test_string_utilities_u16.cpp
test_string_utilities_u32.cpp
test_string_utilities_wchar_t.cpp
@ -247,10 +252,12 @@ add_executable(etl_tests
test_task_scheduler.cpp
test_threshold.cpp
test_to_arithmetic.cpp
test_to_arithmetic_u8.cpp
test_to_arithmetic_u16.cpp
test_to_arithmetic_u32.cpp
test_to_arithmetic_wchar_t.cpp
test_to_string.cpp
test_to_u8string.cpp
test_to_u16string.cpp
test_to_u32string.cpp
test_to_wstring.cpp

View File

@ -210,6 +210,8 @@ etl_test_sources = files(
'test_string_char.cpp',
'test_string_char_external_buffer.cpp',
'test_string_stream.cpp',
'test_string_u8.cpp',
'test_string_u8_external_buffer.cpp',
'test_string_stream_u16.cpp',
'test_string_stream_u32.cpp',
'test_string_stream_wchar_t.cpp',

View File

@ -263,6 +263,7 @@ target_sources(t98 PRIVATE etl_profile.h
../timer.h.t.cpp
../to_arithmetic.h.t.cpp
../to_string.h.t.cpp
../to_u8string.h.t.cpp
../to_u16string.h.t.cpp
../to_u32string.h.t.cpp
../to_wstring.h.t.cpp
@ -270,12 +271,16 @@ target_sources(t98 PRIVATE etl_profile.h
../type_lookup.h.t.cpp
../type_select.h.t.cpp
../type_traits.h.t.cpp
../u8format_spec.h.t.cpp
../u8string.h.t.cpp
../u8string_stream.h.t.cpp
../u16format_spec.h.t.cpp
../u16string.h.t.cpp
../u16string_stream.h.t.cpp
../u32format_spec.h.t.cpp
../u32string.h.t.cpp
../u32string_stream.h.t.cpp
../u8tring.h.t.cpp
../unaligned_type.h.t.cpp
../unordered_map.h.t.cpp
../unordered_multimap.h.t.cpp

View File

@ -216,8 +216,8 @@ target_sources(t11 PRIVATE etl_profile.h
../pearson.h.t.cpp
../permutations.h.t.cpp
../placement_new.h.t.cpp
../platform.h.t.cpp
../poly_span.h.t.cpp
../platform.h.t.cpp
../pool.h.t.cpp
../power.h.t.cpp
../priority_queue.h.t.cpp
@ -263,6 +263,7 @@ target_sources(t11 PRIVATE etl_profile.h
../timer.h.t.cpp
../to_arithmetic.h.t.cpp
../to_string.h.t.cpp
../to_u8string.h.t.cpp
../to_u16string.h.t.cpp
../to_u32string.h.t.cpp
../to_wstring.h.t.cpp
@ -270,12 +271,16 @@ target_sources(t11 PRIVATE etl_profile.h
../type_lookup.h.t.cpp
../type_select.h.t.cpp
../type_traits.h.t.cpp
../u8format_spec.h.t.cpp
../u8string.h.t.cpp
../u8string_stream.h.t.cpp
../u16format_spec.h.t.cpp
../u16string.h.t.cpp
../u16string_stream.h.t.cpp
../u32format_spec.h.t.cpp
../u32string.h.t.cpp
../u32string_stream.h.t.cpp
../u8tring.h.t.cpp
../unaligned_type.h.t.cpp
../unordered_map.h.t.cpp
../unordered_multimap.h.t.cpp

View File

@ -216,8 +216,8 @@ target_sources(t14 PRIVATE etl_profile.h
../pearson.h.t.cpp
../permutations.h.t.cpp
../placement_new.h.t.cpp
../platform.h.t.cpp
../poly_span.h.t.cpp
../platform.h.t.cpp
../pool.h.t.cpp
../power.h.t.cpp
../priority_queue.h.t.cpp
@ -263,6 +263,7 @@ target_sources(t14 PRIVATE etl_profile.h
../timer.h.t.cpp
../to_arithmetic.h.t.cpp
../to_string.h.t.cpp
../to_u8string.h.t.cpp
../to_u16string.h.t.cpp
../to_u32string.h.t.cpp
../to_wstring.h.t.cpp
@ -270,12 +271,16 @@ target_sources(t14 PRIVATE etl_profile.h
../type_lookup.h.t.cpp
../type_select.h.t.cpp
../type_traits.h.t.cpp
../u8format_spec.h.t.cpp
../u8string.h.t.cpp
../u8string_stream.h.t.cpp
../u16format_spec.h.t.cpp
../u16string.h.t.cpp
../u16string_stream.h.t.cpp
../u32format_spec.h.t.cpp
../u32string.h.t.cpp
../u32string_stream.h.t.cpp
../u8tring.h.t.cpp
../unaligned_type.h.t.cpp
../unordered_map.h.t.cpp
../unordered_multimap.h.t.cpp

View File

@ -216,8 +216,8 @@ target_sources(t17 PRIVATE etl_profile.h
../pearson.h.t.cpp
../permutations.h.t.cpp
../placement_new.h.t.cpp
../platform.h.t.cpp
../poly_span.h.t.cpp
../platform.h.t.cpp
../pool.h.t.cpp
../power.h.t.cpp
../priority_queue.h.t.cpp
@ -263,6 +263,7 @@ target_sources(t17 PRIVATE etl_profile.h
../timer.h.t.cpp
../to_arithmetic.h.t.cpp
../to_string.h.t.cpp
../to_u8string.h.t.cpp
../to_u16string.h.t.cpp
../to_u32string.h.t.cpp
../to_wstring.h.t.cpp
@ -270,12 +271,16 @@ target_sources(t17 PRIVATE etl_profile.h
../type_lookup.h.t.cpp
../type_select.h.t.cpp
../type_traits.h.t.cpp
../u8format_spec.h.t.cpp
../u8string.h.t.cpp
../u8string_stream.h.t.cpp
../u16format_spec.h.t.cpp
../u16string.h.t.cpp
../u16string_stream.h.t.cpp
../u32format_spec.h.t.cpp
../u32string.h.t.cpp
../u32string_stream.h.t.cpp
../u8tring.h.t.cpp
../unaligned_type.h.t.cpp
../unordered_map.h.t.cpp
../unordered_multimap.h.t.cpp

View File

@ -216,8 +216,8 @@ target_sources(t20 PRIVATE etl_profile.h
../pearson.h.t.cpp
../permutations.h.t.cpp
../placement_new.h.t.cpp
../platform.h.t.cpp
../poly_span.h.t.cpp
../platform.h.t.cpp
../pool.h.t.cpp
../power.h.t.cpp
../priority_queue.h.t.cpp
@ -263,6 +263,7 @@ target_sources(t20 PRIVATE etl_profile.h
../timer.h.t.cpp
../to_arithmetic.h.t.cpp
../to_string.h.t.cpp
../to_u8string.h.t.cpp
../to_u16string.h.t.cpp
../to_u32string.h.t.cpp
../to_wstring.h.t.cpp
@ -270,12 +271,16 @@ target_sources(t20 PRIVATE etl_profile.h
../type_lookup.h.t.cpp
../type_select.h.t.cpp
../type_traits.h.t.cpp
../u8format_spec.h.t.cpp
../u8string.h.t.cpp
../u8string_stream.h.t.cpp
../u16format_spec.h.t.cpp
../u16string.h.t.cpp
../u16string_stream.h.t.cpp
../u32format_spec.h.t.cpp
../u32string.h.t.cpp
../u32string_stream.h.t.cpp
../u8tring.h.t.cpp
../unaligned_type.h.t.cpp
../unordered_map.h.t.cpp
../unordered_multimap.h.t.cpp

View File

@ -0,0 +1,29 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include <etl/u8format_spec.h>

View File

@ -0,0 +1,29 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include <etl/u8string.h>

View File

@ -0,0 +1,29 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include <etl/u8string_stream.h>

View File

@ -0,0 +1,295 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "etl/platform.h"
#if ETL_USING_CPP20
#include "unit_test_framework.h"
#include <ostream>
#include <sstream>
#include <iomanip>
#include "etl/u8string_stream.h"
#include "etl/u8string.h"
#include "etl/format_spec.h"
#undef STR
#define STR(x) u8##x
namespace
{
using String = etl::u8string<50>;
using IString = etl::iu8string;
using Stream = etl::u8string_stream;
using Format = etl::u8format_spec;
//***********************************
struct Custom
{
int x;
int y;
};
//***********************************
Stream& operator <<(Stream& ss, const Custom& value)
{
ss << STR("X = ") << value.x << STR(" : Y = ") << value.y;
return ss;
}
}
namespace etl
{
//***********************************
std::ostream& operator << (std::ostream& os, const IString& str)
{
for (auto c : str)
{
os << uint16_t(c);
}
return os;
}
}
namespace
{
SUITE(test_string_stream)
{
//*************************************************************************
TEST(test_default_format_from_const_char)
{
String str;
Stream ss(str);
int value = 123;
String hello(STR("Hello"));
ss << hello << STR(" World ") << value;
String result = ss.str();
CHECK_EQUAL(String(STR("Hello World 123")), result);
}
//*************************************************************************
TEST(test_default_format_from_char)
{
String str;
Stream ss(str);
int value = 123;
String hello(STR("Hello"));
ss << hello << const_cast<char8_t*>(STR(" World ")) << value;
String result = ss.str();
CHECK_EQUAL(String(STR("Hello World 123")), result);
}
//*************************************************************************
TEST(test_custom_format)
{
String str;
Format format = Format().base(10).width(10).fill(STR('#'));
Stream ss(str);
int value = 123;
String hello(STR("Hello"));
ss << format << hello << STR("World") << value;
String result = ss.str();
CHECK_EQUAL(String(STR("#####Hello#####World#######123")), result);
}
//*************************************************************************
TEST(test_custom_multi_format)
{
String str;
Format format1 = Format().base(10).width(10).fill(STR('#'));
Format format2 = Format().base(10).width(8).fill(STR('*')).left();
Format format3 = Format().base(16).width(4).fill(STR(' ')).right();
Stream ss(str);
int value = 123;
String hello(STR("Hello"));
ss << format1 << hello << format2 << STR("World") << format3 << value;
String result = ss.str();
CHECK_EQUAL(String(STR("#####HelloWorld*** 7b")), result);
}
//*************************************************************************
TEST(test_custom_inline_format)
{
String str;
Stream ss(str);
int value = 123456;
ss << etl::setw(20) << etl::setfill(STR('-')) << etl::left;
ss << etl::bin << value;
CHECK_EQUAL(String(STR("11110001001000000---")), ss.str());
ss.str().clear();
ss << etl::oct << value;
CHECK_EQUAL(String(STR("361100--------------")), ss.str());
ss.str().clear();
ss << etl::dec << value;
CHECK_EQUAL(String(STR("123456--------------")), ss.str());
ss.str().clear();
ss << etl::hex << etl::uppercase << value;
CHECK_EQUAL(String(STR("1E240---------------")), ss.str());
ss.str().clear();
ss << etl::hex << etl::nouppercase << value;
CHECK_EQUAL(String(STR("1e240---------------")), ss.str());
ss.str().clear();
ss << etl::setw(0);
ss << etl::noboolalpha << false << STR(" ") << true << STR(" ") << etl::boolalpha << false << STR(" ") << true;
CHECK_EQUAL(String(STR("0 1 false true")), ss.str());
ss.str().clear();
ss << etl::setprecision(4) << 3.1415927;
CHECK_EQUAL(String(STR("3.1416")), ss.str());
ss.str().clear();
ss << STR("abcdef") << STR(" ") << etl::uppercase << STR("abcdef");
CHECK_EQUAL(String(STR("abcdef abcdef")), ss.str());
}
//*************************************************************************
TEST(test_custom_multi_inline_format)
{
String str;
Stream ss(str);
int value = 123;
String hello(STR("Hello"));
ss << etl::dec << etl::setw(10) << etl::setfill(STR('#')) << hello
<< etl::setw(8) << etl::setfill(STR('*')) << etl::left << STR("World")
<< etl::hex << etl::setw(4) << etl::setfill(STR(' ')) << etl::right << value;
String result = ss.str();
CHECK_EQUAL(String(STR("#####HelloWorld*** 7b")), result);
}
//*************************************************************************
TEST(test_custom_class_default_format)
{
String str;
Stream ss(str);
String value_str(STR("Value: "));
IString& ivalue_str = value_str;
Custom value = { 1, 2 };
ss << ivalue_str << value;
String result = ss.str();
CHECK_EQUAL(String(STR("Value: X = 1 : Y = 2")), result);
}
//*************************************************************************
TEST(test_get_format)
{
String str;
Format format = Format().base(16).width(4).fill(STR(' ')).right();
Stream ss(str, format);
Format format2 = ss.get_format();
CHECK(format == format2);
}
//*************************************************************************
TEST(test_set_from_character_pointer)
{
String str;
Stream ss(str);
ss.str(STR("Hello"));
CHECK_EQUAL(String(STR("Hello")), ss.str());
}
//*************************************************************************
TEST(test_set_from_string)
{
String str;
Stream ss(str);
ss.str(String(STR("Hello")));
CHECK_EQUAL(String(STR("Hello")), ss.str());
}
//*************************************************************************
TEST(test_get_istring)
{
String str;
Stream ss(str);
ss.str(String(STR("Hello")));
IString& istr = ss.str();
istr.resize(istr.size() - 1);
CHECK_EQUAL(String(STR("Hell")), istr);
}
//*************************************************************************
TEST(test_get_const_istring)
{
String str;
Stream ss(str);
ss.str(String(STR("Hello")));
const IString& istr = ss.str();
CHECK_EQUAL(String(STR("Hello")), istr);
}
};
}
#endif

4473
test/test_string_u8.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,9 @@ SOFTWARE.
#include "etl/string_view.h"
#include "etl/string.h"
#include "etl/wstring.h"
#if ETL_USING_CPP20
#include "etl/u8string.h"
#endif
#include "etl/u16string.h"
#include "etl/u32string.h"
#include "etl/hash.h"
@ -45,12 +48,16 @@ namespace
{
using View = etl::string_view;
using WView = etl::wstring_view;
using U8View = etl::u8string_view;
using U16View = etl::u16string_view;
using U32View = etl::u32string_view;
etl::string<11> etltext = "Hello World";
std::string text = "Hello World";
std::wstring wtext = L"Hello World";
#if ETL_USING_CPP20
std::u8string u8text = u8"Hello World";
#endif
std::u16string u16text = u"Hello World";
std::u32string u32text = U"Hello World";
std::string text_smaller = "Hello Worlc";
@ -59,11 +66,17 @@ namespace
constexpr char cctext[] = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '\0' };
constexpr wchar_t cwtext[] = { L'H', L'e', L'l', L'l', L'o', L' ', L'W', L'o', L'r', L'l', L'd', L'\0' };
#if ETL_USING_CPP20
constexpr char8_t cu8text[] = { u8'H', u8'e', u8'l', u8'l', u8'o', u8' ', u8'W', u8'o', u8'r', u8'l', u8'd', u8'\0' };
#endif
constexpr char16_t cu16text[] = { u'H', u'e', u'l', u'l', u'o', u' ', u'W', u'o', u'r', u'l', u'd', u'\0' };
constexpr char32_t cu32text[] = { U'H', U'e', U'l', U'l', U'o', U' ', U'W', U'o', U'r', U'l', U'd', U'\0' };
const char* pctext = cctext;
const wchar_t* pwtext = cwtext;
#if ETL_USING_CPP20
const char8_t* pu8text = cu8text;
#endif
const char16_t* pu16text = cu16text;
const char32_t* pu32text = cu32text;
@ -126,6 +139,20 @@ namespace
CHECK(isEqual);
}
//*************************************************************************
#if ETL_USING_CPP20
TEST(test_constructor_pointer_range_u8char_t)
{
U8View view(pu8text, pu8text + etl::strlen(pu8text));
CHECK(text.size() == view.size());
CHECK(text.size() == view.max_size());
bool isEqual = std::equal(view.begin(), view.end(), text.begin());
CHECK(isEqual);
}
#endif
//*************************************************************************
TEST(test_constructor_pointer_range_u16char_t)
{
@ -203,12 +230,18 @@ namespace
{
auto cview = etl::make_string_view("Hello World");
auto wview = etl::make_string_view(L"Hello World");
#if ETL_USING_CPP20
auto u8view = etl::make_string_view(u8"Hello World");
#endif
auto u16view = etl::make_string_view(u"Hello World");
auto u32view = etl::make_string_view(U"Hello World");
CHECK(std::equal(cview.begin(), cview.end(), text.begin()));
CHECK(std::equal(wview.begin(), wview.end(), wtext.begin()));
CHECK(std::equal(u16view.begin(), u16view.end(), u16text.begin()));
#if ETL_USING_CPP20
CHECK(std::equal(u8view.begin(), u8view.end(), u8text.begin()));
#endif
CHECK(std::equal(u32view.begin(), u32view.end(), u32text.begin()));
}
@ -218,13 +251,19 @@ namespace
{
constexpr auto cview = etl::make_string_view(cctext);
constexpr auto wview = etl::make_string_view(cwtext);
#if ETL_USING_CPP20
constexpr auto u8view = etl::make_string_view(cu8text);
#endif
constexpr auto u16view = etl::make_string_view(cu16text);
constexpr auto u32view = etl::make_string_view(cu32text);
CHECK(std::equal(cview.begin(), cview.end(), text.begin()));
CHECK(std::equal(wview.begin(), wview.end(), text.begin()));
CHECK(std::equal(u16view.begin(), u16view.end(), text.begin()));
CHECK(std::equal(u32view.begin(), u32view.end(), text.begin()));
CHECK(std::equal(wview.begin(), wview.end(), wtext.begin()));
#if ETL_USING_CPP20
CHECK(std::equal(u8view.begin(), u8view.end(), u8text.begin()));
#endif
CHECK(std::equal(u16view.begin(), u16view.end(), u16text.begin()));
CHECK(std::equal(u32view.begin(), u32view.end(), u32text.begin()));
}
#endif

File diff suppressed because it is too large Load Diff

574
test/test_to_u8string.cpp Normal file
View File

@ -0,0 +1,574 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "etl/platform.h"
#if ETL_USING_CPP20
#include "unit_test_framework.h"
#include "etl/to_u8string.h"
#include "etl/u8string.h"
#include "etl/format_spec.h"
#undef STR
#define STR(x) u8##x
namespace
{
typedef etl::u8format_spec Format;
SUITE(test_to_u8string)
{
//*************************************************************************
TEST(test_default_format_no_append)
{
etl::u8string<20> str;
CHECK(etl::u8string<20>(STR("0")) == etl::to_string(uint8_t(0), str));
CHECK(etl::u8string<20>(STR("0")) == etl::to_string(uint16_t(0), str));
CHECK(etl::u8string<20>(STR("0")) == etl::to_string(uint32_t(0), str));
CHECK(etl::u8string<20>(STR("0")) == etl::to_string(uint64_t(0), str));
CHECK(etl::u8string<20>(STR("128")) == etl::to_string(uint8_t(128), str));
CHECK(etl::u8string<20>(STR("32768")) == etl::to_string(uint16_t(32768), str));
CHECK(etl::u8string<20>(STR("2147483648")) == etl::to_string(uint32_t(2147483648ul), str));
CHECK(etl::u8string<20>(STR("9223372036854775808")) == etl::to_string(uint64_t(9223372036854775808ull), str));
CHECK(etl::u8string<20>(STR("127")) == etl::to_string(int8_t(INT8_MAX), str));
CHECK(etl::u8string<20>(STR("32767")) == etl::to_string(int16_t(INT16_MAX), str));
CHECK(etl::u8string<20>(STR("2147483647")) == etl::to_string(int32_t(INT32_MAX), str));
CHECK(etl::u8string<20>(STR("9223372036854775807")) == etl::to_string(int64_t(INT64_MAX), str));
CHECK(etl::u8string<20>(STR("-128")) == etl::to_string(int8_t(INT8_MIN), str));
CHECK(etl::u8string<20>(STR("-32768")) == etl::to_string(int16_t(INT16_MIN), str));
CHECK(etl::u8string<20>(STR("-2147483648")) == etl::to_string(int32_t(INT32_MIN), str));
CHECK(etl::u8string<20>(STR("-9223372036854775808")) == etl::to_string(int64_t(INT64_MIN), str));
}
//*************************************************************************
TEST(test_default_format_append)
{
etl::u8string<120> str;
CHECK(etl::u8string<120>(STR("0")) == etl::to_string(uint8_t(0), str, true));
CHECK(etl::u8string<120>(STR("00")) == etl::to_string(uint16_t(0), str, true));
CHECK(etl::u8string<120>(STR("000")) == etl::to_string(uint32_t(0), str, true));
CHECK(etl::u8string<120>(STR("0000")) == etl::to_string(uint64_t(0), str, true));
CHECK(etl::u8string<120>(STR("0000128")) == etl::to_string(uint8_t(128), str, true));
CHECK(etl::u8string<120>(STR("000012832768")) == etl::to_string(uint16_t(32768), str, true));
CHECK(etl::u8string<120>(STR("0000128327682147483648")) == etl::to_string(uint32_t(2147483648ul), str, true));
CHECK(etl::u8string<120>(STR("00001283276821474836489223372036854775808")) == etl::to_string(uint64_t(9223372036854775808ull), str, true));
CHECK(etl::u8string<120>(STR("00001283276821474836489223372036854775808127")) == etl::to_string(int8_t(INT8_MAX), str, true));
CHECK(etl::u8string<120>(STR("0000128327682147483648922337203685477580812732767")) == etl::to_string(int16_t(INT16_MAX), str, true));
CHECK(etl::u8string<120>(STR("00001283276821474836489223372036854775808127327672147483647")) == etl::to_string(int32_t(INT32_MAX), str, true));
CHECK(etl::u8string<120>(STR("000012832768214748364892233720368547758081273276721474836479223372036854775807")) == etl::to_string(int64_t(INT64_MAX), str, true));
CHECK(etl::u8string<120>(STR("000012832768214748364892233720368547758081273276721474836479223372036854775807-128")) == etl::to_string(int8_t(INT8_MIN), str, true));
CHECK(etl::u8string<120>(STR("000012832768214748364892233720368547758081273276721474836479223372036854775807-128-32768")) == etl::to_string(int16_t(INT16_MIN), str, true));
CHECK(etl::u8string<120>(STR("000012832768214748364892233720368547758081273276721474836479223372036854775807-128-32768-2147483648")) == etl::to_string(int32_t(INT32_MIN), str, true));
CHECK(etl::u8string<120>(STR("000012832768214748364892233720368547758081273276721474836479223372036854775807-128-32768-2147483648-9223372036854775808")) == etl::to_string(int64_t(INT64_MIN), str, true));
}
//*************************************************************************
TEST(test_format_right_justified_no_append)
{
etl::u8string<20> str;
Format format = Format().base(10).width(20).fill(STR('#'));
CHECK(etl::u8string<20>(STR("###################0")) == etl::to_string(uint8_t(0), str, format));
CHECK(etl::u8string<20>(STR("###################0")) == etl::to_string(uint16_t(0), str, format));
CHECK(etl::u8string<20>(STR("###################0")) == etl::to_string(uint32_t(0), str, format));
CHECK(etl::u8string<20>(STR("###################0")) == etl::to_string(uint64_t(0), str, format));
CHECK(etl::u8string<20>(STR("#################128")) == etl::to_string(uint8_t(128), str, format));
CHECK(etl::u8string<20>(STR("###############32768")) == etl::to_string(uint16_t(32768), str, format));
CHECK(etl::u8string<20>(STR("##########2147483648")) == etl::to_string(uint32_t(2147483648ul), str, format));
CHECK(etl::u8string<20>(STR("#9223372036854775808")) == etl::to_string(uint64_t(9223372036854775808ull), str, format));
CHECK(etl::u8string<20>(STR("#################127")) == etl::to_string(int8_t(INT8_MAX), str, format));
CHECK(etl::u8string<20>(STR("###############32767")) == etl::to_string(int16_t(INT16_MAX), str, format));
CHECK(etl::u8string<20>(STR("##########2147483647")) == etl::to_string(int32_t(INT32_MAX), str, format));
CHECK(etl::u8string<20>(STR("#9223372036854775807")) == etl::to_string(int64_t(INT64_MAX), str, format));
CHECK(etl::u8string<20>(STR("################-128")) == etl::to_string(int8_t(INT8_MIN), str, format));
CHECK(etl::u8string<20>(STR("##############-32768")) == etl::to_string(int16_t(INT16_MIN), str, format));
CHECK(etl::u8string<20>(STR("#########-2147483648")) == etl::to_string(int32_t(INT32_MIN), str, format));
CHECK(etl::u8string<20>(STR("-9223372036854775808")) == etl::to_string(int64_t(INT64_MIN), str, format));
}
//*************************************************************************
TEST(test_format_left_justified_no_append)
{
etl::u8string<20> str;
Format format = Format().base(10).width(20).fill(STR('#')).left();
CHECK(etl::u8string<20>(STR("0###################")) == etl::to_string(uint8_t(0), str, format));
CHECK(etl::u8string<20>(STR("0###################")) == etl::to_string(uint16_t(0), str, format));
CHECK(etl::u8string<20>(STR("0###################")) == etl::to_string(uint32_t(0), str, format));
CHECK(etl::u8string<20>(STR("0###################")) == etl::to_string(uint64_t(0), str, format));
CHECK(etl::u8string<20>(STR("128#################")) == etl::to_string(uint8_t(128), str, format));
CHECK(etl::u8string<20>(STR("32768###############")) == etl::to_string(uint16_t(32768), str, format));
CHECK(etl::u8string<20>(STR("2147483648##########")) == etl::to_string(uint32_t(2147483648ul), str, format));
CHECK(etl::u8string<20>(STR("9223372036854775808#")) == etl::to_string(uint64_t(9223372036854775808ull), str, format));
CHECK(etl::u8string<20>(STR("127#################")) == etl::to_string(int8_t(INT8_MAX), str, format));
CHECK(etl::u8string<20>(STR("32767###############")) == etl::to_string(int16_t(INT16_MAX), str, format));
CHECK(etl::u8string<20>(STR("2147483647##########")) == etl::to_string(int32_t(INT32_MAX), str, format));
CHECK(etl::u8string<20>(STR("9223372036854775807#")) == etl::to_string(int64_t(INT64_MAX), str, format));
CHECK(etl::u8string<20>(STR("-128################")) == etl::to_string(int8_t(INT8_MIN), str, format));
CHECK(etl::u8string<20>(STR("-32768##############")) == etl::to_string(int16_t(INT16_MIN), str, format));
CHECK(etl::u8string<20>(STR("-2147483648#########")) == etl::to_string(int32_t(INT32_MIN), str, format));
CHECK(etl::u8string<20>(STR("-9223372036854775808")) == etl::to_string(int64_t(INT64_MIN), str, format));
}
//*************************************************************************
TEST(test_binary_format_no_append)
{
etl::u8string<64> str;
CHECK(etl::u8string<64>(STR("00000000")) == etl::to_string(uint8_t(0), str, Format().base(2).width(8).fill(STR('0'))));
CHECK(etl::u8string<64>(STR("0000000000000000")) == etl::to_string(uint16_t(0), str, Format().base(2).width(16).fill(STR('0'))));
CHECK(etl::u8string<64>(STR("00000000000000000000000000000000")) == etl::to_string(uint32_t(0), str, Format().base(2).width(32).fill(STR('0'))));
CHECK(etl::u8string<64>(STR("0000000000000000000000000000000000000000000000000000000000000000")) == etl::to_string(uint64_t(0), str, Format().base(2).width(64).fill(STR('0'))));
CHECK(etl::u8string<64>(STR("10000000")) == etl::to_string(uint8_t(128), str, Format().base(2).width(8).fill(STR('0'))));
CHECK(etl::u8string<64>(STR("1000000000000000")) == etl::to_string(uint16_t(32768), str, Format().base(2).width(16).fill(STR('0'))));
CHECK(etl::u8string<64>(STR("10000000000000000000000000000000")) == etl::to_string(uint32_t(2147483648ul), str, Format().base(2).width(32).fill(STR('0'))));
CHECK(etl::u8string<64>(STR("1000000000000000000000000000000000000000000000000000000000000000")) == etl::to_string(uint64_t(9223372036854775808ull), str, Format().base(2).width(64).fill(STR('0'))));
CHECK(etl::u8string<64>(STR("01111111")) == etl::to_string(int8_t(INT8_MAX), str, Format().base(2).width(8).fill(STR('0'))));
CHECK(etl::u8string<64>(STR("0111111111111111")) == etl::to_string(int16_t(INT16_MAX), str, Format().base(2).width(16).fill(STR('0'))));
CHECK(etl::u8string<64>(STR("01111111111111111111111111111111")) == etl::to_string(int32_t(INT32_MAX), str, Format().base(2).width(32).fill(STR('0'))));
CHECK(etl::u8string<64>(STR("0111111111111111111111111111111111111111111111111111111111111111")) == etl::to_string(int64_t(INT64_MAX), str, Format().base(2).width(64).fill(STR('0'))));
CHECK(etl::u8string<64>(STR("10000000")) == etl::to_string(int8_t(INT8_MIN), str, Format().base(2).width(8).fill(STR('0'))));
CHECK(etl::u8string<64>(STR("1000000000000000")) == etl::to_string(int16_t(INT16_MIN), str, Format().base(2).width(16).fill(STR('0'))));
CHECK(etl::u8string<64>(STR("10000000000000000000000000000000")) == etl::to_string(int32_t(INT32_MIN), str, Format().base(2).width(32).fill(STR('0'))));
CHECK(etl::u8string<64>(STR("1000000000000000000000000000000000000000000000000000000000000000")) == etl::to_string(int64_t(INT64_MIN), str, Format().base(2).width(64).fill(STR('0'))));
}
//*************************************************************************
TEST(test_octal_format_no_append)
{
etl::u8string<22> str;
CHECK(etl::u8string<22>(STR("000")) == etl::to_string(uint8_t(0), str, Format().base(8).width(3).fill(STR('0'))));
CHECK(etl::u8string<22>(STR("000000")) == etl::to_string(uint16_t(0), str, Format().base(8).width(6).fill(STR('0'))));
CHECK(etl::u8string<22>(STR("00000000000")) == etl::to_string(uint32_t(0), str, Format().base(8).width(11).fill(STR('0'))));
CHECK(etl::u8string<22>(STR("0000000000000000000000")) == etl::to_string(uint64_t(0), str, Format().base(8).width(22).fill(STR('0'))));
CHECK(etl::u8string<22>(STR("200")) == etl::to_string(uint8_t(128), str, Format().base(8).width(3).fill(STR('0'))));
CHECK(etl::u8string<22>(STR("100000")) == etl::to_string(uint16_t(32768), str, Format().base(8).width(6).fill(STR('0'))));
CHECK(etl::u8string<22>(STR("20000000000")) == etl::to_string(uint32_t(2147483648ul), str, Format().base(8).width(11).fill(STR('0'))));
CHECK(etl::u8string<22>(STR("1000000000000000000000")) == etl::to_string(uint64_t(9223372036854775808ull), str, Format().base(8).width(22).fill(STR('0'))));
CHECK(etl::u8string<22>(STR("177")) == etl::to_string(int8_t(INT8_MAX), str, Format().base(8).width(3).fill(STR('0'))));
CHECK(etl::u8string<22>(STR("077777")) == etl::to_string(int16_t(INT16_MAX), str, Format().base(8).width(6).fill(STR('0'))));
CHECK(etl::u8string<22>(STR("17777777777")) == etl::to_string(int32_t(INT32_MAX), str, Format().base(8).width(11).fill(STR('0'))));
CHECK(etl::u8string<22>(STR("0777777777777777777777")) == etl::to_string(int64_t(INT64_MAX), str, Format().base(8).width(22).fill(STR('0'))));
CHECK(etl::u8string<22>(STR("200")) == etl::to_string(int8_t(INT8_MIN), str, Format().base(8).width(3).fill(STR('0'))));
CHECK(etl::u8string<22>(STR("100000")) == etl::to_string(int16_t(INT16_MIN), str, Format().base(8).width(6).fill(STR('0'))));
CHECK(etl::u8string<22>(STR("20000000000")) == etl::to_string(int32_t(INT32_MIN), str, Format().base(8).width(11).fill(STR('0'))));
CHECK(etl::u8string<22>(STR("1000000000000000000000")) == etl::to_string(int64_t(INT64_MIN), str, Format().base(8).width(22).fill(STR('0'))));
}
//*************************************************************************
TEST(test_hex_format_no_append)
{
etl::u8string<16> str;
CHECK(etl::u8string<16>(STR("00")) == etl::to_string(uint8_t(0), str, Format().base(16).width(2).fill(STR('0'))));
CHECK(etl::u8string<16>(STR("0000")) == etl::to_string(uint16_t(0), str, Format().base(16).width(4).fill(STR('0'))));
CHECK(etl::u8string<16>(STR("00000000")) == etl::to_string(uint32_t(0), str, Format().base(16).width(8).fill(STR('0'))));
CHECK(etl::u8string<16>(STR("0000000000000000")) == etl::to_string(uint64_t(0), str, Format().base(16).width(16).fill(STR('0'))));
CHECK(etl::u8string<16>(STR("80")) == etl::to_string(uint8_t(128), str, Format().base(16).width(2).fill(STR('0'))));
CHECK(etl::u8string<16>(STR("8000")) == etl::to_string(uint16_t(32768), str, Format().base(16).width(4).fill(STR('0'))));
CHECK(etl::u8string<16>(STR("80000000")) == etl::to_string(uint32_t(2147483648ul), str, Format().base(16).width(8).fill(STR('0'))));
CHECK(etl::u8string<16>(STR("8000000000000000")) == etl::to_string(uint64_t(9223372036854775808ull), str, Format().base(16).width(16).fill(STR('0'))));
CHECK(etl::u8string<16>(STR("7f")) == etl::to_string(int8_t(INT8_MAX), str, Format().base(16).width(2).fill(STR('0'))));
CHECK(etl::u8string<16>(STR("7fff")) == etl::to_string(int16_t(INT16_MAX), str, Format().base(16).width(4).fill(STR('0'))));
CHECK(etl::u8string<16>(STR("7fffffff")) == etl::to_string(int32_t(INT32_MAX), str, Format().base(16).width(8).fill(STR('0'))));
CHECK(etl::u8string<16>(STR("7fffffffffffffff")) == etl::to_string(int64_t(INT64_MAX), str, Format().base(16).width(16).fill(STR('0'))));
CHECK(etl::u8string<16>(STR("80")) == etl::to_string(int8_t(INT8_MIN), str, Format().base(16).width(2).fill(STR('0'))));
CHECK(etl::u8string<16>(STR("8000")) == etl::to_string(int16_t(INT16_MIN), str, Format().base(16).width(4).fill(STR('0'))));
CHECK(etl::u8string<16>(STR("80000000")) == etl::to_string(int32_t(INT32_MIN), str, Format().base(16).width(8).fill(STR('0'))));
CHECK(etl::u8string<16>(STR("8000000000000000")) == etl::to_string(int64_t(INT64_MIN), str, Format().base(16).width(16).fill(STR('0'))));
}
//*************************************************************************
TEST(test_named_format_no_append)
{
etl::u8string<17> str;
CHECK(etl::u8string<17>(STR("11110001001000000")) == etl::to_string(123456, str, Format().binary()));
CHECK(etl::u8string<17>(STR("361100")) == etl::to_string(123456, str, Format().octal()));
CHECK(etl::u8string<17>(STR("123456")) == etl::to_string(123456, str, Format().decimal()));
CHECK(etl::u8string<17>(STR("1e240")) == etl::to_string(123456, str, Format().hex()));
}
//*************************************************************************
TEST(test_floating_point_no_append)
{
etl::u8string<20> str;
CHECK(etl::u8string<20>(STR(" 0.000000")) == etl::to_string(0.0, str, Format().precision(6).width(10).right()));
CHECK(etl::u8string<20>(STR("0.000000 ")) == etl::to_string(0.0, str, Format().precision(6).width(10).left()));
CHECK(etl::u8string<20>(STR(" 0.000001")) == etl::to_string(0.000001, str, Format().precision(6).width(10).right()));
CHECK(etl::u8string<20>(STR("0.000001 ")) == etl::to_string(0.000001, str, Format().precision(6).width(10).left()));
CHECK(etl::u8string<20>(STR(" 1.000000")) == etl::to_string(1.0, str, Format().precision(6).width(10).right()));
CHECK(etl::u8string<20>(STR("1.000000 ")) == etl::to_string(1.0, str, Format().precision(6).width(10).left()));
CHECK(etl::u8string<20>(STR(" 1.000001")) == etl::to_string(1.000001, str, Format().precision(6).width(10).right()));
CHECK(etl::u8string<20>(STR("1.000001 ")) == etl::to_string(1.000001, str, Format().precision(6).width(10).left()));
CHECK(etl::u8string<20>(STR(" 12.345678")) == etl::to_string(12.345678, str, Format().precision(6).width(10).right()));
CHECK(etl::u8string<20>(STR("12.345678 ")) == etl::to_string(12.345678, str, Format().precision(6).width(10).left()));
CHECK(etl::u8string<20>(STR(" -12.345678")) == etl::to_string(-12.345678, str, Format().precision(6).width(11).right()));
CHECK(etl::u8string<20>(STR("-12.345678 ")) == etl::to_string(-12.345678, str, Format().precision(6).width(11).left()));
CHECK(etl::u8string<20>(STR(" -0.123456")) == etl::to_string(-0.123456, str, Format().precision(6).width(10).right()));
CHECK(etl::u8string<20>(STR("-0.123456 ")) == etl::to_string(-0.123456, str, Format().precision(6).width(10).left()));
}
//*************************************************************************
TEST(test_floating_point_append)
{
etl::u8string<20> str;
str.assign(STR("Result "));
CHECK(etl::u8string<20>(STR("Result 12.345678")) == etl::to_string(12.345678, str, Format().precision(6).width(10).right(), true));
str.assign(STR("Result "));
CHECK(etl::u8string<20>(STR("Result 12.345678 ")) == etl::to_string(12.345678, str, Format().precision(6).width(10).left(), true));
str.assign(STR("Result "));
CHECK(etl::u8string<20>(STR("Result -12.345678")) == etl::to_string(-12.345678, str, Format().precision(6).width(11).right(), true));
str.assign(STR("Result "));
CHECK(etl::u8string<20>(STR("Result -12.345678 ")) == etl::to_string(-12.345678, str, Format().precision(6).width(11).left(), true));
str.assign(STR("Result "));
CHECK(etl::u8string<20>(STR("Result -0.123456 ")) == etl::to_string(-0.123456, str, Format().precision(6).width(10).left(), true));
}
//*************************************************************************
TEST(test_floating_point_rounding)
{
etl::u8string<20> str;
CHECK(etl::u8string<20>(STR("0.00001")) == etl::to_string(0.000009, str, Format().precision(5).width(7).right()));
CHECK(etl::u8string<20>(STR("0.0001")) == etl::to_string(0.000099, str, Format().precision(4).width(6).right()));
CHECK(etl::u8string<20>(STR("0.001")) == etl::to_string(0.000999, str, Format().precision(3).width(5).right()));
CHECK(etl::u8string<20>(STR("0.01")) == etl::to_string(0.009999, str, Format().precision(2).width(4).right()));
CHECK(etl::u8string<20>(STR("0.1")) == etl::to_string(0.099999, str, Format().precision(1).width(3).right()));
CHECK(etl::u8string<20>(STR("1.0")) == etl::to_string(0.999999, str, Format().precision(1).width(3).right()));
CHECK(etl::u8string<20>(STR("1")) == etl::to_string(0.999999, str, Format().precision(0).width(1).right()));
CHECK(etl::u8string<20>(STR("2")) == etl::to_string(1.999999, str, Format().precision(0).width(1).right()));
CHECK(etl::u8string<20>(STR("10.0")) == etl::to_string(9.999999, str, Format().precision(1).width(4).right()));
CHECK(etl::u8string<20>(STR("20.0")) == etl::to_string(19.999999, str, Format().precision(1).width(4).right()));
}
//*************************************************************************
TEST(test_bool_no_append)
{
etl::u8string<20> str;
CHECK(etl::u8string<20>(STR(" 0")) == to_string(false, str, Format().precision(6).width(10).right().boolalpha(false)));
CHECK(etl::u8string<20>(STR(" 1")) == to_string(true, str, Format().precision(6).width(10).right().boolalpha(false)));
CHECK(etl::u8string<20>(STR("0 ")) == to_string(false, str, Format().precision(6).width(10).left().boolalpha(false)));
CHECK(etl::u8string<20>(STR("1 ")) == to_string(true, str, Format().precision(6).width(10).left().boolalpha(false)));
CHECK(etl::u8string<20>(STR(" false")) == to_string(false, str, Format().precision(6).width(10).right().boolalpha(true)));
CHECK(etl::u8string<20>(STR(" true")) == to_string(true, str, Format().precision(6).width(10).right().boolalpha(true)));
CHECK(etl::u8string<20>(STR("false ")) == to_string(false, str, Format().precision(6).width(10).left().boolalpha(true)));
CHECK(etl::u8string<20>(STR("true ")) == to_string(true, str, Format().precision(6).width(10).left().boolalpha(true)));
}
//*************************************************************************
TEST(test_bool_append)
{
etl::u8string<20> str;
str.assign(STR("Result "));
CHECK(etl::u8string<20>(STR("Result 0")) == to_string(false, str, Format().precision(6).width(10).right().boolalpha(false), true));
str.assign(STR("Result "));
CHECK(etl::u8string<20>(STR("Result 1")) == to_string(true, str, Format().precision(6).width(10).right().boolalpha(false), true));
str.assign(STR("Result "));
CHECK(etl::u8string<20>(STR("Result 0 ")) == to_string(false, str, Format().precision(6).width(10).left().boolalpha(false), true));
str.assign(STR("Result "));
CHECK(etl::u8string<20>(STR("Result 1 ")) == to_string(true, str, Format().precision(6).width(10).left().boolalpha(false), true));
str.assign(STR("Result "));
CHECK(etl::u8string<20>(STR("Result false")) == to_string(false, str, Format().precision(6).width(10).right().boolalpha(true), true));
str.assign(STR("Result "));
CHECK(etl::u8string<20>(STR("Result true")) == to_string(true, str, Format().precision(6).width(10).right().boolalpha(true), true));
str.assign(STR("Result "));
CHECK(etl::u8string<20>(STR("Result false ")) == to_string(false, str, Format().precision(6).width(10).left().boolalpha(true), true));
str.assign(STR("Result "));
CHECK(etl::u8string<20>(STR("Result true ")) == to_string(true, str, Format().precision(6).width(10).left().boolalpha(true), true));
}
//*************************************************************************
TEST(test_integer_denominator_default_format)
{
etl::u8string<20> result;
int value = -1234567;
etl::to_string(value, 6U, result);
CHECK(etl::u8string<20>(STR("-1")) == result);
}
//*************************************************************************
TEST(test_integer_denominator_huge_precision)
{
etl::u8string<20> result;
int value = -1234560;
Format format = Format().precision(100);
etl::to_string(value, 6U, result, format);
CHECK(etl::u8string<20>(STR("-1.234560")) == result);
}
//*************************************************************************
TEST(test_integer_denominator_huge_precision_64bit)
{
etl::u8string<20> result;
int64_t value = INT64_MIN;
Format format = Format().precision(100);
etl::to_string(value, 12U, result, format);
CHECK(etl::u8string<20>(STR("-9223372.036854775808")) == result);
}
//*************************************************************************
TEST(test_integer_denominator_zero_fractional)
{
etl::u8string<20> result_i;
int value_i = -1000000;
etl::u8string<20> result_d;
double value_d = -1.000000;
Format format = Format().precision(4);
etl::to_string(value_i, 6U, result_i, format);
etl::to_string(value_d, result_d, format);
CHECK(etl::u8string<20>(STR("-1.0000")) == result_i);
CHECK(result_d == result_i);
}
//*************************************************************************
TEST(test_integer_denominator_zero_value)
{
etl::u8string<20> result_i;
int value_i = 0;
etl::u8string<20> result_d;
double value_d = -0.000000;
Format format = Format().precision(4);
etl::to_string(value_i, 6U, result_i, format);
etl::to_string(value_d, result_d, format);
CHECK(etl::u8string<20>(STR("0.0000")) == result_i);
CHECK(result_d == result_i);
}
//*************************************************************************
TEST(test_integer_denominator_zero_integral_small_fractional)
{
etl::u8string<20> result_i;
int value_i = -400;
etl::u8string<20> result_d;
double value_d = -0.000400;
Format format = Format().precision(4);
etl::to_string(value_i, 6U, result_i, format);
etl::to_string(value_d, result_d, format);
CHECK(etl::u8string<20>(STR("-0.0004")) == result_i);
CHECK(result_d == result_i);
}
//*************************************************************************
TEST(test_integer_denominator_small_fractional)
{
etl::u8string<20> result_i;
int value_i = -123000400;
etl::u8string<20> result_d;
double value_d = -123.000400;
Format format = Format().precision(4);
etl::to_string(value_i, 6U, result_i, format);
etl::to_string(value_d, result_d, format);
CHECK(etl::u8string<20>(STR("-123.0004")) == result_i);
CHECK(result_d == result_i);
}
//*************************************************************************
TEST(test_integer_denominator_very_small_fractional)
{
etl::u8string<20> result_i;
int value_i = -123000004;
etl::u8string<20> result_d;
double value_d = -123.000004;
Format format = Format().precision(4);
etl::to_string(value_i, 6U, result_i, format);
etl::to_string(value_d, result_d, format);
CHECK(etl::u8string<20>(STR("-123.0000")) == result_i);
CHECK(result_d == result_i);
}
//*************************************************************************
TEST(test_integer_denominator_very_small_fractional_rounded_up)
{
etl::u8string<20> result_i;
int value_i = -123000050;
etl::u8string<20> result_d;
double value_d = -123.000050;
Format format = Format().precision(4);
etl::to_string(value_i, 6U, result_i, format);
etl::to_string(value_d, result_d, format);
CHECK(etl::u8string<20>(STR("-123.0001")) == result_i);
CHECK(result_d == result_i);
}
//*************************************************************************
TEST(test_integer_denominator_shorter_width)
{
etl::u8string<20> result_i;
int value_i = -123456780;
etl::u8string<20> result_d;
double value_d = -123.456780;
Format format = Format().precision(4).width(6).right();
etl::to_string(value_i, 6U, result_i, format);
etl::to_string(value_d, result_d, format);
CHECK(etl::u8string<20>(STR("-123.4568")) == result_i);
CHECK(result_d == result_i);
}
//*************************************************************************
TEST(test_integer_denominator_larger_width)
{
etl::u8string<20> result_i;
int value_i = -123456780;
etl::u8string<20> result_d;
double value_d = -123.456780;
Format format = Format().precision(4).width(15).right();
etl::to_string(value_i, 6U, result_i, format);
etl::to_string(value_d, result_d, format);
CHECK(etl::u8string<20>(STR(" -123.4568")) == result_i);
CHECK(result_d == result_i);
}
//*************************************************************************
TEST(test_integer_denominator_positive_rollover)
{
etl::u8string<20> result_i;
int value_i = 123999990;
etl::u8string<20> result_d;
double value_d = 123.999990;
Format format = Format().precision(4).right();
etl::to_string(value_i, 6U, result_i, format);
etl::to_string(value_d, result_d, format);
CHECK(etl::u8string<20>(STR("124.0000")) == result_i);
CHECK(result_d == result_i);
}
//*************************************************************************
TEST(test_integer_denominator_negative_rollover)
{
etl::u8string<20> result_i;
int value_i = -123999990;
etl::u8string<20> result_d;
double value_d = -123.999990;
Format format = Format().precision(4).right();
etl::to_string(value_i, 6U, result_i, format);
etl::to_string(value_d, result_d, format);
CHECK(etl::u8string<20>(STR("-124.0000")) == result_i);
CHECK(result_d == result_i);
}
};
}
#endif

View File

@ -3154,6 +3154,7 @@
<ClInclude Include="..\..\include\etl\to_string.h" />
<ClInclude Include="..\..\include\etl\to_u16string.h" />
<ClInclude Include="..\..\include\etl\to_u32string.h" />
<ClInclude Include="..\..\include\etl\to_u8string.h" />
<ClInclude Include="..\..\include\etl\to_wstring.h" />
<ClInclude Include="..\..\include\etl\type_lookup.h" />
<ClInclude Include="..\..\include\etl\type_select.h" />
@ -3161,6 +3162,9 @@
<ClInclude Include="..\..\include\etl\u16string_stream.h" />
<ClInclude Include="..\..\include\etl\u32format_spec.h" />
<ClInclude Include="..\..\include\etl\u32string_stream.h" />
<ClInclude Include="..\..\include\etl\u8format_spec.h" />
<ClInclude Include="..\..\include\etl\u8string.h" />
<ClInclude Include="..\..\include\etl\u8string_stream.h" />
<ClInclude Include="..\..\include\etl\unaligned_type.h" />
<ClInclude Include="..\..\include\etl\variance.h" />
<ClInclude Include="..\..\include\etl\variant_pool.h" />
@ -6941,6 +6945,48 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++14 - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - Force C++03|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\syntax_check\u8format_spec.h.t.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No virtual imessage|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++ 20 - No Tests|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++14|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release MSVC C++20 - No STL - Optimised -O2|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++17|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++17 - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release MSVC C++20 - Optimised O2|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No virtual messages|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++14 - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - Force C++03|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\syntax_check\u8string.h.t.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No virtual imessage|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++ 20 - No Tests|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++14|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release MSVC C++20 - No STL - Optimised -O2|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++17|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++17 - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release MSVC C++20 - Optimised O2|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No virtual messages|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++14 - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - Force C++03|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\syntax_check\u8string_stream.h.t.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No virtual imessage|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++ 20 - No Tests|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++14|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release MSVC C++20 - No STL - Optimised -O2|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++17|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++17 - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release MSVC C++20 - Optimised O2|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No virtual messages|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++14 - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - Force C++03|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\syntax_check\unaligned_type.h.t.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No virtual imessage|Win32'">true</ExcludedFromBuild>
@ -8181,6 +8227,9 @@
<ClCompile Include="..\test_state_chart_compile_time_with_data_parameter.cpp" />
<ClCompile Include="..\test_state_chart_with_data_parameter.cpp" />
<ClCompile Include="..\test_state_chart_with_rvalue_data_parameter.cpp" />
<ClCompile Include="..\test_string_stream_u8.cpp" />
<ClCompile Include="..\test_string_u8.cpp" />
<ClCompile Include="..\test_string_u8_external_buffer.cpp" />
<ClCompile Include="..\test_string_utilities_std.cpp" />
<ClCompile Include="..\test_string_char.cpp" />
<ClCompile Include="..\test_string_char_external_buffer.cpp" />
@ -8192,9 +8241,11 @@
<ClCompile Include="..\test_string_utilities.cpp" />
<ClCompile Include="..\test_string_utilities_std_u16.cpp" />
<ClCompile Include="..\test_string_utilities_std_u32.cpp" />
<ClCompile Include="..\test_string_utilities_std_u8.cpp" />
<ClCompile Include="..\test_string_utilities_std_wchar_t.cpp" />
<ClCompile Include="..\test_string_utilities_u16.cpp" />
<ClCompile Include="..\test_string_utilities_u32.cpp" />
<ClCompile Include="..\test_string_utilities_u8.cpp" />
<ClCompile Include="..\test_string_utilities_wchar_t.cpp" />
<ClCompile Include="..\test_string_view.cpp" />
<ClCompile Include="..\test_string_wchar_t.cpp" />
@ -8205,10 +8256,12 @@
<ClCompile Include="..\test_to_arithmetic.cpp" />
<ClCompile Include="..\test_to_arithmetic_u16.cpp" />
<ClCompile Include="..\test_to_arithmetic_u32.cpp" />
<ClCompile Include="..\test_to_arithmetic_u8.cpp" />
<ClCompile Include="..\test_to_arithmetic_wchar_t.cpp" />
<ClCompile Include="..\test_to_string.cpp" />
<ClCompile Include="..\test_to_u16string.cpp" />
<ClCompile Include="..\test_to_u32string.cpp" />
<ClCompile Include="..\test_to_u8string.cpp" />
<ClCompile Include="..\test_to_wstring.cpp" />
<ClCompile Include="..\test_type_def.cpp" />
<ClCompile Include="..\test_type_lookup.cpp" />

View File

@ -1371,6 +1371,18 @@
<ClInclude Include="..\..\include\etl\base64.h">
<Filter>ETL\Codecs</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\u8string.h">
<Filter>ETL\Strings</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\u8string_stream.h">
<Filter>ETL\Strings</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\u8format_spec.h">
<Filter>ETL\Strings</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\to_u8string.h">
<Filter>ETL\Strings</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\test_string_char.cpp">
@ -2354,81 +2366,6 @@
<ClCompile Include="..\test_successor.cpp">
<Filter>Tests\Patterns</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc8_ebu.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc8_icode.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc8_itu.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc8_maxim.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc8_wcdma.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_a.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_arc.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_buypass.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_cdma2000.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_dds110.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_dectr.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_dectx.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_dnp.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_en13757.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_maxim.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_mcrf4xx.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_profibus.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_riello.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_t10dif.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_teledisk.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_tms37157.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc32_d.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc32_jamcrc.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc32_q.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc32_xfer.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\test_bit_stream_writer_big_endian.cpp">
<Filter>Tests\Binary</Filter>
</ClCompile>
@ -3299,6 +3236,36 @@
<ClCompile Include="..\syntax_check\base64.h.t.cpp">
<Filter>Tests\Syntax Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\test_string_u8.cpp">
<Filter>Tests\Strings</Filter>
</ClCompile>
<ClCompile Include="..\test_string_u8_external_buffer.cpp">
<Filter>Tests\Strings</Filter>
</ClCompile>
<ClCompile Include="..\syntax_check\u8string.h.t.cpp">
<Filter>Tests\Syntax Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\test_string_utilities_u8.cpp">
<Filter>Tests\Strings</Filter>
</ClCompile>
<ClCompile Include="..\test_string_utilities_std_u8.cpp">
<Filter>Tests\Strings</Filter>
</ClCompile>
<ClCompile Include="..\test_string_stream_u8.cpp">
<Filter>Tests\Strings</Filter>
</ClCompile>
<ClCompile Include="..\test_to_u8string.cpp">
<Filter>Tests\Strings</Filter>
</ClCompile>
<ClCompile Include="..\test_to_arithmetic_u8.cpp">
<Filter>Tests\Strings</Filter>
</ClCompile>
<ClCompile Include="..\syntax_check\u8format_spec.h.t.cpp">
<Filter>Tests\Syntax Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\syntax_check\u8string_stream.h.t.cpp">
<Filter>Tests\Syntax Checks\Source</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\library.properties">