diff options
author | thegeorg <thegeorg@yandex-team.ru> | 2022-02-10 16:45:12 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:12 +0300 |
commit | 49116032d905455a7b1c994e4a696afc885c1e71 (patch) | |
tree | be835aa92c6248212e705f25388ebafcf84bc7a1 /util/generic/string.h | |
parent | 4e839db24a3bbc9f1c610c43d6faaaa99824dcca (diff) | |
download | ydb-49116032d905455a7b1c994e4a696afc885c1e71.tar.gz |
Restoring authorship annotation for <thegeorg@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'util/generic/string.h')
-rw-r--r-- | util/generic/string.h | 464 |
1 files changed, 232 insertions, 232 deletions
diff --git a/util/generic/string.h b/util/generic/string.h index e7ff1c7f5f..8cd8aa6917 100644 --- a/util/generic/string.h +++ b/util/generic/string.h @@ -3,9 +3,9 @@ #include <cstddef> #include <cstring> #include <stlfwd> -#include <stdexcept> +#include <stdexcept> #include <string> -#include <string_view> +#include <string_view> #include <util/system/yassert.h> #include <util/system/atomic.h> @@ -15,7 +15,7 @@ #include "bitops.h" #include "explicit_type.h" #include "reserve.h" -#include "singleton.h" +#include "singleton.h" #include "strbase.h" #include "strbuf.h" #include "string_hash.h" @@ -82,12 +82,12 @@ struct TStdString: public TRefCountHolder, public B { #ifdef _LIBCPP_VERSION return (TStdString*)NULL_STRING_REPR; #else - return Singleton<TStdString>(); + return Singleton<TStdString>(); #endif } -private: - friend TStringPtrOps<TStdString>; +private: + friend TStringPtrOps<TStdString>; inline void Ref() noexcept { C.Inc(); } @@ -138,36 +138,36 @@ public: return this->operator=(static_cast<TChar>(other)); } - /* - * WARN: - * Though references are copyable types according to the standard, - * the behavior of this explicit default specification is different from the one - * implemented by the assignment operator above. - * - * An attempt to explicitly delete it will break valid invocations like - * auto c = flag ? s[i] : s[j]; - */ - TBasicCharRef(const TBasicCharRef&) = default; - + /* + * WARN: + * Though references are copyable types according to the standard, + * the behavior of this explicit default specification is different from the one + * implemented by the assignment operator above. + * + * An attempt to explicitly delete it will break valid invocations like + * auto c = flag ? s[i] : s[j]; + */ + TBasicCharRef(const TBasicCharRef&) = default; + private: TStringType& S_; size_t Pos_; }; #endif -template <typename TCharType, typename TTraits> -class TBasicString: public TStringBase<TBasicString<TCharType, TTraits>, TCharType, TTraits> { +template <typename TCharType, typename TTraits> +class TBasicString: public TStringBase<TBasicString<TCharType, TTraits>, TCharType, TTraits> { public: // TODO: Move to private section - using TBase = TStringBase<TBasicString, TCharType, TTraits>; + using TBase = TStringBase<TBasicString, TCharType, TTraits>; using TStringType = std::basic_string<TCharType, TTraits>; #ifdef TSTRING_IS_STD_STRING using TStorage = TStringType; - using reference = typename TStorage::reference; + using reference = typename TStorage::reference; #else using TStdStr = TStdString<TStringType>; using TStorage = TIntrusivePtr<TStdStr, TStringPtrOps<TStdStr>>; - using reference = TBasicCharRef<TBasicString>; + using reference = TBasicCharRef<TBasicString>; #endif using char_type = TCharType; // TODO: DROP using value_type = TCharType; @@ -175,9 +175,9 @@ public: using iterator = TCharType*; using reverse_iterator = typename TBase::template TReverseIteratorBase<iterator>; - using typename TBase::const_iterator; + using typename TBase::const_iterator; using typename TBase::const_reference; - using typename TBase::const_reverse_iterator; + using typename TBase::const_reverse_iterator; struct TUninitialized { explicit TUninitialized(size_t size) @@ -227,7 +227,7 @@ protected: } size_t RefCount() const noexcept { - return S_.RefCount(); + return S_.RefCount(); } #endif @@ -250,47 +250,47 @@ public: #endif } - inline const_reference operator[](size_t pos) const noexcept { + inline const_reference operator[](size_t pos) const noexcept { Y_ASSERT(pos <= length()); return this->data()[pos]; } - inline reference operator[](size_t pos) noexcept { + inline reference operator[](size_t pos) noexcept { Y_ASSERT(pos <= length()); #ifdef TSTRING_IS_STD_STRING return Storage_[pos]; #else - return reference(*this, pos); + return reference(*this, pos); #endif } using TBase::back; - inline reference back() noexcept { + inline reference back() noexcept { Y_ASSERT(!this->empty()); #ifdef TSTRING_IS_STD_STRING return Storage_.back(); #else if (Y_UNLIKELY(this->empty())) { - return reference(*this, 0); + return reference(*this, 0); } - return reference(*this, length() - 1); + return reference(*this, length() - 1); #endif } using TBase::front; - inline reference front() noexcept { + inline reference front() noexcept { Y_ASSERT(!this->empty()); #ifdef TSTRING_IS_STD_STRING return Storage_.front(); #else - return reference(*this, 0); + return reference(*this, 0); #endif } @@ -332,7 +332,7 @@ public: using TBase::rbegin; //!< const_reverse_iterator TStringBase::rbegin() const using TBase::rend; //!< const_reverse_iterator TStringBase::rend() const - inline size_t capacity() const noexcept { + inline size_t capacity() const noexcept { #ifdef TSTRING_IS_STD_STRING return Storage_.capacity(); #else @@ -365,7 +365,7 @@ public: } // ~~~ Size and capacity ~~~ - TBasicString& resize(size_t n, TCharType c = ' ') { // remove or append + TBasicString& resize(size_t n, TCharType c = ' ') { // remove or append MutRef().resize(n, c); return *this; @@ -383,11 +383,11 @@ public: #ifndef TSTRING_IS_STD_STRING : S_(Construct()) #endif - { - reserve(rt.Capacity); - } - - inline TBasicString(const TBasicString& s) + { + reserve(rt.Capacity); + } + + inline TBasicString(const TBasicString& s) #ifdef TSTRING_IS_STD_STRING : Storage_(s.Storage_) #else @@ -396,19 +396,19 @@ public: { } - inline TBasicString(TBasicString&& s) noexcept + inline TBasicString(TBasicString&& s) noexcept #ifdef TSTRING_IS_STD_STRING : Storage_(std::move(s.Storage_)) #else : S_(Construct()) #endif - { + { #ifdef TSTRING_IS_STD_STRING #else s.swap(*this); #endif - } - + } + template <typename T, typename A> explicit inline TBasicString(const std::basic_string<TCharType, T, A>& s) : TBasicString(s.data(), s.size()) @@ -438,8 +438,8 @@ public: : TBasicString(pc, TBase::StrLen(pc)) { } - // TODO thegeorg@: uncomment and fix clients - // TBasicString(std::nullptr_t) = delete; + // TODO thegeorg@: uncomment and fix clients + // TBasicString(std::nullptr_t) = delete; TBasicString(const TCharType* pc, size_t n) #ifdef TSTRING_IS_STD_STRING @@ -449,17 +449,17 @@ public: #endif { } - TBasicString(std::nullptr_t, size_t) = delete; + TBasicString(std::nullptr_t, size_t) = delete; TBasicString(const TCharType* pc, size_t pos, size_t n) : TBasicString(pc + pos, n) { } -#ifdef TSTRING_IS_STD_STRING +#ifdef TSTRING_IS_STD_STRING explicit TBasicString(TExplicitType<TCharType> c) { Storage_.push_back(c); - } + } #else explicit TBasicString(TExplicitType<TCharType> c) : TBasicString(&c.Value(), 1) @@ -509,25 +509,25 @@ public: { } - /** + /** * WARN: * Certain invocations of this method will result in link-time error. - * You are free to implement corresponding methods in string.cpp if you need them. - */ + * You are free to implement corresponding methods in string.cpp if you need them. + */ static TBasicString FromAscii(const ::TStringBuf& s) { - return TBasicString().AppendAscii(s); - } - + return TBasicString().AppendAscii(s); + } + static TBasicString FromUtf8(const ::TStringBuf& s) { - return TBasicString().AppendUtf8(s); - } - + return TBasicString().AppendUtf8(s); + } + static TBasicString FromUtf16(const ::TWtringBuf& s) { - return TBasicString().AppendUtf16(s); - } - - static TBasicString Uninitialized(size_t n) { - return TBasicString(TUninitialized(n)); + return TBasicString().AppendUtf16(s); + } + + static TBasicString Uninitialized(size_t n) { + return TBasicString(TUninitialized(n)); } private: @@ -547,7 +547,7 @@ private: template <typename... R> static void CopyAll(TCharType* p, const TBasicStringBuf<TCharType, TTraits> s, const R&... r) { - TTraits::copy(p, s.data(), s.size()); + TTraits::copy(p, s.data(), s.size()); CopyAll(p + s.size(), r...); } @@ -576,7 +576,7 @@ public: } template <typename... R> - static inline TBasicString Join(const R&... r) { + static inline TBasicString Join(const R&... r) { TBasicString s{TUninitialized{SumLength(r...)}}; TBasicString::CopyAll((TCharType*)s.data(), r...); @@ -585,31 +585,31 @@ public: } // ~~~ Assignment ~~~ : FAMILY0(TBasicString&, assign); - TBasicString& assign(size_t size, TCharType ch) { - ReserveAndResize(size); - std::fill(begin(), vend(), ch); - return *this; - } - - TBasicString& assign(const TBasicString& s) { - TBasicString(s).swap(*this); + TBasicString& assign(size_t size, TCharType ch) { + ReserveAndResize(size); + std::fill(begin(), vend(), ch); + return *this; + } + + TBasicString& assign(const TBasicString& s) { + TBasicString(s).swap(*this); - return *this; + return *this; } - TBasicString& assign(const TBasicString& s, size_t pos, size_t n) { - return assign(TBasicString(s, pos, n)); + TBasicString& assign(const TBasicString& s, size_t pos, size_t n) { + return assign(TBasicString(s, pos, n)); } - TBasicString& assign(const TCharType* pc) { + TBasicString& assign(const TCharType* pc) { return assign(pc, TBase::StrLen(pc)); } - TBasicString& assign(TCharType ch) { + TBasicString& assign(TCharType ch) { return assign(&ch, 1); } - TBasicString& assign(const TCharType* pc, size_t len) { + TBasicString& assign(const TCharType* pc, size_t len) { #if defined(address_sanitizer_enabled) || defined(thread_sanitizer_enabled) pc = (const TCharType*)HidePointerOrigin((void*)pc); #endif @@ -619,14 +619,14 @@ public: TBasicString(pc, len).swap(*this); } - return *this; + return *this; } - TBasicString& assign(const TCharType* first, const TCharType* last) { + TBasicString& assign(const TCharType* first, const TCharType* last) { return assign(first, last - first); } - TBasicString& assign(const TCharType* pc, size_t pos, size_t n) { + TBasicString& assign(const TCharType* pc, size_t pos, size_t n) { return assign(pc + pos, n); } @@ -654,35 +654,35 @@ public: return AssignNoAlias(s.SubString(spos, sn)); } - /** + /** * WARN: * Certain invocations of this method will result in link-time error. - * You are free to implement corresponding methods in string.cpp if you need them. - */ + * You are free to implement corresponding methods in string.cpp if you need them. + */ auto AssignAscii(const ::TStringBuf& s) { - clear(); - return AppendAscii(s); - } - + clear(); + return AppendAscii(s); + } + auto AssignUtf8(const ::TStringBuf& s) { - clear(); - return AppendUtf8(s); - } - + clear(); + return AppendUtf8(s); + } + auto AssignUtf16(const ::TWtringBuf& s) { - clear(); - return AppendUtf16(s); - } - - TBasicString& operator=(const TBasicString& s) { + clear(); + return AppendUtf16(s); + } + + TBasicString& operator=(const TBasicString& s) { return assign(s); } - TBasicString& operator=(TBasicString&& s) noexcept { - swap(s); - return *this; - } - + TBasicString& operator=(TBasicString&& s) noexcept { + swap(s); + return *this; + } + template <typename T, typename A> TBasicString& operator=(std::basic_string<TCharType, T, A>&& s) noexcept { TBasicString(std::move(s)).swap(*this); @@ -694,16 +694,16 @@ public: return assign(s); } - TBasicString& operator=(std::initializer_list<TCharType> il) { - return assign(il.begin(), il.end()); - } - - TBasicString& operator=(const TCharType* s) { + TBasicString& operator=(std::initializer_list<TCharType> il) { + return assign(il.begin(), il.end()); + } + + TBasicString& operator=(const TCharType* s) { return assign(s); } - TBasicString& operator=(std::nullptr_t) = delete; + TBasicString& operator=(std::nullptr_t) = delete; - TBasicString& operator=(TExplicitType<TCharType> ch) { + TBasicString& operator=(TExplicitType<TCharType> ch) { return assign(ch); } @@ -712,19 +712,19 @@ public: } // ~~~ Appending ~~~ : FAMILY0(TBasicString&, append); - inline TBasicString& append(size_t count, TCharType ch) { + inline TBasicString& append(size_t count, TCharType ch) { MutRef().append(count, ch); - return *this; + return *this; } - inline TBasicString& append(const TBasicString& s) { + inline TBasicString& append(const TBasicString& s) { MutRef().append(s.ConstRef()); return *this; } - inline TBasicString& append(const TBasicString& s, size_t pos, size_t n) { + inline TBasicString& append(const TBasicString& s, size_t pos, size_t n) { MutRef().append(s.ConstRef(), pos, n); return *this; @@ -736,19 +736,19 @@ public: return *this; } - inline TBasicString& append(TCharType c) { + inline TBasicString& append(TCharType c) { MutRef().push_back(c); - return *this; + return *this; } - inline TBasicString& append(const TCharType* first, const TCharType* last) { + inline TBasicString& append(const TCharType* first, const TCharType* last) { MutRef().append(first, last); return *this; } - inline TBasicString& append(const TCharType* pc, size_t len) { + inline TBasicString& append(const TCharType* pc, size_t len) { MutRef().append(pc, len); return *this; @@ -766,7 +766,7 @@ public: memcpy(&*(begin() + s), pc, len * sizeof(*pc)); } - return *this; + return *this; } TBasicString& AppendNoAlias(const TBasicStringBuf<TCharType, TTraits> s) { @@ -789,30 +789,30 @@ public: return append(pc + pos, Min(n, pc_len - pos)); } - /** + /** * WARN: * Certain invocations of this method will result in link-time error. - * You are free to implement corresponding methods in string.cpp if you need them. - */ + * You are free to implement corresponding methods in string.cpp if you need them. + */ TBasicString& AppendAscii(const ::TStringBuf& s); - + TBasicString& AppendUtf8(const ::TStringBuf& s); - + TBasicString& AppendUtf16(const ::TWtringBuf& s); - + inline void push_back(TCharType c) { // TODO append(c); } template <class T> - TBasicString& operator+=(const T& s) { + TBasicString& operator+=(const T& s) { return append(s); } template <class T> - friend TBasicString operator*(const TBasicString& s, T count) { - TBasicString result; + friend TBasicString operator*(const TBasicString& s, T count) { + TBasicString result; for (T i = 0; i < count; ++i) { result += s; @@ -822,16 +822,16 @@ public: } template <class T> - TBasicString& operator*=(T count) { - TBasicString temp; + TBasicString& operator*=(T count) { + TBasicString temp; for (T i = 0; i < count; ++i) { - temp += *this; + temp += *this; } swap(temp); - return *this; + return *this; } operator const TStringType&() const noexcept { @@ -863,17 +863,17 @@ public: * malloc + memcpy + memcpy. */ - friend TBasicString operator+(TBasicString&& s1, const TBasicString& s2) Y_WARN_UNUSED_RESULT { + friend TBasicString operator+(TBasicString&& s1, const TBasicString& s2) Y_WARN_UNUSED_RESULT { s1 += s2; return std::move(s1); } - friend TBasicString operator+(const TBasicString& s1, TBasicString&& s2) Y_WARN_UNUSED_RESULT { + friend TBasicString operator+(const TBasicString& s1, TBasicString&& s2) Y_WARN_UNUSED_RESULT { s2.prepend(s1); return std::move(s2); } - friend TBasicString operator+(TBasicString&& s1, TBasicString&& s2) Y_WARN_UNUSED_RESULT { + friend TBasicString operator+(TBasicString&& s1, TBasicString&& s2) Y_WARN_UNUSED_RESULT { #if 0 && !defined(TSTRING_IS_STD_STRING) if (!s1.IsDetached() && s2.IsDetached()) { s2.prepend(s1); @@ -889,21 +889,21 @@ public: return std::move(s1); } - friend TBasicString operator+(TBasicString&& s1, const TCharType* s2) Y_WARN_UNUSED_RESULT { + friend TBasicString operator+(TBasicString&& s1, const TCharType* s2) Y_WARN_UNUSED_RESULT { s1 += s2; return std::move(s1); } - friend TBasicString operator+(TBasicString&& s1, TCharType s2) Y_WARN_UNUSED_RESULT { + friend TBasicString operator+(TBasicString&& s1, TCharType s2) Y_WARN_UNUSED_RESULT { s1 += s2; return std::move(s1); } friend TBasicString operator+(TExplicitType<TCharType> ch, const TBasicString& s) Y_WARN_UNUSED_RESULT { - return Join(TCharType(ch), s); - } - - friend TBasicString operator+(const TBasicString& s1, const TBasicString& s2) Y_WARN_UNUSED_RESULT { + return Join(TCharType(ch), s); + } + + friend TBasicString operator+(const TBasicString& s1, const TBasicString& s2) Y_WARN_UNUSED_RESULT { return Join(s1, s2); } @@ -911,15 +911,15 @@ public: return Join(s1, s2); } - friend TBasicString operator+(const TBasicString& s1, const TCharType* s2) Y_WARN_UNUSED_RESULT { + friend TBasicString operator+(const TBasicString& s1, const TCharType* s2) Y_WARN_UNUSED_RESULT { return Join(s1, s2); } - friend TBasicString operator+(const TBasicString& s1, TCharType s2) Y_WARN_UNUSED_RESULT { + friend TBasicString operator+(const TBasicString& s1, TCharType s2) Y_WARN_UNUSED_RESULT { return Join(s1, TBasicStringBuf<TCharType, TTraits>(&s2, 1)); } - friend TBasicString operator+(const TCharType* s1, TBasicString&& s2) Y_WARN_UNUSED_RESULT { + friend TBasicString operator+(const TCharType* s1, TBasicString&& s2) Y_WARN_UNUSED_RESULT { s2.prepend(s1); return std::move(s2); } @@ -933,7 +933,7 @@ public: return Join(s1, s2); } - friend TBasicString operator+(const TCharType* s1, const TBasicString& s2) Y_WARN_UNUSED_RESULT { + friend TBasicString operator+(const TCharType* s1, const TBasicString& s2) Y_WARN_UNUSED_RESULT { return Join(s1, s2); } @@ -945,32 +945,32 @@ public: return l.ConstRef() + r; } - // ~~~ Prepending ~~~ : FAMILY0(TBasicString&, prepend); - TBasicString& prepend(const TBasicString& s) { + // ~~~ Prepending ~~~ : FAMILY0(TBasicString&, prepend); + TBasicString& prepend(const TBasicString& s) { MutRef().insert(0, s.ConstRef()); return *this; } - TBasicString& prepend(const TBasicString& s, size_t pos, size_t n) { + TBasicString& prepend(const TBasicString& s, size_t pos, size_t n) { MutRef().insert(0, s.ConstRef(), pos, n); return *this; } - TBasicString& prepend(const TCharType* pc) { + TBasicString& prepend(const TCharType* pc) { MutRef().insert(0, pc); return *this; } - TBasicString& prepend(size_t n, TCharType c) { + TBasicString& prepend(size_t n, TCharType c) { MutRef().insert(size_t(0), n, c); return *this; } - TBasicString& prepend(TCharType c) { + TBasicString& prepend(TCharType c) { MutRef().insert(size_t(0), 1, c); return *this; @@ -980,32 +980,32 @@ public: return insert(0, s, spos, sn); } - // ~~~ Insertion ~~~ : FAMILY1(TBasicString&, insert, size_t pos); - TBasicString& insert(size_t pos, const TBasicString& s) { + // ~~~ Insertion ~~~ : FAMILY1(TBasicString&, insert, size_t pos); + TBasicString& insert(size_t pos, const TBasicString& s) { MutRef().insert(pos, s.ConstRef()); return *this; } - TBasicString& insert(size_t pos, const TBasicString& s, size_t pos1, size_t n1) { + TBasicString& insert(size_t pos, const TBasicString& s, size_t pos1, size_t n1) { MutRef().insert(pos, s.ConstRef(), pos1, n1); return *this; } - TBasicString& insert(size_t pos, const TCharType* pc) { + TBasicString& insert(size_t pos, const TCharType* pc) { MutRef().insert(pos, pc); return *this; } - TBasicString& insert(size_t pos, const TCharType* pc, size_t len) { + TBasicString& insert(size_t pos, const TCharType* pc, size_t len) { MutRef().insert(pos, pc, len); return *this; } - TBasicString& insert(const_iterator pos, const_iterator b, const_iterator e) { + TBasicString& insert(const_iterator pos, const_iterator b, const_iterator e) { #ifdef TSTRING_IS_STD_STRING Storage_.insert(Storage_.begin() + this->off(pos), b, e); @@ -1015,17 +1015,17 @@ public: #endif } - TBasicString& insert(size_t pos, size_t n, TCharType c) { + TBasicString& insert(size_t pos, size_t n, TCharType c) { MutRef().insert(pos, n, c); return *this; } - TBasicString& insert(const_iterator pos, size_t len, TCharType ch) { + TBasicString& insert(const_iterator pos, size_t len, TCharType ch) { return this->insert(this->off(pos), len, ch); } - TBasicString& insert(const_iterator pos, TCharType ch) { + TBasicString& insert(const_iterator pos, TCharType ch) { return this->insert(pos, 1, ch); } @@ -1045,11 +1045,11 @@ public: } TBasicString& remove(size_t pos = 0) Y_NOEXCEPT { - if (pos < length()) { + if (pos < length()) { MutRef().erase(pos); } - return *this; + return *this; } TBasicString& erase(size_t pos = 0, size_t n = TBase::npos) Y_NOEXCEPT { @@ -1074,7 +1074,7 @@ public: return *this; } - // ~~~ replacement ~~~ : FAMILY2(TBasicString&, replace, size_t pos, size_t n); + // ~~~ replacement ~~~ : FAMILY2(TBasicString&, replace, size_t pos, size_t n); TBasicString& replace(size_t pos, size_t n, const TBasicString& s) Y_NOEXCEPT { MutRef().replace(pos, n, s.ConstRef()); @@ -1114,10 +1114,10 @@ public: TBasicString& replace(size_t pos, size_t n, const TBasicStringBuf<TCharType, TTraits> s, size_t spos = 0, size_t sn = TBase::npos) Y_NOEXCEPT { MutRef().replace(pos, n, s, spos, sn); - return *this; + return *this; } - void swap(TBasicString& s) noexcept { + void swap(TBasicString& s) noexcept { #ifdef TSTRING_IS_STD_STRING std::swap(Storage_, s.Storage_); #else @@ -1129,43 +1129,43 @@ public: * @returns String suitable for debug printing (like Python's `repr()`). * Format of the string is unspecified and may be changed over time. */ - TBasicString Quote() const { - extern TBasicString EscapeC(const TBasicString&); - - return TBasicString() + '"' + EscapeC(*this) + '"'; - } - - /** - * Modifies the case of the string, depending on the operation. - * @return false if no changes have been made. - * - * @warning when the value_type is char, these methods will not work with non-ASCII letters. - */ - bool to_lower(size_t pos = 0, size_t n = TBase::npos); - bool to_upper(size_t pos = 0, size_t n = TBase::npos); - bool to_title(size_t pos = 0, size_t n = TBase::npos); - -public: - /** - * Modifies the substring of length `n` starting from `pos`, applying `f` to each position and symbol. - * - * @return false if no changes have been made. - */ - template <typename T> - bool Transform(T&& f, size_t pos = 0, size_t n = TBase::npos) { - size_t len = length(); - - if (pos > len) { - pos = len; - } - - if (n > len - pos) { - n = len - pos; - } - - bool changed = false; - - for (size_t i = pos; i != pos + n; ++i) { + TBasicString Quote() const { + extern TBasicString EscapeC(const TBasicString&); + + return TBasicString() + '"' + EscapeC(*this) + '"'; + } + + /** + * Modifies the case of the string, depending on the operation. + * @return false if no changes have been made. + * + * @warning when the value_type is char, these methods will not work with non-ASCII letters. + */ + bool to_lower(size_t pos = 0, size_t n = TBase::npos); + bool to_upper(size_t pos = 0, size_t n = TBase::npos); + bool to_title(size_t pos = 0, size_t n = TBase::npos); + +public: + /** + * Modifies the substring of length `n` starting from `pos`, applying `f` to each position and symbol. + * + * @return false if no changes have been made. + */ + template <typename T> + bool Transform(T&& f, size_t pos = 0, size_t n = TBase::npos) { + size_t len = length(); + + if (pos > len) { + pos = len; + } + + if (n > len - pos) { + n = len - pos; + } + + bool changed = false; + + for (size_t i = pos; i != pos + n; ++i) { #ifdef TSTRING_IS_STD_STRING auto c = f(i, Storage_[i]); @@ -1177,44 +1177,44 @@ public: #else auto c = f(i, data()[i]); if (c != data()[i]) { - if (!changed) { - Detach(); - changed = true; - } - + if (!changed) { + Detach(); + changed = true; + } + begin()[i] = c; - } + } #endif - } - - return changed; - } + } + + return changed; + } }; -std::ostream& operator<<(std::ostream&, const TString&); -std::istream& operator>>(std::istream&, TString&); +std::ostream& operator<<(std::ostream&, const TString&); +std::istream& operator>>(std::istream&, TString&); template <typename TCharType, typename TTraits> -TBasicString<TCharType> to_lower(const TBasicString<TCharType, TTraits>& s) { - TBasicString<TCharType> ret(s); - ret.to_lower(); - return ret; -} - +TBasicString<TCharType> to_lower(const TBasicString<TCharType, TTraits>& s) { + TBasicString<TCharType> ret(s); + ret.to_lower(); + return ret; +} + template <typename TCharType, typename TTraits> -TBasicString<TCharType> to_upper(const TBasicString<TCharType, TTraits>& s) { - TBasicString<TCharType> ret(s); - ret.to_upper(); - return ret; -} - +TBasicString<TCharType> to_upper(const TBasicString<TCharType, TTraits>& s) { + TBasicString<TCharType> ret(s); + ret.to_upper(); + return ret; +} + template <typename TCharType, typename TTraits> -TBasicString<TCharType> to_title(const TBasicString<TCharType, TTraits>& s) { - TBasicString<TCharType> ret(s); - ret.to_title(); - return ret; -} - +TBasicString<TCharType> to_title(const TBasicString<TCharType, TTraits>& s) { + TBasicString<TCharType> ret(s); + ret.to_title(); + return ret; +} + namespace std { template <> struct hash<TString> { |