diff --git a/include/etl/char_traits.h b/include/etl/char_traits.h index 96e4cfe1..f9b9247f 100644 --- a/include/etl/char_traits.h +++ b/include/etl/char_traits.h @@ -65,7 +65,6 @@ namespace etl typedef char state_type; }; -#if ETL_USING_CPP20 template<> struct char_traits_types { 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 { diff --git a/include/etl/platform.h b/include/etl/platform.h index d53d5460..294ee7cf 100644 --- a/include/etl/platform.h +++ b/include/etl/platform.h @@ -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 diff --git a/include/etl/string_utilities.h b/include/etl/string_utilities.h index e3df4698..459c5cb0 100644 --- a/include/etl/string_utilities.h +++ b/include/etl/string_utilities.h @@ -77,6 +77,17 @@ namespace etl } }; +#if ETL_USING_CPP20 + template <> + struct whitespace + { + static ETL_CONSTEXPR const char8_t* value() + { + return u8" \t\n\r\f\v"; + } + }; +#endif + template <> struct whitespace { diff --git a/include/etl/string_view.h b/include/etl/string_view.h index eebaefb9..a196b908 100644 --- a/include/etl/string_view.h +++ b/include/etl/string_view.h @@ -802,6 +802,7 @@ namespace etl typedef etl::basic_string_view string_view; typedef etl::basic_string_view wstring_view; + typedef etl::basic_string_view u8string_view; typedef etl::basic_string_view u16string_view; typedef etl::basic_string_view u32string_view; @@ -825,6 +826,15 @@ namespace etl return wstring_view(text, length); } + //*********************************** + template + ETL_CONSTEXPR14 u8string_view make_string_view(const char8_t(&text)[Array_Size]) + { + size_t length = etl::char_traits::length(text, Array_Size - 1U); + + return u8string_view(text, length); + } + //*********************************** template ETL_CONSTEXPR14 u16string_view make_string_view(const char16_t(&text)[Array_Size]) diff --git a/include/etl/to_u8string.h b/include/etl/to_u8string.h new file mode 100644 index 00000000..18a5caff --- /dev/null +++ b/include/etl/to_u8string.h @@ -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 etl::enable_if::value && !etl::is_same::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 etl::enable_if::value && !etl::is_same::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 etl::enable_if::value && !etl::is_same::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 etl::enable_if::value && !etl::is_same::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 etl::enable_if::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 etl::enable_if::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 etl::enable_if::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 etl::enable_if::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 diff --git a/include/etl/u8format_spec.h b/include/etl/u8format_spec.h new file mode 100644 index 00000000..6c66956b --- /dev/null +++ b/include/etl/u8format_spec.h @@ -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 u8format_spec; +} + +#endif diff --git a/include/etl/u8string.h b/include/etl/u8string.h new file mode 100644 index 00000000..f767cd74 --- /dev/null +++ b/include/etl/u8string.h @@ -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 + +#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 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 + 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(&buffer), MAX_SIZE) + { + this->initialise(); + } + + //************************************************************************* + /// Copy constructor. + ///\param other The other u8string. + //************************************************************************* + u8string(const etl::u8string& other) + : iu8string(reinterpret_cast(&buffer), MAX_SIZE) + { + this->assign(other); + } + + //************************************************************************* + /// From other iu8string. + ///\param other The other iu8string. + //************************************************************************* + u8string(const etl::iu8string& other) + : iu8string(reinterpret_cast(&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(&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(&buffer), MAX_SIZE) + { + this->assign(text, text + etl::char_traits::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(&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(&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 + u8string(TIterator first, TIterator last, typename etl::enable_if::value, int>::type = 0) + : iu8string(reinterpret_cast(&buffer), MAX_SIZE) + { + this->assign(first, last); + } + +#if ETL_HAS_INITIALIZER_LIST + //************************************************************************* + /// Construct from initializer_list. + //************************************************************************* + u8string(std::initializer_list init) + : iu8string(reinterpret_cast(&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(&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 substr(size_type position = 0, size_type length_ = npos) const + { + etl::u8string 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 + ETL_CONSTANT size_t u8string::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 + u8string_ext(TIterator first, TIterator last, value_type* buffer, size_type buffer_size, typename etl::enable_if::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 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 + { + size_t operator()(const etl::iu8string& text) const + { + return etl::private_hash::generic_hash(reinterpret_cast(text.data()), + reinterpret_cast(text.data() + text.size())); + } + }; + + template + struct hash > + { + size_t operator()(const etl::u8string& text) const + { + return etl::private_hash::generic_hash(reinterpret_cast(text.data()), + reinterpret_cast(text.data() + text.size())); + } + }; + + template <> + struct hash + { + size_t operator()(const etl::u8string_ext& text) const + { + return etl::private_hash::generic_hash(reinterpret_cast(text.data()), + reinterpret_cast(text.data() + text.size())); + } + }; +#endif + + //*************************************************************************** + /// Make u8string from u8string literal or array + //*************************************************************************** + template + etl::u8string make_string(const char(&text)[Array_Size]) + { + return etl::u8string(text, etl::strlen(text, Array_Size - 1)); + } + + //*************************************************************************** + /// Make u8string with max capacity from u8string literal or array + //*************************************************************************** + template + etl::u8string make_string_with_capacity(const char(&text)[SIZE]) + { + return etl::u8string(text, etl::strlen(text, SIZE)); + } +} +#endif + +#include "private/minmax_pop.h" + +#endif diff --git a/include/etl/u8string_stream.h b/include/etl/u8string_stream.h new file mode 100644 index 00000000..675f8022 --- /dev/null +++ b/include/etl/u8string_stream.h @@ -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 u8string_stream; +} + +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e8ecf183..70895b13 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -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 diff --git a/test/meson.build b/test/meson.build index eefedd14..c03e8cfc 100644 --- a/test/meson.build +++ b/test/meson.build @@ -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', diff --git a/test/syntax_check/c++03/CMakeLists.txt b/test/syntax_check/c++03/CMakeLists.txt index 7d5f43c1..3845a114 100644 --- a/test/syntax_check/c++03/CMakeLists.txt +++ b/test/syntax_check/c++03/CMakeLists.txt @@ -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 diff --git a/test/syntax_check/c++11/CMakeLists.txt b/test/syntax_check/c++11/CMakeLists.txt index 25a620bb..5b7e9e73 100644 --- a/test/syntax_check/c++11/CMakeLists.txt +++ b/test/syntax_check/c++11/CMakeLists.txt @@ -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 diff --git a/test/syntax_check/c++14/CMakeLists.txt b/test/syntax_check/c++14/CMakeLists.txt index 9c28613b..ec56d606 100644 --- a/test/syntax_check/c++14/CMakeLists.txt +++ b/test/syntax_check/c++14/CMakeLists.txt @@ -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 diff --git a/test/syntax_check/c++17/CMakeLists.txt b/test/syntax_check/c++17/CMakeLists.txt index 3c1fe0ba..c4776403 100644 --- a/test/syntax_check/c++17/CMakeLists.txt +++ b/test/syntax_check/c++17/CMakeLists.txt @@ -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 diff --git a/test/syntax_check/c++20/CMakeLists.txt b/test/syntax_check/c++20/CMakeLists.txt index 4d05bc19..ac005e03 100644 --- a/test/syntax_check/c++20/CMakeLists.txt +++ b/test/syntax_check/c++20/CMakeLists.txt @@ -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 diff --git a/test/syntax_check/u8format_spec.h.t.cpp b/test/syntax_check/u8format_spec.h.t.cpp new file mode 100644 index 00000000..2518b0a7 --- /dev/null +++ b/test/syntax_check/u8format_spec.h.t.cpp @@ -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 diff --git a/test/syntax_check/u8string.h.t.cpp b/test/syntax_check/u8string.h.t.cpp new file mode 100644 index 00000000..2230d9fc --- /dev/null +++ b/test/syntax_check/u8string.h.t.cpp @@ -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 diff --git a/test/syntax_check/u8string_stream.h.t.cpp b/test/syntax_check/u8string_stream.h.t.cpp new file mode 100644 index 00000000..398990aa --- /dev/null +++ b/test/syntax_check/u8string_stream.h.t.cpp @@ -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 diff --git a/test/test_string_stream_u8.cpp b/test/test_string_stream_u8.cpp new file mode 100644 index 00000000..10b08976 --- /dev/null +++ b/test/test_string_stream_u8.cpp @@ -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 +#include +#include + +#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(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 diff --git a/test/test_string_u8.cpp b/test/test_string_u8.cpp new file mode 100644 index 00000000..0e890387 --- /dev/null +++ b/test/test_string_u8.cpp @@ -0,0 +1,4473 @@ +/****************************************************************************** +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 +#include +#include + +#include "etl/u8string.h" + +#undef STR +#define STR(x) u8##x + +namespace +{ + bool compares_agree(int result1, int result2) + { + return ((result1 < 0) && (result2 < 0)) || + ((result1 == 0) && (result2 == 0)) || + ((result1 > 0) && (result2 > 0)); + } + + //*********************************** + //std::ostream& operator << (std::ostream& os, const etl::iu8string::value_type& c) + //{ + // os << uint16_t(c); + + // return os; + //} + + //*********************************** + //std::ostream& operator << (std::ostream& os, const etl::iu8string::value_type* c) + //{ + // os << (void*)c; + + // return os; + //} + + SUITE(test_string_char8_t) + { + static const size_t SIZE = 11; + + using Text = etl::u8string; + using IText = etl::iu8string; + using Compare_Text = std::u8string; + using value_t = Text::value_type; + using TextL = etl::u8string<52>; + using TextS = etl::u8string<4>; + + Compare_Text initial_text; + Compare_Text less_text; + Compare_Text greater_text; + Compare_Text shorter_text; + Compare_Text different_text; + Compare_Text insert_text; + Compare_Text longer_text; + Compare_Text short_text; + + const value_t* pinitial_text = STR("Hello World"); + + //************************************************************************* + template + bool Equal(const T1& compare_text, const T2& text) + { + return (compare_text.size() == text.size()) && std::equal(text.begin(), text.end(), compare_text.begin()); + } + + //************************************************************************* + struct SetupFixture + { + SetupFixture() + { + initial_text = STR("Hello World"); + initial_text = STR("Hello World"); + insert_text = STR("Insert"); + less_text = STR("Hello Vorld"); + greater_text = STR("Hello Xorld"); + shorter_text = STR("Hello Worl"); + different_text = STR("Byee Planet"); + longer_text = STR("Hello World There"); + short_text = STR("Hello"); + } + }; + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_default_constructor) + { + Text text; + + CHECK_EQUAL(text.size(), size_t(0)); + CHECK(text.empty()); + CHECK_EQUAL(text.capacity(), SIZE); + CHECK_EQUAL(text.max_size(), SIZE); + CHECK(text.begin() == text.end()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST(test_iterator_comparison_empty) + { + Text text; + + CHECK(text.begin() == text.end()); + CHECK(text.cbegin() == text.cend()); + CHECK(text.rbegin() == text.rend()); + CHECK(text.crbegin() == text.crend()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_size_value) + { + const size_t INITIAL_SIZE = 5; + const value_t INITIAL_VALUE = STR('A'); + + Compare_Text compare_text(INITIAL_SIZE, INITIAL_VALUE); + Text text(INITIAL_SIZE, INITIAL_VALUE); + + CHECK(text.size() == INITIAL_SIZE); + CHECK(!text.empty()); + + bool is_equal = Equal(compare_text, text); + + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_size_excess) + { + Text text(SIZE + 1, STR('A')); + + CHECK_EQUAL(SIZE, text.size()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_char_pointer) + { + Compare_Text compare_text(initial_text.c_str()); + + Text text(initial_text.c_str()); + + CHECK(!text.empty()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_excess) + { + Compare_Text compare_text(initial_text.c_str()); + + Text text(longer_text.c_str()); + + CHECK(!text.empty()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_size) + { + Compare_Text compare_text(SIZE, STR('A')); + + Text text(SIZE, STR('A')); + + CHECK(!text.empty()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_size_excess) + { + Compare_Text compare_text(SIZE, STR('A')); + + Text text(SIZE + 1, STR('A')); + + CHECK(!text.empty()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_size_char) + { + Compare_Text compare_text(initial_text.c_str(), initial_text.size() / 2); + + Text text(initial_text.c_str(), initial_text.size() / 2); + + CHECK(!text.empty()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_size_char_excess) + { + Compare_Text compare_text(initial_text.c_str(), initial_text.size()); + + Text text(longer_text.c_str(), longer_text.size()); + + CHECK(!text.empty()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_range) + { + Compare_Text compare_text(initial_text.begin(), initial_text.end()); + + Text text(compare_text.begin(), compare_text.end()); + + CHECK(text.size() == SIZE); + CHECK(!text.empty()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_range_excess) + { + Text text(longer_text.begin(), longer_text.end()); + + bool is_equal = Equal(initial_text, text); + CHECK(is_equal); + CHECK(text.size() == SIZE); + CHECK(!text.empty()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_from_literal) + { + Text text(STR("Hello World")); + + bool is_equal = Equal(initial_text, text); + CHECK(is_equal); + CHECK(text.size() == SIZE); + CHECK(!text.empty()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_from_string_view) + { + etl::u8string_view view(initial_text.data(), initial_text.size()); + Text text(view); + + bool is_equal = Equal(initial_text, text); + CHECK(is_equal); + CHECK(text.size() == SIZE); + CHECK(!text.empty()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_copy_constructor) + { + Text text(initial_text.c_str()); + Text text2(text); + CHECK(text2 == text); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text2.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_copy_constructor_i) + { + Text text(initial_text.c_str()); + IText& itext = text; + Text text2(itext); + CHECK(text2 == text); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text2.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_copy_constructor_excess) + { + Text text(initial_text.c_str()); + TextL textl(longer_text.c_str()); + Text text2(textl); + CHECK(text2 == text); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text2.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_copy_constructor_from_truncated) + { + Text text(longer_text.c_str()); + Text text2(text); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text2.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_construct_position_length) + { + Compare_Text compare_text(initial_text.c_str()); + Compare_Text compare_text2(compare_text, 2, 4); + + Text text(initial_text.c_str()); + Text text2(text, 2, 4); + + bool is_equal = Equal(compare_text2, text2); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text2.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_construct_position_length_excess) + { + Compare_Text compare_text(longer_text.c_str()); + Compare_Text compare_text2(compare_text, 2, 11); + + TextL textl(longer_text.c_str()); + Text text2(textl, 2, 12); + + bool is_equal = Equal(compare_text2, text2); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text2.is_truncated()); +#endif + } + +#if ETL_HAS_INITIALIZER_LIST + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_construct_initializer_list) + { + Compare_Text compare_text = { STR('H'), STR('e'), STR('l') , STR('l') , STR('o') }; + Text text = { STR('H'), STR('e'), STR('l') , STR('l') , STR('o') }; + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_construct_initializer_list_excess) + { + Compare_Text compare_text = { STR('H'), STR('e'), STR('l'), STR('l'), STR('o'), STR(' '), + STR('W'), STR('o'), STR('r'), STR('l'), STR('d') }; + Text text = { STR('H'), STR('e'), STR('l'), STR('l'), STR('o'), STR(' '), + STR('W'), STR('o'), STR('r'), STR('l'), STR('d'), STR(' '), + STR('T'), STR('h'), STR('e'), STR('r'), STR('e') }; + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } +#endif + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment) + { + Text text(initial_text.begin(), initial_text.end()); + Text other_text; + + other_text = text; + + bool is_equal = Equal(text, other_text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); + CHECK(!other_text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment_excess) + { + Text text(longer_text.begin(), longer_text.end()); + Text other_text; + + other_text = text; + + bool is_equal = Equal(text, other_text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); + CHECK(other_text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment_iterface) + { + Text text1(initial_text.begin(), initial_text.end()); + Text text2; + + IText& itext1 = text1; + IText& itext2 = text2; + + itext2 = itext1; + + bool is_equal = Equal(text1, text2); + + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text1.is_truncated()); + CHECK(!text2.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment_iterface_excess) + { + Text text1(longer_text.begin(), longer_text.end()); + Text text2; + + IText& itext1 = text1; + IText& itext2 = text2; + + itext2 = itext1; + + bool is_equal = Equal(text1, text2); + + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text1.is_truncated()); + CHECK(text2.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_self_assignment) + { + Text text(initial_text.begin(), initial_text.end()); + Text other_text(text); + +#include "etl/private/diagnostic_self_assign_overloaded_push.h" + other_text = other_text; +#include "etl/private/diagnostic_pop.h" + + bool is_equal = Equal(text, other_text); + + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); + CHECK(!other_text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_self_assignment_excess) + { + Text text(longer_text.begin(), longer_text.end()); + Text other_text(text); + +#include "etl/private/diagnostic_self_assign_overloaded_push.h" + other_text = other_text; +#include "etl/private/diagnostic_pop.h" + + bool is_equal = Equal(text, other_text); + + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); + CHECK(other_text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment_from_literal) + { + Text text; + + text = STR("Hello World"); + + bool is_equal = Equal(std::u8string(STR("Hello World")), text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment_from_literal_excess) + { + Text text; + + text = STR("Hello World There"); + + bool is_equal = Equal(std::u8string(STR("Hello World")), text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment_from_literal_via_interface) + { + Text text; + IText& itext = text; + + itext = STR("Hello World"); + + bool is_equal = Equal(std::u8string(STR("Hello World")), itext); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!itext.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment_from_literal_via_interface_excess) + { + Text text; + IText& itext = text; + + itext = STR("Hello World There"); + + bool is_equal = Equal(std::u8string(STR("Hello World")), itext); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(itext.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_begin) + { + Text text(initial_text.c_str()); + const Text constText(initial_text.c_str()); + + CHECK_EQUAL(&text[0], text.begin()); + CHECK_EQUAL(&constText[0], constText.begin()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_end) + { + Text text(initial_text.c_str()); + const Text constText(initial_text.c_str()); + + CHECK_EQUAL(&text[initial_text.size()], text.end()); + CHECK_EQUAL(&constText[initial_text.size()], constText.end()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_resize_up) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = 8; + + Text text(initial_text.c_str(), INITIAL_SIZE); + text.resize(NEW_SIZE); + + CHECK_EQUAL(text.size(), NEW_SIZE); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_resize_up_value) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = 8; + const value_t INITIAL_VALUE = STR('A'); + + Text text(INITIAL_SIZE, INITIAL_VALUE); + text.resize(NEW_SIZE, INITIAL_VALUE); + + std::array compare_text; + compare_text.fill(INITIAL_VALUE); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_resize_excess) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = SIZE + 1; + + Text text(INITIAL_SIZE, STR('A')); + text.resize(NEW_SIZE, STR('A')); + CHECK_EQUAL(SIZE, text.size()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_resize_down) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = 2; + + Text text(INITIAL_SIZE, STR('A')); + text.resize(NEW_SIZE); + + CHECK_EQUAL(text.size(), NEW_SIZE); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_resize_down_value) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = 2; + const value_t INITIAL_VALUE = STR('A'); + + Text text(INITIAL_SIZE, INITIAL_VALUE); + text.resize(NEW_SIZE, INITIAL_VALUE); + + CHECK_EQUAL(text.size(), NEW_SIZE); + + std::array compare_text; + compare_text.fill(INITIAL_VALUE); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_uninitialized_resize_up) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = 8; + const value_t INITIAL_VALUE = STR('A'); + const value_t FILL_VALUE = STR('B'); + + Text text(INITIAL_SIZE, INITIAL_VALUE); + + Text::pointer pbegin = &text.front(); + Text::pointer pend = &text.back() + 1; + Text::pointer pmax = pbegin + text.max_size(); + + // Fill free space with a pattern. + std::fill(pend, pmax, FILL_VALUE); + + text.uninitialized_resize(NEW_SIZE); + + std::array compare_text; + compare_text.fill(FILL_VALUE); + std::fill(compare_text.begin(), compare_text.begin() + INITIAL_SIZE, INITIAL_VALUE); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); + + CHECK_EQUAL(text.size(), NEW_SIZE); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_uninitialized_resize_up_excess) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = SIZE + 1; + + Text text(INITIAL_SIZE, STR('A')); + + text.uninitialized_resize(NEW_SIZE); + + CHECK_EQUAL(text.size(), SIZE); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_uninitialized_resize_down) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = 2; + const value_t INITIAL_VALUE = STR('A'); + const value_t FILL_VALUE = STR('B'); + + Text text(INITIAL_SIZE, INITIAL_VALUE); + + Text::pointer pbegin = &text.front(); + Text::pointer pend = &text.back() + 1; + Text::pointer pmax = pbegin + text.max_size(); + + // Fill free space with a pattern. + std::fill(pend, pmax, FILL_VALUE); + + text.uninitialized_resize(NEW_SIZE); + + std::array compare_text; + compare_text.fill(INITIAL_VALUE); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); + + CHECK_EQUAL(text.size(), NEW_SIZE); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_fill) + { + Text text(SIZE, STR('A')); + Text expected(SIZE, STR('B')); + + text.fill(STR('B')); + + bool is_equal = Equal(expected, text); + CHECK(is_equal); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_empty_full) + { + Text text; + text.resize(text.max_size(), STR('A')); + + CHECK(!text.empty()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_empty_half) + { + Text text; + text.resize(text.max_size() / 2, STR('A')); + + CHECK(!text.empty()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_empty_empty) + { + Text text; + + CHECK(text.empty()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_full_full) + { + Text text; + text.resize(text.max_size(), STR('A')); + + CHECK(text.full()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_full_half) + { + Text text; + text.resize(text.max_size() / 2, STR('A')); + + CHECK(!text.full()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_full_empty) + { + Text text; + + CHECK(!text.full()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_index) + { + Compare_Text compare_text(initial_text.c_str()); + Text text(initial_text.c_str()); + + for (size_t i = 0UL; i < text.size(); ++i) + { + CHECK_EQUAL(text[i], compare_text[i]); + } + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_index_const) + { + const Compare_Text compare_text(initial_text.c_str()); + const Text text(initial_text.c_str()); + + for (size_t i = 0UL; i < text.size(); ++i) + { + CHECK_EQUAL(text[i], compare_text[i]); + } + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_at) + { + Compare_Text compare_text(initial_text.c_str()); + Text text(initial_text.c_str()); + + for (size_t i = 0UL; i < text.size(); ++i) + { + CHECK_EQUAL(text.at(i), compare_text.at(i)); + } + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + CHECK_THROW(text.at(text.size()), etl::string_out_of_bounds); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_at_const) + { + const Compare_Text compare_text(initial_text.c_str()); + const Text text(initial_text.c_str()); + + for (size_t i = 0UL; i < text.size(); ++i) + { + CHECK_EQUAL(text.at(i), compare_text.at(i)); + } + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + CHECK_THROW(text.at(text.size()), etl::string_out_of_bounds); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_front) + { + Compare_Text compare_text(initial_text.c_str()); + Text text(initial_text.c_str()); + + CHECK(text.front() == compare_text.front()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_front_const) + { + const Compare_Text compare_text(initial_text.c_str()); + const Text text(initial_text.c_str()); + + CHECK(text.front() == compare_text.front()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_back) + { + Compare_Text compare_text(initial_text.c_str()); + Text text(initial_text.c_str()); + + CHECK(text.back() == compare_text.back()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_back_const) + { + const Compare_Text compare_text(initial_text.c_str()); + const Text text(initial_text.c_str()); + + CHECK(text.back() == compare_text.back()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_data) + { + Compare_Text compare_text(initial_text.c_str()); + + Text text(compare_text.begin(), compare_text.end()); + + bool is_equal = std::equal(text.data(), + text.data() + text.size(), + compare_text.begin()); + + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_data_const) + { + Compare_Text compare_text(initial_text.c_str()); + + const Text text(compare_text.begin(), compare_text.end()); + + bool is_equal = std::equal(text.data(), + text.data() + text.size(), + compare_text.begin()); + + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_string) + { + Compare_Text compare_input(initial_text.c_str()); + Text input(initial_text.c_str()); + + Compare_Text compare_text; + Text text; + + compare_text.assign(compare_input); + text.assign(input); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_string_excess) + { + Compare_Text compare_input(initial_text.c_str()); + TextL input(longer_text.c_str()); + + Compare_Text compare_text; + Text text; + + compare_text.assign(compare_input); + text.assign(input); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_pointer) + { + Compare_Text compare_text(initial_text.c_str()); + + Text text; + text.assign(initial_text.c_str()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_pointer_excess) + { + Compare_Text compare_text(initial_text.c_str()); + + Text text; + text.assign(longer_text.c_str()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_pointer_length) + { + Compare_Text compare_text(initial_text.c_str()); + + Text text; + text.assign(initial_text.c_str(), initial_text.size()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_pointer_length_excess) + { + Compare_Text compare_text(longer_text.c_str()); + + Text text; + text.assign(longer_text.c_str(), longer_text.size()); + + compare_text.resize(text.max_size()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_range) + { + Compare_Text compare_text(initial_text.c_str()); + + Text text; + + text.assign(compare_text.begin(), compare_text.end()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_range_excess) + { + Text text; + + text.assign(longer_text.begin(), longer_text.end()); + + CHECK_EQUAL(initial_text.size(), text.size()); + + bool is_equal = Equal(initial_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_size_value) + { + const size_t INITIAL_SIZE = 5; + const value_t INITIAL_VALUE = STR('A'); + + std::array compare_text; + compare_text.fill(INITIAL_VALUE); + + Text text; + text.assign(INITIAL_SIZE, INITIAL_VALUE); + + CHECK(text.size() == INITIAL_SIZE); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_size_value_excess) + { + const size_t INITIAL_SIZE = SIZE; + const size_t EXCESS_SIZE = SIZE + 1; + const value_t INITIAL_VALUE = STR('A'); + std::array compare_text; + compare_text.fill(INITIAL_VALUE); + + Text text; + text.assign(EXCESS_SIZE, INITIAL_VALUE); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_push_back) + { + Compare_Text compare_text; + Text text; + + for (size_t i = 0UL; i < SIZE; ++i) + { + compare_text.push_back(STR('A') + value_t(i)); + } + + for (size_t i = 0UL; i < SIZE; ++i) + { + text.push_back(STR('A') + value_t(i)); + } + + CHECK_EQUAL(etl::strlen(compare_text.data()), etl::strlen(text.data())); + CHECK_EQUAL(compare_text.size(), text.size()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_push_back_excess) + { + Compare_Text compare_text; + Text text; + + for (size_t i = 0UL; i < SIZE; ++i) + { + compare_text.push_back(STR('A') + value_t(i)); + } + + for (size_t i = 0UL; i < SIZE; ++i) + { + text.push_back(STR('A') + value_t(i)); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + text.push_back(STR('A') + value_t(SIZE)); + + CHECK_EQUAL(etl::strlen(compare_text.data()), etl::strlen(text.data())); + CHECK_EQUAL(compare_text.size(), text.size()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_pop_back) + { + Compare_Text compare_text(initial_text.c_str()); + Text text(initial_text.c_str()); + + compare_text.pop_back(); + compare_text.pop_back(); + + text.pop_back(); + text.pop_back(); + + CHECK_EQUAL(compare_text.size(), text.size()); + + bool is_equal = Equal(compare_text, text); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_value) + { + const size_t INITIAL_SIZE = 5; + const value_t INITIAL_VALUE = STR('A'); + + for (size_t offset = 0; offset <= INITIAL_SIZE; ++offset) + { + Compare_Text compare_text; + Text text; + + text.assign(initial_text.begin(), initial_text.begin() + INITIAL_SIZE); + compare_text.assign(initial_text.begin(), initial_text.begin() + INITIAL_SIZE); + + text.insert(text.begin() + offset, INITIAL_VALUE); + compare_text.insert(compare_text.begin() + offset, INITIAL_VALUE); + + CHECK_EQUAL(compare_text.size(), text.size()); + + bool is_equal = Equal(compare_text, text); + + CHECK(is_equal); + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_value_excess) + { + Compare_Text compare_text(initial_text.begin(), initial_text.end()); + Text text(initial_text.begin(), initial_text.end()); + + const value_t INITIAL_VALUE = STR('A'); + + size_t offset = 2; + text.insert(text.begin() + offset, INITIAL_VALUE); + compare_text.insert(compare_text.begin() + offset, INITIAL_VALUE); + compare_text.erase(compare_text.end() - 1); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); + + offset = 0; + text.insert(text.begin() + offset, STR('A')); + compare_text.insert(compare_text.begin() + offset, STR('A')); + compare_text.erase(compare_text.end() - 1); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + is_equal = Equal(compare_text, text); + CHECK(is_equal); + + offset = text.size(); + text.insert(text.begin() + offset, STR('A')); + compare_text.insert(compare_text.begin() + offset, STR('A')); + compare_text.erase(compare_text.end() - 1); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + is_equal = Equal(compare_text, text); + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_n_value) + { + Compare_Text compare_text; + Text text; + + const size_t INITIAL_SIZE = 5; + const size_t INSERT_SIZE = 3; + const value_t INITIAL_VALUE = STR('A'); + + for (size_t offset = 0; offset <= INITIAL_SIZE; ++offset) + { + text.assign(initial_text.begin(), initial_text.begin() + INITIAL_SIZE); + compare_text.assign(initial_text.begin(), initial_text.begin() + INITIAL_SIZE); + text.insert(text.begin() + offset, INSERT_SIZE, INITIAL_VALUE); + compare_text.insert(compare_text.begin() + offset, INSERT_SIZE, INITIAL_VALUE); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_n_value_excess) + { + Compare_Text compare_text; + Text text; + + const size_t INSERT_SIZE = 4; + const value_t INSERT_VALUE = STR('A'); + + size_t offset = 0; + compare_text.assign(initial_text.begin(), initial_text.end()); + text.assign(initial_text.begin(), initial_text.end()); + compare_text.insert(compare_text.begin() + offset, INSERT_SIZE, INSERT_VALUE); + compare_text.erase(compare_text.end() - INSERT_SIZE, compare_text.end()); + text.insert(text.begin() + offset, INSERT_SIZE, INSERT_VALUE); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); + + offset = 2; + compare_text.assign(initial_text.begin(), initial_text.end()); + text.assign(initial_text.begin(), initial_text.end()); + compare_text.insert(compare_text.begin() + offset, INSERT_SIZE, INSERT_VALUE); + compare_text.erase(compare_text.end() - INSERT_SIZE, compare_text.end()); + text.assign(initial_text.begin(), initial_text.end()); + text.insert(text.begin() + offset, INSERT_SIZE, INSERT_VALUE); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + is_equal = Equal(compare_text, text); + CHECK(is_equal); + + offset = 4; + compare_text.assign(initial_text.begin(), initial_text.end()); + text.assign(initial_text.begin(), initial_text.end()); + compare_text.insert(compare_text.begin() + offset, INSERT_SIZE, INSERT_VALUE); + compare_text.erase(compare_text.end() - INSERT_SIZE, compare_text.end()); + text.assign(initial_text.begin(), initial_text.end()); + text.insert(text.begin() + offset, INSERT_SIZE, INSERT_VALUE); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + is_equal = Equal(compare_text, text); + CHECK(is_equal); + + offset = text.size(); + compare_text.assign(initial_text.begin(), initial_text.end()); + text.assign(initial_text.begin(), initial_text.end()); + compare_text.insert(compare_text.begin() + offset, INSERT_SIZE, INSERT_VALUE); + compare_text.erase(compare_text.end() - INSERT_SIZE, compare_text.end()); + text.assign(initial_text.begin(), initial_text.end()); + text.insert(text.begin() + offset, INSERT_SIZE, INSERT_VALUE); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + is_equal = Equal(compare_text, text); + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_range) + { + const size_t INITIAL_SIZE = 5; + + for (size_t offset = 0; offset <= INITIAL_SIZE; ++offset) + { + Compare_Text compare_text; + Text text; + + text.assign(initial_text.begin(), initial_text.begin() + INITIAL_SIZE); + compare_text.assign(initial_text.begin(), initial_text.begin() + INITIAL_SIZE); + text.insert(text.begin() + offset, insert_text.begin(), insert_text.end()); + compare_text.insert(compare_text.begin() + offset, insert_text.begin(), insert_text.end()); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_range_excess) + { + const size_t INITIAL_SIZE = 5; + const value_t INITIAL_VALUE = STR('A'); + + Compare_Text compare_text; + Text text; + + size_t offset = 0; + + compare_text.assign(INITIAL_SIZE, INITIAL_VALUE); + text.assign(INITIAL_SIZE, INITIAL_VALUE); + compare_text.insert(compare_text.begin() + offset, initial_text.begin(), initial_text.end()); + compare_text.resize(initial_text.size()); + text.insert(text.begin() + offset, initial_text.begin(), initial_text.end()); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); + + offset = 2; + + compare_text.assign(INITIAL_SIZE, INITIAL_VALUE); + text.assign(INITIAL_SIZE, INITIAL_VALUE); + compare_text.insert(compare_text.begin() + offset, initial_text.begin(), initial_text.end()); + compare_text.resize(initial_text.size()); + text.insert(text.begin() + offset, initial_text.begin(), initial_text.end()); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + is_equal = Equal(compare_text, text); + CHECK(is_equal); + + + offset = 4; + + compare_text.assign(INITIAL_SIZE, INITIAL_VALUE); + text.assign(INITIAL_SIZE, INITIAL_VALUE); + compare_text.insert(compare_text.begin() + offset, initial_text.begin(), initial_text.end()); + compare_text.resize(initial_text.size()); + text.insert(text.begin() + offset, initial_text.begin(), initial_text.end()); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + CHECK_EQUAL(compare_text.size(), text.size()); + is_equal = Equal(compare_text, text); + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_range_self) + { + size_t length = TextL::MAX_SIZE / 2; + + for (size_t offset = 10; offset < length; ++offset) + { + Compare_Text compare_text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + TextL text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + + text.insert(text.begin() + offset, text.begin() + 5, text.begin() + 10); + compare_text.insert(compare_text.begin() + offset, compare_text.begin() + 5, compare_text.begin() + 10); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_size_t_position_string) + { + for (size_t offset = 0; offset <= short_text.size(); ++offset) + { + Compare_Text compare_text(short_text.begin(), short_text.end()); + Text text(short_text.begin(), short_text.end()); + Text insert(insert_text.begin(), insert_text.end()); + + text.insert(offset, insert); + compare_text.insert(offset, insert_text); + compare_text.resize(std::min(compare_text.size(), SIZE)); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_size_t_position_string_excess) + { + for (size_t offset = 0; offset <= initial_text.size(); ++offset) + { + Compare_Text compare_text(initial_text.begin(), initial_text.end()); + Text text(initial_text.begin(), initial_text.end()); + Text insert(insert_text.begin(), insert_text.end()); + + text.insert(offset, insert); + compare_text.insert(offset, insert_text); + compare_text.resize(std::min(compare_text.size(), SIZE)); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_size_t_position_string_from_truncated) + { + for (size_t offset = 0; offset <= short_text.size(); ++offset) + { + Compare_Text compare_text(short_text.begin(), short_text.end()); + Text text(short_text.begin(), short_text.end()); + Text insert(longer_text.begin(), longer_text.end()); + insert.erase(insert.begin(), insert.end()); + insert.append(insert_text.begin(), insert_text.end()); + + text.insert(offset, insert); + compare_text.insert(offset, insert_text); + compare_text.resize(std::min(compare_text.size(), SIZE)); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_size_t_position_string_subpos_sunlen) + { + Compare_Text compare_text(short_text.begin(), short_text.end()); + Text text(short_text.begin(), short_text.end()); + Text insert(insert_text.begin(), insert_text.end()); + + text.insert(0, insert, 0, insert.size()); + compare_text.insert(0, insert_text, 0, insert_text.size()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + compare_text.assign(short_text.begin(), short_text.end()); + text.assign(short_text.begin(), short_text.end()); + + text.insert(2, insert, 2, insert.size() - 2); + compare_text.insert(2, insert_text, 2, insert_text.size() - 2); + compare_text.resize(std::min(compare_text.size(), SIZE)); + + CHECK_EQUAL(compare_text.size(), text.size()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + compare_text.assign(short_text.begin(), short_text.end()); + text.assign(short_text.begin(), short_text.end()); + + text.insert(short_text.size(), insert, 0, insert.size()); + compare_text.insert(short_text.size(), insert_text, 0, insert_text.size()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_append_string) + { + Compare_Text compare_text(short_text.c_str()); + Text text(short_text.c_str()); + Text append(insert_text.c_str()); + + // Non-overflow. + compare_text.append(insert_text); + text.append(append); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + append.assign(initial_text.c_str()); + + compare_text.append(initial_text); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.append(append); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_append_truncated_string) + { +#include "etl/private/diagnostic_array_bounds_push.h" + Text text(short_text.c_str()); + TextS append(short_text.c_str()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(append.is_truncated()); +#endif + + text.append(append); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_append_string_to_self) + { + Compare_Text compare_text(short_text.c_str()); + Text text(short_text.c_str()); + + // Non-overflow. + compare_text.append(compare_text); + text.append(text); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(shorter_text.c_str()); + text.assign(shorter_text.c_str()); + + compare_text.append(compare_text); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.append(text); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_append_string_subpos_sublen) + { + Compare_Text compare_text(short_text.c_str()); + Text text(short_text.c_str()); + Text append(insert_text.c_str()); + + // Whole string. + compare_text.append(insert_text, 0, std::u8string::npos); + text.append(append, 0, Text::npos); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Partial string. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + append.assign(initial_text.c_str()); + + compare_text.append(short_text, 1, 3); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.append(append, 1, 3); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + append.assign(initial_text.c_str()); + + compare_text.append(initial_text, 1, initial_text.size() - 1); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.append(append, 1, append.size() - 1); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_append_truncated_string_subpos_sublen) + { + Text text(short_text.c_str()); + TextS append(short_text.c_str()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(append.is_truncated()); +#endif + + text.append(append, 1, 2); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_append_c_string) + { + // Non-overflow. + Compare_Text compare_text(short_text.c_str()); + Text text(short_text.c_str()); + + // Whole string. + compare_text.append(insert_text.c_str()); + text.append(insert_text.c_str()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.append(initial_text.c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.append(initial_text.c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_append_n_c) + { + // Non-overflow. + Compare_Text compare_text(short_text.c_str()); + Text text(short_text.c_str()); + + // Non-overflow. + compare_text.append(5, STR('A')); + text.append(5, STR('A')); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.append(SIZE, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.append(SIZE, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_append_range) + { + // Non-overflow. + Compare_Text compare_text(short_text.c_str()); + Text text(short_text.c_str()); + Text append(insert_text.c_str()); + + compare_text.append(insert_text.begin(), insert_text.end()); + text.append(append.begin(), append.end()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + append.assign(initial_text.c_str()); + + compare_text.append(initial_text.begin(), initial_text.end()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.append(append.begin(), append.end()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_position_length_string) + { + // Non-overflow short text, npos. + Compare_Text compare_text(short_text.c_str()); + Text text(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, Text(STR("Replace"))); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Non-overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, 2, Compare_Text(STR("Replace"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 2, Text(STR("Replace"))); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, 2, Compare_Text(STR("Replace with some text"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 2, Text(STR("Replace with some text"))); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow short text, npos. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace with some text"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, Text(STR("Replace with some text"))); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 7, Compare_Text(STR("Replace"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 7, Text(STR("Replace"))); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 2, Compare_Text(STR("Replace with some text"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 2, Text(STR("Replace with some text"))); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow, npos. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace with some text"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, Text(STR("Replace with some text"))); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_first_last_string) + { + // Non-overflow short text. + Compare_Text compare_text(short_text.c_str()); + Text text(short_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, Compare_Text(STR("Replace"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, Text(STR("Replace"))); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, Compare_Text(STR("Replace with some text"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, Text(STR("Replace with some text"))); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 9, Compare_Text(STR("Replace"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 9, Text(STR("Replace"))); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, Compare_Text(STR("Replace with some text"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, Text(STR("Replace with some text"))); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_position_length_string_subposition_sublength) + { + // Non-overflow short text. + Compare_Text compare_text(short_text.c_str()); + Text text(short_text.c_str()); + + compare_text.replace(2, 4, Compare_Text(STR("Replace")), 1, 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, Text(STR("Replace")), 1, 5); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Non-overflow short text, npos. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace")), 1, Compare_Text::npos); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, Text(STR("Replace")), 1, Text::npos); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, 4, Compare_Text(STR("Replace with some text")), 1, 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, Text(STR("Replace with some text")), 1, 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow short text, npos. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace with some text")), 1, Compare_Text::npos); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, Text(STR("Replace with some text")), 1, Text::npos); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 7, Compare_Text(STR("Replace")), 1, 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 7, Text(STR("Replace")), 1, 5); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Non-overflow, npos. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace")), 1, Compare_Text::npos); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, Text(STR("Replace")), 1, Text::npos); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 4, Compare_Text(STR("Replace with some text")), 1, 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, Text(STR("Replace with some text")), 1, 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow, npos. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace with some text")), 1, Compare_Text::npos); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, Text(STR("Replace with some text")), 1, Text::npos); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_position_length_pointer) + { + // Non-overflow short text. + Compare_Text compare_text(short_text.c_str()); + Text text(short_text.c_str()); + + compare_text.replace(2, 4, Compare_Text(STR("Replace")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, Text(STR("Replace")).c_str()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Non-overflow short text, npos. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, Text(STR("Replace")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, 4, Compare_Text(STR("Replace with some text")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, Text(STR("Replace with some text")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow short text, npos. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace with some text")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, Text(STR("Replace with some text")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 7, Compare_Text(STR("Replace")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 7, Text(STR("Replace")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Non-overflow, npos. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, Text(STR("Replace")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 4, Compare_Text(STR("Replace with some text")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, Text(STR("Replace with some text")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow, npos. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace with some text")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, Text(STR("Replace with some text")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_first_last_pointer) + { + // Non-overflow short text. + Compare_Text compare_text(short_text.c_str()); + Text text(short_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, Compare_Text(STR("Replace")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, Text(STR("Replace")).c_str()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, Compare_Text(STR("Replace with some text")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, Text(STR("Replace with some text")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 9, Compare_Text(STR("Replace")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 9, Text(STR("Replace")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, Compare_Text(STR("Replace with some text")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, Text(STR("Replace with some text")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_position_length_pointer_n) + { + // Non-overflow short text. + Compare_Text compare_text(short_text.c_str()); + Text text(short_text.c_str()); + + compare_text.replace(2, 4, Compare_Text(STR("Replace")).c_str(), 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, Text(STR("Replace")).c_str(), 5); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Non-overflow short text, npos. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace")).c_str(), 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, Text(STR("Replace")).c_str(), 5); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, 4, Compare_Text(STR("Replace with some text")).c_str(), 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, Text(STR("Replace with some text")).c_str(), 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow short text, npos. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace with some text")).c_str(), 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, Text(STR("Replace with some text")).c_str(), 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 7, Compare_Text(STR("Replace")).c_str(), 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 7, Text(STR("Replace")).c_str(), 5); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Non-overflow, npos. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace")).c_str(), 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, Text(STR("Replace")).c_str(), 5); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 4, Compare_Text(STR("Replace with some text")).c_str(), 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, Text(STR("Replace with some text")).c_str(), 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow, npos. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace with some text")).c_str(), 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, Text(STR("Replace with some text")).c_str(), 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_first_last_pointer_n) + { + // Non-overflow short text. + Compare_Text compare_text(short_text.c_str()); + Text text(short_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, Compare_Text(STR("Replace")).c_str(), 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, Text(STR("Replace")).c_str(), 5); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + +#include "etl/private/diagnostic_array_bounds_push.h" +#include "etl/private/diagnostic_stringop_overread_push.h" + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, Compare_Text(STR("Replace with some text")).c_str(), 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, Text(STR("Replace with some text")).c_str(), 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif +#include "etl/private/diagnostic_pop.h" +#include "etl/private/diagnostic_pop.h" + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 9, Compare_Text(STR("Replace")).c_str(), 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 9, Text(STR("Replace")).c_str(), 5); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + +#include "etl/private/diagnostic_array_bounds_push.h" +#include "etl/private/diagnostic_stringop_overread_push.h" + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, Compare_Text(STR("Replace with some text")).c_str(), 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, Text(STR("Replace with some text")).c_str(), 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif +#include "etl/private/diagnostic_pop.h" +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_position_length_n_c) + { + // Non-overflow short text. + Compare_Text compare_text(short_text.c_str()); + Text text(short_text.c_str()); + + compare_text.replace(2, 4, 7, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, 7, STR('A')); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Non-overflow short text, npos. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, 7, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, 7, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, 4, 15, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, 15, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow short text, npos. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, 15, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, 15, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 7, 7, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 7, 7, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Non-overflow, npos. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, 7, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, 7, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 4, 15, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, 15, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow, npos. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, 15, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, 15, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_first_last_n_c) + { + // Non-overflow short text. + Compare_Text compare_text(short_text.c_str()); + Text text(short_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, 7, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, 7, STR('A')); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, 15, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, 15, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 9, 7, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 9, 7, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, 15, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, 15, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_first_last_first_last) + { + // Non-overflow short text. + Compare_Text compare_text(short_text.c_str()); + Text text(short_text.c_str()); + + Compare_Text replace(STR("Replace")); + Compare_Text replace_long(STR("Replace with some text")); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, replace.begin() + 1, replace.begin() + 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, replace.begin() + 1, replace.begin() + 5); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, replace_long.begin() + 1, replace_long.begin() + 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, replace_long.begin() + 1, replace_long.begin() + 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 7, replace.begin() + 1, replace.begin() + 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 7, replace_long.begin() + 1, replace_long.begin() + 5); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, replace_long.begin() + 1, replace_long.begin() + 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, replace_long.begin() + 1, replace_long.begin() + 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_erase_single_iterator) + { + Compare_Text compare_text(initial_text.c_str()); + Text text(initial_text.c_str()); + + Compare_Text::iterator citr = compare_text.erase(compare_text.begin() + 2); + Text::iterator ditr = text.erase(text.begin() + 2); + CHECK(*citr == *ditr); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_erase_single_const_iterator) + { + Compare_Text compare_text(initial_text.c_str()); + Text text(initial_text.c_str()); + + Compare_Text::iterator citr = compare_text.erase(compare_text.cbegin() + 2); + Text::iterator ditr = text.erase(text.cbegin() + 2); + CHECK(*citr == *ditr); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_erase_range) + { + Compare_Text compare_text(initial_text.c_str()); + Text text(initial_text.c_str()); + + Compare_Text::iterator citr = compare_text.erase(compare_text.cbegin() + 2, compare_text.cbegin() + 4); + Text::iterator ditr = text.erase(text.cbegin() + 2, text.cbegin() + 4); + CHECK(*citr == *ditr); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_clear) + { + Text text(initial_text.c_str()); + text.clear(); + + CHECK_EQUAL(text.size(), size_t(0)); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_iterator) + { + Compare_Text compare_text(initial_text.c_str()); + Text text(initial_text.c_str()); + + bool is_equal = std::equal(text.begin(), text.end(), compare_text.begin()); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_const_iterator) + { + Compare_Text compare_text(initial_text.c_str()); + Text text(initial_text.c_str()); + + bool is_equal = std::equal(text.cbegin(), text.cend(), compare_text.cbegin()); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_reverse_iterator) + { + Compare_Text compare_text(initial_text.c_str()); + Text text(initial_text.c_str()); + + bool is_equal = std::equal(text.rbegin(), text.rend(), compare_text.rbegin()); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_const_reverse_iterator) + { + Compare_Text compare_text(initial_text.c_str()); + Text text(initial_text.c_str()); + + bool is_equal = std::equal(text.crbegin(), text.crend(), compare_text.crbegin()); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_equal) + { + const Text initial1(initial_text.c_str()); + const Text initial2(initial_text.c_str()); + + CHECK(initial1 == initial2); + + const Text different(different_text.c_str()); + + CHECK(!(initial1 == different)); + + const Text shorter(shorter_text.c_str()); + + CHECK(!(shorter == initial1)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_not_equal) + { + const Text initial1(initial_text.c_str()); + const Text initial2(initial_text.c_str()); + + CHECK(!(initial1 != initial2)); + + const Text different(different_text.begin(), different_text.end()); + + CHECK(initial1 != different); + + const Text shorter(shorter_text.begin(), shorter_text.end()); + + CHECK(shorter != initial1); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_less_than) + { + const Text less(less_text.c_str()); + const Text initial(initial_text.c_str()); + + // String-String + CHECK((less < initial) == (less_text < initial_text)); + CHECK((initial < less) == (initial_text < less_text)); + + const Text greater(greater_text.c_str()); + CHECK((greater < initial) == (greater_text < initial_text)); + CHECK((initial < greater) == (initial_text < greater_text)); + + const Text shorter(shorter_text.c_str()); + CHECK((shorter < initial) == (shorter_text < initial_text)); + CHECK((initial < shorter) == (initial_text < shorter_text)); + + CHECK((initial < initial) == (initial_text < initial_text)); + CHECK((initial < initial) == (initial_text < initial_text)); + + // String-Pointer Pointer-String + CHECK((less < pinitial_text) == (less_text < pinitial_text)); + CHECK((pinitial_text < less) == (pinitial_text < less_text)); + + CHECK((greater < pinitial_text) == (greater_text < pinitial_text)); + CHECK((pinitial_text < greater) == (pinitial_text < greater_text)); + + CHECK((shorter < pinitial_text) == (shorter_text < pinitial_text)); + CHECK((pinitial_text < shorter) == (pinitial_text < shorter_text)); + + CHECK((initial < pinitial_text) == (initial_text < pinitial_text)); + CHECK((pinitial_text < initial) == (pinitial_text < initial_text)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_less_than_or_equal) + { + const Text less(less_text.c_str()); + const Text initial(initial_text.c_str()); + + // String-String + CHECK((less <= initial) == (less_text <= initial_text)); + CHECK((initial <= less) == (initial_text <= less_text)); + + const Text greater(greater_text.c_str()); + CHECK((greater <= initial) == (greater_text <= initial_text)); + CHECK((initial <= greater) == (initial_text <= greater_text)); + + const Text shorter(shorter_text.c_str()); + CHECK((shorter <= initial) == (shorter_text <= initial_text)); + CHECK((initial <= shorter) == (initial_text <= shorter_text)); + + CHECK((initial <= initial) == (initial_text <= initial_text)); + CHECK((initial <= initial) == (initial_text <= initial_text)); + + // String-Pointer Pointer-String + CHECK((less <= pinitial_text) == (less_text <= pinitial_text)); + CHECK((pinitial_text <= less) == (pinitial_text <= less_text)); + + CHECK((greater <= pinitial_text) == (greater_text <= pinitial_text)); + CHECK((pinitial_text <= greater) == (pinitial_text <= greater_text)); + + CHECK((shorter <= pinitial_text) == (shorter_text <= pinitial_text)); + CHECK((pinitial_text <= shorter) == (pinitial_text <= shorter_text)); + + CHECK((initial <= pinitial_text) == (initial_text <= pinitial_text)); + CHECK((pinitial_text <= initial) == (pinitial_text <= initial_text)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_greater_than) + { + const Text less(less_text.c_str()); + const Text initial(initial_text.c_str()); + + // String-String + CHECK((less > initial) == (less_text > initial_text)); + CHECK((initial > less) == (initial_text > less_text)); + + const Text greater(greater_text.c_str()); + CHECK((greater > initial) == (greater_text > initial_text)); + CHECK((initial > greater) == (initial_text > greater_text)); + + const Text shorter(shorter_text.c_str()); + CHECK((shorter > initial) == (shorter_text > initial_text)); + CHECK((initial > shorter) == (initial_text > shorter_text)); + + CHECK((initial > initial) == (initial_text > initial_text)); + CHECK((initial > initial) == (initial_text > initial_text)); + + // String-Pointer Pointer-String + CHECK((less > pinitial_text) == (less_text > pinitial_text)); + CHECK((pinitial_text > less) == (pinitial_text > less_text)); + + CHECK((greater > pinitial_text) == (greater_text > pinitial_text)); + CHECK((pinitial_text > greater) == (pinitial_text > greater_text)); + + CHECK((shorter > pinitial_text) == (shorter_text > pinitial_text)); + CHECK((pinitial_text > shorter) == (pinitial_text > shorter_text)); + + CHECK((initial > pinitial_text) == (initial_text > pinitial_text)); + CHECK((pinitial_text > initial) == (pinitial_text > initial_text)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_greater_than_or_equal) + { + const Text less(less_text.begin(), less_text.end()); + const Text initial(initial_text.begin(), initial_text.end()); + + // String-String + CHECK((less >= initial) == (less_text >= initial_text)); + CHECK((initial >= less) == (initial_text >= less_text)); + + const Text greater(greater_text.begin(), greater_text.end()); + CHECK((greater >= initial) == (greater_text >= initial_text)); + CHECK((initial >= greater) == (initial_text >= greater_text)); + + const Text shorter(shorter_text.begin(), shorter_text.end()); + CHECK((shorter >= initial) == (shorter_text >= initial_text)); + CHECK((initial >= shorter) == (initial_text > shorter_text)); + + CHECK((initial >= initial) == (initial_text >= initial_text)); + CHECK((initial >= initial) == (initial_text >= initial_text)); + + // String-Pointer Pointer-String + CHECK((less >= pinitial_text) == (less_text >= pinitial_text)); + CHECK((pinitial_text >= less) == (pinitial_text >= less_text)); + + CHECK((greater >= pinitial_text) == (greater_text >= pinitial_text)); + CHECK((pinitial_text >= greater) == (pinitial_text >= greater_text)); + + CHECK((shorter >= pinitial_text) == (shorter_text >= pinitial_text)); + CHECK((pinitial_text >= shorter) == (pinitial_text >= shorter_text)); + + CHECK((initial >= pinitial_text) == (initial_text >= pinitial_text)); + CHECK((pinitial_text >= initial) == (pinitial_text >= initial_text)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_copy) + { + Compare_Text compare_text(initial_text.c_str()); + Text text(initial_text.c_str()); + + value_t buffer1[SIZE]; + value_t buffer2[SIZE]; + + size_t length1 = compare_text.copy(buffer1, 5, 2); + buffer1[length1] = STR('\0'); + + size_t length2 = text.copy(buffer2, 5, 2); + buffer2[length2] = STR('\0'); + + CHECK_EQUAL(length1, length2); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + bool is_equal = std::equal(buffer1, + buffer1 + length1, + buffer2); + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_copy_start_pos_too_large) + { + Text text(initial_text.c_str()); + + value_t buffer1[SIZE]; + + size_t length1 = text.copy(buffer1, 5, SIZE); + + CHECK_EQUAL(0U, length1); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_copy_count_equals_npos) + { + Compare_Text compare_text(initial_text.c_str()); + Text text(initial_text.c_str()); + + value_t buffer1[SIZE]; + value_t buffer2[SIZE]; + + size_t length1 = compare_text.copy(buffer1, Compare_Text::npos, 2); + buffer1[length1] = STR('\0'); + + size_t length2 = text.copy(buffer2, Text::npos, 2); + buffer2[length2] = STR('\0'); + + CHECK_EQUAL(length1, length2); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + bool is_equal = std::equal(buffer1, + buffer1 + length1, + buffer2); + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_copy_count_too_large) + { + Compare_Text compare_text(initial_text.c_str()); + Text text(initial_text.c_str()); + + value_t buffer1[SIZE]; + value_t buffer2[SIZE]; + + size_t length1 = compare_text.copy(buffer1, SIZE, 2); + buffer1[length1] = STR('\0'); + + size_t length2 = text.copy(buffer2, SIZE, 2); + buffer2[length2] = STR('\0'); + + CHECK_EQUAL(length1, length2); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + bool is_equal = std::equal(buffer1, + buffer1 + length1, + buffer2); + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_string) + { + const value_t* the_haystack = STR("A haystack with a needle and another needle"); + + std::u8string compare_needle(STR("needle")); + etl::u8string<50> needle(STR("needle")); + + std::u8string compare_haystack(the_haystack); + etl::u8string<50> haystack(the_haystack); + + size_t position1 = 0; + size_t position2 = 0; + + position1 = compare_haystack.find(compare_needle, position1); + position2 = haystack.find(needle, position2); + CHECK_EQUAL(position1, position2); + + position1 = compare_haystack.find(compare_needle, position1 + 1); + position2 = haystack.find(needle, position2 + 1); + CHECK_EQUAL(position1, position2); + + position2 = haystack.find(needle, position2 + 1); + CHECK_EQUAL(etl::u8string<50>::npos, position2); + + etl::u8string<50> pin(STR("pin")); + position2 = haystack.find(pin); + CHECK_EQUAL(etl::iu8string::npos, position2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_pointer) + { + const value_t* the_haystack = STR("A haystack with a needle and another needle"); + + const value_t* needle = STR("needle"); + + std::u8string compare_haystack(the_haystack); + etl::u8string<50> haystack(the_haystack); + + size_t position1 = 0; + size_t position2 = 0; + + position1 = compare_haystack.find(needle, position1); + position2 = haystack.find(needle, position2); + CHECK_EQUAL(position1, position2); + + position1 = compare_haystack.find(needle, position1 + 1); + position2 = haystack.find(needle, position2 + 1); + CHECK_EQUAL(position1, position2); + + position2 = haystack.find(needle, position2 + 1); + CHECK_EQUAL(etl::iu8string::npos, position2); + + const value_t* pin = STR("pin"); + position2 = haystack.find(pin); + CHECK_EQUAL(etl::iu8string::npos, position2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_char_pointer_n) + { + const value_t* the_haystack = STR("A haystack with a needle and another needle"); + + const value_t* needle = STR("needle"); + + std::u8string compare_haystack(the_haystack); + etl::u8string<50> haystack(the_haystack); + + size_t position1 = 0; + size_t position2 = 0; + + position1 = compare_haystack.find(needle, position1, 3); + position2 = haystack.find(needle, position2, 3); + CHECK_EQUAL(position1, position2); + + position1 = compare_haystack.find(needle, position1 + 1, 3); + position2 = haystack.find(needle, position2 + 1, 3); + CHECK_EQUAL(position1, position2); + + position2 = haystack.find(needle, position2 + 1, 3); + CHECK_EQUAL(etl::iu8string::npos, position2); + + const value_t* pin = STR("pin"); + position2 = haystack.find(pin, 0, 3); + CHECK_EQUAL(etl::iu8string::npos, position2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_rfind_string) + { + const value_t* the_haystack = STR("A haystack with a needle and another needle"); + + std::u8string compare_needle(STR("needle")); + etl::u8string<50> needle(STR("needle")); + + std::u8string compare_haystack(the_haystack); + etl::u8string<50> haystack(the_haystack); + + size_t position1 = std::u8string::npos; + size_t position2 = etl::u8string<50>::npos; + + position1 = compare_haystack.rfind(compare_needle, position1); + position2 = haystack.rfind(needle, position2); + CHECK_EQUAL(position1, position2); + + position1 = compare_haystack.rfind(compare_needle, compare_haystack.size() - 10); + position2 = haystack.rfind(needle, haystack.size() - 10); + CHECK_EQUAL(position1, position2); + + etl::u8string<50> pin(STR("pin")); + position2 = haystack.rfind(pin); + CHECK_EQUAL(etl::iu8string::npos, position2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_rfind_pointer) + { + const value_t* the_haystack = STR("A haystack with a needle and another needle"); + + std::u8string compare_haystack(the_haystack); + etl::u8string<50> haystack(the_haystack); + + const value_t* needle = STR("needle"); + + size_t position1 = std::u8string::npos; + size_t position2 = etl::u8string<50>::npos; + + position1 = compare_haystack.rfind(needle, position1); + position2 = haystack.rfind(needle, position2); + CHECK_EQUAL(position1, position2); + + position1 = compare_haystack.rfind(needle, compare_haystack.size() - 10); + position2 = haystack.rfind(needle, haystack.size() - 10); + CHECK_EQUAL(position1, position2); + + etl::u8string<50> pin(STR("pin")); + position2 = haystack.rfind(pin); + CHECK_EQUAL(etl::iu8string::npos, position2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_rfind_pointer_n) + { + const value_t* the_haystack = STR("A haystack with a needle and another needle"); + + std::u8string compare_haystack(the_haystack); + etl::u8string<50> haystack(the_haystack); + + const value_t* needle = STR("needle"); + + size_t position1 = std::u8string::npos; + size_t position2 = etl::u8string<50>::npos; + + position1 = compare_haystack.rfind(needle, position1, 3); + position2 = haystack.rfind(needle, position2, 3); + CHECK_EQUAL(position1, position2); + + position1 = compare_haystack.rfind(needle, compare_haystack.size() - 10, 3); + position2 = haystack.rfind(needle, haystack.size() - 10, 3); + CHECK_EQUAL(position1, position2); + + position2 = haystack.rfind(STR("pin"), 3); + CHECK_EQUAL(etl::iu8string::npos, position2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_rfind_c_position) + { + const value_t* the_haystack = STR("A haystack with a needle and another needle"); + + std::u8string compare_haystack(the_haystack); + etl::u8string<50> haystack(the_haystack); + + size_t position1 = std::u8string::npos; + size_t position2 = etl::u8string<50>::npos; + + position1 = compare_haystack.rfind(STR('e'), position1); + position2 = haystack.rfind(STR('e'), position2); + CHECK_EQUAL(position1, position2); + + position1 = compare_haystack.rfind(STR('e'), compare_haystack.size() - 10); + position2 = haystack.rfind(STR('e'), haystack.size() - 10); + CHECK_EQUAL(position1, position2); + + position2 = haystack.rfind(STR('z')); + CHECK_EQUAL(etl::iu8string::npos, position2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_substr) + { + Compare_Text compare_text(initial_text.c_str()); + Text text(initial_text.c_str()); + + Compare_Text compare_result; + Text result; + + // Equal. + compare_result = compare_text.substr(compare_text.size()); + result = text.substr(text.size()); + CHECK(Equal(compare_result, result)); + + // Whole string. + compare_result = compare_text.substr(); + result = text.substr(); + CHECK(Equal(compare_result, result)); + + // Starting from position 2. + compare_result = compare_text.substr(2); + result = text.substr(2); + CHECK(Equal(compare_result, result)); + + // Starting from position 2 for 3 characters. + compare_result = compare_text.substr(2, 3); + result = text.substr(2, 3); + CHECK(Equal(compare_result, result)); + + // Starting from position 2 for too many characters. + compare_result = compare_text.substr(2, compare_text.size()); + result = text.substr(2, text.size()); + CHECK(Equal(compare_result, result)); + + // Starting from beyond the end of the string. + CHECK_THROW(text.substr(text.size() + 1), etl::string_out_of_bounds); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_compare_string) + { + Compare_Text compare_text(STR("ABCDEF")); + Text text(STR("ABCDEF")); + + int compare_result; + int result; + + // Equal. + compare_result = compare_text.compare(Compare_Text(STR("ABCDEF"))); + result = text.compare(Text(STR("ABCDEF"))); + CHECK(compares_agree(compare_result, result)); + + // Less. + compare_result = compare_text.compare(Compare_Text(STR("ABCDEE"))); + result = text.compare(Text(STR("ABCDEE"))); + CHECK(compares_agree(compare_result, result)); + + // Greater. + compare_result = compare_text.compare(Compare_Text(STR("ABCDEG"))); + result = text.compare(Text(STR("ABCDEG"))); + CHECK(compares_agree(compare_result, result)); + + // Shorter. + compare_result = compare_text.compare(Compare_Text(STR("ABCDE"))); + result = text.compare(Text(STR("ABCDE"))); + CHECK(compares_agree(compare_result, result)); + + // Longer. + compare_result = compare_text.compare(Compare_Text(STR("ABCDEFG"))); + result = text.compare(Text(STR("ABCDEFG"))); + CHECK(compares_agree(compare_result, result)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_compare_position_length_string) + { + Compare_Text compare_text(STR("xxxABCDEFyyy")); + Text text(STR("xxxABCDEFyyy")); + + int compare_result; + int result; + + // Equal. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("ABCDEF"))); + result = text.compare(3, 6, Text(STR("ABCDEF"))); + CHECK(compares_agree(compare_result, result)); + + // Less. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("ABCDEE"))); + result = text.compare(3, 6, Text(STR("ABCDEE"))); + CHECK(compares_agree(compare_result, result)); + + // Greater. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("ABCDEG"))); + result = text.compare(3, 6, Text(STR("ABCDEG"))); + CHECK(compares_agree(compare_result, result)); + + // Shorter. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("ABCDE"))); + result = text.compare(3, 6, Text(STR("ABCDE"))); + CHECK(compares_agree(compare_result, result)); + + // Longer. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("ABCDEFG"))); + result = text.compare(3, 6, Text(STR("ABCDEFG"))); + CHECK(compares_agree(compare_result, result)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_compare_position_length_string_subposition_sublength) + { + Compare_Text compare_text(STR("xxxABCDEFyyy")); + Text text(STR("xxxABCDEFyyy")); + + int compare_result; + int result; + + // Equal. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("aaABCDEFbb")), 2, 6); + result = text.compare(3, 6, Text(STR("aaABCDEFbb")), 2, 6); + CHECK(compares_agree(compare_result, result)); + + // Less. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("aaABCDEEbb")), 2, 6); + result = text.compare(3, 6, Text(STR("aaABCDEEbb")), 2, 6); + CHECK(compares_agree(compare_result, result)); + + // Greater. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("aaABCDEGbb")), 2, 6); + result = text.compare(3, 6, Text(STR("aaABCDEGbb")), 2, 6); + CHECK(compares_agree(compare_result, result)); + + // Shorter. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("aaABCDEbb")), 2, 5); + result = text.compare(3, 6, Text(STR("aaABCDEbb")), 2, 5); + CHECK(compares_agree(compare_result, result)); + + // Longer. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("aaABCDEFGbb")), 2, 7); + result = text.compare(3, 6, Text(STR("aaABCDEFGbb")), 2, 7); + CHECK(compares_agree(compare_result, result)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_compare_c_string) + { + Compare_Text compare_text(STR("ABCDEF")); + Text text(STR("ABCDEF")); + + int compare_result; + int result; + + // Equal. + compare_result = compare_text.compare(STR("ABCDEF")); + result = text.compare(STR("ABCDEF")); + CHECK(compares_agree(compare_result, result)); + + // Less. + compare_result = compare_text.compare(STR("ABCDEE")); + result = text.compare(STR("ABCDEE")); + CHECK(compares_agree(compare_result, result)); + + // Greater. + compare_result = compare_text.compare(STR("ABCDEG")); + result = text.compare(STR("ABCDEG")); + CHECK(compares_agree(compare_result, result)); + + // Shorter. + compare_result = compare_text.compare(STR("ABCDE")); + result = text.compare(STR("ABCDE")); + CHECK(compares_agree(compare_result, result)); + + // Longer. + compare_result = compare_text.compare(STR("ABCDEFG")); + result = text.compare(STR("ABCDEFG")); + CHECK(compares_agree(compare_result, result)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_compare_position_length_c_string) + { + Compare_Text compare_text(STR("xxxABCDEFyyy")); + Text text(STR("xxxABCDEFyyy")); + + int compare_result; + int result; + + // Equal. + compare_result = compare_text.compare(3, 6, STR("ABCDEF")); + result = text.compare(3, 6, STR("ABCDEF")); + CHECK(compares_agree(compare_result, result)); + + // Less. + compare_result = compare_text.compare(3, 6, STR("ABCDEE")); + result = text.compare(3, 6, STR("ABCDEE")); + CHECK(compares_agree(compare_result, result)); + + // Greater. + compare_result = compare_text.compare(3, 6, STR("ABCDEG")); + result = text.compare(3, 6, STR("ABCDEG")); + CHECK(compares_agree(compare_result, result)); + + // Shorter. + compare_result = compare_text.compare(3, 6, STR("ABCDE")); + result = text.compare(3, 6, STR("ABCDE")); + CHECK(compares_agree(compare_result, result)); + + // Longer. + compare_result = compare_text.compare(3, 6, STR("ABCDEFG")); + result = text.compare(3, 6, STR("ABCDEFG")); + CHECK(compares_agree(compare_result, result)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_compare_position_length_c_string_n) + { + Compare_Text compare_text(STR("xxxABCDEFyyy")); + Text text(STR("xxxABCDEFyyy")); + + int compare_result; + int result; + + // Equal. + compare_result = compare_text.compare(3, 6, STR("ABCDEFbb"), 6); + result = text.compare(3, 6, STR("ABCDEFbb"), 6); + CHECK(compares_agree(compare_result, result)); + + // Less. + compare_result = compare_text.compare(3, 6, STR("ABCDEEbb"), 6); + result = text.compare(3, 6, STR("ABCDEEbb"), 6); + CHECK(compares_agree(compare_result, result)); + + // Greater. + compare_result = compare_text.compare(3, 6, STR("ABCDEGbb"), 6); + result = text.compare(3, 6, STR("ABCDEGbb"), 6); + CHECK(compares_agree(compare_result, result)); + + // Shorter. + compare_result = compare_text.compare(3, 6, STR("ABCDEbb"), 5); + result = text.compare(3, 6, STR("ABCDEbb"), 5); + CHECK(compares_agree(compare_result, result)); + + // Longer. + compare_result = compare_text.compare(3, 6, STR("ABCDEFGbb"), 7); + result = text.compare(3, 6, STR("ABCDEFGbb"), 7); + CHECK(compares_agree(compare_result, result)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_first_of_string_position) + { + Compare_Text compare_text(STR("ABCDEF")); + Text text(STR("ABCDEF")); + + size_t position1 = compare_text.find_first_of(Compare_Text(STR("ZCXF"))); + size_t position2 = text.find_first_of(Text(STR("ZCXF"))); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(Compare_Text(STR("WXYZ"))); + position2 = text.find_first_of(Text(STR("WXYZ"))); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(Compare_Text(STR("ZCXF")), 3); + position2 = text.find_first_of(Text(STR("ZCXF")), 3); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_first_of(Compare_Text(STR("ZCXF")), 100); + position2 = text.find_first_of(Text(STR("ZCXF")), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_first_of_pointer_position) + { + Compare_Text compare_text(STR("ABCDEF")); + Text text(STR("ABCDEF")); + + size_t position1 = compare_text.find_first_of(STR("ZCXF")); + size_t position2 = text.find_first_of(STR("ZCXF")); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(STR("WXYZ")); + position2 = text.find_first_of(STR("WXYZ")); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(STR("ZCXF"), 3); + position2 = text.find_first_of(STR("ZCXF"), 3); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_first_of(STR("ZCXF"), 100); + position2 = text.find_first_of(STR("ZCXF"), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_first_of_pointer_position_n) + { + Compare_Text compare_text(STR("ABCDEF")); + Text text(STR("ABCDEF")); + + size_t position1 = compare_text.find_first_of(STR("ZCXF"), 0, 4); + size_t position2 = text.find_first_of(STR("ZCXF"), 0, 4); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(STR("WXYZ"), 0, 4); + position2 = text.find_first_of(STR("WXYZ"), 0, 4); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(STR("ZCXF"), 1, 3); + position2 = text.find_first_of(STR("ZCXF"), 1, 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(STR("ZCXF"), 3, 3); + position2 = text.find_first_of(STR("ZCXF"), 3, 3); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_first_of(STR("ZCXF"), 100); + position2 = text.find_first_of(STR("ZCXF"), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_first_of_character_position) + { + Compare_Text compare_text(STR("ABCDEF")); + Text text(STR("ABCDEF")); + + size_t position1 = compare_text.find_first_of(STR('C')); + size_t position2 = text.find_first_of(STR('C')); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(STR('Z')); + position2 = text.find_first_of(STR('Z')); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(STR('F'), 3); + position2 = text.find_first_of(STR('F'), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(STR('C'), 3); + position2 = text.find_first_of(STR('C'), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(STR('C'), compare_text.size()); + position2 = text.find_first_of(STR('C'), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_first_of(STR('C'), 100); + position2 = text.find_first_of(STR('C'), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_last_of_string_position) + { + Compare_Text compare_text(STR("ABCDEFABCDE")); + Text text(STR("ABCDEFABCDE")); + + size_t position1 = compare_text.find_last_of(Compare_Text(STR("ZCXE"))); + size_t position2 = text.find_last_of(Text(STR("ZCXE"))); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(Compare_Text(STR("WXYZ")), 3); + position2 = text.find_last_of(Text(STR("WXYZ")), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(Compare_Text(STR("ZCXE")), 5); + position2 = text.find_last_of(Text(STR("ZCXE")), 5); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(Compare_Text(STR("ZCXE")), compare_text.size()); + position2 = text.find_last_of(Text(STR("ZCXE")), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_last_of(Compare_Text(STR("ZCXE")), 100); + position2 = text.find_last_of(Text(STR("ZCXE")), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_last_of_pointer_position) + { + Compare_Text compare_text(STR("ABCDEFABCDE")); + Text text(STR("ABCDEFABCDE")); + + size_t position1 = compare_text.find_last_of(STR("ZCXE")); + size_t position2 = text.find_last_of(STR("ZCXE")); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR("WXYZ"), 3); + position2 = text.find_last_of(STR("WXYZ"), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR("ZCXE"), 5); + position2 = text.find_last_of(STR("ZCXE"), 5); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR("ZCXE"), 6); + position2 = text.find_last_of(STR("ZCXE"), 6); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR("ZCXE"), compare_text.size()); + position2 = text.find_last_of(STR("ZCXE"), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_last_of(STR("ZCXE"), 100); + position2 = text.find_last_of(STR("ZCXE"), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_last_of_pointer_position_n) + { + Compare_Text compare_text(STR("ABCDEFABCDE")); + Text text(STR("ABCDEFABCDE")); + + size_t position1 = compare_text.find_last_of(STR("AZCXE"), 0, 4); + size_t position2 = text.find_last_of(STR("AZCXE"), 0, 4); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR("WXYZ"), 4, 3); + position2 = text.find_last_of(STR("WXYZ"), 4, 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR("ZCXE"), 5, 3); + position2 = text.find_last_of(STR("ZCXE"), 5, 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR("ZCXE"), 1, 3); + position2 = text.find_last_of(STR("ZCXE"), 1, 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR("ZCXE"), compare_text.size(), 4); + position2 = text.find_last_of(STR("ZCXE"), text.size(), 4); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR("ZCXE"), 100, 4); + position2 = text.find_last_of(STR("ZCXE"), 100, 4); + + CHECK_EQUAL(position1, position2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_last_of_character_position) + { + Compare_Text compare_text(STR("ABCDEF")); + Text text(STR("ABCDEF")); + + size_t position1 = compare_text.find_last_of(STR('C')); + size_t position2 = text.find_last_of(STR('C')); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR('Z')); + position2 = text.find_last_of(STR('Z')); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR('F'), compare_text.size()); + position2 = text.find_last_of(STR('F'), text.size()); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR('C'), 3); + position2 = text.find_last_of(STR('C'), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR('C'), compare_text.size()); + position2 = text.find_last_of(STR('C'), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_last_of(STR('C'), 100); + position2 = text.find_last_of(STR('C'), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_first_not_of_string_position) + { + Compare_Text compare_text(STR("ABCDEF")); + Text text(STR("ABCDEF")); + + size_t position1 = compare_text.find_first_not_of(Compare_Text(STR("ZAXB"))); + size_t position2 = text.find_first_not_of(Text(STR("ZAXB"))); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(Compare_Text(STR("ZAXB"))); + position2 = text.find_first_not_of(Text(STR("ZAXB"))); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(Compare_Text(STR("ZAXB")), 3); + position2 = text.find_first_not_of(Text(STR("ZAXB")), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(Compare_Text(STR("ZAXB")), compare_text.size()); + position2 = text.find_first_not_of(Text(STR("ZAXB")), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_first_not_of(Compare_Text(STR("ZAXB")), 100); + position2 = text.find_first_not_of(Text(STR("ZAXB")), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_first_not_of_pointer_position) + { + Compare_Text compare_text(STR("ABCDEF")); + Text text(STR("ABCDEF")); + + size_t position1 = compare_text.find_first_not_of(STR("ZAXB")); + size_t position2 = text.find_first_not_of(STR("ZAXB")); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR("ZAXB")); + position2 = text.find_first_not_of(STR("ZAXB")); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR("ZAXB"), 3); + position2 = text.find_first_not_of(STR("ZAXB"), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR("ZAXB"), compare_text.size()); + position2 = text.find_first_not_of(STR("ZAXB"), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_first_not_of(STR("ZAXB"), 100); + position2 = text.find_first_not_of(STR("ZAXB"), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_first_not_of_pointer_position_n) + { + Compare_Text compare_text(STR("ABCDEF")); + Text text(STR("ABCDEF")); + + size_t position1 = compare_text.find_first_not_of(STR("ZAXB"), 0, 4); + size_t position2 = text.find_first_not_of(STR("ZAXB"), 0, 4); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR("ZAXB"), 0, 4); + position2 = text.find_first_not_of(STR("ZAXB"), 0, 4); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR("ZAXB"), 1, 3); + position2 = text.find_first_not_of(STR("ZAXB"), 1, 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR("ZAXB"), 3, 3); + position2 = text.find_first_not_of(STR("ZAXB"), 3, 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR("ZAXB"), compare_text.size(), 3); + position2 = text.find_first_not_of(STR("ZAXB"), text.size(), 3); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_first_not_of(STR("ZAXB"), 100); + position2 = text.find_first_not_of(STR("ZAXB"), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_first_not_of_character_position) + { + Compare_Text compare_text(STR("ABCDEF")); + Text text(STR("ABCDEF")); + + size_t position1 = compare_text.find_first_not_of(STR('A')); + size_t position2 = text.find_first_not_of(STR('A')); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR('B')); + position2 = text.find_first_not_of(STR('B')); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR('C'), 3); + position2 = text.find_first_not_of(STR('C'), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR('D'), 3); + position2 = text.find_first_not_of(STR('D'), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR('C'), compare_text.size()); + position2 = text.find_first_not_of(STR('C'), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_first_not_of(STR('C'), 100); + position2 = text.find_first_not_of(STR('C'), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_last_not_of_string_position) + { + Compare_Text compare_text(STR("ABCDEFABCDE")); + Text text(STR("ABCDEFABCDE")); + + size_t position1 = compare_text.find_last_not_of(Compare_Text(STR("ZEXD"))); + size_t position2 = text.find_last_not_of(Text(STR("ZEXD"))); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(Compare_Text(STR("ZEXD")), 3); + position2 = text.find_last_not_of(Text(STR("ZEXD")), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(Compare_Text(STR("ZEXD")), 5); + position2 = text.find_last_not_of(Text(STR("ZEXD")), 5); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(Compare_Text(STR("ZEXD")), compare_text.size()); + position2 = text.find_last_not_of(Text(STR("ZEXD")), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_last_not_of(Compare_Text(STR("ZEXD")), 100); + position2 = text.find_last_not_of(Text(STR("ZEXD")), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_last_not_of_pointer_position) + { + Compare_Text compare_text(STR("ABCDEFABCDE")); + Text text(STR("ABCDEFABCDE")); + + size_t position1 = compare_text.find_last_not_of(STR("ZEXD")); + size_t position2 = text.find_last_not_of(STR("ZEXD")); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR("ZEXD"), 3); + position2 = text.find_last_not_of(STR("ZEXD"), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR("ZEXD"), 5); + position2 = text.find_last_not_of(STR("ZEXD"), 5); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR("ZEXD"), compare_text.size()); + position2 = text.find_last_not_of(STR("ZEXD"), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_last_not_of(STR("ZEXD"), 100); + position2 = text.find_last_not_of(STR("ZEXD"), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_last_not_of_pointer_position_n) + { + Compare_Text compare_text(STR("ABCDEFABCDE")); + Text text(STR("ABCDEFABCDE")); + + size_t position1 = compare_text.find_last_not_of(STR("ZEXD"), 0, 4); + size_t position2 = text.find_last_not_of(STR("ZEXD"), 0, 4); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR("ZEXD"), 5, 3); + position2 = text.find_last_not_of(STR("ZEXD"), 5, 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR("ZEXD"), 1, 3); + position2 = text.find_last_not_of(STR("ZEXD"), 1, 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR("ZEXD"), compare_text.size(), 4); + position2 = text.find_last_not_of(STR("ZEXD"), text.size(), 4); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR("ZEXD"), 100, 4); + position2 = text.find_last_not_of(STR("ZEXD"), 100, 4); + + CHECK_EQUAL(position1, position2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_last_not_of_character_position) + { + Compare_Text compare_text(STR("ABCDEF")); + Text text(STR("ABCDEF")); + + size_t position1 = compare_text.find_last_not_of(STR('F')); + size_t position2 = text.find_last_not_of(STR('F')); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR('Z')); + position2 = text.find_last_not_of(STR('Z')); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR('A'), compare_text.size()); + position2 = text.find_last_not_of(STR('A'), text.size()); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR('C'), 3); + position2 = text.find_last_not_of(STR('C'), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR('C'), compare_text.size()); + position2 = text.find_last_not_of(STR('C'), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_last_not_of(STR('C'), 100); + position2 = text.find_last_not_of(STR('C'), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_hash) + { + // Test with actual string type. + Text text(STR("ABCDEFHIJKL")); + size_t hash = etl::hash()(text); + size_t compare_hash = etl::private_hash::generic_hash(reinterpret_cast(&text[0]), reinterpret_cast(&text[text.size()])); + CHECK_EQUAL(compare_hash, hash); + + // Test with interface string type. + IText& itext = text; + hash = etl::hash()(itext); + CHECK_EQUAL(compare_hash, hash); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_memcpy_repair) + { + Text text; + + text.assign(STR("ABCDEF")); + + char buffer[sizeof(Text)]; + + memcpy(&buffer, (const void*)&text, sizeof(text)); + + Text& rtext(*reinterpret_cast(buffer)); + rtext.repair(); + + CHECK(!rtext.empty()); + CHECK(!rtext.full()); + + bool is_equal = Equal(text, rtext); + CHECK(is_equal); + + text = STR("GHIJKL"); + is_equal = Equal(text, rtext); + CHECK(!is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_memcpy_repair_virtual) + { + Text text; + + text.assign(STR("ABCDEF")); + + char buffer[sizeof(Text)]; + + memcpy(&buffer, (const void*)&text, sizeof(text)); + + IText& itext(*reinterpret_cast(buffer)); + itext.repair(); + + CHECK(!itext.empty()); + CHECK(!itext.full()); + + bool is_equal = Equal(text, itext); + CHECK(is_equal); + + text = STR("GHIJKL"); + is_equal = Equal(text, itext); + CHECK(!is_equal); + } + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_truncate_over_many_operations) + { + Text text(short_text.c_str()); + CHECK(!text.is_truncated()); + + text.insert(3, initial_text.c_str()); + CHECK(text.is_truncated()); + + while (text.size() != 0) + { + text.pop_back(); + CHECK(text.is_truncated()); + } + + text.clear(); + CHECK(!text.is_truncated()); + + text.assign(longer_text.c_str()); + CHECK(text.is_truncated()); + + text.assign(short_text.c_str()); + CHECK(!text.is_truncated()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_add_from_truncated) + { + Text text1(short_text.c_str()); + TextS text2(short_text.c_str()); + + CHECK(!text1.is_truncated()); + CHECK(text2.is_truncated()); + + // text2 has the truncate flag set. + text1 += text2; + + CHECK(text1.is_truncated()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_add_to_truncated) + { + Text text1(longer_text.c_str()); + Text text2(short_text.c_str()); + + CHECK(text1.is_truncated()); + CHECK(!text2.is_truncated()); + + // Clear text but not the truncate flag. + text1.erase(text1.begin(), text1.end()); + + // text1 still has the truncate flag set. + text1 += text2; + + CHECK(text1.is_truncated()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_clear_truncated) + { + Text text(longer_text.c_str()); + CHECK(text.is_truncated()); + + text.clear_truncated(); + CHECK(!text.is_truncated()); + } +#endif + +#if ETL_HAS_STRING_CLEAR_AFTER_USE + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_secure_after_destructor) + { + char buffer[sizeof(Text)]; + std::fill_n(buffer, sizeof(Text), 0); + ::new (buffer) Text(STR("ABCDEF")); + + Text& text = *reinterpret_cast(buffer); + text.set_secure(); + + CHECK(Text(STR("ABCDEF")) == text); + + Text::pointer pb = text.begin(); + Text::pointer pe = text.end(); + + // Destroy the text object. + text.~Text(); + + // Check there no non-zero values in the string. + CHECK(std::find_if(pb, pe, [](Text::value_type x) { return x != 0; }) == pe); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_secure_after_assign) + { + Text text; + text.set_secure(); + text.assign(STR("ABCDEF")); + + Text::pointer pe = text.end(); + + text.assign(STR("ABC")); + + CHECK(std::find_if(text.end(), pe, [](Text::value_type x) { return x != 0; }) == pe); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_secure_after_resize_down) + { + Text text; + text.set_secure(); + text.assign(STR("ABCDEF")); + + Text::pointer pe = text.end(); + + text.resize(text.size() - 3U); + + CHECK(std::find_if(text.end(), pe, [](Text::value_type x) { return x != 0; }) == pe); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_secure_after_erase) + { + Text text; + text.set_secure(); + text.assign(STR("ABCDEF")); + + Text::pointer pb = text.begin(); + Text::pointer pe = text.end(); + + text.erase(pb + 2, pb + 5); + + // Check there no non-zero values in the remainder of the string. + CHECK(std::find_if(text.end(), pe, [](Text::value_type x) { return x != 0; }) == pe); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_secure_after_replace) + { + Text text; + text.set_secure(); + text.assign(STR("ABCDEF")); + + Text::pointer pb = text.begin(); + Text::pointer pe = text.end(); + + text.replace(pb + 1, pb + 4, STR("G")); + + // Check there no non-zero values in the remainder of the string. + CHECK(std::find_if(text.end(), pe, [](Text::value_type x) { return x != 0; }) == pe); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_secure_after_clear) + { + Text text; + text.set_secure(); + text.assign(STR("ABCDEF")); + + Text::pointer pb = text.begin(); + Text::pointer pe = text.end(); + + text.clear(); + + // Check there no non-zero values in the remainder of the string. + CHECK(std::find_if(pb, pe, [](Text::value_type x) { return x != 0; }) == pe); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_secure_flag_after_copy) + { + Text text1 = STR("Hello World"); + text1.set_secure(); + + Text text2(text1); + + Text text3; + text3 = text1; + + Text text4(text1, 6U, 3U); + + CHECK(text2.is_secure()); + CHECK(text3.is_secure()); + CHECK(text4.is_secure()); + } +#endif + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_initialize_free_space_empty_string) + { + Text empty; + Text text; + + text.initialize_free_space(); + + CHECK(text.empty()); + CHECK(text == empty); + + for (size_t i = text.size(); i < text.max_size(); ++i) + { + CHECK_EQUAL(0, text[i]); + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_initialize_free_space_part_filled_string) + { + Text empty; + Text initial = STR("ABC"); + Text text(initial); + + text.initialize_free_space(); + + CHECK(text == initial); + CHECK(text != empty); + + for (size_t i = text.size(); i < text.max_size(); ++i) + { + CHECK_EQUAL(0, text[i]); + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_update_after_c_string_max_size) + { + Text text; + + text.initialize_free_space(); + std::fill(text.data(), text.data() + text.max_size(), STR('A')); + text.trim_to_terminator(); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + CHECK_EQUAL(text.max_size(), text.size()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_update_after_c_string_shorter_size) + { + Text text; + + text.initialize_free_space(); + std::fill(text.data(), text.data() + text.max_size() - 1, STR('A')); + text.trim_to_terminator(); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + CHECK_EQUAL(text.max_size() - 1, text.size()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_update_after_c_string_greater_size) + { + Text text; + + text.initialize_free_space(); + std::fill(text.data(), text.data() + text.max_size() + 1, STR('A')); // Overwrites to terminating null. + text.trim_to_terminator(); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + CHECK_EQUAL(text.max_size(), text.size()); + } + }; +} + +#endif diff --git a/test/test_string_u8_external_buffer.cpp b/test/test_string_u8_external_buffer.cpp new file mode 100644 index 00000000..aa532457 --- /dev/null +++ b/test/test_string_u8_external_buffer.cpp @@ -0,0 +1,4859 @@ +/****************************************************************************** +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 +#include +#include + +#include "etl/u8string.h" +#include "etl/fnv_1.h" + +#undef STR +#define STR(x) u8##x + +namespace +{ + bool compares_agree(int result1, int result2) + { + return ((result1 < 0) && (result2 < 0)) || + ((result1 == 0) && (result2 == 0)) || + ((result1 > 0) && (result2 > 0)); + } + + ////*********************************** + //std::ostream& operator << (std::ostream& os, const etl::iu8string::value_type& c) + //{ + // os << uint16_t(c); + + // return os; + //} + + ////*********************************** + //std::ostream& operator << (std::ostream& os, const etl::iu8string::value_type* c) + //{ + // os << (void*)c; + + // return os; + //} + + SUITE(test_string_char16_t_external_buffer) + { + static constexpr size_t SIZE = 11; + static constexpr size_t SIZE_L = 52; + static constexpr size_t SIZE_S = 4; + + using Text = etl::u8string_ext; + using IText = etl::iu8string; + using TextT = etl::u8string; + using Compare_Text = std::u8string; + using value_t = Text::value_type; + using TextBuffer = std::array; + using TextBufferL = std::array; + using TextBufferS = std::array; + + Compare_Text initial_text; + Compare_Text less_text; + Compare_Text greater_text; + Compare_Text shorter_text; + Compare_Text different_text; + Compare_Text insert_text; + Compare_Text longer_text; + Compare_Text short_text; + + const value_t* pinitial_text = STR("Hello World"); + + value_t array_text[12]; + value_t* p_text = array_text; + + //************************************************************************* + template + bool Equal(const T1& compare_text, const T2& text) + { + return (compare_text.size() == text.size()) && std::equal(text.begin(), text.end(), compare_text.begin()); + } + + //************************************************************************* + struct SetupFixture + { + SetupFixture() + { + initial_text = STR("Hello World"); + insert_text = STR("Insert"); + less_text = STR("Hello Vorld"); + greater_text = STR("Hello Xorld"); + shorter_text = STR("Hello Worl"); + different_text = STR("Byee Planet"); + longer_text = STR("Hello World There"); + short_text = STR("Hello"); + + std::copy(pinitial_text, pinitial_text + etl::strlen(pinitial_text), array_text); + } + }; + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_default_constructor) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + + CHECK_EQUAL(text.size(), size_t(0)); + CHECK(text.empty()); + CHECK_EQUAL(SIZE, text.capacity()); + CHECK_EQUAL(SIZE, text.max_size()); + CHECK(text.begin() == text.end()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_default_constructor_use_buffer_and_size) + { + size_t length = etl::strlen(p_text); + Text text(p_text, length + 1); + + CHECK_EQUAL(0U, text.size()); + CHECK(text.empty()); + CHECK_EQUAL(length, text.capacity()); + CHECK_EQUAL(length, text.max_size()); + CHECK(text.begin() == text.end()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_default_constructor_use_buffer_text_and_size) + { + Text text(p_text, p_text, etl::strlen(p_text) + 1); + + CHECK_EQUAL(text.size(), etl::strlen(p_text)); + CHECK(!text.empty()); + CHECK_EQUAL(etl::strlen(p_text), text.capacity()); + CHECK_EQUAL(etl::strlen(p_text), text.max_size()); + CHECK(text.begin() != text.end()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_default_constructor_use_array_buffer) + { + Text text(array_text, ETL_OR_STD17::size(array_text)); + + CHECK_EQUAL(0U, text.size()); + CHECK(text.empty()); + CHECK_EQUAL(ETL_OR_STD17::size(array_text) - 1, text.capacity()); + CHECK_EQUAL(ETL_OR_STD17::size(array_text) - 1, text.max_size()); + CHECK(text.begin() == text.end()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_default_constructor_use_array_buffer_text) + { + Text text(array_text, array_text, ETL_OR_STD17::size(array_text)); + + CHECK_EQUAL(text.size(), etl::strlen(array_text)); + CHECK(!text.empty()); + CHECK_EQUAL(ETL_OR_STD17::size(array_text) - 1, text.capacity()); + CHECK_EQUAL(ETL_OR_STD17::size(array_text) - 1, text.max_size()); + CHECK(text.begin() != text.end()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST(test_iterator_comparison_empty) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + + CHECK(text.begin() == text.end()); + CHECK(text.cbegin() == text.cend()); + CHECK(text.rbegin() == text.rend()); + CHECK(text.crbegin() == text.crend()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_size_value) + { + const size_t INITIAL_SIZE = 5; + const value_t INITIAL_VALUE = STR('A'); + TextBuffer buffer{0}; + + Compare_Text compare_text(INITIAL_SIZE, INITIAL_VALUE); + Text text(INITIAL_SIZE, INITIAL_VALUE, buffer.data(), buffer.size()); + + CHECK(text.size() == INITIAL_SIZE); + CHECK(!text.empty()); + + bool is_equal = Equal(compare_text, text); + + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_size_excess) + { + TextBuffer buffer{0}; + Text text(buffer.size() + 1, STR('A'), buffer.data(), buffer.size()); + + CHECK_EQUAL(buffer.size() - 1, text.size()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_char_pointer) + { + TextBuffer buffer{0}; + Compare_Text compare_text(initial_text.c_str()); + + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + CHECK(!text.empty()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_excess) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + Text text(longer_text.c_str(), buffer.data(), buffer.size()); + + CHECK(!text.empty()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_size) + { + Compare_Text compare_text(SIZE, STR('A')); + + TextBuffer buffer{0}; + Text text(SIZE, STR('A'), buffer.data(), buffer.size()); + + CHECK(!text.empty()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_size_excess) + { + Compare_Text compare_text(SIZE, STR('A')); + + TextBuffer buffer{0}; + Text text(SIZE + 1, STR('A'), buffer.data(), buffer.size()); + + CHECK(!text.empty()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_size_char) + { + Compare_Text compare_text(initial_text.c_str(), initial_text.size() / 2); + + TextBuffer buffer{0}; + Text text(initial_text.c_str(), initial_text.size() / 2, buffer.data(), buffer.size()); + + CHECK(!text.empty()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_size_char_excess) + { + Compare_Text compare_text(initial_text.c_str(), initial_text.size()); + + TextBuffer buffer{0}; + Text text(longer_text.c_str(), longer_text.size(), buffer.data(), buffer.size()); + + CHECK(!text.empty()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_range) + { + Compare_Text compare_text(initial_text.begin(), initial_text.end()); + + TextBuffer buffer{0}; + Text text(compare_text.begin(), compare_text.end(), buffer.data(), buffer.size()); + + CHECK(text.size() == SIZE); + CHECK(!text.empty()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_range_excess) + { + TextBuffer buffer{0}; + Text text(longer_text.begin(), longer_text.end(), buffer.data(), buffer.size()); + + bool is_equal = Equal(initial_text, text); + CHECK(is_equal); + CHECK(text.size() == SIZE); + CHECK(!text.empty()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_from_literal) + { + TextBuffer buffer{0}; + Text text(STR("Hello World"), buffer.data(), buffer.size()); + + bool is_equal = Equal(initial_text, text); + CHECK(is_equal); + CHECK(text.size() == SIZE); + CHECK(!text.empty()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_from_string_view) + { + etl::u8string_view view(initial_text.data(), initial_text.size()); + + TextBuffer buffer{0}; + Text text(view, buffer.data(), buffer.size()); + + bool is_equal = Equal(initial_text, text); + CHECK(is_equal); + CHECK(text.size() == SIZE); + CHECK(!text.empty()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_copy_constructor) + { + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + Text text2(text, buffer2.data(), buffer2.size()); + CHECK(text2 == text); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text2.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_copy_constructor_i) + { + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + IText& itext = text; + + TextBuffer buffer2{0}; + Text text2(itext, buffer2.data(), buffer2.size()); + CHECK(text2 == text); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text2.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_copy_constructor_excess) + { + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + TextBufferL bufferl{0}; + Text textl(longer_text.c_str(), bufferl.data(), bufferl.size()); + + TextBuffer buffer2{0}; + Text text2(textl, buffer2.data(), buffer2.size()); + CHECK(text2 == text); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text2.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_copy_constructor_from_truncated) + { + TextBuffer buffer{0}; + Text text(longer_text.c_str(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + Text text2(text, buffer2.data(), buffer2.size()); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text2.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_construct_position_length) + { + Compare_Text compare_text(initial_text.c_str()); + Compare_Text compare_text2(compare_text, 2, 4); + + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + Text text2(text, buffer2.data(), buffer2.size(), 2, 4); + + bool is_equal = Equal(compare_text2, text2); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text2.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_construct_position_length_excess) + { + Compare_Text compare_text(longer_text.c_str()); + Compare_Text compare_text2(compare_text, 2, 11); + + TextBufferL bufferl{0}; + Text textl(longer_text.c_str(), bufferl.data(), bufferl.size()); + + TextBuffer buffer{0}; + Text text2(textl, buffer.data(), buffer.size(), 2, 12); + + bool is_equal = Equal(compare_text2, text2); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text2.is_truncated()); +#endif + } + +#if ETL_HAS_INITIALIZER_LIST + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_construct_initializer_list) + { + Compare_Text compare_text = { STR('H'), STR('e'), STR('l') , STR('l') , STR('o') }; + + std::initializer_list il = { STR('H'), STR('e'), STR('l') , STR('l') , STR('o') }; + TextBuffer buffer{0}; + Text text(il, buffer.data(), buffer.size()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_construct_initializer_list_excess) + { + Compare_Text compare_text = { STR('H'), STR('e'), STR('l'), STR('l'), STR('o'), STR(' '), + STR('W'), STR('o'), STR('r'), STR('l'), STR('d') }; + + std::initializer_list il = { STR('H'), STR('e'), STR('l'), STR('l'), STR('o'), STR(' '), + STR('W'), STR('o'), STR('r'), STR('l'), STR('d'), STR(' '), + STR('T'), STR('h'), STR('e'), STR('r'), STR('e') }; + TextBuffer buffer{0}; + Text text(il, buffer.data(), buffer.size()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } +#endif + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment) + { + TextBuffer buffer{0}; + Text text(initial_text.begin(), initial_text.end(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + Text other_text(buffer2.data(), buffer2.size()); + + other_text = text; + + bool is_equal = Equal(text, other_text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); + CHECK(!other_text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment_excess) + { + TextBuffer buffer{0}; + Text text(longer_text.begin(), longer_text.end(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + Text other_text(buffer2.data(), buffer2.size()); + + other_text = text; + + bool is_equal = Equal(text, other_text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); + CHECK(other_text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment_iterface) + { + TextBuffer buffer{0}; + Text text1(initial_text.begin(), initial_text.end(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + Text text2(buffer2.data(), buffer2.size()); + + IText& itext1 = text1; + IText& itext2 = text2; + + itext2 = itext1; + + bool is_equal = Equal(text1, text2); + + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text1.is_truncated()); + CHECK(!text2.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment_iterface_excess) + { + TextBuffer buffer{0}; + Text text1(longer_text.begin(), longer_text.end(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + Text text2(buffer2.data(), buffer2.size()); + + IText& itext1 = text1; + IText& itext2 = text2; + + itext2 = itext1; + + bool is_equal = Equal(text1, text2); + + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text1.is_truncated()); + CHECK(text2.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_self_assignment) + { + TextBuffer buffer{0}; + Text text(initial_text.begin(), initial_text.end(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + Text other_text(text, buffer2.data(), buffer2.size()); + +#include "etl/private/diagnostic_self_assign_overloaded_push.h" + other_text = other_text; +#include "etl/private/diagnostic_pop.h" + + bool is_equal = Equal(text, other_text); + + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); + CHECK(!other_text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_self_assignment_excess) + { + TextBuffer buffer{0}; + Text text(longer_text.begin(), longer_text.end(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + Text other_text(text, buffer2.data(), buffer2.size()); + +#include "etl/private/diagnostic_self_assign_overloaded_push.h" + other_text = other_text; +#include "etl/private/diagnostic_pop.h" + + bool is_equal = Equal(text, other_text); + + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); + CHECK(other_text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment_from_literal) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + + text = STR("Hello World"); + + bool is_equal = Equal(std::u8string(STR("Hello World")), text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment_from_literal_excess) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + + text = STR("Hello World There"); + + bool is_equal = Equal(std::u8string(STR("Hello World")), text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment_from_literal_via_interface) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + IText& itext = text; + + itext = STR("Hello World"); + + bool is_equal = Equal(std::u8string(STR("Hello World")), itext); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!itext.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment_from_literal_via_interface_excess) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + IText& itext = text; + + itext = STR("Hello World There"); + + bool is_equal = Equal(std::u8string(STR("Hello World")), itext); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(itext.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_begin) + { + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + const Text constText(initial_text.c_str(), buffer2.data(), buffer2.size()); + + CHECK_EQUAL(&text[0], text.begin()); + CHECK_EQUAL(&constText[0], constText.begin()); + } + + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_end) + { + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + const Text constText(initial_text.c_str(), buffer2.data(), buffer2.size()); + + CHECK_EQUAL(&text[initial_text.size()], text.end()); + CHECK_EQUAL(&constText[initial_text.size()], constText.end()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_resize_up) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = 8; + + TextBuffer buffer{0}; + Text text(initial_text.c_str(), INITIAL_SIZE, buffer.data(), buffer.size()); + text.resize(NEW_SIZE); + + CHECK_EQUAL(text.size(), NEW_SIZE); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_resize_up_value) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = 8; + const value_t INITIAL_VALUE = STR('A'); + + TextBuffer buffer{0}; + Text text(INITIAL_SIZE, INITIAL_VALUE, buffer.data(), buffer.size()); + text.resize(NEW_SIZE, INITIAL_VALUE); + + std::array compare_text; + compare_text.fill(INITIAL_VALUE); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_resize_excess) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = SIZE + 1; + + TextBuffer buffer{0}; + Text text(INITIAL_SIZE, STR('A'), buffer.data(), buffer.size()); + text.resize(NEW_SIZE, STR('A')); + CHECK_EQUAL(SIZE, text.size()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_resize_down) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = 2; + + TextBuffer buffer{0}; + Text text(INITIAL_SIZE, STR('A'), buffer.data(), buffer.size()); + text.resize(NEW_SIZE); + + CHECK_EQUAL(text.size(), NEW_SIZE); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_resize_down_value) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = 2; + const value_t INITIAL_VALUE = STR('A'); + + TextBuffer buffer{0}; + Text text(INITIAL_SIZE, INITIAL_VALUE, buffer.data(), buffer.size()); + text.resize(NEW_SIZE, INITIAL_VALUE); + + CHECK_EQUAL(text.size(), NEW_SIZE); + + std::array compare_text; + compare_text.fill(INITIAL_VALUE); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_uninitialized_resize_up) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = 8; + const value_t INITIAL_VALUE = STR('A'); + const value_t FILL_VALUE = STR('B'); + + TextBuffer buffer{0}; + Text text(INITIAL_SIZE, INITIAL_VALUE, buffer.data(), buffer.size()); + + Text::pointer pbegin = &text.front(); + Text::pointer pend = &text.back() + 1; + Text::pointer pmax = pbegin + text.max_size(); + + // Fill free space with a pattern. + std::fill(pend, pmax, FILL_VALUE); + + text.uninitialized_resize(NEW_SIZE); + + std::array compare_text; + compare_text.fill(FILL_VALUE); + std::fill(compare_text.begin(), compare_text.begin() + INITIAL_SIZE, INITIAL_VALUE); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); + + CHECK_EQUAL(text.size(), NEW_SIZE); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_uninitialized_resize_up_excess) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = SIZE + 1; + + TextBuffer buffer{0}; + Text text(INITIAL_SIZE, STR('A'), buffer.data(), buffer.size()); + + text.uninitialized_resize(NEW_SIZE); + + CHECK_EQUAL(text.size(), SIZE); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_uninitialized_resize_down) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = 2; + const value_t INITIAL_VALUE = STR('A'); + const value_t FILL_VALUE = STR('B'); + + TextBuffer buffer{0}; + Text text(INITIAL_SIZE, INITIAL_VALUE, buffer.data(), buffer.size()); + + Text::pointer pbegin = &text.front(); + Text::pointer pend = &text.back() + 1; + Text::pointer pmax = pbegin + text.max_size(); + + // Fill free space with a pattern. + std::fill(pend, pmax, FILL_VALUE); + + text.uninitialized_resize(NEW_SIZE); + + std::array compare_text; + compare_text.fill(INITIAL_VALUE); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); + + CHECK_EQUAL(text.size(), NEW_SIZE); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_fill) + { + TextBuffer buffer1{ 0 }; + TextBuffer buffer2{ 0 }; + Text text(11, STR('A'), buffer1.data(), buffer1.size()); + Text expected(11, STR('B'), buffer2.data(), buffer2.size()); + + text.fill(STR('B')); + + bool is_equal = Equal(expected, text); + CHECK(is_equal); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_empty_full) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + text.resize(text.max_size(), STR('A')); + + CHECK(!text.empty()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_empty_half) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + text.resize(text.max_size() / 2, STR('A')); + + CHECK(!text.empty()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_empty_empty) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + + CHECK(text.empty()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_full_full) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + text.resize(text.max_size(), STR('A')); + + CHECK(text.full()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_full_half) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + text.resize(text.max_size() / 2, STR('A')); + + CHECK(!text.full()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_full_empty) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + + CHECK(!text.full()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_index) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + for (size_t i = 0UL; i < text.size(); ++i) + { + CHECK_EQUAL(text[i], compare_text[i]); + } + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_index_const) + { + const Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + const Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + for (size_t i = 0UL; i < text.size(); ++i) + { + CHECK_EQUAL(text[i], compare_text[i]); + } + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_at) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + for (size_t i = 0UL; i < text.size(); ++i) + { + CHECK_EQUAL(text.at(i), compare_text.at(i)); + } + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + CHECK_THROW(text.at(text.size()), etl::string_out_of_bounds); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_at_const) + { + const Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + const Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + for (size_t i = 0UL; i < text.size(); ++i) + { + CHECK_EQUAL(text.at(i), compare_text.at(i)); + } + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + CHECK_THROW(text.at(text.size()), etl::string_out_of_bounds); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_front) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + CHECK(text.front() == compare_text.front()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_front_const) + { + const Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + const Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + CHECK(text.front() == compare_text.front()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_back) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + CHECK(text.back() == compare_text.back()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_back_const) + { + const Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + const Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + CHECK(text.back() == compare_text.back()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_data) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + Text text(compare_text.begin(), compare_text.end(), buffer.data(), buffer.size()); + + bool is_equal = std::equal(text.data(), + text.data() + text.size(), + compare_text.begin()); + + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_data_const) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + const Text text(compare_text.begin(), compare_text.end(), buffer.data(), buffer.size()); + + bool is_equal = std::equal(text.data(), + text.data() + text.size(), + compare_text.begin()); + + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_string) + { + Compare_Text compare_input(initial_text.c_str()); + + TextBuffer buffer{0}; + Text input(initial_text.c_str(), buffer.data(), buffer.size()); + + Compare_Text compare_text; + + TextBuffer buffer2{0}; + Text text(buffer2.data(), buffer2.size()); + + compare_text.assign(compare_input); + text.assign(input); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_string_excess) + { + Compare_Text compare_input(initial_text.c_str()); + + TextBufferL bufferl{0}; + Text input(longer_text.c_str(), bufferl.data(), bufferl.size()); + + Compare_Text compare_text; + + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + + compare_text.assign(compare_input); + text.assign(input); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_pointer) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + text.assign(initial_text.c_str()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_pointer_excess) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + text.assign(longer_text.c_str()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_pointer_length) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + text.assign(initial_text.c_str(), initial_text.size()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_pointer_length_excess) + { + Compare_Text compare_text(longer_text.c_str()); + + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + text.assign(longer_text.c_str(), longer_text.size()); + + compare_text.resize(text.max_size()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_range) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + + text.assign(compare_text.begin(), compare_text.end()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_range_excess) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + + text.assign(longer_text.begin(), longer_text.end()); + + CHECK_EQUAL(initial_text.size(), text.size()); + + bool is_equal = Equal(initial_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_size_value) + { + const size_t INITIAL_SIZE = 5; + const value_t INITIAL_VALUE = STR('A'); + + std::array compare_text; + compare_text.fill(INITIAL_VALUE); + + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + text.assign(INITIAL_SIZE, INITIAL_VALUE); + + CHECK(text.size() == INITIAL_SIZE); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_size_value_excess) + { + const size_t INITIAL_SIZE = SIZE; + const size_t EXCESS_SIZE = SIZE + 1; + const value_t INITIAL_VALUE = STR('A'); + std::array compare_text; + compare_text.fill(INITIAL_VALUE); + + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + text.assign(EXCESS_SIZE, INITIAL_VALUE); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_push_back) + { + Compare_Text compare_text; + + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + + for (size_t i = 0UL; i < SIZE; ++i) + { + compare_text.push_back(STR('A') + value_t(i)); + } + + for (size_t i = 0UL; i < SIZE; ++i) + { + text.push_back(STR('A') + value_t(i)); + } + + CHECK_EQUAL(etl::strlen(compare_text.data()), etl::strlen(text.data())); + CHECK_EQUAL(compare_text.size(), text.size()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_push_back_excess) + { + Compare_Text compare_text; + + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + + for (size_t i = 0UL; i < SIZE; ++i) + { + compare_text.push_back(STR('A') + value_t(i)); + } + + for (size_t i = 0UL; i < SIZE; ++i) + { + text.push_back(STR('A') + value_t(i)); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + text.push_back(STR('A') + value_t(SIZE)); + + CHECK_EQUAL(etl::strlen(compare_text.data()), etl::strlen(text.data())); + CHECK_EQUAL(compare_text.size(), text.size()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_pop_back) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + compare_text.pop_back(); + compare_text.pop_back(); + + text.pop_back(); + text.pop_back(); + + CHECK_EQUAL(compare_text.size(), text.size()); + + bool is_equal = Equal(compare_text, text); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_value) + { + const size_t INITIAL_SIZE = 5; + const value_t INITIAL_VALUE = STR('A'); + + for (size_t offset = 0; offset <= INITIAL_SIZE; ++offset) + { + Compare_Text compare_text; + + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + + text.assign(initial_text.begin(), initial_text.begin() + INITIAL_SIZE); + compare_text.assign(initial_text.begin(), initial_text.begin() + INITIAL_SIZE); + + text.insert(text.begin() + offset, INITIAL_VALUE); + compare_text.insert(compare_text.begin() + offset, INITIAL_VALUE); + + CHECK_EQUAL(compare_text.size(), text.size()); + + bool is_equal = Equal(compare_text, text); + + CHECK(is_equal); + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_value_excess) + { + Compare_Text compare_text(initial_text.begin(), initial_text.end()); + TextBuffer buffer{0}; + Text text(initial_text.begin(), initial_text.end(), buffer.data(), buffer.size()); + + const value_t INITIAL_VALUE = STR('A'); + + size_t offset = 2UL; + text.insert(text.cbegin() + offset, INITIAL_VALUE); + compare_text.insert(compare_text.cbegin() + offset, INITIAL_VALUE); + compare_text.erase(compare_text.cend() - 1); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); + + offset = 0; + text.insert(text.cbegin() + offset, STR('A')); + compare_text.insert(compare_text.cbegin() + offset, STR('A')); + compare_text.erase(compare_text.cend() - 1); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + is_equal = Equal(compare_text, text); + CHECK(is_equal); + + offset = text.size(); + text.insert(text.cbegin() + offset, STR('A')); + compare_text.insert(compare_text.cbegin() + offset, STR('A')); + compare_text.erase(compare_text.cend() - 1); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + is_equal = Equal(compare_text, text); + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_n_value) + { + Compare_Text compare_text; + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + + const size_t INITIAL_SIZE = 5UL; + const size_t INSERT_SIZE = 3UL; + const value_t INITIAL_VALUE = STR('A'); + + for (size_t offset = 0UL; offset <= INITIAL_SIZE; ++offset) + { + text.assign(initial_text.begin(), initial_text.begin() + INITIAL_SIZE); + compare_text.assign(initial_text.begin(), initial_text.begin() + INITIAL_SIZE); + text.insert(text.begin() + offset, INSERT_SIZE, INITIAL_VALUE); + compare_text.insert(compare_text.begin() + offset, INSERT_SIZE, INITIAL_VALUE); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_n_value_excess) + { + Compare_Text compare_text; + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + + const size_t INSERT_SIZE = 4UL; + const value_t INSERT_VALUE = STR('A'); + + size_t offset = 0UL; + compare_text.assign(initial_text.cbegin(), initial_text.cend()); + text.assign(initial_text.cbegin(), initial_text.cend()); + compare_text.insert(compare_text.cbegin() + offset, INSERT_SIZE, INSERT_VALUE); + compare_text.erase(compare_text.cend() - INSERT_SIZE, compare_text.cend()); + text.insert(text.cbegin() + offset, INSERT_SIZE, INSERT_VALUE); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); + + offset = 2; + compare_text.assign(initial_text.cbegin(), initial_text.cend()); + text.assign(initial_text.cbegin(), initial_text.cend()); + compare_text.insert(compare_text.cbegin() + offset, INSERT_SIZE, INSERT_VALUE); + compare_text.erase(compare_text.cend() - INSERT_SIZE, compare_text.cend()); + text.assign(initial_text.cbegin(), initial_text.cend()); + text.insert(text.cbegin() + offset, INSERT_SIZE, INSERT_VALUE); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + is_equal = Equal(compare_text, text); + CHECK(is_equal); + + offset = 4; + compare_text.assign(initial_text.cbegin(), initial_text.cend()); + text.assign(initial_text.cbegin(), initial_text.cend()); + compare_text.insert(compare_text.cbegin() + offset, INSERT_SIZE, INSERT_VALUE); + compare_text.erase(compare_text.cend() - INSERT_SIZE, compare_text.cend()); + text.assign(initial_text.cbegin(), initial_text.cend()); + text.insert(text.cbegin() + offset, INSERT_SIZE, INSERT_VALUE); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + is_equal = Equal(compare_text, text); + CHECK(is_equal); + + offset = text.size(); + compare_text.assign(initial_text.cbegin(), initial_text.cend()); + text.assign(initial_text.cbegin(), initial_text.cend()); + compare_text.insert(compare_text.cbegin() + offset, INSERT_SIZE, INSERT_VALUE); + compare_text.erase(compare_text.cend() - INSERT_SIZE, compare_text.cend()); + text.assign(initial_text.cbegin(), initial_text.cend()); + text.insert(text.cbegin() + offset, INSERT_SIZE, INSERT_VALUE); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + is_equal = Equal(compare_text, text); + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_range) + { + const size_t INITIAL_SIZE = 5UL; + + for (size_t offset = 0UL; offset <= INITIAL_SIZE; ++offset) + { + Compare_Text compare_text; + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + + text.assign(initial_text.cbegin(), initial_text.cbegin() + INITIAL_SIZE); + compare_text.assign(initial_text.cbegin(), initial_text.cbegin() + INITIAL_SIZE); + text.insert(text.cbegin() + offset, insert_text.cbegin(), insert_text.cend()); + compare_text.insert(compare_text.cbegin() + offset, insert_text.cbegin(), insert_text.cend()); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_range_excess) + { + const size_t INITIAL_SIZE = 5UL; + const value_t INITIAL_VALUE = STR('A'); + + Compare_Text compare_text; + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + + size_t offset = 0UL; + + compare_text.assign(INITIAL_SIZE, INITIAL_VALUE); + text.assign(INITIAL_SIZE, INITIAL_VALUE); + compare_text.insert(compare_text.cbegin() + offset, initial_text.cbegin(), initial_text.cend()); + compare_text.resize(initial_text.size()); + text.insert(text.cbegin() + offset, initial_text.cbegin(), initial_text.cend()); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); + + offset = 2; + + compare_text.assign(INITIAL_SIZE, INITIAL_VALUE); + text.assign(INITIAL_SIZE, INITIAL_VALUE); + compare_text.insert(compare_text.cbegin() + offset, initial_text.cbegin(), initial_text.cend()); + compare_text.resize(initial_text.size()); + text.insert(text.cbegin() + offset, initial_text.cbegin(), initial_text.cend()); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + is_equal = Equal(compare_text, text); + CHECK(is_equal); + + + offset = 4; + + compare_text.assign(INITIAL_SIZE, INITIAL_VALUE); + text.assign(INITIAL_SIZE, INITIAL_VALUE); + compare_text.insert(compare_text.cbegin() + offset, initial_text.cbegin(), initial_text.cend()); + compare_text.resize(initial_text.size()); + text.insert(text.cbegin() + offset, initial_text.cbegin(), initial_text.cend()); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + CHECK_EQUAL(compare_text.size(), text.size()); + is_equal = Equal(compare_text, text); + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_range_self) + { + size_t length = SIZE_L / 2; + + for (size_t offset = 10UL; offset < length; ++offset) + { + Compare_Text compare_text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + TextBufferL bufferl{0}; + Text text(bufferl.data(), bufferl.size()); + text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + + text.insert(text.cbegin() + offset, text.cbegin() + 5, text.cbegin() + 10); + compare_text.insert(compare_text.cbegin() + offset, compare_text.cbegin() + 5, compare_text.cbegin() + 10); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_size_t_position_string) + { + size_t s = short_text.size(); + (void)s; + + assert(s <= 5); + + for (size_t offset = s; offset <= short_text.size(); ++offset) + { + Compare_Text compare_text(short_text.cbegin(), short_text.cend()); + TextBuffer buffer{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + Text text(short_text.begin(), short_text.end(), buffer.data(), buffer.size()); + + TextBuffer buffer2{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + Text insert(insert_text.begin(), insert_text.end(), buffer2.data(), buffer2.size()); + + text.insert(offset, insert); + compare_text.insert(offset, insert_text); + compare_text.resize(std::min(compare_text.size(), SIZE)); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_size_t_position_string_2) + { + + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_size_t_position_string_excess) + { +#include "etl/private/diagnostic_array_bounds_push.h" + for (size_t offset = 0UL; offset <= initial_text.size(); ++offset) + { + Compare_Text compare_text(initial_text.cbegin(), initial_text.cend()); + + TextBuffer buffer{ 0 }; + Text text(initial_text.begin(), initial_text.end(), buffer.data(), buffer.size()); + + TextBuffer buffer2{ 0 }; + Text insert(insert_text.begin(), insert_text.end(), buffer2.data(), buffer2.size()); + + text.insert(offset, insert); + compare_text.insert(offset, insert_text); + compare_text.resize(std::min(compare_text.size(), SIZE)); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_size_t_position_string_from_truncated) + { + for (size_t offset = 0UL; offset <= short_text.size(); ++offset) + { + Compare_Text compare_text(short_text.cbegin(), short_text.cend()); + + TextBuffer buffer{0}; + Text text(short_text.begin(), short_text.end(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + Text insert(longer_text.begin(), longer_text.end(), buffer2.data(), buffer2.size()); + + insert.erase(insert.cbegin(), insert.cend()); + insert.append(insert_text.cbegin(), insert_text.cend()); + + text.insert(offset, insert); + compare_text.insert(offset, insert_text); + compare_text.resize(std::min(compare_text.size(), SIZE)); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_size_t_position_string_subpos_sunlen) + { + Compare_Text compare_text(short_text.cbegin(), short_text.cend()); + + TextBuffer buffer{0}; + Text text(short_text.begin(), short_text.end(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + Text insert(insert_text.begin(), insert_text.end(), buffer2.data(), buffer2.size()); + + text.insert(0, insert, 0, insert.size()); + compare_text.insert(0, insert_text, 0, insert_text.size()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + compare_text.assign(short_text.cbegin(), short_text.cend()); + text.assign(short_text.cbegin(), short_text.cend()); + + text.insert(2, insert, 2, insert.size() - 2); + compare_text.insert(2, insert_text, 2, insert_text.size() - 2); + compare_text.resize(std::min(compare_text.size(), SIZE)); + + CHECK_EQUAL(compare_text.size(), text.size()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + compare_text.assign(short_text.cbegin(), short_text.cend()); + text.assign(short_text.cbegin(), short_text.cend()); + + text.insert(short_text.size(), insert, 0, insert.size()); + compare_text.insert(short_text.size(), insert_text, 0, insert_text.size()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_append_string) + { + Compare_Text compare_text(short_text.c_str()); + + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + Text append(insert_text.c_str(), buffer2.data(), buffer2.size()); + + // Non-overflow. + compare_text.append(insert_text); + text.append(append); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + append.assign(initial_text.c_str()); + + compare_text.append(initial_text); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.append(append); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_append_truncated_string) + { +#include "etl/private/diagnostic_array_bounds_push.h" + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + + TextBufferS buffers{0}; + Text append(short_text.c_str(), buffers.data(), buffers.size()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(append.is_truncated()); +#endif + + text.append(append); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_append_string_to_self) + { + Compare_Text compare_text(short_text.c_str()); + + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + + // Non-overflow. + compare_text.append(compare_text); + text.append(text); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(shorter_text.c_str()); + text.assign(shorter_text.c_str()); + + compare_text.append(compare_text); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.append(text); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_append_string_subpos_sublen) + { + Compare_Text compare_text(short_text.c_str()); + + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + Text append(insert_text.c_str(), buffer2.data(), buffer2.size()); + + // Whole string. + compare_text.append(insert_text, 0, std::u8string::npos); + text.append(append, 0, Text::npos); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Partial string. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + append.assign(initial_text.c_str()); + + compare_text.append(short_text, 1, 3); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.append(append, 1, 3); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + append.assign(initial_text.c_str()); + + compare_text.append(initial_text, 1, initial_text.size()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.append(append, 1, append.size()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_append_truncated_string_subpos_sublen) + { + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + + TextBufferS buffer2{0}; + Text append(short_text.c_str(), buffer2.data(), buffer2.size()); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(append.is_truncated()); +#endif + + text.append(append, 1, 2); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_append_c_string) + { + // Non-overflow. + Compare_Text compare_text(short_text.c_str()); + + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + + // Whole string. + compare_text.append(insert_text.c_str()); + text.append(insert_text.c_str()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.append(initial_text.c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.append(initial_text.c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_append_n_c) + { + // Non-overflow. + Compare_Text compare_text(short_text.c_str()); + + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + + // Non-overflow. + compare_text.append(5, STR('A')); + text.append(5, STR('A')); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.append(SIZE, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.append(SIZE, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_append_range) + { + // Non-overflow. + Compare_Text compare_text(short_text.c_str()); + + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + Text append(insert_text.c_str(), buffer2.data(), buffer2.size()); + + compare_text.append(insert_text.begin(), insert_text.end()); + text.append(append.begin(), append.end()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + append.assign(initial_text.c_str()); + + compare_text.append(initial_text.begin(), initial_text.end()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.append(append.begin(), append.end()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_position_length_string) + { + // Non-overflow short text, npos. + Compare_Text compare_text(short_text.c_str()); + + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, TextT(STR("Replace"))); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Non-overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, 2, Compare_Text(STR("Replace"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 2, TextT(STR("Replace"))); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, 2, Compare_Text(STR("Replace with some text"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 2, TextT(STR("Replace with some text"))); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow short text, npos. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace with some text"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, TextT(STR("Replace with some text"))); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 7, Compare_Text(STR("Replace"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 7, TextT(STR("Replace"))); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 2, Compare_Text(STR("Replace with some text"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 2, TextT(STR("Replace with some text"))); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow, npos. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace with some text"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, TextT(STR("Replace with some text"))); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_first_last_string) + { + // Non-overflow short text. + Compare_Text compare_text(short_text.c_str()); + + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, Compare_Text(STR("Replace"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, TextT(STR("Replace"))); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, Compare_Text(STR("Replace with some text"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, TextT(STR("Replace with some text"))); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 9, Compare_Text(STR("Replace"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 9, TextT(STR("Replace"))); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, Compare_Text(STR("Replace with some text"))); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, TextT(STR("Replace with some text"))); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_position_length_string_subposition_sublength) + { + // Non-overflow short text. + Compare_Text compare_text(short_text.c_str()); + + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + + compare_text.replace(2, 4, Compare_Text(STR("Replace")), 1, 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, TextT(STR("Replace")), 1, 5); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Non-overflow short text, npos. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace")), 1, Compare_Text::npos); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, TextT(STR("Replace")), 1, Text::npos); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, 4, Compare_Text(STR("Replace with some text")), 1, 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, TextT(STR("Replace with some text")), 1, 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow short text, npos. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace with some text")), 1, Compare_Text::npos); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, TextT(STR("Replace with some text")), 1, Text::npos); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 7, Compare_Text(STR("Replace")), 1, 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 7, TextT(STR("Replace")), 1, 5); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Non-overflow, npos. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace")), 1, Compare_Text::npos); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, TextT(STR("Replace")), 1, Text::npos); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 4, Compare_Text(STR("Replace with some text")), 1, 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, TextT(STR("Replace with some text")), 1, 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow, npos. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace with some text")), 1, Compare_Text::npos); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, TextT(STR("Replace with some text")), 1, Text::npos); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_position_length_pointer) + { + // Non-overflow short text. + Compare_Text compare_text(short_text.c_str()); + + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + + compare_text.replace(2, 4, Compare_Text(STR("Replace")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, TextT(STR("Replace")).c_str()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Non-overflow short text, npos. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, TextT(STR("Replace")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, 4, Compare_Text(STR("Replace with some text")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, TextT(STR("Replace with some text")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow short text, npos. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace with some text")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, TextT(STR("Replace with some text")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 7, Compare_Text(STR("Replace")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 7, TextT(STR("Replace")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Non-overflow, npos. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, TextT(STR("Replace")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 4, Compare_Text(STR("Replace with some text")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, TextT(STR("Replace with some text")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow, npos. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace with some text")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, TextT(STR("Replace with some text")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_first_last_pointer) + { + // Non-overflow short text. + Compare_Text compare_text(short_text.c_str()); + + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, Compare_Text(STR("Replace")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, TextT(STR("Replace")).c_str()); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, Compare_Text(STR("Replace with some text")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, TextT(STR("Replace with some text")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 9, Compare_Text(STR("Replace")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 9, TextT(STR("Replace")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, Compare_Text(STR("Replace with some text")).c_str()); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, TextT(STR("Replace with some text")).c_str()); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_position_length_pointer_n) + { + // Non-overflow short text. + Compare_Text compare_text(short_text.c_str()); + + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + + compare_text.replace(2, 4, Compare_Text(STR("Replace")).c_str(), 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, TextT(STR("Replace")).c_str(), 5); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Non-overflow short text, npos. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace")).c_str(), 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, TextT(STR("Replace")).c_str(), 5); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, 4, Compare_Text(STR("Replace with some text")).c_str(), 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, TextT(STR("Replace with some text")).c_str(), 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow short text, npos. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace with some text")).c_str(), 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, TextT(STR("Replace with some text")).c_str(), 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 7, Compare_Text(STR("Replace")).c_str(), 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 7, TextT(STR("Replace")).c_str(), 5); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Non-overflow, npos. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace")).c_str(), 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, TextT(STR("Replace")).c_str(), 5); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 4, Compare_Text(STR("Replace with some text")).c_str(), 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, TextT(STR("Replace with some text")).c_str(), 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow, npos. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, Compare_Text(STR("Replace with some text")).c_str(), 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, TextT(STR("Replace with some text")).c_str(), 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_first_last_pointer_n) + { + // Non-overflow short text. + Compare_Text compare_text(short_text.c_str()); + + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, Compare_Text(STR("Replace")).c_str(), 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, TextT(STR("Replace")).c_str(), 5); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + +#include "etl/private/diagnostic_array_bounds_push.h" +#include "etl/private/diagnostic_stringop_overread_push.h" + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, Compare_Text(STR("Replace with some text")).c_str(), 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, TextT(STR("Replace with some text")).c_str(), 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif +#include "etl/private/diagnostic_pop.h" +#include "etl/private/diagnostic_pop.h" + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 9, Compare_Text(STR("Replace")).c_str(), 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 9, TextT(STR("Replace")).c_str(), 5); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + +#include "etl/private/diagnostic_array_bounds_push.h" +#include "etl/private/diagnostic_stringop_overread_push.h" + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, Compare_Text(STR("Replace with some text")).c_str(), 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, TextT(STR("Replace with some text")).c_str(), 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif +#include "etl/private/diagnostic_pop.h" +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_position_length_n_c) + { + // Non-overflow short text. + Compare_Text compare_text(short_text.c_str()); + + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + + compare_text.replace(2, 4, 7, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, 7, STR('A')); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Non-overflow short text, npos. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, 7, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, 7, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, 4, 15, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, 15, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow short text, npos. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, 15, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, 15, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 7, 7, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 7, 7, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Non-overflow, npos. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, 7, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, 7, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, 4, 15, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, 4, 15, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Overflow, npos. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(2, Compare_Text::npos, 15, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(2, Text::npos, 15, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_first_last_n_c) + { + // Non-overflow short text. + Compare_Text compare_text(short_text.c_str()); + + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, 7, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, 7, STR('A')); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, 15, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, 15, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 9, 7, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 9, 7, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, 15, STR('A')); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, 15, STR('A')); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_replace_first_last_first_last) + { + // Non-overflow short text. + Compare_Text compare_text(short_text.c_str()); + + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + + Compare_Text replace(STR("Replace")); + Compare_Text replace_long(STR("Replace with some text")); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, replace.begin() + 1, replace.begin() + 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, replace.begin() + 1, replace.begin() + 5); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow short text. + compare_text.assign(short_text.c_str()); + text.assign(short_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, replace_long.begin() + 1, replace_long.begin() + 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, replace_long.begin() + 1, replace_long.begin() + 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + + // Non-overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 7, replace.begin() + 1, replace.begin() + 5); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 7, replace_long.begin() + 1, replace_long.begin() + 5); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + // Overflow. + compare_text.assign(initial_text.c_str()); + text.assign(initial_text.c_str()); + + compare_text.replace(compare_text.begin() + 2, compare_text.begin() + 4, replace_long.begin() + 1, replace_long.begin() + 15); + compare_text.resize(std::min(compare_text.size(), SIZE)); + text.replace(text.begin() + 2, text.begin() + 4, replace_long.begin() + 1, replace_long.begin() + 15); + + is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_erase_single_iterator) + { + Compare_Text compare_text(initial_text.c_str()); + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + Compare_Text::iterator citr = compare_text.erase(compare_text.begin() + 2); + Text::iterator ditr = text.erase(text.begin() + 2); + CHECK(*citr == *ditr); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_erase_single_const_iterator) + { + Compare_Text compare_text(initial_text.c_str()); + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + Compare_Text::iterator citr = compare_text.erase(compare_text.cbegin() + 2); + Text::iterator ditr = text.erase(text.cbegin() + 2); + CHECK(*citr == *ditr); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_erase_range) + { + Compare_Text compare_text(initial_text.c_str()); + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + Compare_Text::iterator citr = compare_text.erase(compare_text.cbegin() + 2, compare_text.cbegin() + 4); + Text::iterator ditr = text.erase(text.cbegin() + 2, text.cbegin() + 4); + CHECK(*citr == *ditr); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_clear) + { + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + text.clear(); + + CHECK_EQUAL(text.size(), size_t(0)); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_iterator) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + bool is_equal = std::equal(text.begin(), text.end(), compare_text.begin()); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_const_iterator) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + bool is_equal = std::equal(text.cbegin(), text.cend(), compare_text.cbegin()); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_reverse_iterator) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + bool is_equal = std::equal(text.rbegin(), text.rend(), compare_text.rbegin()); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_const_reverse_iterator) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + bool is_equal = std::equal(text.crbegin(), text.crend(), compare_text.crbegin()); + CHECK(is_equal); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_equal) + { + TextBuffer buffer{0}; + const Text initial1(initial_text.c_str(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + const Text initial2(initial_text.c_str(), buffer2.data(), buffer2.size()); + + CHECK(initial1 == initial2); + + TextBuffer buffer3; + const Text different(different_text.c_str(), buffer3.data(), buffer3.size()); + + CHECK(!(initial1 == different)); + + TextBuffer buffer4; + const Text shorter(shorter_text.c_str(), buffer4.data(), buffer4.size()); + + CHECK(!(shorter == initial1)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_not_equal) + { + TextBuffer buffer{0}; + const Text initial1(initial_text.c_str(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + const Text initial2(initial_text.c_str(), buffer2.data(), buffer2.size()); + + CHECK(!(initial1 != initial2)); + + TextBuffer buffer3; + const Text different(different_text.begin(), different_text.end(), buffer3.data(), buffer3.size()); + + CHECK(initial1 != different); + + TextBuffer buffer4; + const Text shorter(shorter_text.begin(), shorter_text.end(), buffer4.data(), buffer4.size()); + + CHECK(shorter != initial1); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_less_than) + { + TextBuffer buffer{0}; + const Text less(less_text.c_str(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + const Text initial(initial_text.c_str(), buffer2.data(), buffer2.size()); + + // String-String + CHECK((less < initial) == (less_text < initial_text)); + CHECK((initial < less) == (initial_text < less_text)); + + TextBuffer buffer3; + const Text greater(greater_text.c_str(), buffer3.data(), buffer3.size()); + CHECK((greater < initial) == (greater_text < initial_text)); + CHECK((initial < greater) == (initial_text < greater_text)); + + TextBuffer buffer4; + const Text shorter(shorter_text.c_str(), buffer4.data(), buffer4.size()); + CHECK((shorter < initial) == (shorter_text < initial_text)); + CHECK((initial < shorter) == (initial_text < shorter_text)); + + CHECK((initial < initial) == (initial_text < initial_text)); + CHECK((initial < initial) == (initial_text < initial_text)); + + // String-Pointer Pointer-String + CHECK((less < pinitial_text) == (less_text < pinitial_text)); + CHECK((pinitial_text < less) == (pinitial_text < less_text)); + + CHECK((greater < pinitial_text) == (greater_text < pinitial_text)); + CHECK((pinitial_text < greater) == (pinitial_text < greater_text)); + + CHECK((shorter < pinitial_text) == (shorter_text < pinitial_text)); + CHECK((pinitial_text < shorter) == (pinitial_text < shorter_text)); + + CHECK((initial < pinitial_text) == (initial_text < pinitial_text)); + CHECK((pinitial_text < initial) == (pinitial_text < initial_text)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_less_than_or_equal) + { + TextBuffer buffer{0}; + const Text less(less_text.c_str(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + const Text initial(initial_text.c_str(), buffer2.data(), buffer2.size()); + + // String-String + CHECK((less <= initial) == (less_text <= initial_text)); + CHECK((initial <= less) == (initial_text <= less_text)); + + TextBuffer buffer3; + const Text greater(greater_text.c_str(), buffer3.data(), buffer3.size()); + CHECK((greater <= initial) == (greater_text <= initial_text)); + CHECK((initial <= greater) == (initial_text <= greater_text)); + + TextBuffer buffer4; + const Text shorter(shorter_text.c_str(), buffer4.data(), buffer4.size()); + CHECK((shorter <= initial) == (shorter_text <= initial_text)); + CHECK((initial <= shorter) == (initial_text <= shorter_text)); + + CHECK((initial <= initial) == (initial_text <= initial_text)); + CHECK((initial <= initial) == (initial_text <= initial_text)); + + // String-Pointer Pointer-String + CHECK((less <= pinitial_text) == (less_text <= pinitial_text)); + CHECK((pinitial_text <= less) == (pinitial_text <= less_text)); + + CHECK((greater <= pinitial_text) == (greater_text <= pinitial_text)); + CHECK((pinitial_text <= greater) == (pinitial_text <= greater_text)); + + CHECK((shorter <= pinitial_text) == (shorter_text <= pinitial_text)); + CHECK((pinitial_text <= shorter) == (pinitial_text <= shorter_text)); + + CHECK((initial <= pinitial_text) == (initial_text <= pinitial_text)); + CHECK((pinitial_text <= initial) == (pinitial_text <= initial_text)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_greater_than) + { + TextBuffer buffer{0}; + const Text less(less_text.c_str(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + const Text initial(initial_text.c_str(), buffer2.data(), buffer2.size()); + + // String-String + CHECK((less > initial) == (less_text > initial_text)); + CHECK((initial > less) == (initial_text > less_text)); + + TextBuffer buffer3; + const Text greater(greater_text.c_str(), buffer3.data(), buffer3.size()); + CHECK((greater > initial) == (greater_text > initial_text)); + CHECK((initial > greater) == (initial_text > greater_text)); + + TextBuffer buffer4; + const Text shorter(shorter_text.c_str(), buffer4.data(), buffer4.size()); + CHECK((shorter > initial) == (shorter_text > initial_text)); + CHECK((initial > shorter) == (initial_text > shorter_text)); + + CHECK((initial > initial) == (initial_text > initial_text)); + CHECK((initial > initial) == (initial_text > initial_text)); + + // String-Pointer Pointer-String + CHECK((less > pinitial_text) == (less_text > pinitial_text)); + CHECK((pinitial_text > less) == (pinitial_text > less_text)); + + CHECK((greater > pinitial_text) == (greater_text > pinitial_text)); + CHECK((pinitial_text > greater) == (pinitial_text > greater_text)); + + CHECK((shorter > pinitial_text) == (shorter_text > pinitial_text)); + CHECK((pinitial_text > shorter) == (pinitial_text > shorter_text)); + + CHECK((initial > pinitial_text) == (initial_text > pinitial_text)); + CHECK((pinitial_text > initial) == (pinitial_text > initial_text)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_greater_than_or_equal) + { + TextBuffer buffer{0}; + const Text less(less_text.begin(), less_text.end(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + const Text initial(initial_text.begin(), initial_text.end(), buffer2.data(), buffer2.size()); + + // String-String + CHECK((less >= initial) == (less_text >= initial_text)); + CHECK((initial >= less) == (initial_text >= less_text)); + + TextBuffer buffer3; + const Text greater(greater_text.begin(), greater_text.end(), buffer3.data(), buffer3.size()); + CHECK((greater >= initial) == (greater_text >= initial_text)); + CHECK((initial >= greater) == (initial_text >= greater_text)); + + TextBuffer buffer4; + const Text shorter(shorter_text.begin(), shorter_text.end(), buffer4.data(), buffer4.size()); + CHECK((shorter >= initial) == (shorter_text >= initial_text)); + CHECK((initial >= shorter) == (initial_text > shorter_text)); + + CHECK((initial >= initial) == (initial_text >= initial_text)); + CHECK((initial >= initial) == (initial_text >= initial_text)); + + // String-Pointer Pointer-String + CHECK((less >= pinitial_text) == (less_text >= pinitial_text)); + CHECK((pinitial_text >= less) == (pinitial_text >= less_text)); + + CHECK((greater >= pinitial_text) == (greater_text >= pinitial_text)); + CHECK((pinitial_text >= greater) == (pinitial_text >= greater_text)); + + CHECK((shorter >= pinitial_text) == (shorter_text >= pinitial_text)); + CHECK((pinitial_text >= shorter) == (pinitial_text >= shorter_text)); + + CHECK((initial >= pinitial_text) == (initial_text >= pinitial_text)); + CHECK((pinitial_text >= initial) == (pinitial_text >= initial_text)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_copy) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + value_t buffer1[SIZE]; + value_t buffer2[SIZE]; + + size_t length1 = compare_text.copy(buffer1, 5, 2); + buffer1[length1] = STR('\0'); + + size_t length2 = text.copy(buffer2, 5, 2); + buffer2[length2] = STR('\0'); + + CHECK_EQUAL(length1, length2); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + bool is_equal = std::equal(buffer1, + buffer1 + length1, + buffer2); + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_copy_start_pos_too_large) + { + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + value_t buffer1[SIZE]; + + size_t length1 = text.copy(buffer1, 5, SIZE); + + CHECK_EQUAL(0U, length1); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_copy_count_equals_npos) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + value_t buffer1[SIZE]; + value_t buffer2[SIZE]; + + size_t length1 = compare_text.copy(buffer1, Compare_Text::npos, 2); + buffer1[length1] = STR('\0'); + + size_t length2 = text.copy(buffer2, Text::npos, 2); + buffer2[length2] = STR('\0'); + + CHECK_EQUAL(length1, length2); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + bool is_equal = std::equal(buffer1, + buffer1 + length1, + buffer2); + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_copy_count_too_large) + { + Compare_Text compare_text(initial_text.c_str()); + + TextBuffer buffer{0}; + Text text(initial_text.c_str(), buffer.data(), buffer.size()); + + value_t buffer1[SIZE]; + value_t buffer2[SIZE]; + + size_t length1 = compare_text.copy(buffer1, SIZE, 2); + buffer1[length1] = STR('\0'); + + size_t length2 = text.copy(buffer2, SIZE, 2); + buffer2[length2] = STR('\0'); + + CHECK_EQUAL(length1, length2); +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + + bool is_equal = std::equal(buffer1, + buffer1 + length1, + buffer2); + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_string) + { + const value_t* the_haystack = STR("A haystack with a needle and another needle"); + + std::u8string compare_needle(STR("needle")); + + TextBuffer buffer{0}; + Text needle(STR("needle"), buffer.data(), buffer.size()); + + std::u8string compare_haystack(the_haystack); + + TextBufferL buffer2{0}; + Text haystack(the_haystack, buffer2.data(), buffer2.size()); + + size_t position1 = 0; + size_t position2 = 0; + + position1 = compare_haystack.find(compare_needle, position1); + position2 = haystack.find(needle, position2); + CHECK_EQUAL(position1, position2); + + position1 = compare_haystack.find(compare_needle, position1 + 1); + position2 = haystack.find(needle, position2 + 1); + CHECK_EQUAL(position1, position2); + + position2 = haystack.find(needle, position2 + 1); + CHECK_EQUAL(etl::u8string<50>::npos, position2); + + etl::u8string<50> pin(STR("pin")); + position2 = haystack.find(pin); + CHECK_EQUAL(IText::npos, position2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_pointer) + { + const value_t* the_haystack = STR("A haystack with a needle and another needle"); + + const value_t* needle = STR("needle"); + + std::u8string compare_haystack(the_haystack); + + TextBufferL buffer{0}; + Text haystack(the_haystack, buffer.data(), buffer.size()); + + size_t position1 = 0; + size_t position2 = 0; + + position1 = compare_haystack.find(needle, position1); + position2 = haystack.find(needle, position2); + CHECK_EQUAL(position1, position2); + + position1 = compare_haystack.find(needle, position1 + 1); + position2 = haystack.find(needle, position2 + 1); + CHECK_EQUAL(position1, position2); + + position2 = haystack.find(needle, position2 + 1); + CHECK_EQUAL(IText::npos, position2); + + const value_t* pin = STR("pin"); + position2 = haystack.find(pin); + CHECK_EQUAL(IText::npos, position2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_char_pointer_n) + { + const value_t* the_haystack = STR("A haystack with a needle and another needle"); + + const value_t* needle = STR("needle"); + + std::u8string compare_haystack(the_haystack); + + TextBufferL buffer{0}; + Text haystack(the_haystack, buffer.data(), buffer.size()); + + size_t position1 = 0; + size_t position2 = 0; + + position1 = compare_haystack.find(needle, position1, 3); + position2 = haystack.find(needle, position2, 3); + CHECK_EQUAL(position1, position2); + + position1 = compare_haystack.find(needle, position1 + 1, 3); + position2 = haystack.find(needle, position2 + 1, 3); + CHECK_EQUAL(position1, position2); + + position2 = haystack.find(needle, position2 + 1, 3); + CHECK_EQUAL(IText::npos, position2); + + const value_t* pin = STR("pin"); + position2 = haystack.find(pin, 0, 3); + CHECK_EQUAL(IText::npos, position2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_rfind_string) + { + const value_t* the_haystack = STR("A haystack with a needle and another needle"); + + std::u8string compare_needle(STR("needle")); + + TextBufferL buffer{0}; + Text needle(STR("needle"), buffer.data(), buffer.size()); + + std::u8string compare_haystack(the_haystack); + + TextBufferL buffer2{0}; + Text haystack(the_haystack, buffer2.data(), buffer2.size()); + + size_t position1 = std::u8string::npos; + size_t position2 = etl::u8string<50>::npos; + + position1 = compare_haystack.rfind(compare_needle, position1); + position2 = haystack.rfind(needle, position2); + CHECK_EQUAL(position1, position2); + + position1 = compare_haystack.rfind(compare_needle, compare_haystack.size() - 10); + position2 = haystack.rfind(needle, haystack.size() - 10); + CHECK_EQUAL(position1, position2); + + TextBufferL buffer3; + Text pin(STR("pin"), buffer3.data(), buffer3.size()); + position2 = haystack.rfind(pin); + CHECK_EQUAL(IText::npos, position2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_rfind_pointer) + { + const value_t* the_haystack = STR("A haystack with a needle and another needle"); + + std::u8string compare_haystack(the_haystack); + + TextBufferL buffer{0}; + Text haystack(the_haystack, buffer.data(), buffer.size()); + + const value_t* needle = STR("needle"); + + size_t position1 = std::u8string::npos; + size_t position2 = etl::u8string<50>::npos; + + position1 = compare_haystack.rfind(needle, position1); + position2 = haystack.rfind(needle, position2); + CHECK_EQUAL(position1, position2); + + position1 = compare_haystack.rfind(needle, compare_haystack.size() - 10); + position2 = haystack.rfind(needle, haystack.size() - 10); + CHECK_EQUAL(position1, position2); + + TextBufferL buffer2{0}; + Text pin(STR("pin"), buffer2.data(), buffer2.size()); + position2 = haystack.rfind(pin); + CHECK_EQUAL(IText::npos, position2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_rfind_pointer_n) + { + const value_t* the_haystack = STR("A haystack with a needle and another needle"); + + std::u8string compare_haystack(the_haystack); + + TextBufferL buffer{0}; + Text haystack(the_haystack, buffer.data(), buffer.size()); + + const value_t* needle = STR("needle"); + + size_t position1 = std::u8string::npos; + + size_t position2 = Text::npos; + + position1 = compare_haystack.rfind(needle, position1, 3); + position2 = haystack.rfind(needle, position2, 3); + CHECK_EQUAL(position1, position2); + + position1 = compare_haystack.rfind(needle, compare_haystack.size() - 10, 3); + position2 = haystack.rfind(needle, haystack.size() - 10, 3); + CHECK_EQUAL(position1, position2); + + position2 = haystack.rfind(STR("pin"), 3); + CHECK_EQUAL(IText::npos, position2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_rfind_c_position) + { + const value_t* the_haystack = STR("A haystack with a needle and another needle"); + + std::u8string compare_haystack(the_haystack); + + TextBufferL buffer{0}; + Text haystack(the_haystack, buffer.data(), buffer.size()); + + size_t position1 = std::u8string::npos; + size_t position2 = etl::u8string<50>::npos; + + position1 = compare_haystack.rfind(STR('e'), position1); + position2 = haystack.rfind(STR('e'), position2); + CHECK_EQUAL(position1, position2); + + position1 = compare_haystack.rfind(STR('e'), compare_haystack.size() - 10); + position2 = haystack.rfind(STR('e'), haystack.size() - 10); + CHECK_EQUAL(position1, position2); + + position2 = haystack.rfind(STR('z')); + CHECK_EQUAL(IText::npos, position2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_compare_string) + { + Compare_Text compare_text(STR("ABCDEF")); + + TextBuffer buffer{0}; + Text text(STR("ABCDEF"), buffer.data(), buffer.size()); + + int compare_result; + int result; + + // Equal. + compare_result = compare_text.compare(Compare_Text(STR("ABCDEF"))); + result = text.compare(TextT(STR("ABCDEF"))); + CHECK(compares_agree(compare_result, result)); + + // Less. + compare_result = compare_text.compare(Compare_Text(STR("ABCDEE"))); + result = text.compare(TextT(STR("ABCDEE"))); + CHECK(compares_agree(compare_result, result)); + + // Greater. + compare_result = compare_text.compare(Compare_Text(STR("ABCDEG"))); + result = text.compare(TextT(STR("ABCDEG"))); + CHECK(compares_agree(compare_result, result)); + + // Shorter. + compare_result = compare_text.compare(Compare_Text(STR("ABCDE"))); + result = text.compare(TextT(STR("ABCDE"))); + CHECK(compares_agree(compare_result, result)); + + // Longer. + compare_result = compare_text.compare(Compare_Text(STR("ABCDEFG"))); + result = text.compare(TextT(STR("ABCDEFG"))); + CHECK(compares_agree(compare_result, result)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_compare_position_length_string) + { + Compare_Text compare_text(STR("xxxABCDEFyyy")); + + TextBuffer buffer{0}; + Text text(STR("xxxABCDEFyyy"), buffer.data(), buffer.size()); + + int compare_result; + int result; + + // Equal. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("ABCDEF"))); + result = text.compare(3, 6, TextT(STR("ABCDEF"))); + CHECK(compares_agree(compare_result, result)); + + // Less. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("ABCDEE"))); + result = text.compare(3, 6, TextT(STR("ABCDEE"))); + CHECK(compares_agree(compare_result, result)); + + // Greater. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("ABCDEG"))); + result = text.compare(3, 6, TextT(STR("ABCDEG"))); + CHECK(compares_agree(compare_result, result)); + + // Shorter. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("ABCDE"))); + result = text.compare(3, 6, TextT(STR("ABCDE"))); + CHECK(compares_agree(compare_result, result)); + + // Longer. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("ABCDEFG"))); + result = text.compare(3, 6, TextT(STR("ABCDEFG"))); + CHECK(compares_agree(compare_result, result)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_compare_position_length_string_subposition_sublength) + { + Compare_Text compare_text(STR("xxxABCDEFyyy")); + + TextBuffer buffer{0}; + Text text(STR("xxxABCDEFyyy"), buffer.data(), buffer.size()); + + int compare_result; + int result; + + // Equal. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("aaABCDEFbb")), 2, 6); + result = text.compare(3, 6, TextT(STR("aaABCDEFbb")), 2, 6); + CHECK(compares_agree(compare_result, result)); + + // Less. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("aaABCDEEbb")), 2, 6); + result = text.compare(3, 6, TextT(STR("aaABCDEEbb")), 2, 6); + CHECK(compares_agree(compare_result, result)); + + // Greater. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("aaABCDEGbb")), 2, 6); + result = text.compare(3, 6, TextT(STR("aaABCDEGbb")), 2, 6); + CHECK(compares_agree(compare_result, result)); + + // Shorter. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("aaABCDEbb")), 2, 5); + result = text.compare(3, 6, TextT(STR("aaABCDEbb")), 2, 5); + CHECK(compares_agree(compare_result, result)); + + // Longer. + compare_result = compare_text.compare(3, 6, Compare_Text(STR("aaABCDEFGbb")), 2, 7); + result = text.compare(3, 6, TextT(STR("aaABCDEFGbb")), 2, 7); + CHECK(compares_agree(compare_result, result)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_compare_c_string) + { + Compare_Text compare_text(STR("ABCDEF")); + + TextBuffer buffer{0}; + Text text(STR("ABCDEF"), buffer.data(), buffer.size()); + + int compare_result; + int result; + + // Equal. + compare_result = compare_text.compare(STR("ABCDEF")); + result = text.compare(STR("ABCDEF")); + CHECK(compares_agree(compare_result, result)); + + // Less. + compare_result = compare_text.compare(STR("ABCDEE")); + result = text.compare(STR("ABCDEE")); + CHECK(compares_agree(compare_result, result)); + + // Greater. + compare_result = compare_text.compare(STR("ABCDEG")); + result = text.compare(STR("ABCDEG")); + CHECK(compares_agree(compare_result, result)); + + // Shorter. + compare_result = compare_text.compare(STR("ABCDE")); + result = text.compare(STR("ABCDE")); + CHECK(compares_agree(compare_result, result)); + + // Longer. + compare_result = compare_text.compare(STR("ABCDEFG")); + result = text.compare(STR("ABCDEFG")); + CHECK(compares_agree(compare_result, result)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_compare_position_length_c_string) + { + Compare_Text compare_text(STR("xxxABCDEFyyy")); + + TextBuffer buffer{0}; + Text text(STR("xxxABCDEFyyy"), buffer.data(), buffer.size()); + + int compare_result; + int result; + + // Equal. + compare_result = compare_text.compare(3, 6, STR("ABCDEF")); + result = text.compare(3, 6, STR("ABCDEF")); + CHECK(compares_agree(compare_result, result)); + + // Less. + compare_result = compare_text.compare(3, 6, STR("ABCDEE")); + result = text.compare(3, 6, STR("ABCDEE")); + CHECK(compares_agree(compare_result, result)); + + // Greater. + compare_result = compare_text.compare(3, 6, STR("ABCDEG")); + result = text.compare(3, 6, STR("ABCDEG")); + CHECK(compares_agree(compare_result, result)); + + // Shorter. + compare_result = compare_text.compare(3, 6, STR("ABCDE")); + result = text.compare(3, 6, STR("ABCDE")); + CHECK(compares_agree(compare_result, result)); + + // Longer. + compare_result = compare_text.compare(3, 6, STR("ABCDEFG")); + result = text.compare(3, 6, STR("ABCDEFG")); + CHECK(compares_agree(compare_result, result)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_compare_position_length_c_string_n) + { + Compare_Text compare_text(STR("xxxABCDEFyyy")); + + TextBuffer buffer{0}; + Text text(STR("xxxABCDEFyyy"), buffer.data(), buffer.size()); + + int compare_result; + int result; + + // Equal. + compare_result = compare_text.compare(3, 6, STR("ABCDEFbb"), 6); + result = text.compare(3, 6, STR("ABCDEFbb"), 6); + CHECK(compares_agree(compare_result, result)); + + // Less. + compare_result = compare_text.compare(3, 6, STR("ABCDEEbb"), 6); + result = text.compare(3, 6, STR("ABCDEEbb"), 6); + CHECK(compares_agree(compare_result, result)); + + // Greater. + compare_result = compare_text.compare(3, 6, STR("ABCDEGbb"), 6); + result = text.compare(3, 6, STR("ABCDEGbb"), 6); + CHECK(compares_agree(compare_result, result)); + + // Shorter. + compare_result = compare_text.compare(3, 6, STR("ABCDEbb"), 5); + result = text.compare(3, 6, STR("ABCDEbb"), 5); + CHECK(compares_agree(compare_result, result)); + + // Longer. + compare_result = compare_text.compare(3, 6, STR("ABCDEFGbb"), 7); + result = text.compare(3, 6, STR("ABCDEFGbb"), 7); + CHECK(compares_agree(compare_result, result)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_first_of_string_position) + { + Compare_Text compare_text(STR("ABCDEF")); + + TextBuffer buffer{0}; + Text text(STR("ABCDEF"), buffer.data(), buffer.size()); + + size_t position1 = compare_text.find_first_of(Compare_Text(STR("ZCXF"))); + size_t position2 = text.find_first_of(TextT(STR("ZCXF"))); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(Compare_Text(STR("WXYZ"))); + position2 = text.find_first_of(TextT(STR("WXYZ"))); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(Compare_Text(STR("ZCXF")), 3); + position2 = text.find_first_of(TextT(STR("ZCXF")), 3); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_first_of(Compare_Text(STR("ZCXF")), 100); + position2 = text.find_first_of(TextT(STR("ZCXF")), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_first_of_pointer_position) + { + Compare_Text compare_text(STR("ABCDEF")); + + TextBuffer buffer{0}; + Text text(STR("ABCDEF"), buffer.data(), buffer.size()); + + size_t position1 = compare_text.find_first_of(STR("ZCXF")); + size_t position2 = text.find_first_of(STR("ZCXF")); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(STR("WXYZ")); + position2 = text.find_first_of(STR("WXYZ")); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(STR("ZCXF"), 3); + position2 = text.find_first_of(STR("ZCXF"), 3); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_first_of(STR("ZCXF"), 100); + position2 = text.find_first_of(STR("ZCXF"), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_first_of_pointer_position_n) + { + Compare_Text compare_text(STR("ABCDEF")); + + TextBuffer buffer{0}; + Text text(STR("ABCDEF"), buffer.data(), buffer.size()); + + size_t position1 = compare_text.find_first_of(STR("ZCXF"), 0, 4); + size_t position2 = text.find_first_of(STR("ZCXF"), 0, 4); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(STR("WXYZ"), 0, 4); + position2 = text.find_first_of(STR("WXYZ"), 0, 4); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(STR("ZCXF"), 1, 3); + position2 = text.find_first_of(STR("ZCXF"), 1, 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(STR("ZCXF"), 3, 3); + position2 = text.find_first_of(STR("ZCXF"), 3, 3); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_first_of(STR("ZCXF"), 100); + position2 = text.find_first_of(STR("ZCXF"), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_first_of_character_position) + { + Compare_Text compare_text(STR("ABCDEF")); + + TextBuffer buffer{0}; + Text text(STR("ABCDEF"), buffer.data(), buffer.size()); + + size_t position1 = compare_text.find_first_of(STR('C')); + size_t position2 = text.find_first_of(STR('C')); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(STR('Z')); + position2 = text.find_first_of(STR('Z')); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(STR('F'), 3); + position2 = text.find_first_of(STR('F'), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(STR('C'), 3); + position2 = text.find_first_of(STR('C'), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_of(STR('C'), compare_text.size()); + position2 = text.find_first_of(STR('C'), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_first_of(STR('C'), 100); + position2 = text.find_first_of(STR('C'), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_last_of_string_position) + { + Compare_Text compare_text(STR("ABCDEFABCDE")); + + TextBuffer buffer{0}; + Text text(STR("ABCDEFABCDE"), buffer.data(), buffer.size()); + + size_t position1 = compare_text.find_last_of(Compare_Text(STR("ZCXE"))); + size_t position2 = text.find_last_of(TextT(STR("ZCXE"))); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(Compare_Text(STR("WXYZ")), 3); + position2 = text.find_last_of(TextT(STR("WXYZ")), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(Compare_Text(STR("ZCXE")), 5); + position2 = text.find_last_of(TextT(STR("ZCXE")), 5); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(Compare_Text(STR("ZCXE")), compare_text.size()); + position2 = text.find_last_of(TextT(STR("ZCXE")), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_last_of(Compare_Text(STR("ZCXE")), 100); + position2 = text.find_last_of(TextT(STR("ZCXE")), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_last_of_pointer_position) + { + Compare_Text compare_text(STR("ABCDEFABCDE")); + + TextBuffer buffer{0}; + Text text(STR("ABCDEFABCDE"), buffer.data(), buffer.size()); + + size_t position1 = compare_text.find_last_of(STR("ZCXE")); + size_t position2 = text.find_last_of(STR("ZCXE")); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR("WXYZ"), 3); + position2 = text.find_last_of(STR("WXYZ"), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR("ZCXE"), 5); + position2 = text.find_last_of(STR("ZCXE"), 5); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR("ZCXE"), 6); + position2 = text.find_last_of(STR("ZCXE"), 6); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR("ZCXE"), compare_text.size()); + position2 = text.find_last_of(STR("ZCXE"), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_last_of(STR("ZCXE"), 100); + position2 = text.find_last_of(STR("ZCXE"), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_last_of_pointer_position_n) + { + Compare_Text compare_text(STR("ABCDEFABCDE")); + + TextBuffer buffer{0}; + Text text(STR("ABCDEFABCDE"), buffer.data(), buffer.size()); + + size_t position1 = compare_text.find_last_of(STR("AZCXE"), 0, 4); + size_t position2 = text.find_last_of(STR("AZCXE"), 0, 4); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR("WXYZ"), 4, 3); + position2 = text.find_last_of(STR("WXYZ"), 4, 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR("ZCXE"), 5, 3); + position2 = text.find_last_of(STR("ZCXE"), 5, 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR("ZCXE"), 1, 3); + position2 = text.find_last_of(STR("ZCXE"), 1, 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR("ZCXE"), compare_text.size(), 4); + position2 = text.find_last_of(STR("ZCXE"), text.size(), 4); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR("ZCXE"), 100, 4); + position2 = text.find_last_of(STR("ZCXE"), 100, 4); + + CHECK_EQUAL(position1, position2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_last_of_character_position) + { + Compare_Text compare_text(STR("ABCDEF")); + + TextBuffer buffer{0}; + Text text(STR("ABCDEF"), buffer.data(), buffer.size()); + + size_t position1 = compare_text.find_last_of(STR('C')); + size_t position2 = text.find_last_of(STR('C')); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR('Z')); + position2 = text.find_last_of(STR('Z')); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR('F'), compare_text.size()); + position2 = text.find_last_of(STR('F'), text.size()); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR('C'), 3); + position2 = text.find_last_of(STR('C'), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_of(STR('C'), compare_text.size()); + position2 = text.find_last_of(STR('C'), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_last_of(STR('C'), 100); + position2 = text.find_last_of(STR('C'), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_first_not_of_string_position) + { + Compare_Text compare_text(STR("ABCDEF")); + + TextBuffer buffer{0}; + Text text(STR("ABCDEF"), buffer.data(), buffer.size()); + + size_t position1 = compare_text.find_first_not_of(Compare_Text(STR("ZAXB"))); + size_t position2 = text.find_first_not_of(TextT(STR("ZAXB"))); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(Compare_Text(STR("ZAXB"))); + position2 = text.find_first_not_of(TextT(STR("ZAXB"))); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(Compare_Text(STR("ZAXB")), 3); + position2 = text.find_first_not_of(TextT(STR("ZAXB")), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(Compare_Text(STR("ZAXB")), compare_text.size()); + position2 = text.find_first_not_of(TextT(STR("ZAXB")), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_first_not_of(Compare_Text(STR("ZAXB")), 100); + position2 = text.find_first_not_of(TextT(STR("ZAXB")), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_first_not_of_pointer_position) + { + Compare_Text compare_text(STR("ABCDEF")); + + TextBuffer buffer{0}; + Text text(STR("ABCDEF"), buffer.data(), buffer.size()); + + size_t position1 = compare_text.find_first_not_of(STR("ZAXB")); + size_t position2 = text.find_first_not_of(STR("ZAXB")); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR("ZAXB")); + position2 = text.find_first_not_of(STR("ZAXB")); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR("ZAXB"), 3); + position2 = text.find_first_not_of(STR("ZAXB"), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR("ZAXB"), compare_text.size()); + position2 = text.find_first_not_of(STR("ZAXB"), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_first_not_of(STR("ZAXB"), 100); + position2 = text.find_first_not_of(STR("ZAXB"), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_first_not_of_pointer_position_n) + { + Compare_Text compare_text(STR("ABCDEF")); + + TextBuffer buffer{0}; + Text text(STR("ABCDEF"), buffer.data(), buffer.size()); + + size_t position1 = compare_text.find_first_not_of(STR("ZAXB"), 0, 4); + size_t position2 = text.find_first_not_of(STR("ZAXB"), 0, 4); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR("ZAXB"), 0, 4); + position2 = text.find_first_not_of(STR("ZAXB"), 0, 4); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR("ZAXB"), 1, 3); + position2 = text.find_first_not_of(STR("ZAXB"), 1, 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR("ZAXB"), 3, 3); + position2 = text.find_first_not_of(STR("ZAXB"), 3, 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR("ZAXB"), compare_text.size(), 3); + position2 = text.find_first_not_of(STR("ZAXB"), text.size(), 3); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_first_not_of(STR("ZAXB"), 100); + position2 = text.find_first_not_of(STR("ZAXB"), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_first_not_of_character_position) + { + Compare_Text compare_text(STR("ABCDEF")); + + TextBuffer buffer{0}; + Text text(STR("ABCDEF"), buffer.data(), buffer.size()); + + size_t position1 = compare_text.find_first_not_of(STR('A')); + size_t position2 = text.find_first_not_of(STR('A')); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR('B')); + position2 = text.find_first_not_of(STR('B')); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR('C'), 3); + position2 = text.find_first_not_of(STR('C'), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR('D'), 3); + position2 = text.find_first_not_of(STR('D'), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_first_not_of(STR('C'), compare_text.size()); + position2 = text.find_first_not_of(STR('C'), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_first_not_of(STR('C'), 100); + position2 = text.find_first_not_of(STR('C'), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_last_not_of_string_position) + { + Compare_Text compare_text(STR("ABCDEFABCDE")); + + TextBuffer buffer{0}; + Text text(STR("ABCDEFABCDE"), buffer.data(), buffer.size()); + + size_t position1 = compare_text.find_last_not_of(Compare_Text(STR("ZEXD"))); + size_t position2 = text.find_last_not_of(TextT(STR("ZEXD"))); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(Compare_Text(STR("ZEXD")), 3); + position2 = text.find_last_not_of(TextT(STR("ZEXD")), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(Compare_Text(STR("ZEXD")), 5); + position2 = text.find_last_not_of(TextT(STR("ZEXD")), 5); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(Compare_Text(STR("ZEXD")), compare_text.size()); + position2 = text.find_last_not_of(TextT(STR("ZEXD")), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_last_not_of(Compare_Text(STR("ZEXD")), 100); + position2 = text.find_last_not_of(TextT(STR("ZEXD")), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_last_not_of_pointer_position) + { + Compare_Text compare_text(STR("ABCDEFABCDE")); + + TextBuffer buffer{0}; + Text text(STR("ABCDEFABCDE"), buffer.data(), buffer.size()); + + size_t position1 = compare_text.find_last_not_of(STR("ZEXD")); + size_t position2 = text.find_last_not_of(STR("ZEXD")); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR("ZEXD"), 3); + position2 = text.find_last_not_of(STR("ZEXD"), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR("ZEXD"), 5); + position2 = text.find_last_not_of(STR("ZEXD"), 5); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR("ZEXD"), compare_text.size()); + position2 = text.find_last_not_of(STR("ZEXD"), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_last_not_of(STR("ZEXD"), 100); + position2 = text.find_last_not_of(STR("ZEXD"), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_last_not_of_pointer_position_n) + { + Compare_Text compare_text(STR("ABCDEFABCDE")); + + TextBuffer buffer{0}; + Text text(STR("ABCDEFABCDE"), buffer.data(), buffer.size()); + + size_t position1 = compare_text.find_last_not_of(STR("ZEXD"), 0, 4); + size_t position2 = text.find_last_not_of(STR("ZEXD"), 0, 4); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR("ZEXD"), 5, 3); + position2 = text.find_last_not_of(STR("ZEXD"), 5, 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR("ZEXD"), 1, 3); + position2 = text.find_last_not_of(STR("ZEXD"), 1, 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR("ZEXD"), compare_text.size(), 4); + position2 = text.find_last_not_of(STR("ZEXD"), text.size(), 4); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR("ZEXD"), 100, 4); + position2 = text.find_last_not_of(STR("ZEXD"), 100, 4); + + CHECK_EQUAL(position1, position2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_find_last_not_of_character_position) + { + Compare_Text compare_text(STR("ABCDEF")); + + TextBuffer buffer{0}; + Text text(STR("ABCDEF"), buffer.data(), buffer.size()); + + size_t position1 = compare_text.find_last_not_of(STR('F')); + size_t position2 = text.find_last_not_of(STR('F')); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR('Z')); + position2 = text.find_last_not_of(STR('Z')); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR('A'), compare_text.size()); + position2 = text.find_last_not_of(STR('A'), text.size()); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR('C'), 3); + position2 = text.find_last_not_of(STR('C'), 3); + + CHECK_EQUAL(position1, position2); + + position1 = compare_text.find_last_not_of(STR('C'), compare_text.size()); + position2 = text.find_last_not_of(STR('C'), text.size()); + + CHECK_EQUAL(position1, position2); + +#include "etl/private/diagnostic_array_bounds_push.h" + position1 = compare_text.find_last_not_of(STR('C'), 100); + position2 = text.find_last_not_of(STR('C'), 100); + + CHECK_EQUAL(position1, position2); +#include "etl/private/diagnostic_pop.h" + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_hash) + { + // Test with actual string type. + TextBuffer buffer{0}; + Text text(STR("ABCDEFHIJKL"), buffer.data(), buffer.size()); + size_t hash = etl::hash()(text); + size_t compare_hash = etl::private_hash::generic_hash(reinterpret_cast(&text[0]), reinterpret_cast(&text[text.size()])); + CHECK_EQUAL(compare_hash, hash); + + // Test with interface string type. + IText& itext = text; + hash = etl::hash()(itext); + CHECK_EQUAL(compare_hash, hash); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_memcpy_repair) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + + text.assign(STR("ABCDEF")); + + char buffer2[sizeof(Text)]; + + // Will not copy the buffer! + memcpy(&buffer2, (const void*)&text, sizeof(text)); + + Text& rtext(*reinterpret_cast(buffer2)); + rtext.repair(); + + CHECK(!rtext.empty()); + CHECK(!rtext.full()); + + bool is_equal = Equal(text, rtext); + CHECK(is_equal); + + text = STR("GHIJKL"); + is_equal = Equal(text, rtext); + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_memcpy_repair_virtual) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + + text.assign(STR("ABCDEF")); + + char buffer2[sizeof(Text)]; + + // Will not copy the buffer! + memcpy(&buffer2, (const void*)&text, sizeof(text)); + + IText& itext(*reinterpret_cast(buffer2)); + itext.repair(); + + CHECK(!itext.empty()); + CHECK(!itext.full()); + + bool is_equal = Equal(text, itext); + CHECK(is_equal); + + text = STR("GHIJKL"); + is_equal = Equal(text, itext); + CHECK(is_equal); + } + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_truncate_over_many_operations) + { + TextBuffer buffer{0}; + Text text(short_text.c_str(), buffer.data(), buffer.size()); + CHECK(!text.is_truncated()); + + text.insert(3, initial_text.c_str()); + CHECK(text.is_truncated()); + + while (text.size() != 0) + { + text.pop_back(); + CHECK(text.is_truncated()); + } + + text.clear(); + CHECK(!text.is_truncated()); + + text.assign(longer_text.c_str()); + CHECK(text.is_truncated()); + + text.assign(short_text.c_str()); + CHECK(!text.is_truncated()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_add_from_truncated) + { + TextBuffer buffer{0}; + Text text1(short_text.c_str(), buffer.data(), buffer.size()); + + TextBufferS buffers{0}; + Text text2(short_text.c_str(), buffers.data(), buffers.size()); + + CHECK(!text1.is_truncated()); + CHECK(text2.is_truncated()); + + // text2 has the truncate flag set. + text1 += text2; + + CHECK(text1.is_truncated()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_add_to_truncated) + { + TextBuffer buffer{0}; + Text text1(longer_text.c_str(), buffer.data(), buffer.size()); + + TextBuffer buffer2{0}; + Text text2(short_text.c_str(), buffer2.data(), buffer2.size()); + + CHECK(text1.is_truncated()); + CHECK(!text2.is_truncated()); + + // Clear text but not the truncate flag. + text1.erase(text1.begin(), text1.end()); + + // text1 still has the truncate flag set. + text1 += text2; + + CHECK(text1.is_truncated()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_clear_truncated) + { + TextBuffer buffer{0}; + Text text(longer_text.c_str(), buffer.data(), buffer.size()); + CHECK(text.is_truncated()); + + text.clear_truncated(); + CHECK(!text.is_truncated()); + } +#endif + +#if ETL_HAS_STRING_CLEAR_AFTER_USE + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_secure_after_destructor) + { + char buffer[sizeof(Text)]; + std::fill_n(buffer, sizeof(Text), 0); + + TextBuffer buffer2{0}; + ::new (buffer) Text(STR("ABCDEF"), buffer2.data(), buffer2.size()); + + Text& text = *reinterpret_cast(buffer); + text.set_secure(); + + CHECK(TextT(STR("ABCDEF")) == text); + + Text::pointer pb = text.begin(); + Text::pointer pe = text.end(); + + // Destroy the text object. + text.~Text(); + + // Check there no non-zero values in the string. + CHECK(std::find_if(pb, pe, [](Text::value_type x) { return x != 0; }) == pe); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_secure_after_assign) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + text.set_secure(); + text.assign(STR("ABCDEF")); + + Text::pointer pe = text.end(); + + text.assign(STR("ABC")); + + CHECK(std::find_if(text.end(), pe, [](Text::value_type x) { return x != 0; }) == pe); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_secure_after_resize_down) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + text.set_secure(); + text.assign(STR("ABCDEF")); + + Text::pointer pe = text.end(); + + text.resize(text.size() - 3U); + + CHECK(std::find_if(text.end(), pe, [](Text::value_type x) { return x != 0; }) == pe); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_secure_after_erase) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + text.set_secure(); + text.assign(STR("ABCDEF")); + + Text::pointer pb = text.begin(); + Text::pointer pe = text.end(); + + text.erase(pb + 2, pb + 5); + + // Check there no non-zero values in the remainder of the string. + CHECK(std::find_if(text.end(), pe, [](Text::value_type x) { return x != 0; }) == pe); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_secure_after_replace) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + text.set_secure(); + text.assign(STR("ABCDEF")); + + Text::pointer pb = text.begin(); + Text::pointer pe = text.end(); + + text.replace(pb + 1, pb + 4, STR("G")); + + // Check there no non-zero values in the remainder of the string. + CHECK(std::find_if(text.end(), pe, [](Text::value_type x) { return x != 0; }) == pe); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_secure_after_clear) + { + TextBuffer buffer{0}; + Text text(buffer.data(), buffer.size()); + text.set_secure(); + text.assign(STR("ABCDEF")); + + Text::pointer pb = text.begin(); + Text::pointer pe = text.end(); + + text.clear(); + + // Check there no non-zero values in the remainder of the string. + CHECK(std::find_if(pb, pe, [](Text::value_type x) { return x != 0; }) == pe); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_secure_flag_after_copy) + { + TextBuffer buffer1{0}; + Text text1(STR("Hello World"), buffer1.data(), buffer1.size()); + text1.set_secure(); + + TextBuffer buffer2{0}; + Text text2(text1, buffer2.data(), buffer2.size()); + + TextBuffer buffer3; + Text text3(buffer3.data(), buffer3.size()); + text3 = text1; + + TextBuffer buffer4; + Text text4(text1, buffer4.data(), buffer4.size(), 6U, 2U); + + CHECK(text2.is_secure()); + CHECK(text3.is_secure()); + CHECK(text4.is_secure()); + } +#endif + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_initialize_free_space_empty_string) + { + TextBuffer buffer1{0}; + TextBuffer buffer2{0}; + Text text(buffer1.data(), buffer1.size()); + Text empty(buffer2.data(), buffer2.size()); + + text.initialize_free_space(); + + CHECK(text.empty()); + CHECK(text == empty); + + for (size_t i = text.size(); i < text.max_size(); ++i) + { + CHECK_EQUAL(0, text[i]); + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_initialize_free_space_part_filled_string) + { + TextBuffer buffer1{0}; + TextBuffer buffer2{0}; + Text initial(STR("ABC"), buffer1.data(), buffer1.size()); + Text empty(buffer2.data(), buffer2.size()); + Text text(initial, buffer2.data(), buffer2.size()); + + text.initialize_free_space(); + + CHECK(text == initial); + CHECK(text != empty); + + for (size_t i = text.size(); i < text.max_size(); ++i) + { + CHECK_EQUAL(0, text[i]); + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_update_after_c_string_max_size) + { + TextBuffer buffer1{0}; + Text text(buffer1.data(), buffer1.size()); + + text.initialize_free_space(); + std::fill(text.data(), text.data() + text.max_size(), STR('A')); + text.trim_to_terminator(); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + CHECK_EQUAL(text.max_size(), text.size()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_update_after_c_string_shorter_size) + { + TextBuffer buffer1{0}; + Text text(buffer1.data(), buffer1.size()); + + text.initialize_free_space(); + std::fill(text.data(), text.data() + text.max_size() - 1, STR('A')); + text.trim_to_terminator(); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + CHECK_EQUAL(text.max_size() - 1, text.size()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_update_after_c_string_greater_size) + { + TextBuffer buffer1{0}; + Text text(buffer1.data(), buffer1.size()); + + text.initialize_free_space(); + std::fill(text.data(), text.data() + text.max_size() + 1, STR('A')); // Overwrites to terminating null. + text.trim_to_terminator(); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(text.is_truncated()); +#endif + CHECK_EQUAL(text.max_size(), text.size()); + } + }; +} + +#endif \ No newline at end of file diff --git a/test/test_string_utilities_std_u8.cpp b/test/test_string_utilities_std_u8.cpp new file mode 100644 index 00000000..7d762dba --- /dev/null +++ b/test/test_string_utilities_std_u8.cpp @@ -0,0 +1,1595 @@ +/****************************************************************************** +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 +#include +#include +#include + +#include "etl/string_utilities.h" + +#undef STR +#define STR(x) u8##x + +#undef STR_PTR +#define STR_PTR const char16_t* + +namespace +{ + //*********************************** + //std::ostream& operator << (std::ostream& os, const std::wstring::value_type& c) + //{ + // os << uint8_t(c); + + // return os; + //} + + SUITE(test_string_utilities_std_u8) + { + using String = std::u8string; + using IString = std::u8string; +#if ETL_USING_CPP17 + using StringView = std::u8string_view; +#endif + using Char = std::u8string::value_type; + using Vector = std::vector; + +#if ETL_USING_CPP17 + constexpr auto Whitespace = etl::whitespace_v; +#else + STR_PTR Whitespace = etl::whitespace::value(); +#endif + + //************************************************************************* + TEST(test_trim_whitespace_left_empty) + { + String text(STR("")); + String expected(STR("")); + + etl::trim_whitespace_left(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_whitespace_left_empty) + { + String text(STR("")); + String expected(STR("")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_whitespace_left(textview); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_whitespace_left) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR("Hello World\t\n\r\f\v ")); + + etl::trim_whitespace_left(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_whitespace_left) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR("Hello World\t\n\r\f\v ")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_whitespace_left(textview); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_whitespace_left_nothing_to_trim) + { + String text(STR("Hello World\t\n\r\f\v ")); + String expected(STR("Hello World\t\n\r\f\v ")); + + etl::trim_whitespace_left(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_whitespace_left_nothing_to_trim) + { + String text(STR("Hello World\t\n\r\f\v ")); + String expected(STR("Hello World\t\n\r\f\v ")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_whitespace_left(textview); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from_left_pointer_empty) + { + String text(STR("")); + String expected(STR("")); + + etl::trim_from_left(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_from_view_left_pointer_empty) + { + String text(STR("")); + String expected(STR("")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_from_view_left(textview, STR(" \t\n\r\f\v")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from_left_pointer) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR("Hello World\t\n\r\f\v ")); + + etl::trim_from_left(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_from_view_left_pointer) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR("Hello World\t\n\r\f\v ")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_from_view_left(textview, STR(" \t\n\r\f\v")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from_left_pointer_nothing_to_trim) + { + String text(STR("Hello World\t\n\r\f\v ")); + String expected(STR("Hello World\t\n\r\f\v ")); + + etl::trim_from_left(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_from_view_left_pointer_nothing_to_trim) + { + String text(STR("Hello World\t\n\r\f\v ")); + String expected(STR("Hello World\t\n\r\f\v ")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_from_view_left(textview, STR(" \t\n\r\f\v")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from_left_pointer_length_empty) + { + String text(STR("")); + String expected(STR("")); + + etl::trim_from_left(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_left_delimiters) + { + String text(STR("qztfpHello Worldqztfp")); + String expected(STR("Hello Worldqztfp")); + + etl::trim_left(text, STR("Hel")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_left_delimiters) + { + String text(STR("qztfpHello Worldqztfp")); + String expected(STR("Hello Worldqztfp")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_left(textview, STR("Hel")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_left_delimiters_nothing_to_trim) + { + String text(STR("Hello Worldqztfp")); + String expected(STR("Hello Worldqztfp")); + + etl::trim_left(text, STR("Hel")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_left_delimiters_nothing_to_trim) + { + String text(STR("Hello Worldqztfp")); + String expected(STR("Hello Worldqztfp")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_left(textview, STR("Hel")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_left_delimiters_no_delimiters) + { + String text(STR("Hello Worldqztfp")); + String expected(STR("")); + + etl::trim_left(text, STR("XYZ")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_left_delimiters_no_delimiters) + { + String text(STR("Hello Worldqztfp")); + String expected(STR("")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_left(textview, STR("XYZ")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_view_left_string_delimiters) + { + String text(STR("qztfpHello Worldqztfp")); + String expected(STR("Hello Worldqztfp")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_left(textview, STR("Hel")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_whitespace_right_empty) + { + String text(STR("")); + String expected(STR("")); + + etl::trim_whitespace_right(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_whitespace_right_empty) + { + String text(STR("")); + String expected(STR("")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_whitespace_right(textview); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_whitespace_right) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR(" \t\n\r\f\vHello World")); + + etl::trim_whitespace_right(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_whitespace_right) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR(" \t\n\r\f\vHello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_whitespace_right(textview); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_whitespace_right_nothing_to_trim) + { + String text(STR(" \t\n\r\f\vHello World")); + String expected(STR(" \t\n\r\f\vHello World")); + + etl::trim_whitespace_right(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_whitespace_right_nothing_to_trim) + { + String text(STR(" \t\n\r\f\vHello World")); + String expected(STR(" \t\n\r\f\vHello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_whitespace_right(textview); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from_right_pointer_empty) + { + String text(STR("")); + String expected(STR("")); + + etl::trim_from_right(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_from_view_right_pointer_empty) + { + String text(STR("")); + String expected(STR("")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_from_view_right(textview, STR(" \t\n\r\f\v")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from_right_pointer) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR(" \t\n\r\f\vHello World")); + + etl::trim_from_right(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_from_view_right_pointer) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR(" \t\n\r\f\vHello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_from_view_right(textview, STR(" \t\n\r\f\v")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from_right_pointer_nothing_to_trim) + { + String text(STR(" \t\n\r\f\vHello World")); + String expected(STR(" \t\n\r\f\vHello World")); + + etl::trim_from_right(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_from_view_right_pointer_nothing_to_trim) + { + String text(STR(" \t\n\r\f\vHello World")); + String expected(STR(" \t\n\r\f\vHello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_from_view_right(textview, STR(" \t\n\r\f\v")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_right_delimiters) + { + String text(STR("qztfpHello Worldqztfp")); + String expected(STR("qztfpHello World")); + + etl::trim_right(text, STR("rld")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_right_delimiters) + { + String text(STR("qztfpHello Worldqztfp")); + String expected(STR("qztfpHello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_right(textview, STR("rld")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_right_delimiters_nothing_to_trim) + { + String text(STR("qztfpHello World")); + String expected(STR("qztfpHello World")); + + etl::trim_right(text, STR("rld")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_right_delimiters_nothing_to_trim) + { + String text(STR("qztfpHello World")); + String expected(STR("qztfpHello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_right(textview, STR("rld")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_right_delimiters_no_delimiters) + { + String text(STR("qztfpHello World")); + String expected(STR("")); + + etl::trim_right(text, STR("XYZ")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_right_delimiters_no_delimiters) + { + String text(STR("qztfpHello World")); + String expected(STR("")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_right(textview, STR("XYZ")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_whitespace_empty) + { + String text(STR("")); + String expected(STR("")); + + etl::trim_whitespace(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_whitespace_empty) + { + String text(STR("")); + String expected(STR("")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_whitespace(textview); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_whitespace) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR("Hello World")); + + etl::trim_whitespace(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_whitespace) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR("Hello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_whitespace(textview); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_whitespace_nothing_to_trim) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + etl::trim_whitespace(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_whitespace_nothing_to_trim) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_whitespace(textview); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from_empty) + { + String text(STR("")); + String expected(STR("")); + + etl::trim_from(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_from_view_empty) + { + String text(STR("")); + String expected(STR("")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_from_view(textview, STR(" \t\n\r\f\v")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR("Hello World")); + + etl::trim_from(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_from_view) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR("Hello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_from_view(textview, STR(" \t\n\r\f\v")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from_nothing_to_trim) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + etl::trim_from(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_from_view_nothing_to_trim) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_from_view(textview, STR(" \t\n\r\f\v")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_delimiters) + { + String text(STR("qztfpHello Worldqztfp")); + String expected(STR("Hello World")); + + etl::trim(text, STR("Hd")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_delimiters) + { + String text(STR("qztfpHello Worldqztfp")); + String expected(STR("Hello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view(textview, STR("Hd")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_delimiters_nothing_to_trim) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + etl::trim(text, STR("Hd")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_delimiters_nothing_to_trim) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view(textview, STR("Hd")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_delimiters_no_delimiters) + { + String text(STR("Hello World")); + String expected(STR("")); + + etl::trim(text, STR("XYZ")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_delimiters_no_delimiters) + { + String text(STR("Hello World")); + String expected(STR("")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view(textview, STR("XYZ")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_reverse) + { + String text(STR("Hello World")); + String expected(STR("dlroW olleH")); + + etl::reverse(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_right_n_view) + { + String text(STR("Hello World")); + String expected(STR("World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::right_n_view(textview, expected.size()); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_right_n_view_excess) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::right_n_view(textview, text.size() * 2U); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_right_n_string) + { + String text(STR("Hello World")); + String expected(STR("World")); + + etl::right_n(text, 5U); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_right_n_string_excess) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + etl::right_n(text, text.size() * 2U); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_left_n_view) + { + String text(STR("Hello World")); + String expected(STR("Hello")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::left_n_view(textview, expected.size()); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_left_n_view_excess) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::left_n_view(textview, text.size() * 2U); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_left_n_string) + { + String text(STR("Hello World")); + String expected(STR("Hello")); + + etl::left_n(text, expected.size()); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_left_n_string_excess) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + etl::left_n(text, text.size() * 2U); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_replace_characters) + { + String text(STR("This+++is a *file//name:")); + String expected(STR("This---is_a__-file__name_")); + + etl::pair lookup[] = + { + { STR('+'), STR('-') }, + { STR(' '), STR('_') }, + { STR('*'), STR('-') }, + { STR('/'), STR('_') }, + { STR(':'), STR('_') } + }; + + etl::replace_characters(text, ETL_OR_STD11::begin(lookup), ETL_OR_STD11::end(lookup)); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_replace_characters_empty_string) + { + String text(STR("")); + String expected(STR("")); + + etl::pair lookup[] = + { + { STR('+'), STR('-') }, + { STR(' '), STR('_') }, + { STR('*'), STR('-') }, + { STR('/'), STR('_') }, + { STR(':'), STR('_') } + }; + + etl::replace_characters(text, ETL_OR_STD11::begin(lookup), ETL_OR_STD11::end(lookup)); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_replace_strings) + { + String text(STR("This+++is a *file//name:")); + String expected(STR("Thisxyis%20a%20%20-file_name.txt")); + + etl::pair lookup[] = + { + { STR("+++"), STR("xy") }, + { STR(" "), STR("%20") }, + { STR("*"), STR("-") }, + { STR("//"), STR("_") }, + { STR(":"), STR(".txt") } + }; + + etl::replace_strings(text, ETL_OR_STD11::begin(lookup), ETL_OR_STD11::end(lookup)); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_replace_strings_empty_strings) + { + String text(STR("")); + String expected(STR("")); + + etl::pair lookup[] = + { + { STR("+++"), STR("xy") }, + { STR(" "), STR("%20") }, + { STR("*"), STR("-") }, + { STR("//"), STR("_") }, + { STR(":"), STR(".txt") } + }; + + etl::replace_strings(text, ETL_OR_STD11::begin(lookup), ETL_OR_STD11::end(lookup)); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_get_token_delimiters_ignore_empty_tokens) + { + String text(STR(",,,The,cat,sat,,on,the,mat,,,")); + Vector tokens; + + StringView textview(text.data(), text.size()); + etl::optional token; + + while ((token = etl::get_token(text, STR(","), token, true))) + { + tokens.emplace_back(token.value()); + } + + CHECK_EQUAL(6U, tokens.size()); + } + + //************************************************************************* + TEST(test_get_token_delimiters_keep_empty_tokens) + { + String text(STR(",,,The,cat,sat,,on,the,mat,,,")); + Vector tokens; + + StringView textview(text.data(), text.size()); + etl::optional token; + + while ((token = etl::get_token(text, STR(","), token, false))) + { + tokens.emplace_back(token.value()); + } + + CHECK_EQUAL(13U, tokens.size()); + } + + //************************************************************************* + TEST(test_get_token_delimiters_nothing_to_do) + { + String text(STR("")); + Vector tokens; + + StringView textview(text.data(), text.size()); + etl::optional token; + + while ((token = etl::get_token(text, Whitespace, token, true))) + { + tokens.emplace_back(token.value()); + } + + CHECK_EQUAL(0U, tokens.size()); + } + + //************************************************************************* + TEST(test_get_token_delimiters_no_tokens) + { + String text(STR(" ., ;: .,;:")); + Vector tokens; + + StringView textview(text.data(), text.size()); + etl::optional token; + + while ((token = etl::get_token(text, STR(" .,;:"), token, true))) + { + tokens.emplace_back(token.value()); + } + + CHECK_EQUAL(0U, tokens.size()); + } + + //************************************************************************* + TEST(test_get_token_delimiters_no_delimiters) + { + String text(STR("The cat sat on the mat")); + Vector tokens; + + StringView textview(text.data(), text.size()); + etl::optional token; + + while ((token = etl::get_token(text, STR(","), token, false))) + { + tokens.emplace_back(token.value()); + } + + CHECK_EQUAL(1U, tokens.size()); + } + + //************************************************************************* + TEST(test_get_token_delimiters_empty_string_view) + { + Vector tokens; + + StringView textview; + etl::optional token; + + while ((token = etl::get_token(textview, Whitespace, token, true))) + { + tokens.emplace_back(token.value()); + } + + CHECK_EQUAL(0U, tokens.size()); + } + + //************************************************************************* + TEST(test_pad_left) + { + String text(STR("Hello World")); + String expected(STR("xxxxHello World")); + + etl::pad_left(text, expected.size(), STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_pad_left_smaller) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + etl::pad_left(text, text.size() - 1U, STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_pad_right) + { + String text(STR("Hello World")); + String expected(STR("Hello Worldxxxx")); + + etl::pad_right(text, expected.size(), STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_pad_right_smaller) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + etl::pad_right(text, text.size() - 1U, STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_pad_select_left) + { + String text(STR("Hello World")); + String expected(STR("xxxxHello World")); + + etl::pad(text, expected.size(), etl::string_pad_direction::LEFT, STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_pad_select_left_smaller) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + etl::pad(text, text.size() - 1U, etl::string_pad_direction::LEFT, STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_pad_select_right) + { + String text(STR("Hello World")); + String expected(STR("Hello Worldxxxx")); + + etl::pad(text, expected.size(), etl::string_pad_direction::RIGHT, STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_pad_select_right_smaller) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + etl::pad(text, text.size() - 1U, etl::string_pad_direction::RIGHT, STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_find_first_of_iterator_iterator) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_first_of(text.begin(), text.end(), STR("Hel")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_of_iterator_iterator_not_found) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_first_of(text.begin(), text.end(), STR("xyz")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_first_of_const_iterator_const_iterator) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_first_of(text.cbegin(), text.cend(), STR("Hel")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_of_const_iterator_const_iterator_not_found) + { + String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_first_of(text.begin(), text.end(), STR("xyz")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_first_of_string) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_first_of(text, STR("Hel")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_of_string_not_found) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_first_of(text, STR("xyz")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_first_of_const_string) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_first_of(text, STR("Hel")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_of_const_string_not_found) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_first_of(text, STR("xyz")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_first_of_string_view) + { + const String text(STR("abcHello Worldabc")); + StringView textview(text.data(), text.size()); + + StringView::const_iterator itr = etl::find_first_of(textview, STR("Hel")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_of_string_view_not_found) + { + const String text(STR("abcHello Worldabc")); + StringView textview(text.data(), text.size()); + + StringView::const_iterator itr = etl::find_first_of(textview, STR("xyz")); + + CHECK(textview.end() == itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_iterator_iterator) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_first_not_of(text.begin(), text.end(), STR("abc")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_iterator_iterator_not_found) + { + String text(STR("abcHello Worldabc")); + String::iterator itr = etl::find_first_not_of(text.begin(), text.end(), STR("abcHello World")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_const_iterator_const_iterator) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_first_not_of(text.cbegin(), text.cend(), STR("abc")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_const_iterator_const_iterator_not_found) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_first_not_of(text.cbegin(), text.cend(), STR("abcHello World")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_string) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_first_not_of(text, STR("abc")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_string_not_found) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_first_not_of(text, STR("abcHello World")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_const_string) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_first_not_of(text, STR("abc")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_const_string_not_found) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_first_not_of(text, STR("abcHello World")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_string_view) + { + const String text(STR("abcHello Worldabc")); + StringView textview(text.data(), text.size()); + + StringView::const_iterator itr = etl::find_first_not_of(textview, STR("abc")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_string_view_not_found) + { + const String text(STR("abcHello Worldabc")); + StringView textview(text.data(), text.size()); + + StringView::const_iterator itr = etl::find_first_not_of(textview, STR("abcHello World")); + + CHECK(textview.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_of_iterator_iterator) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_last_of(text.begin(), text.end(), STR("rld")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_of_iterator_iterator_not_found) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_last_of(text.begin(), text.end(), STR("xyz")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_of_const_iterator_const_iterator) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_last_of(text.cbegin(), text.cend(), STR("rld")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_of_const_iterator_const_iterator_not_found) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_last_of(text.cbegin(), text.cend(), STR("xyz")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_of_string) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_last_of(text, STR("rld")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_of_string_not_found) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_last_of(text, STR("xyz")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_of_const_string) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_last_of(text, STR("rld")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_of_const_string_not_found) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_last_of(text, STR("xyz")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_of_string_view) + { + String text(STR("abcHello Worldabc")); + StringView textview(text.data(), text.size()); + + StringView::const_iterator itr = etl::find_last_of(textview, STR("rld")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_of_string_view_not_found) + { + String text(STR("abcHello Worldabc")); + StringView textview(text.data(), text.size()); + + StringView::const_iterator itr = etl::find_last_of(textview, STR("xyz")); + + CHECK(textview.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_iterator_iterator) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_last_not_of(text.begin(), text.end(), STR("abc")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_iterator_iterator_not_found) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_last_not_of(text.begin(), text.end(), STR("abcHello World")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_const_iterator_const_iterator) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_last_not_of(text.cbegin(), text.cend(), STR("abc")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_const_iterator_const_iterator_not_found) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_last_not_of(text.cbegin(), text.cend(), STR("abcHello World")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_string) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_last_not_of(text, STR("abc")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_string_not_found) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_last_not_of(text, STR("abcHello World")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_const_string) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_last_not_of(text, STR("abc")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_const_string_not_found) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_last_not_of(text, STR("abcHello World")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_string_view) + { + String text(STR("abcHello Worldabc")); + StringView textview(text.data(), text.size()); + + StringView::const_iterator itr = etl::find_last_not_of(textview, STR("abc")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_string_view_not_found) + { + String text(STR("abcHello Worldabc")); + StringView textview(text.data(), text.size()); + + StringView::const_iterator itr = etl::find_last_not_of(textview, STR("abcHello World")); + + CHECK(textview.end() == itr); + } + }; +} + +#endif diff --git a/test/test_string_utilities_u8.cpp b/test/test_string_utilities_u8.cpp new file mode 100644 index 00000000..c5f0da76 --- /dev/null +++ b/test/test_string_utilities_u8.cpp @@ -0,0 +1,1641 @@ +/****************************************************************************** +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/u8string.h" +#include "etl/string_view.h" +#include "etl/string_utilities.h" +#include "etl/vector.h" + +#undef STR +#define STR(x) u8##x + +#undef STR_PTR +#define STR_PTR const char8_t* + +namespace +{ + //*********************************** + //std::ostream& operator << (std::ostream& os, const std::u16string::value_type& c) + //{ + // os << uint16_t(c); + + // return os; + //} + + SUITE(test_string_utilities_u8) + { + static const size_t SIZE = 50; + + using String = etl::u8string; + using IString = etl::iu8string; + using StringView = etl::u8string_view; + using Char = etl::iu8string::value_type; + using Vector = etl::vector; + +#if ETL_USING_CPP17 + constexpr auto Whitespace = etl::whitespace_v; +#else + STR_PTR Whitespace = etl::whitespace::value(); +#endif + + //************************************************************************* + TEST(test_trim_whitespace_left_empty) + { + String text(STR("")); + String expected(STR("")); + + etl::trim_whitespace_left(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_whitespace_left_empty) + { + String text(STR("")); + String expected(STR("")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_whitespace_left(textview); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_whitespace_left) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR("Hello World\t\n\r\f\v ")); + + etl::trim_whitespace_left(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_whitespace_left) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR("Hello World\t\n\r\f\v ")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_whitespace_left(textview); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_whitespace_left_nothing_to_trim) + { + String text(STR("Hello World\t\n\r\f\v ")); + String expected(STR("Hello World\t\n\r\f\v ")); + + etl::trim_whitespace_left(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_whitespace_left_nothing_to_trim) + { + String text(STR("Hello World\t\n\r\f\v ")); + String expected(STR("Hello World\t\n\r\f\v ")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_whitespace_left(textview); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from_left_pointer_empty) + { + String text(STR("")); + String expected(STR("")); + + etl::trim_from_left(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_from_view_left_pointer_empty) + { + String text(STR("")); + String expected(STR("")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_from_view_left(textview, STR(" \t\n\r\f\v")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from_left_pointer) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR("Hello World\t\n\r\f\v ")); + + etl::trim_from_left(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_from_view_left_pointer) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR("Hello World\t\n\r\f\v ")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_from_view_left(textview, STR(" \t\n\r\f\v")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from_left_pointer_nothing_to_trim) + { + String text(STR("Hello World\t\n\r\f\v ")); + String expected(STR("Hello World\t\n\r\f\v ")); + + etl::trim_from_left(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_from_view_left_pointer_nothing_to_trim) + { + String text(STR("Hello World\t\n\r\f\v ")); + String expected(STR("Hello World\t\n\r\f\v ")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_from_view_left(textview, STR(" \t\n\r\f\v")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from_left_pointer_length_empty) + { + String text(STR("")); + String expected(STR("")); + + etl::trim_from_left(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_left_delimiters) + { + String text(STR("qztfpHello Worldqztfp")); + String expected(STR("Hello Worldqztfp")); + + etl::trim_left(text, STR("Hel")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_left_delimiters) + { + String text(STR("qztfpHello Worldqztfp")); + String expected(STR("Hello Worldqztfp")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_left(textview, STR("Hel")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_left_delimiters_nothing_to_trim) + { + String text(STR("Hello Worldqztfp")); + String expected(STR("Hello Worldqztfp")); + + etl::trim_left(text, STR("Hel")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_left_delimiters_nothing_to_trim) + { + String text(STR("Hello Worldqztfp")); + String expected(STR("Hello Worldqztfp")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_left(textview, STR("Hel")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_left_delimiters_no_delimiters) + { + String text(STR("Hello Worldqztfp")); + String expected(STR("")); + + etl::trim_left(text, STR("XYZ")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_left_delimiters_no_delimiters) + { + String text(STR("Hello Worldqztfp")); + String expected(STR("")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_left(textview, STR("XYZ")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_view_left_string_delimiters) + { + String text(STR("qztfpHello Worldqztfp")); + String expected(STR("Hello Worldqztfp")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_left(textview, STR("Hel")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_whitespace_right_empty) + { + String text(STR("")); + String expected(STR("")); + + etl::trim_whitespace_right(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_whitespace_right_empty) + { + String text(STR("")); + String expected(STR("")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_whitespace_right(textview); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_whitespace_right) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR(" \t\n\r\f\vHello World")); + + etl::trim_whitespace_right(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_whitespace_right) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR(" \t\n\r\f\vHello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_whitespace_right(textview); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_whitespace_right_nothing_to_trim) + { + String text(STR(" \t\n\r\f\vHello World")); + String expected(STR(" \t\n\r\f\vHello World")); + + etl::trim_whitespace_right(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_whitespace_right_nothing_to_trim) + { + String text(STR(" \t\n\r\f\vHello World")); + String expected(STR(" \t\n\r\f\vHello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_whitespace_right(textview); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from_right_pointer_empty) + { + String text(STR("")); + String expected(STR("")); + + etl::trim_from_right(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_from_view_right_pointer_empty) + { + String text(STR("")); + String expected(STR("")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_from_view_right(textview, STR(" \t\n\r\f\v")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from_right_pointer) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR(" \t\n\r\f\vHello World")); + + etl::trim_from_right(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_from_view_right_pointer) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR(" \t\n\r\f\vHello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_from_view_right(textview, STR(" \t\n\r\f\v")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from_right_pointer_nothing_to_trim) + { + String text(STR(" \t\n\r\f\vHello World")); + String expected(STR(" \t\n\r\f\vHello World")); + + etl::trim_from_right(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_from_view_right_pointer_nothing_to_trim) + { + String text(STR(" \t\n\r\f\vHello World")); + String expected(STR(" \t\n\r\f\vHello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_from_view_right(textview, STR(" \t\n\r\f\v")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_right_delimiters) + { + String text(STR("qztfpHello Worldqztfp")); + String expected(STR("qztfpHello World")); + + etl::trim_right(text, STR("rld")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_right_delimiters) + { + String text(STR("qztfpHello Worldqztfp")); + String expected(STR("qztfpHello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_right(textview, STR("rld")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_right_delimiters_nothing_to_trim) + { + String text(STR("qztfpHello World")); + String expected(STR("qztfpHello World")); + + etl::trim_right(text, STR("rld")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_right_delimiters_nothing_to_trim) + { + String text(STR("qztfpHello World")); + String expected(STR("qztfpHello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_right(textview, STR("rld")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_right_delimiters_no_delimiters) + { + String text(STR("qztfpHello World")); + String expected(STR("")); + + etl::trim_right(text, STR("XYZ")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_right_delimiters_no_delimiters) + { + String text(STR("qztfpHello World")); + String expected(STR("")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_right(textview, STR("XYZ")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_whitespace_empty) + { + String text(STR("")); + String expected(STR("")); + + etl::trim_whitespace(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_whitespace_empty) + { + String text(STR("")); + String expected(STR("")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_whitespace(textview); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_whitespace) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR("Hello World")); + + etl::trim_whitespace(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_whitespace) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR("Hello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_whitespace(textview); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_whitespace_nothing_to_trim) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + etl::trim_whitespace(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_whitespace_nothing_to_trim) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view_whitespace(textview); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from_empty) + { + String text(STR("")); + String expected(STR("")); + + etl::trim_from(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_from_view_empty) + { + String text(STR("")); + String expected(STR("")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_from_view(textview, STR(" \t\n\r\f\v")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR("Hello World")); + + etl::trim_from(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_from_view) + { + String text(STR(" \t\n\r\f\vHello World\t\n\r\f\v ")); + String expected(STR("Hello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_from_view(textview, STR(" \t\n\r\f\v")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_from_nothing_to_trim) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + etl::trim_from(text, STR(" \t\n\r\f\v")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_from_view_nothing_to_trim) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_from_view(textview, STR(" \t\n\r\f\v")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_delimiters) + { + String text(STR("qztfpHello Worldqztfp")); + String expected(STR("Hello World")); + + etl::trim(text, STR("Hd")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_delimiters) + { + String text(STR("qztfpHello Worldqztfp")); + String expected(STR("Hello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view(textview, STR("Hd")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_delimiters_nothing_to_trim) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + etl::trim(text, STR("Hd")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_delimiters_nothing_to_trim) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view(textview, STR("Hd")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_trim_delimiters_no_delimiters) + { + String text(STR("Hello World")); + String expected(STR("")); + + etl::trim(text, STR("XYZ")); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_trim_view_delimiters_no_delimiters) + { + String text(STR("Hello World")); + String expected(STR("")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::trim_view(textview, STR("XYZ")); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_reverse) + { + String text(STR("Hello World")); + String expected(STR("dlroW olleH")); + + etl::reverse(text); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_right_n_view) + { + String text(STR("Hello World")); + String expected(STR("World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::right_n_view(textview, expected.size()); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_right_n_view_excess) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::right_n_view(textview, text.size() * 2U); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_right_n_string) + { + String text(STR("Hello World")); + String expected(STR("World")); + + etl::right_n(text, 5U); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_right_n_string_excess) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + etl::right_n(text, text.size() * 2U); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_left_n_view) + { + String text(STR("Hello World")); + String expected(STR("Hello")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::left_n_view(textview, expected.size()); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_left_n_view_excess) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + StringView textview(text.data(), text.size()); + StringView expectedview(expected.data(), expected.size()); + + StringView view = etl::left_n_view(textview, text.size() * 2U); + + CHECK_EQUAL(expectedview.size(), view.size()); + CHECK(std::equal(expectedview.begin(), expectedview.end(), view.begin())); + } + + //************************************************************************* + TEST(test_left_n_string) + { + String text(STR("Hello World")); + String expected(STR("Hello")); + + etl::left_n(text, expected.size()); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_left_n_string_excess) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + etl::left_n(text, text.size() * 2U); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_replace_characters) + { + String text(STR("This+++is a *file//name:")); + String expected(STR("This---is_a__-file__name_")); + + etl::pair lookup[] = + { + { STR('+'), STR('-') }, + { STR(' '), STR('_') }, + { STR('*'), STR('-') }, + { STR('/'), STR('_') }, + { STR(':'), STR('_') } + }; + + etl::replace_characters(text, ETL_OR_STD11::begin(lookup), ETL_OR_STD11::end(lookup)); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_replace_characters_empty_string) + { + String text(STR("")); + String expected(STR("")); + + etl::pair lookup[] = + { + { STR('+'), STR('-') }, + { STR(' '), STR('_') }, + { STR('*'), STR('-') }, + { STR('/'), STR('_') }, + { STR(':'), STR('_') } + }; + + etl::replace_characters(text, ETL_OR_STD11::begin(lookup), ETL_OR_STD11::end(lookup)); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_replace_strings) + { + String text(STR("This+++is a *file//name:")); + String expected(STR("Thisxyis%20a%20%20-file_name.txt")); + + etl::pair lookup[] = + { + { STR("+++"), STR("xy") }, + { STR(" "), STR("%20") }, + { STR("*"), STR("-") }, + { STR("//"), STR("_") }, + { STR(":"), STR(".txt") } + }; + + etl::replace_strings(text, ETL_OR_STD11::begin(lookup), ETL_OR_STD11::end(lookup)); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_replace_strings_empty_strings) + { + String text(STR("")); + String expected(STR("")); + + etl::pair lookup[] = + { + { STR("+++"), STR("xy") }, + { STR(" "), STR("%20") }, + { STR("*"), STR("-") }, + { STR("//"), STR("_") }, + { STR(":"), STR(".txt") } + }; + + etl::replace_strings(text, ETL_OR_STD11::begin(lookup), ETL_OR_STD11::end(lookup)); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_get_token_delimiters_ignore_empty_tokens) + { + String text(STR(",,,The,cat,sat,,on,the,mat,,,")); + Vector tokens; + + StringView textview(text.data(), text.size()); + etl::optional token; + + while ((token = etl::get_token(text, STR(","), token, true))) + { + tokens.emplace_back(token.value()); + } + + CHECK_EQUAL(6U, tokens.size()); + } + + //************************************************************************* + TEST(test_get_token_delimiters_keep_empty_tokens) + { + String text(STR(",,,The,cat,sat,,on,the,mat,,,")); + Vector tokens; + + StringView textview(text.data(), text.size()); + etl::optional token; + + while ((token = etl::get_token(text, STR(","), token, false))) + { + tokens.emplace_back(token.value()); + } + + CHECK_EQUAL(13U, tokens.size()); + } + + //************************************************************************* + TEST(test_get_token_delimiters_nothing_to_do) + { + String text(STR("")); + Vector tokens; + + StringView textview(text.data(), text.size()); + etl::optional token; + + while ((token = etl::get_token(text, Whitespace, token, true))) + { + tokens.emplace_back(token.value()); + } + + CHECK_EQUAL(0U, tokens.size()); + } + + //************************************************************************* + TEST(test_get_token_delimiters_no_tokens) + { + String text(STR(" ., ;: .,;:")); + Vector tokens; + + StringView textview(text.data(), text.size()); + etl::optional token; + + while ((token = etl::get_token(text, STR(" .,;:"), token, true))) + { + tokens.emplace_back(token.value()); + } + + CHECK_EQUAL(0U, tokens.size()); + } + + //************************************************************************* + TEST(test_get_token_delimiters_no_delimiters) + { + String text(STR("The cat sat on the mat")); + Vector tokens; + + StringView textview(text.data(), text.size()); + etl::optional token; + + while ((token = etl::get_token(text, STR(","), token, false))) + { + tokens.emplace_back(token.value()); + } + + CHECK_EQUAL(1U, tokens.size()); + } + + //************************************************************************* + TEST(test_get_token_delimiters_empty_string_view) + { + Vector tokens; + + StringView textview; + etl::optional token; + + while ((token = etl::get_token(textview, Whitespace, token, true))) + { + tokens.emplace_back(token.value()); + } + + CHECK_EQUAL(0U, tokens.size()); + } + + //************************************************************************* + TEST(test_pad_left) + { + String text(STR("Hello World")); + String expected(STR("xxxxHello World")); + + etl::pad_left(text, expected.size(), STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_pad_left_smaller) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + etl::pad_left(text, text.size() - 1U, STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_pad_left_greater_than_capacity) + { + String text(STR("Hello World")); + String expected(text); + expected.insert(String::size_type(0U), text.capacity() - expected.size(), STR('x')); + + etl::pad_left(text, text.capacity() + 1U, STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_pad_right) + { + String text(STR("Hello World")); + String expected(STR("Hello Worldxxxx")); + + etl::pad_right(text, expected.size(), STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_pad_right_smaller) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + etl::pad_right(text, text.size() - 1U, STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_pad_right_greater_than_capacity) + { + String text(STR("Hello World")); + String expected(text); + expected.insert(text.size(), text.capacity() - expected.size(), STR('x')); + + etl::pad_right(text, text.capacity() + 1U, STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_pad_select_left) + { + String text(STR("Hello World")); + String expected(STR("xxxxHello World")); + + etl::pad(text, expected.size(), etl::string_pad_direction::LEFT, STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_pad_select_left_smaller) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + etl::pad(text, text.size() - 1U, etl::string_pad_direction::LEFT, STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_pad_select_left_greater_than_capacity) + { + String text(STR("Hello World")); + String expected(text); + expected.insert(String::size_type(0U), text.capacity() - expected.size(), STR('x')); + + etl::pad(text, text.capacity() + 1U, etl::string_pad_direction::LEFT, STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_pad_select_right) + { + String text(STR("Hello World")); + String expected(STR("Hello Worldxxxx")); + + etl::pad(text, expected.size(), etl::string_pad_direction::RIGHT, STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_pad_select_right_smaller) + { + String text(STR("Hello World")); + String expected(STR("Hello World")); + + etl::pad(text, text.size() - 1U, etl::string_pad_direction::RIGHT, STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_pad_select_right_greater_than_capacity) + { + String text(STR("Hello World")); + String expected(text); + expected.insert(text.size(), text.capacity() - expected.size(), STR('x')); + + etl::pad(text, text.capacity() + 1U, etl::string_pad_direction::RIGHT, STR('x')); + + CHECK(expected == text); + } + + //************************************************************************* + TEST(test_find_first_of_iterator_iterator) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_first_of(text.begin(), text.end(), STR("Hel")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_of_iterator_iterator_not_found) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_first_of(text.begin(), text.end(), STR("xyz")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_first_of_const_iterator_const_iterator) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_first_of(text.cbegin(), text.cend(), STR("Hel")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_of_const_iterator_const_iterator_not_found) + { + String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_first_of(text.begin(), text.end(), STR("xyz")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_first_of_string) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_first_of(text, STR("Hel")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_of_string_not_found) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_first_of(text, STR("xyz")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_first_of_const_string) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_first_of(text, STR("Hel")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_of_const_string_not_found) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_first_of(text, STR("xyz")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_first_of_string_view) + { + const String text(STR("abcHello Worldabc")); + StringView textview(text.data(), text.size()); + + StringView::const_iterator itr = etl::find_first_of(textview, STR("Hel")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_of_string_view_not_found) + { + const String text(STR("abcHello Worldabc")); + StringView textview(text.data(), text.size()); + + StringView::const_iterator itr = etl::find_first_of(textview, STR("xyz")); + + CHECK(textview.end() == itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_iterator_iterator) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_first_not_of(text.begin(), text.end(), STR("abc")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_iterator_iterator_not_found) + { + String text(STR("abcHello Worldabc")); + String::iterator itr = etl::find_first_not_of(text.begin(), text.end(), STR("abcHello World")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_const_iterator_const_iterator) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_first_not_of(text.cbegin(), text.cend(), STR("abc")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_const_iterator_const_iterator_not_found) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_first_not_of(text.cbegin(), text.cend(), STR("abcHello World")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_string) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_first_not_of(text, STR("abc")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_string_not_found) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_first_not_of(text, STR("abcHello World")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_const_string) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_first_not_of(text, STR("abc")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_const_string_not_found) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_first_not_of(text, STR("abcHello World")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_string_view) + { + const String text(STR("abcHello Worldabc")); + StringView textview(text.data(), text.size()); + + StringView::const_iterator itr = etl::find_first_not_of(textview, STR("abc")); + + CHECK_EQUAL(STR('H'), *itr); + } + + //************************************************************************* + TEST(test_find_first_not_of_string_view_not_found) + { + const String text(STR("abcHello Worldabc")); + StringView textview(text.data(), text.size()); + + StringView::const_iterator itr = etl::find_first_not_of(textview, STR("abcHello World")); + + CHECK(textview.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_of_iterator_iterator) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_last_of(text.begin(), text.end(), STR("rld")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_of_iterator_iterator_not_found) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_last_of(text.begin(), text.end(), STR("xyz")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_of_const_iterator_const_iterator) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_last_of(text.cbegin(), text.cend(), STR("rld")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_of_const_iterator_const_iterator_not_found) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_last_of(text.cbegin(), text.cend(), STR("xyz")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_of_string) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_last_of(text, STR("rld")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_of_string_not_found) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_last_of(text, STR("xyz")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_of_const_string) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_last_of(text, STR("rld")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_of_const_string_not_found) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_last_of(text, STR("xyz")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_of_string_view) + { + String text(STR("abcHello Worldabc")); + StringView textview(text.data(), text.size()); + + StringView::const_iterator itr = etl::find_last_of(textview, STR("rld")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_of_string_view_not_found) + { + String text(STR("abcHello Worldabc")); + StringView textview(text.data(), text.size()); + + StringView::const_iterator itr = etl::find_last_of(textview, STR("xyz")); + + CHECK(textview.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_iterator_iterator) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_last_not_of(text.begin(), text.end(), STR("abc")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_iterator_iterator_not_found) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_last_not_of(text.begin(), text.end(), STR("abcHello World")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_const_iterator_const_iterator) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_last_not_of(text.cbegin(), text.cend(), STR("abc")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_const_iterator_const_iterator_not_found) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_last_not_of(text.cbegin(), text.cend(), STR("abcHello World")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_string) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_last_not_of(text, STR("abc")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_string_not_found) + { + String text(STR("abcHello Worldabc")); + + String::iterator itr = etl::find_last_not_of(text, STR("abcHello World")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_const_string) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_last_not_of(text, STR("abc")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_const_string_not_found) + { + const String text(STR("abcHello Worldabc")); + + String::const_iterator itr = etl::find_last_not_of(text, STR("abcHello World")); + + CHECK(text.end() == itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_string_view) + { + String text(STR("abcHello Worldabc")); + StringView textview(text.data(), text.size()); + + StringView::const_iterator itr = etl::find_last_not_of(textview, STR("abc")); + + CHECK_EQUAL(STR('d'), *itr); + } + + //************************************************************************* + TEST(test_find_last_not_of_string_view_not_found) + { + String text(STR("abcHello Worldabc")); + StringView textview(text.data(), text.size()); + + StringView::const_iterator itr = etl::find_last_not_of(textview, STR("abcHello World")); + + CHECK(textview.end() == itr); + } + }; +} + +#endif diff --git a/test/test_string_view.cpp b/test/test_string_view.cpp index 08c28a55..8588e3f4 100644 --- a/test/test_string_view.cpp +++ b/test/test_string_view.cpp @@ -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 diff --git a/test/test_to_arithmetic_u8.cpp b/test/test_to_arithmetic_u8.cpp new file mode 100644 index 00000000..1e9e027f --- /dev/null +++ b/test/test_to_arithmetic_u8.cpp @@ -0,0 +1,1026 @@ +/****************************************************************************** +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 +#include +#include +#include + +#include "etl/to_arithmetic.h" +#include "etl/u8string.h" +#include "etl/format_spec.h" + +#undef STR +#define STR(x) u8##x +using Text = std::u8string; + +namespace +{ + //************************************************************************* + template + std::ostream& operator <<(std::ostream& os, const etl::to_arithmetic_result& result) + { + if (result.has_value()) + { + os << result.value(); + } + else + { + os << result.error().c_str(); + } + + return os; + } + + typedef etl::format_spec Format; + + SUITE(test_to_arithmetic) + { + //************************************************************************* + TEST(test_invalid_radixes) + { + const Text text(STR("128")); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 0)); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 1)); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 3)); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 4)); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 5)); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 6)); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 7)); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 9)); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 11)); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 12)); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 13)); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 14)); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 15)); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 17)); + + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 0).has_value()); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 1).has_value()); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 3).has_value()); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 4).has_value()); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 5).has_value()); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 6).has_value()); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 7).has_value()); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 9).has_value()); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 11).has_value()); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 12).has_value()); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 13).has_value()); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 14).has_value()); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 15).has_value()); + CHECK(!etl::to_arithmetic(text.c_str(), text.size(), 17).has_value()); + + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Radix, etl::to_arithmetic(text.c_str(), text.size(), 0).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Radix, etl::to_arithmetic(text.c_str(), text.size(), 1).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Radix, etl::to_arithmetic(text.c_str(), text.size(), 3).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Radix, etl::to_arithmetic(text.c_str(), text.size(), 4).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Radix, etl::to_arithmetic(text.c_str(), text.size(), 5).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Radix, etl::to_arithmetic(text.c_str(), text.size(), 6).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Radix, etl::to_arithmetic(text.c_str(), text.size(), 7).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Radix, etl::to_arithmetic(text.c_str(), text.size(), 9).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Radix, etl::to_arithmetic(text.c_str(), text.size(), 11).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Radix, etl::to_arithmetic(text.c_str(), text.size(), 12).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Radix, etl::to_arithmetic(text.c_str(), text.size(), 13).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Radix, etl::to_arithmetic(text.c_str(), text.size(), 14).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Radix, etl::to_arithmetic(text.c_str(), text.size(), 15).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Radix, etl::to_arithmetic(text.c_str(), text.size(), 17).error()); + } + + //************************************************************************* + TEST(test_invalid_binary_numerics) + { + const Text text1(STR(" 101")); + const Text text2(STR("101 ")); + const Text text3(STR("121")); + const Text text4(STR("")); + const Text text5(STR("-101")); + + CHECK(!etl::to_arithmetic(text1.c_str(), text1.size(), etl::bin)); + CHECK(!etl::to_arithmetic(text2.c_str(), text2.size(), etl::bin)); + CHECK(!etl::to_arithmetic(text3.c_str(), text3.size(), etl::bin)); + CHECK(!etl::to_arithmetic(text4.c_str(), text4.size(), etl::bin)); + CHECK(!etl::to_arithmetic(text5.c_str(), text5.size(), etl::bin)); + + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text1.c_str(), text1.size(), etl::bin).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text2.c_str(), text2.size(), etl::bin).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text3.c_str(), text3.size(), etl::bin).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text4.c_str(), text4.size(), etl::bin).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Signed_To_Unsigned, etl::to_arithmetic(text5.c_str(), text5.size(), etl::bin).error()); + } + + //************************************************************************* + TEST(test_valid_binary_numerics) + { + const Text value1(STR("0")); + const Text value2(STR("1")); + const Text value3(STR("0101")); + const Text value4(STR("1010")); + const Text value5(STR("01010011")); + const Text value6(STR("10101100")); + const Text value7(STR("-01010100")); + + CHECK_EQUAL(int(0), int(etl::to_arithmetic(value1.c_str(), value1.size(), etl::bin).value())); + CHECK_EQUAL(int(1), int(etl::to_arithmetic(value2.c_str(), value2.size(), etl::bin).value())); + CHECK_EQUAL(int(5), int(etl::to_arithmetic(value3.c_str(), value3.size(), etl::bin).value())); + CHECK_EQUAL(int(10), int(etl::to_arithmetic(value4.c_str(), value4.size(), etl::bin).value())); + CHECK_EQUAL(int(83), int(etl::to_arithmetic(value5.c_str(), value5.size(), etl::bin).value())); + CHECK_EQUAL(int(-84), int(etl::to_arithmetic(value6.c_str(), value6.size(), etl::bin).value())); + CHECK_EQUAL(int(-84), int(etl::to_arithmetic(value7.c_str(), value7.size(), etl::bin).value())); + + CHECK(etl::to_arithmetic(value1.c_str(), value1.size(), etl::bin).has_value()); + CHECK(etl::to_arithmetic(value2.c_str(), value2.size(), etl::bin).has_value()); + CHECK(etl::to_arithmetic(value3.c_str(), value3.size(), etl::bin).has_value()); + CHECK(etl::to_arithmetic(value4.c_str(), value4.size(), etl::bin).has_value()); + CHECK(etl::to_arithmetic(value5.c_str(), value5.size(), etl::bin).has_value()); + CHECK(etl::to_arithmetic(value6.c_str(), value6.size(), etl::bin).has_value()); + CHECK(etl::to_arithmetic(value7.c_str(), value7.size(), etl::bin).has_value()); + } + + //************************************************************************* + TEST(test_maximum_binary_numerics) + { + const Text int8_max(STR("01111111")); + const Text int8_min_neg(STR("-10000000")); + const Text int8_min_2c(STR("10000000")); + + const Text uint8_max(STR("11111111")); + const Text uint8_min(STR("00000000")); + + const Text int16_max(STR("0111111111111111")); + const Text int16_min_neg(STR("-1000000000000000")); + const Text int16_min_2c(STR("1000000000000000")); + + const Text uint16_max(STR("1111111111111111")); + const Text uint16_min(STR("0000000000000000")); + + const Text int32_max(STR("01111111111111111111111111111111")); + const Text int32_min_neg(STR("-10000000000000000000000000000000")); + const Text int32_min_2c(STR("10000000000000000000000000000000")); + + const Text uint32_max(STR("11111111111111111111111111111111")); + const Text uint32_min(STR("0")); + + const Text int64_max(STR("0111111111111111111111111111111111111111111111111111111111111111")); + const Text int64_min_neg(STR("-1000000000000000000000000000000000000000000000000000000000000000")); + const Text int64_min_2c(STR("1000000000000000000000000000000000000000000000000000000000000000")); + + const Text uint64_max(STR("1111111111111111111111111111111111111111111111111111111111111111")); + const Text uint64_min(STR("0")); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(int8_max.c_str(), int8_max.size(), etl::bin).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int8_min_neg.c_str(), int8_min_neg.size(), etl::bin).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int8_min_2c.c_str(), int8_min_2c.size(), etl::bin).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(uint8_max.c_str(), uint8_max.size(), etl::bin).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(uint8_min.c_str(), uint8_min.size(), etl::bin).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(int16_max.c_str(), int16_max.size(), etl::bin).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int16_min_neg.c_str(), int16_min_neg.size(), etl::bin).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int16_min_2c.c_str(), int16_min_2c.size(), etl::bin).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(uint16_max.c_str(), uint16_max.size(), etl::bin).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(uint16_min.c_str(), uint16_min.size(), etl::bin).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(int32_max.c_str(), int32_max.size(), etl::bin).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int32_min_neg.c_str(), int32_min_neg.size(), etl::bin).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int32_min_2c.c_str(), int32_min_2c.size(), etl::bin).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(uint32_max.c_str(), uint32_max.size(), etl::bin).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(uint32_min.c_str(), uint32_min.size(), etl::bin).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(int64_max.c_str(), int64_max.size(), etl::bin).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int64_min_neg.c_str(), int64_min_neg.size(), etl::bin).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int64_min_2c.c_str(), int64_min_2c.size(), etl::bin).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(uint64_max.c_str(), uint64_max.size(), etl::bin).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(uint64_min.c_str(), uint64_min.size(), etl::bin).value()); + } + + //************************************************************************* + TEST(test_binary_numerics_overflow) + { + const Text int8_overflow_max(STR("100000000")); + const Text int8_overflow_min(STR("-100000000")); + + const Text uint8_overflow_max(STR("100000000")); + + const Text int16_overflow_max(STR("10000000000000000")); + const Text int16_overflow_min(STR("-10000000000000000")); + + const Text uint16_overflow_max(STR("10000000000000000")); + + const Text int32_overflow_max(STR("100000000000000000000000000000000")); + const Text int32_overflow_min(STR("-100000000000000000000000000000000")); + + const Text uint32_overflow_max(STR("100000000000000000000000000000000")); + + const Text int64_overflow_max(STR("10000000000000000000000000000000000000000000000000000000000000000")); + const Text int64_overflow_min(STR("-10000000000000000000000000000000000000000000000000000000000000000")); + + const Text uint64_overflow_max(STR("10000000000000000000000000000000000000000000000000000000000000000")); + + CHECK(!etl::to_arithmetic(int8_overflow_max.c_str(), int8_overflow_max.size(), etl::bin)); + CHECK(!etl::to_arithmetic(int8_overflow_min.c_str(), int8_overflow_min.size(), etl::bin)); + + CHECK(!etl::to_arithmetic(uint8_overflow_max.c_str(), uint8_overflow_max.size(), etl::bin)); + + CHECK(!etl::to_arithmetic(int16_overflow_max.c_str(), int16_overflow_max.size(), etl::bin)); + CHECK(!etl::to_arithmetic(int16_overflow_min.c_str(), int16_overflow_min.size(), etl::bin)); + + CHECK(!etl::to_arithmetic(uint16_overflow_max.c_str(), uint16_overflow_max.size(), etl::bin)); + + CHECK(!etl::to_arithmetic(int32_overflow_max.c_str(), int32_overflow_max.size(), etl::bin)); + CHECK(!etl::to_arithmetic(int32_overflow_min.c_str(), int32_overflow_min.size(), etl::bin)); + + CHECK(!etl::to_arithmetic(uint32_overflow_max.c_str(), uint32_overflow_max.size(), etl::bin)); + + CHECK(!etl::to_arithmetic(int64_overflow_max.c_str(), int64_overflow_max.size(), etl::bin)); + CHECK(!etl::to_arithmetic(int64_overflow_min.c_str(), int64_overflow_min.size(), etl::bin)); + + CHECK(!etl::to_arithmetic(uint64_overflow_max.c_str(), uint64_overflow_max.size(), etl::bin)); + + + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(int8_overflow_max.c_str(), int8_overflow_max.size(), etl::bin).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(int8_overflow_min.c_str(), int8_overflow_min.size(), etl::bin).error()); + + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(uint8_overflow_max.c_str(), uint8_overflow_max.size(), etl::bin).error()); + + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(int16_overflow_max.c_str(), int16_overflow_max.size(), etl::bin).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(int16_overflow_min.c_str(), int16_overflow_min.size(), etl::bin).error()); + + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(uint16_overflow_max.c_str(), uint16_overflow_max.size(), etl::bin).error()); + + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(int32_overflow_max.c_str(), int32_overflow_max.size(), etl::bin).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(int32_overflow_min.c_str(), int32_overflow_min.size(), etl::bin).error()); + + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(uint32_overflow_max.c_str(), uint32_overflow_max.size(), etl::bin).error()); + + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(int64_overflow_max.c_str(), int64_overflow_max.size(), etl::bin).error()); + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(int64_overflow_min.c_str(), int64_overflow_min.size(), etl::bin).error()); + + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(uint64_overflow_max.c_str(), uint64_overflow_max.size(), etl::bin).error()); + } + + //************************************************************************* + TEST(test_invalid_octal_numerics) + { + const Text text1(STR(" 127")); + const Text text2(STR("127 ")); + const Text text3(STR("187")); + const Text text4(STR("-187")); + + CHECK(!etl::to_arithmetic(text1.c_str(), text1.size(), etl::oct)); + CHECK(!etl::to_arithmetic(text2.c_str(), text2.size(), etl::oct)); + CHECK(!etl::to_arithmetic(text3.c_str(), text3.size(), etl::oct)); + CHECK(!etl::to_arithmetic(text4.c_str(), text4.size(), etl::oct)); + } + + //************************************************************************* + TEST(test_valid_octal_numerics) + { + const Text value1(STR("0")); + const Text value2(STR("01")); + const Text value3(STR("05")); + const Text value4(STR("012")); + const Text value5(STR("0123")); + const Text value6(STR("0254")); + const Text value7(STR("-0124")); + + CHECK_EQUAL(int(0), int(etl::to_arithmetic(value1.c_str(), value1.size(), etl::oct).value())); + CHECK_EQUAL(int(1), int(etl::to_arithmetic(value2.c_str(), value2.size(), etl::oct).value())); + CHECK_EQUAL(int(5), int(etl::to_arithmetic(value3.c_str(), value3.size(), etl::oct).value())); + CHECK_EQUAL(int(10), int(etl::to_arithmetic(value4.c_str(), value4.size(), etl::oct).value())); + CHECK_EQUAL(int(83), int(etl::to_arithmetic(value5.c_str(), value5.size(), etl::oct).value())); + CHECK_EQUAL(int(-84), int(etl::to_arithmetic(value6.c_str(), value6.size(), etl::oct).value())); + CHECK_EQUAL(int(-84), int(etl::to_arithmetic(value7.c_str(), value7.size(), etl::oct).value())); + } + + //************************************************************************* + TEST(test_maximum_octal_numerics) + { + const Text int8_max(STR("177")); + const Text int8_min_neg(STR("-200")); + const Text int8_min_2c(STR("200")); + + const Text uint8_max(STR("377")); + const Text uint8_min(STR("0")); + + const Text int16_max(STR("77777")); + const Text int16_min_neg(STR("-100000")); + const Text int16_min_2c(STR("100000")); + + const Text uint16_max(STR("177777")); + const Text uint16_min(STR("0")); + + const Text int32_max(STR("17777777777")); + const Text int32_min_neg(STR("-20000000000")); + const Text int32_min_2c(STR("20000000000")); + + const Text uint32_max(STR("37777777777")); + const Text uint32_min(STR("0")); + + const Text int64_max(STR("777777777777777777777")); + const Text int64_min_neg(STR("-1000000000000000000000")); + const Text int64_min_2c(STR("1000000000000000000000")); + + const Text uint64_max(STR("1777777777777777777777")); + const Text uint64_min(STR("0")); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(int8_max.c_str(), int8_max.size(), etl::oct).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int8_min_neg.c_str(), int8_min_neg.size(), etl::oct).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int8_min_2c.c_str(), int8_min_2c.size(), etl::oct).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(uint8_max.c_str(), uint8_max.size(), etl::oct).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(uint8_min.c_str(), uint8_min.size(), etl::oct).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(int16_max.c_str(), int16_max.size(), etl::oct).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int16_min_neg.c_str(), int16_min_neg.size(), etl::oct).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int16_min_2c.c_str(), int16_min_2c.size(), etl::oct).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(uint16_max.c_str(), uint16_max.size(), etl::oct).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(uint16_min.c_str(), uint16_min.size(), etl::oct).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(int32_max.c_str(), int32_max.size(), etl::oct).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int32_min_neg.c_str(), int32_min_neg.size(), etl::oct).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int32_min_2c.c_str(), int32_min_2c.size(), etl::oct).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(uint32_max.c_str(), uint32_max.size(), etl::oct).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(uint32_min.c_str(), uint32_min.size(), etl::oct).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(int64_max.c_str(), int64_max.size(), etl::oct).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int64_min_neg.c_str(), int64_min_neg.size(), etl::oct).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int64_min_2c.c_str(), int64_min_2c.size(), etl::oct).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(uint64_max.c_str(), uint64_max.size(), etl::oct).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(uint64_min.c_str(), uint64_min.size(), etl::oct).value()); + } + + //************************************************************************* + TEST(test_octal_numerics_overflow) + { + const Text int8_overflow_max(STR("400")); + const Text int8_overflow_min(STR("-400")); + + const Text uint8_overflow_max(STR("400")); + + const Text int16_overflow_max(STR("200000")); + const Text int16_overflow_min(STR("-200000")); + + const Text uint16_overflow_max(STR("200000")); + + const Text int32_overflow_max(STR("40000000000")); + const Text int32_overflow_min(STR("-40000000000")); + + const Text uint32_overflow_max(STR("40000000000")); + + const Text int64_overflow_max(STR("2000000000000000000000")); + const Text int64_overflow_min(STR("-2000000000000000000000")); + + const Text uint64_overflow_max(STR("2000000000000000000000")); + + CHECK(!etl::to_arithmetic(int8_overflow_max.c_str(), int8_overflow_max.size(), etl::oct)); + CHECK(!etl::to_arithmetic(int8_overflow_min.c_str(), int8_overflow_min.size(), etl::oct)); + + CHECK(!etl::to_arithmetic(uint8_overflow_max.c_str(), uint8_overflow_max.size(), etl::oct)); + + CHECK(!etl::to_arithmetic(int16_overflow_max.c_str(), int16_overflow_max.size(), etl::oct)); + CHECK(!etl::to_arithmetic(int16_overflow_min.c_str(), int16_overflow_min.size(), etl::oct)); + + CHECK(!etl::to_arithmetic(uint16_overflow_max.c_str(), uint16_overflow_max.size(), etl::oct)); + + CHECK(!etl::to_arithmetic(int32_overflow_max.c_str(), int32_overflow_max.size(), etl::oct)); + CHECK(!etl::to_arithmetic(int32_overflow_min.c_str(), int32_overflow_min.size(), etl::oct)); + + CHECK(!etl::to_arithmetic(uint32_overflow_max.c_str(), uint32_overflow_max.size(), etl::oct)); + + CHECK(!etl::to_arithmetic(int64_overflow_max.c_str(), int64_overflow_max.size(), etl::oct)); + CHECK(!etl::to_arithmetic(int64_overflow_min.c_str(), int64_overflow_min.size(), etl::oct)); + + CHECK(!etl::to_arithmetic(uint64_overflow_max.c_str(), uint64_overflow_max.size(), etl::oct)); + } + + //************************************************************************* + TEST(test_invalid_decimal_numerics) + { + const Text text1(STR(" 128")); + const Text text2(STR("128 ")); + const Text text3(STR("1A8")); + const Text text4(STR("++128")); + const Text text5(STR("-+128")); + const Text text6(STR("+-128")); + const Text text7(STR("--128")); + const Text text8(STR("+")); + const Text text9(STR("-")); + const Text text10(STR("")); + + CHECK(!etl::to_arithmetic(text1.c_str(), text1.size(), etl::dec)); + CHECK(!etl::to_arithmetic(text2.c_str(), text2.size(), etl::dec)); + CHECK(!etl::to_arithmetic(text3.c_str(), text3.size(), etl::dec)); + CHECK(!etl::to_arithmetic(text4.c_str(), text4.size(), etl::dec)); + CHECK(!etl::to_arithmetic(text5.c_str(), text5.size(), etl::dec)); + CHECK(!etl::to_arithmetic(text6.c_str(), text6.size(), etl::dec)); + CHECK(!etl::to_arithmetic(text7.c_str(), text7.size(), etl::dec)); + CHECK(!etl::to_arithmetic(text8.c_str(), text8.size(), etl::dec)); + CHECK(!etl::to_arithmetic(text9.c_str(), text9.size(), etl::dec)); + CHECK(!etl::to_arithmetic(text10.c_str(), text10.size(), etl::dec)); + } + + //************************************************************************* + TEST(test_valid_decimal_numerics) + { + const Text text1(STR("0")); + const Text text2(STR("1")); + const Text text3(STR("5")); + const Text text4(STR("+10")); + const Text text5(STR("83")); + const Text text6(STR("-84")); + + CHECK_EQUAL(int(0), int(etl::to_arithmetic(text1.c_str(), text1.size(), etl::dec).value())); + CHECK_EQUAL(int(1), int(etl::to_arithmetic(text2.c_str(), text2.size(), etl::dec).value())); + CHECK_EQUAL(int(5), int(etl::to_arithmetic(text3.c_str(), text3.size(), etl::dec).value())); + CHECK_EQUAL(int(10), int(etl::to_arithmetic(text4.c_str(), text4.size(), etl::dec).value())); + CHECK_EQUAL(int(83), int(etl::to_arithmetic(text5.c_str(), text5.size(), etl::dec).value())); + CHECK_EQUAL(int(83), int(etl::to_arithmetic(text5.c_str(), text5.size(), etl::dec).value())); + CHECK_EQUAL(int(-84), int(etl::to_arithmetic(text6.c_str(), text6.size(), etl::dec).value())); + } + + //************************************************************************* + TEST(test_maximum_decimal_numerics) + { + const Text int8_max(STR("127")); + const Text int8_min(STR("-128")); + + const Text uint8_max(STR("255")); + const Text uint8_min(STR("0")); + + const Text int16_max(STR("32767")); + const Text int16_min(STR("-32768")); + + const Text uint16_max(STR("65535")); + const Text uint16_min(STR("0")); + + const Text int32_max(STR("2147483647")); + const Text int32_min(STR("-2147483648")); + + const Text uint32_max(STR("4294967295")); + const Text uint32_min(STR("0")); + + const Text int64_max(STR("9223372036854775807")); + const Text int64_min(STR("-9223372036854775808")); + + const Text uint64_max(STR("18446744073709551615")); + const Text uint64_min(STR("0")); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(int8_max.c_str(), int8_max.size(), etl::dec).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int8_min.c_str(), int8_min.size(), etl::dec).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(uint8_max.c_str(), uint8_max.size(), etl::dec).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(uint8_min.c_str(), uint8_min.size(), etl::dec).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(int16_max.c_str(), int16_max.size(), etl::dec).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int16_min.c_str(), int16_min.size(), etl::dec).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(uint16_max.c_str(), uint16_max.size(), etl::dec).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(uint16_min.c_str(), uint16_min.size(), etl::dec).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(int32_max.c_str(), int32_max.size(), etl::dec).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int32_min.c_str(), int32_min.size(), etl::dec).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(uint32_max.c_str(), uint32_max.size(), etl::dec).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(uint32_min.c_str(), uint32_min.size(), etl::dec).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(int64_max.c_str(), int64_max.size(), etl::dec).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int64_min.c_str(), int64_min.size(), etl::dec).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(uint64_max.c_str(), uint64_max.size(), etl::dec).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(uint64_min.c_str(), uint64_min.size(), etl::dec).value()); + } + + //************************************************************************* + TEST(test_decimal_numerics_overflow) + { + const Text int8_overflow_max(STR("128")); + const Text int8_overflow_min(STR("-129")); + + const Text int8_overflow_max_plus(STR("1000")); + const Text int8_overflow_min_plus(STR("-1000")); + + const Text uint8_overflow_max(STR("256")); + + const Text int16_overflow_max(STR("32768")); + const Text int16_overflow_min(STR("-32769")); + + const Text uint16_overflow_max(STR("65536")); + + const Text int32_overflow_max(STR("2147483648")); + const Text int32_overflow_min(STR("-2147483649")); + + const Text uint32_overflow_max(STR("4294967296")); + + const Text int64_overflow_max(STR("9223372036854775808")); + const Text int64_overflow_min(STR("-9223372036854775809")); + + const Text uint64_overflow_max(STR("18446744073709551616")); + + CHECK(!etl::to_arithmetic(int8_overflow_max.c_str(), int8_overflow_max.size(), etl::dec)); + CHECK(!etl::to_arithmetic(int8_overflow_min.c_str(), int8_overflow_min.size(), etl::dec)); + + CHECK(!etl::to_arithmetic(int8_overflow_max_plus.c_str(), int8_overflow_max_plus.size(), etl::dec)); + CHECK(!etl::to_arithmetic(int8_overflow_min_plus.c_str(), int8_overflow_min_plus.size(), etl::dec)); + + CHECK(!etl::to_arithmetic(uint8_overflow_max.c_str(), uint8_overflow_max.size(), etl::dec)); + + CHECK(!etl::to_arithmetic(int16_overflow_max.c_str(), int16_overflow_max.size(), etl::dec)); + CHECK(!etl::to_arithmetic(int16_overflow_min.c_str(), int16_overflow_min.size(), etl::dec)); + + CHECK(!etl::to_arithmetic(uint16_overflow_max.c_str(), uint16_overflow_max.size(), etl::dec)); + + CHECK(!etl::to_arithmetic(int32_overflow_max.c_str(), int32_overflow_max.size(), etl::dec)); + CHECK(!etl::to_arithmetic(int32_overflow_min.c_str(), int32_overflow_min.size(), etl::dec)); + + CHECK(!etl::to_arithmetic(uint32_overflow_max.c_str(), uint32_overflow_max.size(), etl::dec)); + + CHECK(!etl::to_arithmetic(int64_overflow_max.c_str(), int64_overflow_max.size(), etl::dec)); + CHECK(!etl::to_arithmetic(int64_overflow_min.c_str(), int64_overflow_min.size(), etl::dec)); + + CHECK(!etl::to_arithmetic(uint64_overflow_max.c_str(), uint64_overflow_max.size(), etl::dec)); + } + + //************************************************************************* + TEST(test_invalid_hex_numerics) + { + const Text text1(STR(" 1Af")); + const Text text2(STR("1Af ")); + const Text text3(STR("1Gf")); + const Text text4(STR("-1Af")); + + CHECK(!etl::to_arithmetic(text1.c_str(), text1.size(), etl::hex)); + CHECK(!etl::to_arithmetic(text2.c_str(), text2.size(), etl::hex)); + CHECK(!etl::to_arithmetic(text3.c_str(), text3.size(), etl::hex)); + CHECK(!etl::to_arithmetic(text4.c_str(), text4.size(), etl::hex)); + } + + //************************************************************************* + TEST(test_valid_hex_numerics) + { + const Text text1(STR("0")); + const Text text2(STR("1")); + const Text text3(STR("5")); + const Text text4(STR("a")); + const Text text5(STR("53")); + const Text text6(STR("Ac")); + const Text text7(STR("-54")); + + CHECK_EQUAL(int(0), int(etl::to_arithmetic(text1.c_str(), text1.size(), etl::hex).value())); + CHECK_EQUAL(int(1), int(etl::to_arithmetic(text2.c_str(), text2.size(), etl::hex).value())); + CHECK_EQUAL(int(5), int(etl::to_arithmetic(text3.c_str(), text3.size(), etl::hex).value())); + CHECK_EQUAL(int(10), int(etl::to_arithmetic(text4.c_str(), text4.size(), etl::hex).value())); + CHECK_EQUAL(int(83), int(etl::to_arithmetic(text5.c_str(), text5.size(), etl::hex).value())); + CHECK_EQUAL(int(-84), int(etl::to_arithmetic(text6.c_str(), text6.size(), etl::hex).value())); + CHECK_EQUAL(int(-84), int(etl::to_arithmetic(text7.c_str(), text7.size(), etl::hex).value())); + } + + //************************************************************************* + TEST(test_maximum_hex_numerics) + { + const Text int8_max(STR("7F")); + const Text int8_min_neg(STR("-80")); + const Text int8_min_2c(STR("80")); + + const Text uint8_max(STR("FF")); + const Text uint8_min(STR("0")); + + const Text int16_max(STR("7FFF")); + const Text int16_min_neg(STR("-8000")); + const Text int16_min_2c(STR("8000")); + + const Text uint16_max(STR("FFFF")); + const Text uint16_min(STR("0")); + + const Text int32_max(STR("7FFFFFFF")); + const Text int32_min_neg(STR("-80000000")); + const Text int32_min_2c(STR("80000000")); + + const Text uint32_max(STR("FFFFFFFF")); + const Text uint32_min(STR("0")); + + const Text int64_max(STR("7FFFFFFFFFFFFFFF")); + const Text int64_min_neg(STR("-8000000000000000")); + const Text int64_min_2c(STR("8000000000000000")); + + const Text uint64_max(STR("FFFFFFFFFFFFFFFF")); + const Text uint64_min(STR("0")); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(int8_max.c_str(), int8_max.size(), etl::hex).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int8_min_neg.c_str(), int8_min_neg.size(), etl::hex).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int8_min_2c.c_str(), int8_min_2c.size(), etl::hex).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(uint8_max.c_str(), uint8_max.size(), etl::hex).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(uint8_min.c_str(), uint8_min.size(), etl::hex).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(int16_max.c_str(), int16_max.size(), etl::hex).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int16_min_neg.c_str(), int16_min_neg.size(), etl::hex).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int16_min_2c.c_str(), int16_min_2c.size(), etl::hex).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(uint16_max.c_str(), uint16_max.size(), etl::hex).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(uint16_min.c_str(), uint16_min.size(), etl::hex).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(int32_max.c_str(), int32_max.size(), etl::hex).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int32_min_neg.c_str(), int32_min_neg.size(), etl::hex).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int32_min_2c.c_str(), int32_min_2c.size(), etl::hex).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(uint32_max.c_str(), uint32_max.size(), etl::hex).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(uint32_min.c_str(), uint32_min.size(), etl::hex).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(int64_max.c_str(), int64_max.size(), etl::hex).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int64_min_neg.c_str(), int64_min_neg.size(), etl::hex).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(int64_min_2c.c_str(), int64_min_2c.size(), etl::hex).value()); + + CHECK_EQUAL(std::numeric_limits::max(), etl::to_arithmetic(uint64_max.c_str(), uint64_max.size(), etl::hex).value()); + CHECK_EQUAL(std::numeric_limits::min(), etl::to_arithmetic(uint64_min.c_str(), uint64_min.size(), etl::hex).value()); + } + + //************************************************************************* + TEST(test_hex_numerics_overflow) + { + const Text int8_overflow_max(STR("100")); + const Text int8_overflow_min(STR("-100")); + + const Text uint8_overflow_max(STR("100")); + + const Text int16_overflow_max(STR("10000")); + const Text int16_overflow_min(STR("-10000")); + + const Text uint16_overflow_max(STR("10000")); + + const Text int32_overflow_max(STR("100000000")); + const Text int32_overflow_min(STR("-100000000")); + + const Text uint32_overflow_max(STR("100000000")); + + const Text int64_overflow_max(STR("10000000000000000")); + const Text int64_overflow_min(STR("-10000000000000000")); + + const Text uint64_overflow_max(STR("10000000000000000")); + + CHECK(!etl::to_arithmetic(int8_overflow_max.c_str(), int8_overflow_max.size(), etl::hex)); + CHECK(!etl::to_arithmetic(int8_overflow_min.c_str(), int8_overflow_min.size(), etl::hex)); + + CHECK(!etl::to_arithmetic(uint8_overflow_max.c_str(), uint8_overflow_max.size(), etl::hex)); + + CHECK(!etl::to_arithmetic(int16_overflow_max.c_str(), int16_overflow_max.size(), etl::hex)); + CHECK(!etl::to_arithmetic(int16_overflow_min.c_str(), int16_overflow_min.size(), etl::hex)); + + CHECK(!etl::to_arithmetic(uint16_overflow_max.c_str(), uint16_overflow_max.size(), etl::hex)); + + CHECK(!etl::to_arithmetic(int32_overflow_max.c_str(), int32_overflow_max.size(), etl::hex)); + CHECK(!etl::to_arithmetic(int32_overflow_min.c_str(), int32_overflow_min.size(), etl::hex)); + + CHECK(!etl::to_arithmetic(uint32_overflow_max.c_str(), uint32_overflow_max.size(), etl::hex)); + + CHECK(!etl::to_arithmetic(int64_overflow_max.c_str(), int64_overflow_max.size(), etl::hex)); + CHECK(!etl::to_arithmetic(int64_overflow_min.c_str(), int64_overflow_min.size(), etl::hex)); + + CHECK(!etl::to_arithmetic(uint64_overflow_max.c_str(), uint64_overflow_max.size(), etl::hex)); + } + + //************************************************************************* + TEST(test_valid_float) + { + Text text; + + //********************************* + text = STR("-123.456789"); + + float f1 = strtof("-123.456789", nullptr); + float f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK(etl::to_arithmetic(text.c_str(), text.size()).has_value()); + + //********************************* + text = STR("123.456789"); + + f1 = strtof("123.456789", nullptr); + f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK(etl::to_arithmetic(text.c_str(), text.size()).has_value()); + + //********************************* + text = STR("-1.23456789e2"); + + f1 = strtof("-1.23456789e2", nullptr); + f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK(etl::to_arithmetic(text.c_str(), text.size()).has_value()); + + //********************************* + text = STR("-12345.6789e-2"); + + f1 = strtof("-12345.6789e-2", nullptr); + f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK(etl::to_arithmetic(text.c_str(), text.size()).has_value()); + + //********************************* + text = STR("+12345E-2"); + + f1 = strtof("+12345E-2", nullptr); + f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK(etl::to_arithmetic(text.c_str(), text.size()).has_value()); + + //********************************* + text = STR("+12345.6789E000"); + + f1 = strtof("+12345.6789E000", nullptr); + f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK(etl::to_arithmetic(text.c_str(), text.size()).has_value()); + } + + //************************************************************************* + TEST(test_invalid_float) + { + Text text; + + //********************************* + text = STR(" -123.456789"); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("-123.456789 "); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("-12A.456789"); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("-123.456A89"); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("123.-456789"); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("123E.45"); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("123.45E10000"); + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("-123.45E10000"); + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(text.c_str(), text.size()).error()); + } + + //************************************************************************* + TEST(test_valid_double) + { + Text text; + + //********************************* + text = STR("-123.45678901234567"); + + double f1 = strtod("-123.45678901234567", nullptr); + double f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK(etl::to_arithmetic(text.c_str(), text.size()).has_value()); + + //********************************* + text = STR("123.45678901234567"); + + f1 = strtod("123.45678901234567", nullptr); + f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK(etl::to_arithmetic(text.c_str(), text.size()).has_value()); + + //********************************* + text = STR("-1.2345678901234567e7"); + + f1 = strtod("-1.2345678901234567e7", nullptr); + f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK(etl::to_arithmetic(text.c_str(), text.size()).has_value()); + + //********************************* + text = STR("-12345.678901234567e-2"); + + f1 = strtod("-12345.678901234567e-2", nullptr); + f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK(etl::to_arithmetic(text.c_str(), text.size()).has_value()); + + //********************************* + text = STR("+12345E-2"); + + f1 = strtod("+12345E-2", nullptr); + f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK(etl::to_arithmetic(text.c_str(), text.size()).has_value()); + + //********************************* + text = STR("+12345.678901234567E0"); + + f1 = strtod("+12345.678901234567E0", nullptr); + f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK(etl::to_arithmetic(text.c_str(), text.size()).has_value()); + } + + //************************************************************************* + TEST(test_invalid_double) + { + Text text; + + //********************************* + text = STR(" -123.456789"); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("-123.456789 "); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("-12A.456789"); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("-123.456A89"); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("123.-456789"); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("123E.45"); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("123.45E10000"); + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("-123.45E10000"); + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(text.c_str(), text.size()).error()); + } + + //************************************************************************* + TEST(test_valid_long_double) + { + Text text; + + //********************************* + text = STR("-123.45678901234567"); + + long double f1 = strtold("-123.45678901234567", nullptr); + long double f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK(etl::to_arithmetic(text.c_str(), text.size()).has_value()); + + //********************************* + text = STR("123.45678901234567"); + + f1 = strtold("123.45678901234567", nullptr); + f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK(etl::to_arithmetic(text.c_str(), text.size()).has_value()); + + //********************************* + text = STR("-1.2345678901234567e2"); + + f1 = strtold("-1.2345678901234567e2", nullptr); + f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK(etl::to_arithmetic(text.c_str(), text.size()).has_value()); + + //********************************* + text = STR("-12345.678901234567e-2"); + + f1 = strtold("-12345.678901234567e-2", nullptr); + f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK(etl::to_arithmetic(text.c_str(), text.size()).has_value()); + + //********************************* + text = STR("+12345E-2"); + + f1 = strtold("+12345E-2", nullptr); + f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK(etl::to_arithmetic(text.c_str(), text.size()).has_value()); + + //********************************* + text = STR("+12345.678901234567E000"); + + f1 = strtold("+12345.678901234567E000", nullptr); + f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK(etl::to_arithmetic(text.c_str(), text.size()).has_value()); + } + + //************************************************************************* + TEST(test_invalid_long_double) + { + Text text; + + //********************************* + text = STR(" -123.456789"); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("-123.456789 "); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("-12A.456789"); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("-123.456A89"); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("123.-456789"); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("123E.45"); + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("123.45E10000"); + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(text.c_str(), text.size()).error()); + + //********************************* + text = STR("-123.45E10000"); + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(text.c_str(), text.size()).error()); + } + + //************************************************************************* +#if ETL_USING_CPP14 + TEST(test_constexpr_integral) + { + constexpr Text::const_pointer text{ STR("123") }; + + constexpr etl::to_arithmetic_result result = etl::to_arithmetic(text, 3U, etl::radix::decimal); + constexpr int i = result.value(); + + CHECK_EQUAL(123, i); + } +#endif + } +} + +#endif diff --git a/test/test_to_u8string.cpp b/test/test_to_u8string.cpp new file mode 100644 index 00000000..f551799e --- /dev/null +++ b/test/test_to_u8string.cpp @@ -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 diff --git a/test/vs2022/etl.vcxproj b/test/vs2022/etl.vcxproj index 6d02d902..1de173d6 100644 --- a/test/vs2022/etl.vcxproj +++ b/test/vs2022/etl.vcxproj @@ -3154,6 +3154,7 @@ + @@ -3161,6 +3162,9 @@ + + + @@ -6941,6 +6945,48 @@ true true + + true + true + true + true + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + true + true + true + true + true true @@ -8181,6 +8227,9 @@ + + + @@ -8192,9 +8241,11 @@ + + @@ -8205,10 +8256,12 @@ + + diff --git a/test/vs2022/etl.vcxproj.filters b/test/vs2022/etl.vcxproj.filters index 04a0462b..dc9db11f 100644 --- a/test/vs2022/etl.vcxproj.filters +++ b/test/vs2022/etl.vcxproj.filters @@ -1371,6 +1371,18 @@ ETL\Codecs + + ETL\Strings + + + ETL\Strings + + + ETL\Strings + + + ETL\Strings + @@ -2354,81 +2366,6 @@ Tests\Patterns - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - Tests\Binary @@ -3299,6 +3236,36 @@ Tests\Syntax Checks\Source + + Tests\Strings + + + Tests\Strings + + + Tests\Syntax Checks\Source + + + Tests\Strings + + + Tests\Strings + + + Tests\Strings + + + Tests\Strings + + + Tests\Strings + + + Tests\Syntax Checks\Source + + + Tests\Syntax Checks\Source +