diff options
author | Alexey Salmin <alexey.salmin@gmail.com> | 2022-02-10 16:49:37 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:49:37 +0300 |
commit | 71af077a5dfe7e9f932a508422c2dac81a57ebc0 (patch) | |
tree | 5d5cb817648f650d76cf1076100726fd9b8448e8 /util/string/join.h | |
parent | 3c5b1607b38f637d2f3313791ed25c2e080d2647 (diff) | |
download | ydb-71af077a5dfe7e9f932a508422c2dac81a57ebc0.tar.gz |
Restoring authorship annotation for Alexey Salmin <alexey.salmin@gmail.com>. Commit 2 of 2.
Diffstat (limited to 'util/string/join.h')
-rw-r--r-- | util/string/join.h | 158 |
1 files changed, 79 insertions, 79 deletions
diff --git a/util/string/join.h b/util/string/join.h index a49e6dfe50..b166fad1f3 100644 --- a/util/string/join.h +++ b/util/string/join.h @@ -5,31 +5,31 @@ #include <util/string/cast.h> #include "cast.h" -/* - * Default implementation of AppendToString uses a temporary TString object which is inefficient. You can overload it - * for your type to speed up string joins. If you already have an Out() or operator<<() implementation you can simply - * do the following: - * - * inline void AppendToString(TString& dst, const TMyType& t) { - * TStringOutput o(dst); - * o << t; - * } - * - * Unfortunately we can't do this by default because for some types ToString() is defined while Out() is not. - * For standard types (strings of all kinds and arithmetic types) we don't use a temporary TString in AppendToString(). - */ - +/* + * Default implementation of AppendToString uses a temporary TString object which is inefficient. You can overload it + * for your type to speed up string joins. If you already have an Out() or operator<<() implementation you can simply + * do the following: + * + * inline void AppendToString(TString& dst, const TMyType& t) { + * TStringOutput o(dst); + * o << t; + * } + * + * Unfortunately we can't do this by default because for some types ToString() is defined while Out() is not. + * For standard types (strings of all kinds and arithmetic types) we don't use a temporary TString in AppendToString(). + */ + template <typename TCharType, typename T> -inline std::enable_if_t<!std::is_arithmetic<std::remove_cv_t<T>>::value, void> +inline std::enable_if_t<!std::is_arithmetic<std::remove_cv_t<T>>::value, void> AppendToString(TBasicString<TCharType>& dst, const T& t) { dst.AppendNoAlias(ToString(t)); -} +} template <typename TCharType, typename T> -inline std::enable_if_t<std::is_arithmetic<std::remove_cv_t<T>>::value, void> +inline std::enable_if_t<std::is_arithmetic<std::remove_cv_t<T>>::value, void> AppendToString(TBasicString<TCharType>& dst, const T& t) { - char buf[512]; - dst.append(buf, ToString<std::remove_cv_t<T>>(t, buf, sizeof(buf))); + char buf[512]; + dst.append(buf, ToString<std::remove_cv_t<T>>(t, buf, sizeof(buf))); } template <typename TCharType> @@ -42,59 +42,59 @@ inline void AppendToString(TBasicString<TCharType>& dst, TBasicStringBuf<TCharTy dst.append(t); } -namespace NPrivate { - template <typename T> - inline size_t GetLength(const T&) { - // By default don't pre-allocate space when joining and appending non-string types. - // This code can be extended by estimating stringified length for specific types (e.g. 10 for ui32). - return 0; - } - - template <> - inline size_t GetLength(const TString& s) { - return s.length(); - } - - template <> - inline size_t GetLength(const TStringBuf& s) { - return s.length(); - } - - template <> - inline size_t GetLength(const char* const& s) { +namespace NPrivate { + template <typename T> + inline size_t GetLength(const T&) { + // By default don't pre-allocate space when joining and appending non-string types. + // This code can be extended by estimating stringified length for specific types (e.g. 10 for ui32). + return 0; + } + + template <> + inline size_t GetLength(const TString& s) { + return s.length(); + } + + template <> + inline size_t GetLength(const TStringBuf& s) { + return s.length(); + } + + template <> + inline size_t GetLength(const char* const& s) { return (s ? std::char_traits<char>::length(s) : 0); - } - - inline size_t GetAppendLength(const TStringBuf /*delim*/) { - return 0; - } - - template <typename TFirst, typename... TRest> - size_t GetAppendLength(const TStringBuf delim, const TFirst& f, const TRest&... r) { - return delim.length() + ::NPrivate::GetLength(f) + ::NPrivate::GetAppendLength(delim, r...); - } + } + + inline size_t GetAppendLength(const TStringBuf /*delim*/) { + return 0; + } + + template <typename TFirst, typename... TRest> + size_t GetAppendLength(const TStringBuf delim, const TFirst& f, const TRest&... r) { + return delim.length() + ::NPrivate::GetLength(f) + ::NPrivate::GetAppendLength(delim, r...); + } } template <typename TCharType> inline void AppendJoinNoReserve(TBasicString<TCharType>&, TBasicStringBuf<TCharType>) { -} - +} + template <typename TCharType, typename TFirst, typename... TRest> inline void AppendJoinNoReserve(TBasicString<TCharType>& dst, TBasicStringBuf<TCharType> delim, const TFirst& f, const TRest&... r) { AppendToString(dst, delim); AppendToString(dst, f); - AppendJoinNoReserve(dst, delim, r...); + AppendJoinNoReserve(dst, delim, r...); +} + +template <typename... TValues> +inline void AppendJoin(TString& dst, const TStringBuf delim, const TValues&... values) { + const size_t appendLength = ::NPrivate::GetAppendLength(delim, values...); + if (appendLength > 0) { + dst.reserve(dst.length() + appendLength); + } + AppendJoinNoReserve(dst, delim, values...); } -template <typename... TValues> -inline void AppendJoin(TString& dst, const TStringBuf delim, const TValues&... values) { - const size_t appendLength = ::NPrivate::GetAppendLength(delim, values...); - if (appendLength > 0) { - dst.reserve(dst.length() + appendLength); - } - AppendJoinNoReserve(dst, delim, values...); -} - template <typename TFirst, typename... TRest> inline TString Join(const TStringBuf delim, const TFirst& f, const TRest&... r) { TString ret = ToString(f); @@ -127,8 +127,8 @@ namespace NPrivate { for (TIter pos = beg; ++pos != end;) { AppendJoinNoReserve(out, delim, *pos); } - } - + } + return out; } @@ -241,25 +241,25 @@ constexpr auto MakeRangeJoiner(TStringBuf delim, const std::initializer_list<TVa return MakeRangeJoiner(delim, std::cbegin(data), std::cend(data)); } -/* We force (std::initializer_list<TStringBuf>) input type for (TString) and (const char*) types because: - * # When (std::initializer_list<TString>) is used, TString objects are copied into the initializer_list object. - * Storing TStringBufs instead is faster, even with COW-enabled strings. - * # For (const char*) we calculate length only once and store it in TStringBuf. Otherwise strlen scan would be executed - * in both GetAppendLength and AppendToString. For string literals constant lengths get propagated in compile-time. - * - * This way JoinSeq(",", { s1, s2 }) always does the right thing whatever types s1 and s2 have. - * - * If someone needs to join std::initializer_list<TString> -- it still works because of the TContainer template above. -*/ - +/* We force (std::initializer_list<TStringBuf>) input type for (TString) and (const char*) types because: + * # When (std::initializer_list<TString>) is used, TString objects are copied into the initializer_list object. + * Storing TStringBufs instead is faster, even with COW-enabled strings. + * # For (const char*) we calculate length only once and store it in TStringBuf. Otherwise strlen scan would be executed + * in both GetAppendLength and AppendToString. For string literals constant lengths get propagated in compile-time. + * + * This way JoinSeq(",", { s1, s2 }) always does the right thing whatever types s1 and s2 have. + * + * If someone needs to join std::initializer_list<TString> -- it still works because of the TContainer template above. +*/ + template <typename T> inline std::enable_if_t< !std::is_same<std::decay_t<T>, TString>::value && !std::is_same<std::decay_t<T>, const char*>::value, TString> -JoinSeq(const TStringBuf delim, const std::initializer_list<T>& data) { +JoinSeq(const TStringBuf delim, const std::initializer_list<T>& data) { + return JoinRange(delim, data.begin(), data.end()); +} + +inline TString JoinSeq(const TStringBuf delim, const std::initializer_list<TStringBuf>& data) { return JoinRange(delim, data.begin(), data.end()); } - -inline TString JoinSeq(const TStringBuf delim, const std::initializer_list<TStringBuf>& data) { - return JoinRange(delim, data.begin(), data.end()); -} |