From 2f1343ec0e794bdad01fa683cb04f5c66cb332c5 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 5 Jul 2020 19:39:50 +0100 Subject: [PATCH 1/2] Initial string stream commit --- include/etl/basic_format_spec.h | 22 +++ include/etl/private/to_string_helper.h | 88 +++++++--- include/etl/string_stream.h | 180 ++++++++++++++++++++ include/etl/to_string.h | 58 ++++++- include/etl/to_u16string.h | 60 ++++++- include/etl/to_u32string.h | 60 ++++++- include/etl/to_wstring.h | 60 ++++++- include/etl/u16string_stream.h | 180 ++++++++++++++++++++ include/etl/u32string_stream.h | 180 ++++++++++++++++++++ include/etl/wstring_stream.h | 180 ++++++++++++++++++++ test/test_string_stream.cpp | 220 +++++++++++++++++++++++++ test/test_u16string_stream.cpp | 220 +++++++++++++++++++++++++ test/test_u32string_stream.cpp | 220 +++++++++++++++++++++++++ test/test_wstring_stream.cpp | 220 +++++++++++++++++++++++++ test/vs2019/etl.vcxproj | 8 + test/vs2019/etl.vcxproj.filters | 24 +++ 16 files changed, 1946 insertions(+), 34 deletions(-) create mode 100644 include/etl/string_stream.h create mode 100644 include/etl/u16string_stream.h create mode 100644 include/etl/u32string_stream.h create mode 100644 include/etl/wstring_stream.h create mode 100644 test/test_string_stream.cpp create mode 100644 test/test_u16string_stream.cpp create mode 100644 test/test_u32string_stream.cpp create mode 100644 test/test_wstring_stream.cpp diff --git a/include/etl/basic_format_spec.h b/include/etl/basic_format_spec.h index ca3da502..6ffa332b 100644 --- a/include/etl/basic_format_spec.h +++ b/include/etl/basic_format_spec.h @@ -248,6 +248,28 @@ namespace etl return boolalpha_; } + //*************************************************************************** + /// Equality operator. + //*************************************************************************** + friend bool operator ==(const basic_format_spec& lhs, const basic_format_spec& rhs) + { + return (lhs.base_ == rhs.base_) && + (lhs.width_ == rhs.width_) && + (lhs.precision_ == rhs.precision_) && + (lhs.upper_case_ == rhs.upper_case_) && + (lhs.left_justified_ == rhs.left_justified_) && + (lhs.boolalpha_ == rhs.boolalpha_) && + (lhs.fill_ == rhs.fill_); + } + + //*************************************************************************** + /// Inequality operator. + //*************************************************************************** + friend bool operator !=(const basic_format_spec& lhs, const basic_format_spec& rhs) + { + return !(lhs == rhs); + } + private: uint_least8_t base_; diff --git a/include/etl/private/to_string_helper.h b/include/etl/private/to_string_helper.h index 8f83b73d..9f0b2234 100644 --- a/include/etl/private/to_string_helper.h +++ b/include/etl/private/to_string_helper.h @@ -88,7 +88,7 @@ namespace etl void add_boolean(const bool value, TIString& str, const etl::basic_format_spec& format, - const bool append) + bool append) { typedef typename TIString::value_type type; typedef typename TIString::iterator iterator; @@ -136,7 +136,7 @@ namespace etl void add_integral(T value, TIString& str, const etl::basic_format_spec& format, - const bool append) + bool append) { typedef typename TIString::value_type type; typedef typename TIString::iterator iterator; @@ -228,7 +228,7 @@ namespace etl void add_floating_point(T value, TIString& str, const etl::basic_format_spec& format, - const bool append) + bool append) { typedef typename TIString::iterator iterator; typedef typename TIString::value_type type; @@ -289,22 +289,64 @@ namespace etl void add_pointer(const volatile void* value, TIString& str, const etl::basic_format_spec& format, - const bool append) + bool append) { uintptr_t p = reinterpret_cast(value); return etl::private_to_string::add_integral(p, str, format, append); } + //*************************************************************************** + /// Helper function for strings. + //*************************************************************************** + template + void add_string(const TIString& value, + TIString& str, + const etl::basic_format_spec& format, + bool append) + { + if (!append) + { + str.clear(); + } + + typename TIString::iterator start = str.end(); + + str.insert(str.end(), value.begin(), value.end()); + + etl::private_to_string::add_alignment(str, start, format); + } + + //*************************************************************************** +/// Helper function for string views. +//*************************************************************************** + template + void add_string_view(const TSringView& value, + TIString& str, + const etl::basic_format_spec& format, + bool append) + { + if (!append) + { + str.clear(); + } + + typename TIString::iterator start = str.end(); + + str.insert(str.end(), value.begin(), value.end()); + + etl::private_to_string::add_alignment(str, start, format); + } + //********************************************************************************************************* //*************************************************************************** /// For booleans. Default format spec. - //***************************************************************************etl::basic_format_spec + //*************************************************************************** template const TIString& to_string(const bool value, TIString& str, - const bool append = false) + bool append = false) { etl::basic_format_spec format; @@ -320,7 +362,7 @@ namespace etl const TIString& to_string(const bool value, TIString& str, const etl::basic_format_spec& format, - const bool append = false) + bool append = false) { etl::private_to_string::add_boolean(value, str, format, append); @@ -333,7 +375,7 @@ namespace etl template const TIString& to_string(const volatile void* value, TIString& str, - const bool append = false) + bool append = false) { etl::basic_format_spec format; @@ -349,7 +391,7 @@ namespace etl const TIString& to_string(const volatile void* value, TIString& str, const etl::basic_format_spec& format, - const bool append = false) + bool append = false) { etl::private_to_string::add_pointer(value, str, format, append); @@ -364,7 +406,7 @@ namespace etl typename etl::enable_if::value && etl::is_signed::value && !etl::is_same::value>::value, const TIString& > ::type - to_string(const T value, TIString& str, const bool append = false) + to_string(const T value, TIString& str, bool append = false) { etl::basic_format_spec format; @@ -380,7 +422,7 @@ namespace etl typename etl::enable_if::value && etl::is_signed::value && !etl::is_same::value>::value, const TIString& > ::type - to_string(const T value, TIString& str, const etl::basic_format_spec& format, const bool append = false) + to_string(const T value, TIString& str, const etl::basic_format_spec& format, bool append = false) { etl::private_to_string::add_integral(int32_t(value), str, format, append); @@ -394,7 +436,7 @@ namespace etl typename etl::enable_if::value && etl::is_unsigned::value && !etl::is_same::value>::value, const TIString& > ::type - to_string(const T value, TIString& str, const bool append = false) + to_string(const T value, TIString& str, bool append = false) { etl::basic_format_spec format; @@ -410,7 +452,7 @@ namespace etl typename etl::enable_if::value && etl::is_unsigned::value && !etl::is_same::value>::value, const TIString& > ::type - to_string(const T value, TIString& str, const etl::basic_format_spec& format, const bool append = false) + to_string(const T value, TIString& str, const etl::basic_format_spec& format, bool append = false) { etl::private_to_string::add_integral(uint32_t(value), str, format, append); @@ -425,7 +467,7 @@ namespace etl etl::is_signed::value && !etl::is_same::value && !etl::is_same::value, const TIString&>::type - to_string(const T value, TIString& str, const bool append = false) + to_string(const T value, TIString& str, bool append = false) { etl::basic_format_spec format; @@ -442,7 +484,7 @@ namespace etl etl::is_signed::value && !etl::is_same::value && !etl::is_same::value, const TIString&>::type - to_string(const T value, TIString& str, const etl::basic_format_spec& format, const bool append = false) + to_string(const T value, TIString& str, const etl::basic_format_spec& format, bool append = false) { etl::private_to_string::add_integral(int32_t(value), str, format, append); @@ -457,7 +499,7 @@ namespace etl etl::is_unsigned::value && !etl::is_same::value && !etl::is_same::value, const TIString&>::type - to_string(const T value, TIString& str, const bool append = false) + to_string(const T value, TIString& str, bool append = false) { etl::basic_format_spec format; @@ -474,7 +516,7 @@ namespace etl etl::is_unsigned::value && !etl::is_same::value && !etl::is_same::value, const TIString&>::type - to_string(const T value, TIString& str, const etl::basic_format_spec& format, const bool append = false) + to_string(const T value, TIString& str, const etl::basic_format_spec& format, bool append = false) { etl::private_to_string::add_integral(uint32_t(value), str, format, append); @@ -489,7 +531,7 @@ namespace etl etl::is_signed::value && !etl::is_same::value && etl::is_same::value, const TIString&>::type - to_string(const T value, TIString& str, const bool append = false) + to_string(const T value, TIString& str, bool append = false) { etl::basic_format_spec format; @@ -506,7 +548,7 @@ namespace etl etl::is_signed::value && !etl::is_same::value && etl::is_same::value, const TIString&>::type - to_string(const T value, TIString& str, const etl::basic_format_spec& format, const bool append = false) + to_string(const T value, TIString& str, const etl::basic_format_spec& format, bool append = false) { etl::private_to_string::add_integral(int64_t(value), str, format, append); @@ -521,7 +563,7 @@ namespace etl etl::is_unsigned::value && !etl::is_same::value && etl::is_same::value, const TIString&>::type - to_string(const T value, TIString& str, const bool append = false) + to_string(const T value, TIString& str, bool append = false) { etl::basic_format_spec format; @@ -538,7 +580,7 @@ namespace etl etl::is_unsigned::value && !etl::is_same::value && etl::is_same::value, const TIString&>::type - to_string(const T value, TIString& str, const etl::basic_format_spec& format, const bool append = false) + to_string(const T value, TIString& str, const etl::basic_format_spec& format, bool append = false) { etl::private_to_string::add_integral(uint64_t(value), str, format, append); @@ -551,7 +593,7 @@ namespace etl //*************************************************************************** template typename etl::enable_if::value, const TIString&>::type - to_string(const T value, TIString& str, const bool append = false) + to_string(const T value, TIString& str, bool append = false) { etl::basic_format_spec format; @@ -565,7 +607,7 @@ namespace etl //*************************************************************************** template typename etl::enable_if::value, const TIString&>::type - to_string(const T value, TIString& str, const etl::basic_format_spec& format, const bool append = false) + to_string(const T value, TIString& str, const etl::basic_format_spec& format, bool append = false) { etl::private_to_string::add_floating_point(value, str, format, append); diff --git a/include/etl/string_stream.h b/include/etl/string_stream.h new file mode 100644 index 00000000..7842c157 --- /dev/null +++ b/include/etl/string_stream.h @@ -0,0 +1,180 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2020 jwellbelove + +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_STRING_STREAM_INCLUDED +#define ETL_STRING_STREAM_INCLUDED + +///\ingroup string + +#include "platform.h" +#include "cstring.h" +#include "format_spec.h" +#include "to_string.h" +#include "string_view.h" + +namespace etl +{ + class string_stream + { + public: + + typedef etl::format_spec format_spec_type; + typedef etl::istring istring_type; + typedef etl::istring::value_type value_type; + + //************************************************************************* + /// Construct from text. + //************************************************************************* + explicit string_stream(etl::istring& text_) + : text(text_) + { + } + + //************************************************************************* + /// Construct from text and format spec. + //************************************************************************* + string_stream(etl::istring& text_, etl::format_spec spec_) + : text(text_) + , spec(spec_) + { + } + + //************************************************************************* + /// Set the format spec. + //************************************************************************* + void set_format(etl::format_spec spec_) + { + spec = spec_; + } + + //************************************************************************* + /// Get a const reference to the format spec. + //************************************************************************* + const etl::format_spec& get_format() const + { + return spec; + } + + //************************************************************************* + /// Get a reference to the current string. + //************************************************************************* + etl::istring& str() + { + return text; + } + + //************************************************************************* + /// Get a const reference to the current string. + //************************************************************************* + const etl::istring& str() const + { + return text; + } + + //************************************************************************* + /// Resets the stream to the supplied string. + //************************************************************************* + void str(const etl::istring::value_type* p) + { + text.assign(p); + } + + //************************************************************************* + /// Resets the stream to the supplied string. + //************************************************************************* + void str(const etl::istring& is) + { + text.assign(is); + } + + //************************************************************************* + /// Get the current size of the string. + //************************************************************************* + size_t size() const + { + return text.size(); + } + + //************************************************************************* + /// Stream operators. + //************************************************************************* + friend string_stream& operator <<(string_stream& ss, etl::format_spec spec) + { + ss.spec = spec; + return ss; + } + + //********************************* + friend string_stream& operator <<(string_stream& ss, etl::string_view view) + { + etl::to_string(view, ss.text, ss.spec, true); + return ss; + } + + //********************************* + friend string_stream& operator <<(string_stream& ss, etl::istring::const_pointer p) + { + etl::string_view view(p); + ss << view; + return ss; + } + + //********************************* + friend string_stream& operator <<(string_stream& ss, const etl::istring& text) + { + etl::to_string(text, ss.text, ss.spec, true); + return ss; + } + + //********************************* + template + friend string_stream& operator <<(string_stream& ss, const etl::string& text) + { + const etl::istring& itext = text; + etl::to_string(itext, ss.text, ss.spec, true); + return ss; + } + + //********************************* + template + friend string_stream& operator <<(string_stream& ss, const T& value) + { + etl::to_string(value, ss.text, ss.spec, true); + return ss; + } + + private: + + etl::istring& text; + etl::format_spec spec; + }; +} + +#endif diff --git a/include/etl/to_string.h b/include/etl/to_string.h index 7ee633e9..b1cb280f 100644 --- a/include/etl/to_string.h +++ b/include/etl/to_string.h @@ -45,7 +45,8 @@ namespace etl /// Default format spec. //*************************************************************************** template - const etl::istring& to_string(const T value, etl::istring& str, const bool append = false) + typename etl::enable_if::value && !etl::is_same::value, const etl::istring&>::type + to_string(const T value, etl::istring& str, bool append = false) { etl::format_spec format; @@ -56,10 +57,63 @@ namespace etl /// Supplied format spec.. //*************************************************************************** template - const etl::istring& to_string(const T value, etl::istring& str, const etl::format_spec& format, const bool append = false) + typename etl::enable_if::value && !etl::is_same::value, const etl::istring&>::type + to_string(const T value, etl::istring& str, const etl::format_spec& format, bool append = false) { return private_to_string::to_string(value, str, format, append); } + + //*************************************************************************** + /// Default format spec. + //*************************************************************************** + template + typename etl::enable_if::value, const etl::istring&>::type + to_string(const T& value, etl::istring& str, bool append = false) + { + etl::format_spec format; + + private_to_string::add_string(value, str, format, append); + + return str; + } + + //*************************************************************************** + /// Supplied format spec.. + //*************************************************************************** + template + typename etl::enable_if::value, const etl::istring&>::type + to_string(const etl::istring& value, T& str, const etl::format_spec& format, bool append = false) + { + private_to_string::add_string(value, str, format, append); + + return str; + } + + //*************************************************************************** + /// Default format spec. + //*************************************************************************** + template + typename etl::enable_if::value, const etl::istring&>::type + to_string(T value, etl::istring& str, bool append = false) + { + etl::format_spec format; + + private_to_string::add_string_view(value, str, format, append); + + return str; + } + + //*************************************************************************** + /// Supplied format spec.. + //*************************************************************************** + template + typename etl::enable_if::value, const etl::istring&>::type + to_string(T value, etl::istring& str, const etl::format_spec& format, bool append = false) + { + private_to_string::add_string_view(value, str, format, append); + + return str; + } } #endif diff --git a/include/etl/to_u16string.h b/include/etl/to_u16string.h index b87eb7e4..40473e1b 100644 --- a/include/etl/to_u16string.h +++ b/include/etl/to_u16string.h @@ -45,7 +45,8 @@ namespace etl /// Default format spec. //*************************************************************************** template - const etl::iu16string& to_string(const T value, etl::iu16string& str, const bool append = false) + typename etl::enable_if::value && !etl::is_same::value, const etl::iu16string&>::type + to_string(const T value, etl::iu16string& str, bool append = false) { etl::u16format_spec format; @@ -53,13 +54,66 @@ namespace etl } //*************************************************************************** - /// Supplied format spec. + /// Supplied format spec.. //*************************************************************************** template - const etl::iu16string& to_string(const T value, etl::iu16string& str, const etl::u16format_spec& format, const bool append = false) + typename etl::enable_if::value && !etl::is_same::value, const etl::iu16string&>::type + to_string(const T value, etl::iu16string& str, const etl::u16format_spec& format, bool append = false) { return private_to_string::to_string(value, str, format, append); } + + //*************************************************************************** + /// Default format spec. + //*************************************************************************** + template + typename etl::enable_if::value, const etl::iu16string&>::type + to_string(const T& value, etl::iu16string& str, bool append = false) + { + etl::u16format_spec format; + + private_to_string::add_string(value, str, format, append); + + return str; + } + + //*************************************************************************** + /// Supplied format spec.. + //*************************************************************************** + template + typename etl::enable_if::value, const etl::iu16string&>::type + to_string(const etl::iu16string& value, T& str, const etl::u16format_spec& format, bool append = false) + { + private_to_string::add_string(value, str, format, append); + + return str; + } + + //*************************************************************************** + /// Default format spec. + //*************************************************************************** + template + typename etl::enable_if::value, const etl::iu16string&>::type + to_string(T value, etl::iu16string& str, bool append = false) + { + etl::u16format_spec format; + + private_to_string::add_string_view(value, str, format, append); + + return str; + } + + //*************************************************************************** + /// Supplied format spec.. + //*************************************************************************** + template + typename etl::enable_if::value, const etl::iu16string&>::type + to_string(T value, etl::iu16string& str, const etl::u16format_spec& format, bool append = false) + { + private_to_string::add_string_view(value, str, format, append); + + return str; + } } #endif diff --git a/include/etl/to_u32string.h b/include/etl/to_u32string.h index 88b7e3cf..36a7d805 100644 --- a/include/etl/to_u32string.h +++ b/include/etl/to_u32string.h @@ -45,7 +45,8 @@ namespace etl /// Default format spec. //*************************************************************************** template - const etl::iu32string& to_string(const T value, etl::iu32string& str, const bool append = false) + typename etl::enable_if::value && !etl::is_same::value, const etl::iu32string&>::type + to_string(const T value, etl::iu32string& str, bool append = false) { etl::u32format_spec format; @@ -53,13 +54,66 @@ namespace etl } //*************************************************************************** - /// Supplied format spec. + /// Supplied format spec.. //*************************************************************************** template - const etl::iu32string& to_string(const T value, etl::iu32string& str, const etl::u32format_spec& format, const bool append = false) + typename etl::enable_if::value && !etl::is_same::value, const etl::iu32string&>::type + to_string(const T value, etl::iu32string& str, const etl::u32format_spec& format, bool append = false) { return private_to_string::to_string(value, str, format, append); } + + //*************************************************************************** + /// Default format spec. + //*************************************************************************** + template + typename etl::enable_if::value, const etl::iu32string&>::type + to_string(const T& value, etl::iu32string& str, bool append = false) + { + etl::u32format_spec format; + + private_to_string::add_string(value, str, format, append); + + return str; + } + + //*************************************************************************** + /// Supplied format spec.. + //*************************************************************************** + template + typename etl::enable_if::value, const etl::iu32string&>::type + to_string(const etl::iu32string& value, T& str, const etl::u32format_spec& format, bool append = false) + { + private_to_string::add_string(value, str, format, append); + + return str; + } + + //*************************************************************************** + /// Default format spec. + //*************************************************************************** + template + typename etl::enable_if::value, const etl::iu32string&>::type + to_string(T value, etl::iu32string& str, bool append = false) + { + etl::u32format_spec format; + + private_to_string::add_string_view(value, str, format, append); + + return str; + } + + //*************************************************************************** + /// Supplied format spec.. + //*************************************************************************** + template + typename etl::enable_if::value, const etl::iu32string&>::type + to_string(T value, etl::iu32string& str, const etl::u32format_spec& format, bool append = false) + { + private_to_string::add_string_view(value, str, format, append); + + return str; + } } #endif diff --git a/include/etl/to_wstring.h b/include/etl/to_wstring.h index fcbe728a..4ce8e813 100644 --- a/include/etl/to_wstring.h +++ b/include/etl/to_wstring.h @@ -45,7 +45,8 @@ namespace etl /// Default format spec. //*************************************************************************** template - const etl::iwstring& to_string(const T value, etl::iwstring& str, const bool append = false) + typename etl::enable_if::value && !etl::is_same::value, const etl::iwstring&>::type + to_string(const T value, etl::iwstring& str, bool append = false) { etl::wformat_spec format; @@ -53,13 +54,66 @@ namespace etl } //*************************************************************************** - /// Supplied format spec. + /// Supplied format spec.. //*************************************************************************** template - const etl::iwstring& to_string(const T value, etl::iwstring& str, const etl::wformat_spec& format, const bool append = false) + typename etl::enable_if::value && !etl::is_same::value, const etl::iwstring&>::type + to_string(const T value, etl::iwstring& str, const etl::wformat_spec& format, bool append = false) { return private_to_string::to_string(value, str, format, append); } + + //*************************************************************************** + /// Default format spec. + //*************************************************************************** + template + typename etl::enable_if::value, const etl::iwstring&>::type + to_string(const T& value, etl::iwstring& str, bool append = false) + { + etl::wformat_spec format; + + private_to_string::add_string(value, str, format, append); + + return str; + } + + //*************************************************************************** + /// Supplied format spec.. + //*************************************************************************** + template + typename etl::enable_if::value, const etl::iwstring&>::type + to_string(const etl::iwstring& value, T& str, const etl::wformat_spec& format, bool append = false) + { + private_to_string::add_string(value, str, format, append); + + return str; + } + + //*************************************************************************** + /// Default format spec. + //*************************************************************************** + template + typename etl::enable_if::value, const etl::iwstring&>::type + to_string(T value, etl::iwstring& str, bool append = false) + { + etl::wformat_spec format; + + private_to_string::add_string_view(value, str, format, append); + + return str; + } + + //*************************************************************************** + /// Supplied format spec.. + //*************************************************************************** + template + typename etl::enable_if::value, const etl::iwstring&>::type + to_string(T value, etl::iwstring& str, const etl::wformat_spec& format, bool append = false) + { + private_to_string::add_string_view(value, str, format, append); + + return str; + } } #endif diff --git a/include/etl/u16string_stream.h b/include/etl/u16string_stream.h new file mode 100644 index 00000000..f6251ee3 --- /dev/null +++ b/include/etl/u16string_stream.h @@ -0,0 +1,180 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2020 jwellbelove + +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_U16STRING_STREAM_INCLUDED +#define ETL_U16STRING_STREAM_INCLUDED + +///\ingroup string + +#include "platform.h" +#include "u16string.h" +#include "u16format_spec.h" +#include "to_u16string.h" +#include "string_view.h" + +namespace etl +{ + class u16string_stream + { + public: + + typedef etl::u16format_spec format_spec_type; + typedef etl::iu16string istring_type; + typedef etl::iu16string::value_type value_type; + + //************************************************************************* + /// Construct from text. + //************************************************************************* + explicit u16string_stream(etl::iu16string& text_) + : text(text_) + { + } + + //************************************************************************* + /// Construct from text and format spec. + //************************************************************************* + u16string_stream(etl::iu16string& text_, etl::u16format_spec spec_) + : text(text_) + , spec(spec_) + { + } + + //************************************************************************* + /// Set the format spec. + //************************************************************************* + void set_format(etl::u16format_spec spec_) + { + spec = spec_; + } + + //************************************************************************* + /// Get a const reference to the format spec. + //************************************************************************* + const etl::u16format_spec& get_format() const + { + return spec; + } + + //************************************************************************* + /// Get a reference to the current string. + //************************************************************************* + etl::iu16string& str() + { + return text; + } + + //************************************************************************* + /// Get a const reference to the current string. + //************************************************************************* + const etl::iu16string& str() const + { + return text; + } + + //************************************************************************* + /// Resets the stream to the supplied string. + //************************************************************************* + void str(const etl::iu16string::value_type* p) + { + text.assign(p); + } + + //************************************************************************* + /// Resets the stream to the supplied string. + //************************************************************************* + void str(const etl::iu16string& is) + { + text.assign(is); + } + + //************************************************************************* + /// Get the current size of the string. + //************************************************************************* + size_t size() const + { + return text.size(); + } + + //************************************************************************* + /// Stream operators. + //************************************************************************* + friend u16string_stream& operator <<(u16string_stream& ss, etl::u16format_spec spec) + { + ss.spec = spec; + return ss; + } + + //********************************* + friend u16string_stream& operator <<(u16string_stream& ss, etl::u16string_view view) + { + etl::to_string(view, ss.text, ss.spec, true); + return ss; + } + + //********************************* + friend u16string_stream& operator <<(u16string_stream& ss, etl::iu16string::const_pointer p) + { + etl::u16string_view view(p); + ss << view; + return ss; + } + + //********************************* + friend u16string_stream& operator <<(u16string_stream& ss, const etl::iu16string& text) + { + etl::to_string(text, ss.text, ss.spec, true); + return ss; + } + + //********************************* + template + friend u16string_stream& operator <<(u16string_stream& ss, const etl::u16string& text) + { + const etl::iu16string& itext = text; + etl::to_string(itext, ss.text, ss.spec, true); + return ss; + } + + //********************************* + template + friend u16string_stream& operator <<(u16string_stream& ss, const T& value) + { + etl::to_string(value, ss.text, ss.spec, true); + return ss; + } + + private: + + etl::iu16string& text; + etl::u16format_spec spec; + }; +} + +#endif diff --git a/include/etl/u32string_stream.h b/include/etl/u32string_stream.h new file mode 100644 index 00000000..94044744 --- /dev/null +++ b/include/etl/u32string_stream.h @@ -0,0 +1,180 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2020 jwellbelove + +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_U32STRING_STREAM_INCLUDED +#define ETL_U32STRING_STREAM_INCLUDED + +///\ingroup string + +#include "platform.h" +#include "u32string.h" +#include "u32format_spec.h" +#include "to_u32string.h" +#include "string_view.h" + +namespace etl +{ + class u32string_stream + { + public: + + typedef etl::u32format_spec format_spec_type; + typedef etl::iu32string istring_type; + typedef etl::iu32string::value_type value_type; + + //************************************************************************* + /// Construct from text. + //************************************************************************* + explicit u32string_stream(etl::iu32string& text_) + : text(text_) + { + } + + //************************************************************************* + /// Construct from text and format spec. + //************************************************************************* + u32string_stream(etl::iu32string& text_, etl::u32format_spec spec_) + : text(text_) + , spec(spec_) + { + } + + //************************************************************************* + /// Set the format spec. + //************************************************************************* + void set_format(etl::u32format_spec spec_) + { + spec = spec_; + } + + //************************************************************************* + /// Get a const reference to the format spec. + //************************************************************************* + const etl::u32format_spec& get_format() const + { + return spec; + } + + //************************************************************************* + /// Get a reference to the current string. + //************************************************************************* + etl::iu32string& str() + { + return text; + } + + //************************************************************************* + /// Get a const reference to the current string. + //************************************************************************* + const etl::iu32string& str() const + { + return text; + } + + //************************************************************************* + /// Resets the stream to the supplied string. + //************************************************************************* + void str(const etl::iu32string::value_type* p) + { + text.assign(p); + } + + //************************************************************************* + /// Resets the stream to the supplied string. + //************************************************************************* + void str(const etl::iu32string& is) + { + text.assign(is); + } + + //************************************************************************* + /// Get the current size of the string. + //************************************************************************* + size_t size() const + { + return text.size(); + } + + //************************************************************************* + /// Stream operators. + //************************************************************************* + friend u32string_stream& operator <<(u32string_stream& ss, etl::u32format_spec spec) + { + ss.spec = spec; + return ss; + } + + //********************************* + friend u32string_stream& operator <<(u32string_stream& ss, etl::u32string_view view) + { + etl::to_string(view, ss.text, ss.spec, true); + return ss; + } + + //********************************* + friend u32string_stream& operator <<(u32string_stream& ss, etl::iu32string::const_pointer p) + { + etl::u32string_view view(p); + ss << view; + return ss; + } + + //********************************* + friend u32string_stream& operator <<(u32string_stream& ss, const etl::iu32string& text) + { + etl::to_string(text, ss.text, ss.spec, true); + return ss; + } + + //********************************* + template + friend u32string_stream& operator <<(u32string_stream& ss, const etl::u32string& text) + { + const etl::iu32string& itext = text; + etl::to_string(itext, ss.text, ss.spec, true); + return ss; + } + + //********************************* + template + friend u32string_stream& operator <<(u32string_stream& ss, const T& value) + { + etl::to_string(value, ss.text, ss.spec, true); + return ss; + } + + private: + + etl::iu32string& text; + etl::u32format_spec spec; + }; +} + +#endif diff --git a/include/etl/wstring_stream.h b/include/etl/wstring_stream.h new file mode 100644 index 00000000..9c786da6 --- /dev/null +++ b/include/etl/wstring_stream.h @@ -0,0 +1,180 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2020 jwellbelove + +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_WSTRING_STREAM_INCLUDED +#define ETL_WSTRING_STREAM_INCLUDED + +///\ingroup string + +#include "platform.h" +#include "cstring.h" +#include "wformat_spec.h" +#include "to_wstring.h" +#include "string_view.h" + +namespace etl +{ + class wstring_stream + { + public: + + typedef etl::wformat_spec format_spec_type; + typedef etl::iwstring istring_type; + typedef etl::iwstring::value_type value_type; + + //************************************************************************* + /// Construct from text. + //************************************************************************* + explicit wstring_stream(etl::iwstring& text_) + : text(text_) + { + } + + //************************************************************************* + /// Construct from text and format spec. + //************************************************************************* + wstring_stream(etl::iwstring& text_, etl::wformat_spec spec_) + : text(text_) + , spec(spec_) + { + } + + //************************************************************************* + /// Set the format spec. + //************************************************************************* + void set_format(etl::wformat_spec spec_) + { + spec = spec_; + } + + //************************************************************************* + /// Get a const reference to the format spec. + //************************************************************************* + const etl::wformat_spec& get_format() const + { + return spec; + } + + //************************************************************************* + /// Get a reference to the current string. + //************************************************************************* + etl::iwstring& str() + { + return text; + } + + //************************************************************************* + /// Get a const reference to the current string. + //************************************************************************* + const etl::iwstring& str() const + { + return text; + } + + //************************************************************************* + /// Resets the stream to the supplied string. + //************************************************************************* + void str(const etl::iwstring::value_type* p) + { + text.assign(p); + } + + //************************************************************************* + /// Resets the stream to the supplied string. + //************************************************************************* + void str(const etl::iwstring& is) + { + text.assign(is); + } + + //************************************************************************* + /// Get the current size of the string. + //************************************************************************* + size_t size() const + { + return text.size(); + } + + //************************************************************************* + /// Stream operators. + //************************************************************************* + friend wstring_stream& operator <<(wstring_stream& ss, etl::wformat_spec spec) + { + ss.spec = spec; + return ss; + } + + //********************************* + friend wstring_stream& operator <<(wstring_stream& ss, etl::wstring_view view) + { + etl::to_string(view, ss.text, ss.spec, true); + return ss; + } + + //********************************* + friend wstring_stream& operator <<(wstring_stream& ss, etl::iwstring::const_pointer p) + { + etl::wstring_view view(p); + ss << view; + return ss; + } + + //********************************* + friend wstring_stream& operator <<(wstring_stream& ss, const etl::iwstring& text) + { + etl::to_string(text, ss.text, ss.spec, true); + return ss; + } + + //********************************* + template + friend wstring_stream& operator <<(wstring_stream& ss, const etl::wstring& text) + { + const etl::iwstring& itext = text; + etl::to_string(itext, ss.text, ss.spec, true); + return ss; + } + + //********************************* + template + friend wstring_stream& operator <<(wstring_stream& ss, const T& value) + { + etl::to_string(value, ss.text, ss.spec, true); + return ss; + } + + private: + + etl::iwstring& text; + etl::wformat_spec spec; + }; +} + +#endif diff --git a/test/test_string_stream.cpp b/test/test_string_stream.cpp new file mode 100644 index 00000000..82b06836 --- /dev/null +++ b/test/test_string_stream.cpp @@ -0,0 +1,220 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2020 jwellbelove + +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 "UnitTest++/UnitTest++.h" + +#include +#include +#include + +#include "etl/string_stream.h" +#include "etl/cstring.h" +#include "etl/format_spec.h" + +#undef STR +#define STR(x) x + +namespace +{ + using String = etl::string<50>; + using IString = etl::istring; + using Stream = etl::string_stream; + using Format = etl::format_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; + } + + //*********************************** + std::ostream& operator << (std::ostream& os, const IString& str) + { + for (auto c : str) + { + os << c; + } + + return os; + } + + SUITE(test_string_stream) + { + //************************************************************************* + TEST(test_default_format) + { + 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_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_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); + } + + //************************************************************************* + TEST(test_get_size) + { + String str; + Stream ss(str); + + ss.str(String(STR("Hello"))); + + CHECK_EQUAL(str.size(), ss.size()); + } + }; +} + diff --git a/test/test_u16string_stream.cpp b/test/test_u16string_stream.cpp new file mode 100644 index 00000000..9bfa9cfd --- /dev/null +++ b/test/test_u16string_stream.cpp @@ -0,0 +1,220 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2020 jwellbelove + +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 "UnitTest++/UnitTest++.h" + +#include +#include +#include + +#include "etl/u16string_stream.h" +#include "etl/u16string.h" +#include "etl/format_spec.h" + +#undef STR +#define STR(x) u##x + +namespace +{ + using String = etl::u16string<50>; + using IString = etl::iu16string; + using Stream = etl::u16string_stream; + using Format = etl::u16format_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; + } + + //*********************************** + std::ostream& operator << (std::ostream& os, const IString& str) + { + for (auto c : str) + { + os << c; + } + + return os; + } + + SUITE(test_string_stream) + { + //************************************************************************* + TEST(test_default_format) + { + 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_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_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); + } + + //************************************************************************* + TEST(test_get_size) + { + String str; + Stream ss(str); + + ss.str(String(STR("Hello"))); + + CHECK_EQUAL(str.size(), ss.size()); + } + }; +} + diff --git a/test/test_u32string_stream.cpp b/test/test_u32string_stream.cpp new file mode 100644 index 00000000..84f00031 --- /dev/null +++ b/test/test_u32string_stream.cpp @@ -0,0 +1,220 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2020 jwellbelove + +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 "UnitTest++/UnitTest++.h" + +#include +#include +#include + +#include "etl/u32string_stream.h" +#include "etl/u32string.h" +#include "etl/format_spec.h" + +#undef STR +#define STR(x) U##x + +namespace +{ + using String = etl::u32string<50>; + using IString = etl::iu32string; + using Stream = etl::u32string_stream; + using Format = etl::u32format_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; + } + + //*********************************** + std::ostream& operator << (std::ostream& os, const IString& str) + { + for (auto c : str) + { + os << c; + } + + return os; + } + + SUITE(test_string_stream) + { + //************************************************************************* + TEST(test_default_format) + { + 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_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_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); + } + + //************************************************************************* + TEST(test_get_size) + { + String str; + Stream ss(str); + + ss.str(String(STR("Hello"))); + + CHECK_EQUAL(str.size(), ss.size()); + } + }; +} + diff --git a/test/test_wstring_stream.cpp b/test/test_wstring_stream.cpp new file mode 100644 index 00000000..09a72053 --- /dev/null +++ b/test/test_wstring_stream.cpp @@ -0,0 +1,220 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2020 jwellbelove + +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 "UnitTest++/UnitTest++.h" + +#include +#include +#include + +#include "etl/wstring_stream.h" +#include "etl/wstring.h" +#include "etl/format_spec.h" + +#undef STR +#define STR(x) L##x + +namespace +{ + using String = etl::wstring<50>; + using IString = etl::iwstring; + using Stream = etl::wstring_stream; + using Format = etl::wformat_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; + } + + //*********************************** + std::ostream& operator << (std::ostream& os, const IString& str) + { + for (auto c : str) + { + os << c; + } + + return os; + } + + SUITE(test_string_stream) + { + //************************************************************************* + TEST(test_default_format) + { + 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_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_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); + } + + //************************************************************************* + TEST(test_get_size) + { + String str; + Stream ss(str); + + ss.str(String(STR("Hello"))); + + CHECK_EQUAL(str.size(), ss.size()); + } + }; +} + diff --git a/test/vs2019/etl.vcxproj b/test/vs2019/etl.vcxproj index f980b3da..acd09ab1 100644 --- a/test/vs2019/etl.vcxproj +++ b/test/vs2019/etl.vcxproj @@ -1121,6 +1121,7 @@ + @@ -1131,7 +1132,9 @@ + + @@ -1228,6 +1231,7 @@ + @@ -1618,6 +1622,7 @@ + @@ -1634,6 +1639,8 @@ + + @@ -1648,6 +1655,7 @@ + diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters index c727bd0d..8e03bfcc 100644 --- a/test/vs2019/etl.vcxproj.filters +++ b/test/vs2019/etl.vcxproj.filters @@ -855,6 +855,18 @@ ETL\Utilities + + ETL\Strings + + + ETL\Strings + + + ETL\Strings + + + ETL\Strings + @@ -1331,6 +1343,18 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + From 3e2352770bffe3683cd7c894b95c70729c1e0976 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 5 Jul 2020 20:55:14 +0100 Subject: [PATCH 2/2] string streams --- include/etl/to_string.h | 12 +++++++++--- include/etl/to_u16string.h | 12 +++++++++--- include/etl/to_u32string.h | 12 +++++++++--- include/etl/to_wstring.h | 12 +++++++++--- include/etl/version.h | 4 ++-- library.json | 2 +- library.properties | 2 +- support/Release notes.txt | 14 ++++++++++++++ 8 files changed, 54 insertions(+), 16 deletions(-) diff --git a/include/etl/to_string.h b/include/etl/to_string.h index b1cb280f..c8fe60b0 100644 --- a/include/etl/to_string.h +++ b/include/etl/to_string.h @@ -43,6 +43,7 @@ namespace etl { //*************************************************************************** /// Default format spec. + /// !etl::istring && !etl::string_view //*************************************************************************** template typename etl::enable_if::value && !etl::is_same::value, const etl::istring&>::type @@ -54,7 +55,8 @@ namespace etl } //*************************************************************************** - /// Supplied format spec.. + /// Supplied format spec. + /// !etl::istring && !etl::string_view //*************************************************************************** template typename etl::enable_if::value && !etl::is_same::value, const etl::istring&>::type @@ -65,6 +67,7 @@ namespace etl //*************************************************************************** /// Default format spec. + /// etl::istring //*************************************************************************** template typename etl::enable_if::value, const etl::istring&>::type @@ -78,7 +81,8 @@ namespace etl } //*************************************************************************** - /// Supplied format spec.. + /// Supplied format spec. + /// etl::istring //*************************************************************************** template typename etl::enable_if::value, const etl::istring&>::type @@ -91,6 +95,7 @@ namespace etl //*************************************************************************** /// Default format spec. + /// etl::string_view //*************************************************************************** template typename etl::enable_if::value, const etl::istring&>::type @@ -104,7 +109,8 @@ namespace etl } //*************************************************************************** - /// Supplied format spec.. + /// Supplied format spec. + /// etl::string_view //*************************************************************************** template typename etl::enable_if::value, const etl::istring&>::type diff --git a/include/etl/to_u16string.h b/include/etl/to_u16string.h index 40473e1b..cfb6ffe8 100644 --- a/include/etl/to_u16string.h +++ b/include/etl/to_u16string.h @@ -43,6 +43,7 @@ namespace etl { //*************************************************************************** /// Default format spec. + /// !etl::iu16string && !etl::u16string_view //*************************************************************************** template typename etl::enable_if::value && !etl::is_same::value, const etl::iu16string&>::type @@ -54,7 +55,8 @@ namespace etl } //*************************************************************************** - /// Supplied format spec.. + /// Supplied format spec. + /// !etl::iu16string && !etl::u16string_view //*************************************************************************** template typename etl::enable_if::value && !etl::is_same::value, const etl::iu16string&>::type @@ -65,6 +67,7 @@ namespace etl //*************************************************************************** /// Default format spec. + /// etl::iu16string //*************************************************************************** template typename etl::enable_if::value, const etl::iu16string&>::type @@ -78,7 +81,8 @@ namespace etl } //*************************************************************************** - /// Supplied format spec.. + /// Supplied format spec. + /// etl::iu16string //*************************************************************************** template typename etl::enable_if::value, const etl::iu16string&>::type @@ -91,6 +95,7 @@ namespace etl //*************************************************************************** /// Default format spec. + /// etl::u16string_view //*************************************************************************** template typename etl::enable_if::value, const etl::iu16string&>::type @@ -104,7 +109,8 @@ namespace etl } //*************************************************************************** - /// Supplied format spec.. + /// Supplied format spec. + /// etl::u16string_view //*************************************************************************** template typename etl::enable_if::value, const etl::iu16string&>::type diff --git a/include/etl/to_u32string.h b/include/etl/to_u32string.h index 36a7d805..f07451cd 100644 --- a/include/etl/to_u32string.h +++ b/include/etl/to_u32string.h @@ -43,6 +43,7 @@ namespace etl { //*************************************************************************** /// Default format spec. + /// !etl::iu32string && !etl::u32string_view //*************************************************************************** template typename etl::enable_if::value && !etl::is_same::value, const etl::iu32string&>::type @@ -54,7 +55,8 @@ namespace etl } //*************************************************************************** - /// Supplied format spec.. + /// Supplied format spec. + /// !etl::iu32string && !etl::u32string_view //*************************************************************************** template typename etl::enable_if::value && !etl::is_same::value, const etl::iu32string&>::type @@ -65,6 +67,7 @@ namespace etl //*************************************************************************** /// Default format spec. + /// etl::iu32string //*************************************************************************** template typename etl::enable_if::value, const etl::iu32string&>::type @@ -78,7 +81,8 @@ namespace etl } //*************************************************************************** - /// Supplied format spec.. + /// Supplied format spec. + /// etl::iu32string //*************************************************************************** template typename etl::enable_if::value, const etl::iu32string&>::type @@ -91,6 +95,7 @@ namespace etl //*************************************************************************** /// Default format spec. + /// etl::u32string_view //*************************************************************************** template typename etl::enable_if::value, const etl::iu32string&>::type @@ -104,7 +109,8 @@ namespace etl } //*************************************************************************** - /// Supplied format spec.. + /// Supplied format spec. + /// etl::u32string_view //*************************************************************************** template typename etl::enable_if::value, const etl::iu32string&>::type diff --git a/include/etl/to_wstring.h b/include/etl/to_wstring.h index 4ce8e813..1612d02e 100644 --- a/include/etl/to_wstring.h +++ b/include/etl/to_wstring.h @@ -43,6 +43,7 @@ namespace etl { //*************************************************************************** /// Default format spec. + /// !etl::iwstring && !etl::wstring_view //*************************************************************************** template typename etl::enable_if::value && !etl::is_same::value, const etl::iwstring&>::type @@ -54,7 +55,8 @@ namespace etl } //*************************************************************************** - /// Supplied format spec.. + /// Supplied format spec. + /// !etl::iwstring && !etl::wstring_view //*************************************************************************** template typename etl::enable_if::value && !etl::is_same::value, const etl::iwstring&>::type @@ -65,6 +67,7 @@ namespace etl //*************************************************************************** /// Default format spec. + /// etl::iwstring //*************************************************************************** template typename etl::enable_if::value, const etl::iwstring&>::type @@ -78,7 +81,8 @@ namespace etl } //*************************************************************************** - /// Supplied format spec.. + /// Supplied format spec. + /// etl::iwstring //*************************************************************************** template typename etl::enable_if::value, const etl::iwstring&>::type @@ -91,6 +95,7 @@ namespace etl //*************************************************************************** /// Default format spec. + /// etl::wstring_view //*************************************************************************** template typename etl::enable_if::value, const etl::iwstring&>::type @@ -104,7 +109,8 @@ namespace etl } //*************************************************************************** - /// Supplied format spec.. + /// Supplied format spec. + /// etl::wstring_view //*************************************************************************** template typename etl::enable_if::value, const etl::iwstring&>::type diff --git a/include/etl/version.h b/include/etl/version.h index 3ff851c4..81379974 100644 --- a/include/etl/version.h +++ b/include/etl/version.h @@ -38,8 +38,8 @@ SOFTWARE. ///\ingroup utilities #define ETL_VERSION_MAJOR 18 -#define ETL_VERSION_MINOR 3 -#define ETL_VERSION_PATCH 4 +#define ETL_VERSION_MINOR 5 +#define ETL_VERSION_PATCH 0 #define ETL_VERSION ETL_STRINGIFY(ETL_VERSION_MAJOR) "." ETL_STRINGIFY(ETL_VERSION_MINOR) "." ETL_STRINGIFY(ETL_VERSION_PATCH) #define ETL_VERSION_W ETL_STRINGIFY(ETL_VERSION_MAJOR) L"." ETL_STRINGIFY(ETL_VERSION_MINOR) L"." ETL_STRINGIFY(ETL_VERSION_PATCH) #define ETL_VERSION_U16 ETL_STRINGIFY(ETL_VERSION_MAJOR) u"." ETL_STRINGIFY(ETL_VERSION_MINOR) u"." ETL_STRINGIFY(ETL_VERSION_PATCH) diff --git a/library.json b/library.json index 524a76a9..f1494e89 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library", - "version": "18.4.0", + "version": "18.5.0", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/library.properties b/library.properties index a3580b7c..1522a6f5 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Embedded Template Library -version=18.4.0 +version=18.5.0 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/support/Release notes.txt b/support/Release notes.txt index 7e7c253e..9ba7af3b 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,3 +1,17 @@ +=============================================================================== +18.5.0 +Added string streams +etl::string_stream +etl::wstring_stream +etl::u16string_stream +etl::u32string_stream + +Added string formatting to etl::to_string from +etl::string etl::string_view +etl::wstring etl::wstring_view +etl::u16string etl::u16string_view +etl::u32string etl::u32string_view + =============================================================================== 18.4.0 Refactored etl::error_handler to use etl::delegate style implementation.