From 34e628c9fe87464e3948983482ad1c087b29233a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 25 May 2022 22:01:58 +0200 Subject: [PATCH] [wip] Containers: implement also StringView and char concatenation. Because why do the extra work with getting a size of the view if we don't need to. TODO: ambiguous with `ArrayView + int`, how to fix? --- src/Corrade/Containers/StringView.cpp | 30 ++++++++++++++++++++++ src/Corrade/Containers/StringView.h | 14 ++++++++++ src/Corrade/Containers/Test/StringTest.cpp | 17 ++++++++++++ 3 files changed, 61 insertions(+) diff --git a/src/Corrade/Containers/StringView.cpp b/src/Corrade/Containers/StringView.cpp index 43994f8a2..efe1613d8 100644 --- a/src/Corrade/Containers/StringView.cpp +++ b/src/Corrade/Containers/StringView.cpp @@ -618,6 +618,36 @@ String operator+(const StringView a, const StringView b) { return result; } +String operator+(const char a, const StringView b) { + /* Not using the size() accessor to speed up debug builds */ + const std::size_t bSize = b._sizePlusFlags & ~Implementation::StringViewSizeMask; + + String result{Corrade::NoInit, 1 + bSize}; + + /* Apparently memcpy() can't be called with null pointers, even if size is + zero. I call that bullying. */ + char* out = result.data(); + out[0] = a; + if(bSize) std::memcpy(out + 1, b._data, bSize); + + return result; +} + +String operator+(const StringView a, const char b) { + /* Not using the size() accessor to speed up debug builds */ + const std::size_t aSize = a._sizePlusFlags & ~Implementation::StringViewSizeMask; + + String result{Corrade::NoInit, aSize + 1}; + + /* Apparently memcpy() can't be called with null pointers, even if size is + zero. I call that bullying. */ + char* out = result.data(); + if(aSize) std::memcpy(out, a._data, aSize); + out[aSize] = b; + + return result; +} + Utility::Debug& operator<<(Utility::Debug& debug, const StringViewFlag value) { debug << "Containers::StringViewFlag" << Utility::Debug::nospace; diff --git a/src/Corrade/Containers/StringView.h b/src/Corrade/Containers/StringView.h index 46df9ad0d..4d6c4d876 100644 --- a/src/Corrade/Containers/StringView.h +++ b/src/Corrade/Containers/StringView.h @@ -1082,6 +1082,8 @@ template class CORRADE_UTILITY_EXPORT BasicStringView { friend CORRADE_UTILITY_EXPORT bool operator>=(StringView, StringView); friend CORRADE_UTILITY_EXPORT bool operator>(StringView, StringView); friend CORRADE_UTILITY_EXPORT String operator+(StringView, StringView); + friend CORRADE_UTILITY_EXPORT String operator+(char, StringView); + friend CORRADE_UTILITY_EXPORT String operator+(StringView, char); /* Used by the char* constructor, delinlined because it calls into std::strlen() */ @@ -1158,6 +1160,18 @@ needless temporary allocations. */ CORRADE_UTILITY_EXPORT String operator+(StringView a, StringView b); +/** + * @overload + * @m_since_latest + */ +CORRADE_UTILITY_EXPORT String operator+(char a, StringView b); + +/** + * @overload + * @m_since_latest + */ +CORRADE_UTILITY_EXPORT String operator+(StringView a, char b); + /* operator<<(Debug&, StringView) implemented directly in Debug */ namespace Literals { diff --git a/src/Corrade/Containers/Test/StringTest.cpp b/src/Corrade/Containers/Test/StringTest.cpp index a317e2334..d3c74b29f 100644 --- a/src/Corrade/Containers/Test/StringTest.cpp +++ b/src/Corrade/Containers/Test/StringTest.cpp @@ -161,6 +161,7 @@ struct StringTest: TestSuite::Tester { void add(); void addNullViews(); + void addArrayViews(); void join(); void joinNullViews(); @@ -292,6 +293,7 @@ StringTest::StringTest() { &StringTest::add, &StringTest::addNullViews, + &StringTest::addArrayViews, &StringTest::join, &StringTest::joinNullViews, @@ -1842,6 +1844,12 @@ void StringTest::add() { CORRADE_COMPARE("hello"_s + ""_s, "hello"); CORRADE_COMPARE(""_s + "hello"_s, "hello"); CORRADE_COMPARE("hello"_s + "world"_s, "helloworld"); + + /* Single char */ + CORRADE_COMPARE(""_s + '!', "!"); + CORRADE_COMPARE('?' + ""_s, "?"); + CORRADE_COMPARE("hello"_s + '!', "hello!"); + CORRADE_COMPARE('?' + "hello"_s, "?hello"); } void StringTest::addNullViews() { @@ -1851,6 +1859,15 @@ void StringTest::addNullViews() { CORRADE_COMPARE(StringView{} + StringView{}, ""); CORRADE_COMPARE("hello"_s + nullptr, "hello"); CORRADE_COMPARE(nullptr + "hello"_s, "hello"); + + /* Single char */ + CORRADE_COMPARE(StringView{} + '!', "!"); + CORRADE_COMPARE('!' + StringView{}, "!"); +} + +void StringTest::addArrayViews() { + // TODO ambiguous + Containers::ArrayView{} + 3; } void StringTest::join() {