diff options
author | danlark <danlark@yandex-team.ru> | 2022-02-10 16:46:10 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:10 +0300 |
commit | baa58daefa91fde4b4769facdbd2903763b9c6a8 (patch) | |
tree | 1a2c5ffcf89eb53ecd79dbc9bc0a195c27404d0c /util/string | |
parent | 3426a9bc7f169ae9da54cef557ad2a33f6e8eee0 (diff) | |
download | ydb-baa58daefa91fde4b4769facdbd2903763b9c6a8.tar.gz |
Restoring authorship annotation for <danlark@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'util/string')
-rw-r--r-- | util/string/ascii_ut.cpp | 6 | ||||
-rw-r--r-- | util/string/cast.h | 24 | ||||
-rw-r--r-- | util/string/cast_ut.cpp | 8 | ||||
-rw-r--r-- | util/string/escape.cpp | 16 | ||||
-rw-r--r-- | util/string/escape.h | 2 | ||||
-rw-r--r-- | util/string/escape_ut.cpp | 2 | ||||
-rw-r--r-- | util/string/hex.h | 4 | ||||
-rw-r--r-- | util/string/split.cpp | 2 | ||||
-rw-r--r-- | util/string/split.h | 1068 | ||||
-rw-r--r-- | util/string/split_ut.cpp | 1024 | ||||
-rw-r--r-- | util/string/strip.cpp | 2 | ||||
-rw-r--r-- | util/string/strip.h | 2 | ||||
-rw-r--r-- | util/string/subst.cpp | 2 | ||||
-rw-r--r-- | util/string/subst_ut.cpp | 14 | ||||
-rw-r--r-- | util/string/type.h | 2 | ||||
-rw-r--r-- | util/string/vector.cpp | 8 | ||||
-rw-r--r-- | util/string/vector.h | 10 |
17 files changed, 1098 insertions, 1098 deletions
diff --git a/util/string/ascii_ut.cpp b/util/string/ascii_ut.cpp index 5c35f3bda5..89069fee50 100644 --- a/util/string/ascii_ut.cpp +++ b/util/string/ascii_ut.cpp @@ -74,9 +74,9 @@ Y_UNIT_TEST_SUITE(TAsciiTest) { TString z = "qQnB"; TString zz = "qQqq"; TString zzz = "qQqqq"; - TStringBuf xs = TStringBuf(x.data(), 3); - TStringBuf ys = TStringBuf(y.data(), 3); - TStringBuf zs = TStringBuf(z.data(), 3); + TStringBuf xs = TStringBuf(x.data(), 3); + TStringBuf ys = TStringBuf(y.data(), 3); + TStringBuf zs = TStringBuf(z.data(), 3); UNIT_ASSERT(AsciiCompareIgnoreCase(xs, ys) == 0); UNIT_ASSERT(AsciiCompareIgnoreCase(xs, zs) > 0); UNIT_ASSERT(AsciiCompareIgnoreCase(xs, zz) < 0); diff --git a/util/string/cast.h b/util/string/cast.h index a27f5838bd..90e925c194 100644 --- a/util/string/cast.h +++ b/util/string/cast.h @@ -152,12 +152,12 @@ inline T FromString(const TChar* data) { template <class T> inline T FromString(const TStringBuf& s) { - return ::FromString<T>(s.data(), s.size()); + return ::FromString<T>(s.data(), s.size()); } template <class T> inline T FromString(const TString& s) { - return ::FromString<T>(s.data(), s.size()); + return ::FromString<T>(s.data(), s.size()); } template <class T> @@ -172,7 +172,7 @@ inline TString FromString<TString>(const TString& s) { template <class T> inline T FromString(const TWtringBuf& s) { - return ::FromString<T, typename TWtringBuf::char_type>(s.data(), s.size()); + return ::FromString<T, typename TWtringBuf::char_type>(s.data(), s.size()); } template <class T> @@ -212,7 +212,7 @@ inline ::NPrivate::TFromString<TChar> FromString(const TChar* data) { template <typename T> inline ::NPrivate::TFromString<typename T::TChar> FromString(const T& s) { - return ::NPrivate::TFromString<typename T::TChar>(s.data(), s.size()); + return ::NPrivate::TFromString<typename T::TChar>(s.data(), s.size()); } // Conversion exception free versions @@ -247,12 +247,12 @@ inline bool TryFromString(const TChar* data, const size_t len, T& result, const template <class T> inline bool TryFromString(const TStringBuf& s, T& result) { - return TryFromString<T>(s.data(), s.size(), result); + return TryFromString<T>(s.data(), s.size(), result); } template <class T> inline bool TryFromString(const TString& s, T& result) { - return TryFromString<T>(s.data(), s.size(), result); + return TryFromString<T>(s.data(), s.size(), result); } template <class T> @@ -262,17 +262,17 @@ inline bool TryFromString(const std::string& s, T& result) { template <class T> inline bool TryFromString(const TWtringBuf& s, T& result) { - return TryFromString<T>(s.data(), s.size(), result); + return TryFromString<T>(s.data(), s.size(), result); } template <class T> inline bool TryFromString(const TUtf16String& s, T& result) { - return TryFromString<T>(s.data(), s.size(), result); + return TryFromString<T>(s.data(), s.size(), result); } template <class T, class TStringType> inline bool TryFromStringWithDefault(const TStringType& s, T& result, const T& def) { - return TryFromString<T>(s.data(), s.size(), result, def); + return TryFromString<T>(s.data(), s.size(), result, def); } template <class T> @@ -295,7 +295,7 @@ inline T FromString(const TChar* data, const size_t len, const T& def) { template <class T, class TStringType> inline T FromStringWithDefault(const TStringType& s, const T& def) { - return FromString<T>(s.data(), s.size(), def); + return FromString<T>(s.data(), s.size(), def); } template <class T> @@ -328,7 +328,7 @@ bool TryIntFromString(const TChar* data, size_t len, TInt& result); template <int base, class TInt, class TStringType> inline bool TryIntFromString(const TStringType& s, TInt& result) { - return TryIntFromString<base>(s.data(), s.size(), result); + return TryIntFromString<base>(s.data(), s.size(), result); } template <class TInt, int base, class TChar> @@ -341,7 +341,7 @@ inline TInt IntFromString(const TChar* str) { template <class TInt, int base, class TStringType> inline TInt IntFromString(const TStringType& str) { - return IntFromString<TInt, base>(str.data(), str.size()); + return IntFromString<TInt, base>(str.data(), str.size()); } static inline TString ToString(const TStringBuf str) { diff --git a/util/string/cast_ut.cpp b/util/string/cast_ut.cpp index 0b2ca39dc7..033450c38c 100644 --- a/util/string/cast_ut.cpp +++ b/util/string/cast_ut.cpp @@ -324,7 +324,7 @@ Y_UNIT_TEST_SUITE(TCastTest) { TString a = "xyz"; TStringBuf b = FromString<TStringBuf>(a); UNIT_ASSERT_VALUES_EQUAL(a, b); - UNIT_ASSERT_VALUES_EQUAL((void*)a.data(), (void*)b.data()); + UNIT_ASSERT_VALUES_EQUAL((void*)a.data(), (void*)b.data()); } #if 0 @@ -360,14 +360,14 @@ Y_UNIT_TEST_SUITE(TCastTest) { UNIT_ASSERT_VALUES_EQUAL(TryFromString(uw, uv), true); UNIT_ASSERT_VALUES_EQUAL(uv, 21474836470ull); - TWtringBuf bw(uw.data(), uw.size()); + TWtringBuf bw(uw.data(), uw.size()); uv = 0; UNIT_ASSERT_VALUES_EQUAL(TryFromString(uw, uv), true); UNIT_ASSERT_VALUES_EQUAL(uv, 21474836470ull); - const wchar16* beg = uw.data(); + const wchar16* beg = uw.data(); uv = 0; - UNIT_ASSERT_VALUES_EQUAL(TryFromString(beg, uw.size(), uv), true); + UNIT_ASSERT_VALUES_EQUAL(TryFromString(beg, uw.size(), uv), true); UNIT_ASSERT_VALUES_EQUAL(uv, 21474836470ull); } diff --git a/util/string/escape.cpp b/util/string/escape.cpp index 2e8428308e..cd09a7dbd0 100644 --- a/util/string/escape.cpp +++ b/util/string/escape.cpp @@ -401,33 +401,33 @@ template size_t UnescapeCCharLen<char>(const char* begin, const char* end); template size_t UnescapeCCharLen<TUtf16String::TChar>(const TUtf16String::TChar* begin, const TUtf16String::TChar* end); TString& EscapeC(const TStringBuf str, TString& s) { - return EscapeC(str.data(), str.size(), s); + return EscapeC(str.data(), str.size(), s); } TUtf16String& EscapeC(const TWtringBuf str, TUtf16String& w) { - return EscapeC(str.data(), str.size(), w); + return EscapeC(str.data(), str.size(), w); } TString EscapeC(const TString& str) { - return EscapeC(str.data(), str.size()); + return EscapeC(str.data(), str.size()); } TUtf16String EscapeC(const TUtf16String& str) { - return EscapeC(str.data(), str.size()); + return EscapeC(str.data(), str.size()); } TString& UnescapeC(const TStringBuf str, TString& s) { - return UnescapeC(str.data(), str.size(), s); + return UnescapeC(str.data(), str.size(), s); } TUtf16String& UnescapeC(const TWtringBuf str, TUtf16String& w) { - return UnescapeC(str.data(), str.size(), w); + return UnescapeC(str.data(), str.size(), w); } TString UnescapeC(const TStringBuf str) { - return UnescapeC(str.data(), str.size()); + return UnescapeC(str.data(), str.size()); } TUtf16String UnescapeC(const TWtringBuf str) { - return UnescapeC(str.data(), str.size()); + return UnescapeC(str.data(), str.size()); } diff --git a/util/string/escape.h b/util/string/escape.h index b45a4494b6..b01be65b0e 100644 --- a/util/string/escape.h +++ b/util/string/escape.h @@ -25,7 +25,7 @@ static inline TBasicString<TChar> EscapeC(const TChar* str, size_t len) { template <typename TChar> static inline TBasicString<TChar> EscapeC(const TBasicStringBuf<TChar>& str) { - return EscapeC(str.data(), str.size()); + return EscapeC(str.data(), str.size()); } template <typename TChar> diff --git a/util/string/escape_ut.cpp b/util/string/escape_ut.cpp index 9d557621c5..cd38ecffd3 100644 --- a/util/string/escape_ut.cpp +++ b/util/string/escape_ut.cpp @@ -135,7 +135,7 @@ Y_UNIT_TEST_SUITE(TEscapeCTest) { char buf[100000]; for (const auto& x : CommonTestData) { - char* end = UnescapeC(x.Expected.data(), x.Expected.size(), buf); + char* end = UnescapeC(x.Expected.data(), x.Expected.size(), buf); UNIT_ASSERT_VALUES_EQUAL(x.Source, TStringBuf(buf, end)); } diff --git a/util/string/hex.h b/util/string/hex.h index 212d22dcc5..af3d2d528f 100644 --- a/util/string/hex.h +++ b/util/string/hex.h @@ -31,7 +31,7 @@ char* HexEncode(const void* in, size_t len, char* out); TString HexEncode(const void* in, size_t len); inline TString HexEncode(const TStringBuf h) { - return HexEncode(h.data(), h.size()); + return HexEncode(h.data(), h.size()); } //! Convert a hex string @c in of @c len chars (case-insensitive) to array of ints stored at @c ptr and return this array. @@ -55,5 +55,5 @@ TString HexDecode(const void* in, size_t len); //! Convert an ASCII hex-string (case-insensitive) to the binary form. Note that h.Size() must be even (+h % 2 == 0). inline TString HexDecode(const TStringBuf h) { - return HexDecode(h.data(), h.size()); + return HexDecode(h.data(), h.size()); } diff --git a/util/string/split.cpp b/util/string/split.cpp index 9b193e9459..7d26857cc7 100644 --- a/util/string/split.cpp +++ b/util/string/split.cpp @@ -20,5 +20,5 @@ size_t Split(const char* ptr, const char* delim, TVector<TString>& values) { } size_t Split(const TString& in, const TString& delim, TVector<TString>& res) { - return Split(in.data(), delim.data(), res); + return Split(in.data(), delim.data(), res); } diff --git a/util/string/split.h b/util/string/split.h index 5e03d89344..bc46d9e64c 100644 --- a/util/string/split.h +++ b/util/string/split.h @@ -3,24 +3,24 @@ #include "strspn.h" #include "cast.h" -#include <util/generic/algorithm.h> +#include <util/generic/algorithm.h> #include <util/generic/fwd.h> -#include <util/generic/iterator.h> -#include <util/generic/iterator_range.h> -#include <util/generic/store_policy.h> -#include <util/generic/strbuf.h> +#include <util/generic/iterator.h> +#include <util/generic/iterator_range.h> +#include <util/generic/store_policy.h> +#include <util/generic/strbuf.h> #include <util/generic/string.h> #include <util/generic/typetraits.h> -#include <util/generic/vector.h> +#include <util/generic/vector.h> #include <util/generic/ylimits.h> -#include <util/system/compat.h> -#include <util/system/defaults.h> +#include <util/system/compat.h> +#include <util/system/defaults.h> -#include <utility> -#include <stlfwd> +#include <utility> +#include <stlfwd> + +// NOTE: Check StringSplitter below to get more convenient split string interface. -// NOTE: Check StringSplitter below to get more convenient split string interface. - namespace NStringSplitPrivate { template <class T, class I, class = void> @@ -420,7 +420,7 @@ inline size_t Split(const TStringBuf s, const TSetDelimiter<const char>& delim, res.clear(); TContainerConsumer<TVector<TStringBuf>> res1(&res); TSkipEmptyTokens<TContainerConsumer<TVector<TStringBuf>>> consumer(&res1); - SplitString(s.data(), s.data() + s.size(), delim, consumer); + SplitString(s.data(), s.data() + s.size(), delim, consumer); return res.size(); } @@ -455,218 +455,218 @@ void Split(TStringBuf s, D delim, P1& p1, P2& p2, Other&... other) { GetNext(s, delim, p1); Split(s, delim, p2, other...); } - -/** - * \fn auto StringSplitter(...) - * - * Creates a string splitter object. The only use for it is to call one of its - * `Split*` methods, and then do something with the resulting proxy range. - * - * Some examples: - * \code - * TVector<TStringBuf> values = StringSplitter("1\t2\t3").Split('\t'); - * - * for(TStringBuf part: StringSplitter("1::2::::3").SplitByString("::").SkipEmpty()) { - * Cerr << part; - * } - * - * TVector<TString> firstTwoValues = StringSplitter("1\t2\t3").Split('\t').Take(2); - * \endcode - * - * Use `Collect` or `AddTo` to store split results into an existing container: - * \code - * TVector<TStringBuf> values = {"0"}; - * StringSplitter("1\t2\t3").Split('\t').AddTo(&values); - * \endcode - * Note that `Collect` clears target container, while `AddTo` just inserts values. - * You can use these methods with any container that has `emplace` / `emplace_back`. - * - * Use `ParseInto` to also perform string conversions before inserting values - * into target container: - * \code - * TSet<int> values; - * StringSplitter("1\t2\t3").Split('\t').ParseInto(&values); - * \endcode - */ - + +/** + * \fn auto StringSplitter(...) + * + * Creates a string splitter object. The only use for it is to call one of its + * `Split*` methods, and then do something with the resulting proxy range. + * + * Some examples: + * \code + * TVector<TStringBuf> values = StringSplitter("1\t2\t3").Split('\t'); + * + * for(TStringBuf part: StringSplitter("1::2::::3").SplitByString("::").SkipEmpty()) { + * Cerr << part; + * } + * + * TVector<TString> firstTwoValues = StringSplitter("1\t2\t3").Split('\t').Take(2); + * \endcode + * + * Use `Collect` or `AddTo` to store split results into an existing container: + * \code + * TVector<TStringBuf> values = {"0"}; + * StringSplitter("1\t2\t3").Split('\t').AddTo(&values); + * \endcode + * Note that `Collect` clears target container, while `AddTo` just inserts values. + * You can use these methods with any container that has `emplace` / `emplace_back`. + * + * Use `ParseInto` to also perform string conversions before inserting values + * into target container: + * \code + * TSet<int> values; + * StringSplitter("1\t2\t3").Split('\t').ParseInto(&values); + * \endcode + */ + namespace NStringSplitPrivate { - Y_HAS_MEMBER(push_back, PushBack); - Y_HAS_MEMBER(insert, Insert); - Y_HAS_MEMBER(data, Data); - - /** - * This one is needed here so that `std::string_view -> std::string_view` - * conversion works. - */ + Y_HAS_MEMBER(push_back, PushBack); + Y_HAS_MEMBER(insert, Insert); + Y_HAS_MEMBER(data, Data); + + /** + * This one is needed here so that `std::string_view -> std::string_view` + * conversion works. + */ template <class Src, class Dst> - inline void DoFromString(const Src& src, Dst* dst) { - *dst = ::FromString<Dst>(src); - } - + inline void DoFromString(const Src& src, Dst* dst) { + *dst = ::FromString<Dst>(src); + } + template <class T> - inline void DoFromString(const T& src, T* dst) noexcept { - *dst = src; - } - + inline void DoFromString(const T& src, T* dst) noexcept { + *dst = src; + } + template <class T> inline void DoFromString(const T& src, decltype(std::ignore)* dst) noexcept { *dst = src; } template <class Src, class Dst> - inline Y_WARN_UNUSED_RESULT bool TryDoFromString(const Src& src, Dst* dst) noexcept { - return ::TryFromString(src, *dst); - } - + inline Y_WARN_UNUSED_RESULT bool TryDoFromString(const Src& src, Dst* dst) noexcept { + return ::TryFromString(src, *dst); + } + template <class T> - inline Y_WARN_UNUSED_RESULT bool TryDoFromString(const T& src, T* dst) noexcept { - *dst = src; - return true; - } - + inline Y_WARN_UNUSED_RESULT bool TryDoFromString(const T& src, T* dst) noexcept { + *dst = src; + return true; + } + template <class T> inline Y_WARN_UNUSED_RESULT bool TryDoFromString(const T& src, decltype(std::ignore)* dst) noexcept { *dst = src; return true; } - /** - * Consumer that places provided elements into a container. Not using - * `emplace(iterator)` for efficiency. - */ - template <class Container> - struct TContainerConsumer { - using value_type = typename Container::value_type; - - TContainerConsumer(Container* c) - : C_(c) - { - } - - // TODO: return bool (continue) + /** + * Consumer that places provided elements into a container. Not using + * `emplace(iterator)` for efficiency. + */ + template <class Container> + struct TContainerConsumer { + using value_type = typename Container::value_type; + + TContainerConsumer(Container* c) + : C_(c) + { + } + + // TODO: return bool (continue) template <class StringBuf> - void operator()(StringBuf e) const { - this->operator()(C_, e); - } - - private: + void operator()(StringBuf e) const { + this->operator()(C_, e); + } + + private: template <class OtherContainer, class StringBuf> - auto operator()(OtherContainer* c, StringBuf e) const -> decltype(c->emplace_back()) { - return c->emplace_back(value_type(e)); - } - + auto operator()(OtherContainer* c, StringBuf e) const -> decltype(c->emplace_back()) { + return c->emplace_back(value_type(e)); + } + template <class OtherContainer, class StringBuf> - auto operator()(OtherContainer* c, StringBuf e) const -> decltype(c->emplace()) { - return c->emplace(value_type(e)); - } - - Container* C_; - }; - - /** - * Consumer that converts provided elements via `FromString` and places them - * into a container. - */ - template <class Container> - struct TContainerConvertingConsumer { - using value_type = typename Container::value_type; - - TContainerConvertingConsumer(Container* c) - : C_(c) - { - } - - template <class StringBuf> - void operator()(StringBuf e) const { - this->operator()(C_, e); - } - - private: + auto operator()(OtherContainer* c, StringBuf e) const -> decltype(c->emplace()) { + return c->emplace(value_type(e)); + } + + Container* C_; + }; + + /** + * Consumer that converts provided elements via `FromString` and places them + * into a container. + */ + template <class Container> + struct TContainerConvertingConsumer { + using value_type = typename Container::value_type; + + TContainerConvertingConsumer(Container* c) + : C_(c) + { + } + + template <class StringBuf> + void operator()(StringBuf e) const { + this->operator()(C_, e); + } + + private: template <class OtherContainer, class StringBuf> - auto operator()(OtherContainer* c, StringBuf e) const -> decltype(c->emplace_back()) { - value_type v; - DoFromString(e, &v); - return c->emplace_back(std::move(v)); - } - + auto operator()(OtherContainer* c, StringBuf e) const -> decltype(c->emplace_back()) { + value_type v; + DoFromString(e, &v); + return c->emplace_back(std::move(v)); + } + template <class OtherContainer, class StringBuf> - auto operator()(OtherContainer* c, StringBuf e) const -> decltype(c->emplace()) { - value_type v; - DoFromString(e, &v); - return c->emplace(std::move(v)); - } - - Container* C_; - }; - - template <class String> - struct TStringBufOfImpl { - using type = std::conditional_t< - THasData<String>::value, - TBasicStringBuf<typename String::value_type>, + auto operator()(OtherContainer* c, StringBuf e) const -> decltype(c->emplace()) { + value_type v; + DoFromString(e, &v); + return c->emplace(std::move(v)); + } + + Container* C_; + }; + + template <class String> + struct TStringBufOfImpl { + using type = std::conditional_t< + THasData<String>::value, + TBasicStringBuf<typename String::value_type>, TIteratorRange<typename String::const_iterator>>; - }; - - template <class Char, class Traits, class Allocator> - struct TStringBufOfImpl<std::basic_string<Char, Traits, Allocator>> { - using type = std::basic_string_view<Char, Traits>; - }; - - template <class Char, class Traits> - struct TStringBufOfImpl<std::basic_string_view<Char, Traits>> { - using type = std::basic_string_view<Char, Traits>; - }; - - /** - * Metafunction that returns a string buffer for the given type. This is to - * make sure that splitting `std::string` returns `std::string_view`. - */ + }; + + template <class Char, class Traits, class Allocator> + struct TStringBufOfImpl<std::basic_string<Char, Traits, Allocator>> { + using type = std::basic_string_view<Char, Traits>; + }; + + template <class Char, class Traits> + struct TStringBufOfImpl<std::basic_string_view<Char, Traits>> { + using type = std::basic_string_view<Char, Traits>; + }; + + /** + * Metafunction that returns a string buffer for the given type. This is to + * make sure that splitting `std::string` returns `std::string_view`. + */ template <class String> - using TStringBufOf = typename TStringBufOfImpl<String>::type; - + using TStringBufOf = typename TStringBufOfImpl<String>::type; + template <class StringBuf, class Iterator> - StringBuf DoMakeStringBuf(Iterator b, Iterator e, StringBuf*) { - return StringBuf(b, e); - } - + StringBuf DoMakeStringBuf(Iterator b, Iterator e, StringBuf*) { + return StringBuf(b, e); + } + template <class Char, class Traits, class Iterator> - std::basic_string_view<Char, Traits> DoMakeStringBuf(Iterator b, Iterator e, std::basic_string_view<Char, Traits>*) { - return std::basic_string_view<Char, Traits>(b, e - b); - } - + std::basic_string_view<Char, Traits> DoMakeStringBuf(Iterator b, Iterator e, std::basic_string_view<Char, Traits>*) { + return std::basic_string_view<Char, Traits>(b, e - b); + } + template <class StringBuf, class Iterator> - StringBuf MakeStringBuf(Iterator b, Iterator e) { - return DoMakeStringBuf(b, e, static_cast<StringBuf*>(nullptr)); - } - + StringBuf MakeStringBuf(Iterator b, Iterator e) { + return DoMakeStringBuf(b, e, static_cast<StringBuf*>(nullptr)); + } + template <class String> - struct TIteratorOfImpl { - using type = std::conditional_t< - THasData<String>::value, - const typename String::value_type*, + struct TIteratorOfImpl { + using type = std::conditional_t< + THasData<String>::value, + const typename String::value_type*, typename String::const_iterator>; - }; - + }; + template <class String> - using TIteratorOf = typename TIteratorOfImpl<String>::type; - + using TIteratorOf = typename TIteratorOfImpl<String>::type; + template <class String> class TStringSplitter; template <class String> struct TIterState: public TStringBufOf<String> { public: - using TStringBufType = TStringBufOf<String>; - using TIterator = TIteratorOf<String>; + using TStringBufType = TStringBufOf<String>; + using TIterator = TIteratorOf<String>; friend class TStringSplitter<String>; - - TIterState(const String& string) noexcept + + TIterState(const String& string) noexcept : TStringBufType() , DelimiterEnd_(std::begin(string)) , OriginEnd_(std::end(string)) - { - } - + { + } + template < typename Other, typename = std::enable_if_t< @@ -675,397 +675,397 @@ namespace NStringSplitPrivate { return TStringBufType(*this) == TStringBufType(toCompare); } - TIterator TokenStart() const noexcept { + TIterator TokenStart() const noexcept { return this->begin(); - } - - TIterator TokenDelim() const noexcept { + } + + TIterator TokenDelim() const noexcept { return this->end(); - } - - TStringBufType Token() const noexcept { + } + + TStringBufType Token() const noexcept { return *this; - } - - TStringBufType Delim() const noexcept { + } + + TStringBufType Delim() const noexcept { return MakeStringBuf<TStringBufType>(TokenDelim(), DelimiterEnd_); - } - - private: + } + + private: void UpdateParentBuf(TIterator tokenStart, TIterator tokenDelim) noexcept { *static_cast<TStringBufType*>(this) = MakeStringBuf<TStringBufType>(tokenStart, tokenDelim); - } - + } + bool DelimiterIsEmpty() const noexcept { return TokenDelim() == DelimiterEnd_; - } + } private: TIterator DelimiterEnd_; const TIterator OriginEnd_; - }; - - template <class Base> + }; + + template <class Base> class TSplitRange: public Base, public TInputRangeAdaptor<TSplitRange<Base>> { - using TStringBufType = decltype(std::declval<Base>().Next()->Token()); - - public: - template <typename... Args> - inline TSplitRange(Args&&... args) - : Base(std::forward<Args>(args)...) - { - } - - template <class Consumer, std::enable_if_t<std::is_same<decltype(std::declval<Consumer>()(std::declval<TStringBufType>())), void>::value, int>* = nullptr> - inline void Consume(Consumer&& f) { - for (auto&& it : *this) { - f(it.Token()); - } - } - - template <class Consumer, std::enable_if_t<std::is_same<decltype(std::declval<Consumer>()(std::declval<TStringBufType>())), bool>::value, int>* = nullptr> - inline bool Consume(Consumer&& f) { - for (auto&& it : *this) { - if (!f(it.Token())) { - return false; - } - } - return true; - } - + using TStringBufType = decltype(std::declval<Base>().Next()->Token()); + + public: + template <typename... Args> + inline TSplitRange(Args&&... args) + : Base(std::forward<Args>(args)...) + { + } + + template <class Consumer, std::enable_if_t<std::is_same<decltype(std::declval<Consumer>()(std::declval<TStringBufType>())), void>::value, int>* = nullptr> + inline void Consume(Consumer&& f) { + for (auto&& it : *this) { + f(it.Token()); + } + } + + template <class Consumer, std::enable_if_t<std::is_same<decltype(std::declval<Consumer>()(std::declval<TStringBufType>())), bool>::value, int>* = nullptr> + inline bool Consume(Consumer&& f) { + for (auto&& it : *this) { + if (!f(it.Token())) { + return false; + } + } + return true; + } + template <class Container, class = std::enable_if_t<THasInsert<Container>::value || THasPushBack<Container>::value>> - operator Container() { - Container result; - AddTo(&result); - return result; - } - - template <class S> - inline TVector<S> ToList() { - TVector<S> result; - for (auto&& it : *this) { - result.push_back(S(it.Token())); - } - return result; - } - - template <class Container> - inline void Collect(Container* c) { - Y_ASSERT(c); - c->clear(); - AddTo(c); - } - - template <class Container> - inline void AddTo(Container* c) { - Y_ASSERT(c); - TContainerConsumer<Container> consumer(c); - Consume(consumer); - } - - template <class Container> - inline void ParseInto(Container* c) { - Y_ASSERT(c); - TContainerConvertingConsumer<Container> consumer(c); - Consume(consumer); - } - - // TODO: this is actually TryParseInto - /** - * Same as `CollectInto`, just doesn't throw. - * - * \param[out] args Output arguments. - * \returns Whether parsing was successful. - */ - template <typename... Args> - inline bool TryCollectInto(Args*... args) noexcept { - size_t successfullyFilled = 0; - auto it = this->begin(); - - //FIXME: actually, some kind of TryApplyToMany is needed in order to stop iteration upon first failure - ApplyToMany([&](auto&& arg) { - if (it != this->end()) { - if (TryDoFromString(it->Token(), arg)) { - ++successfullyFilled; - } - ++it; - } + operator Container() { + Container result; + AddTo(&result); + return result; + } + + template <class S> + inline TVector<S> ToList() { + TVector<S> result; + for (auto&& it : *this) { + result.push_back(S(it.Token())); + } + return result; + } + + template <class Container> + inline void Collect(Container* c) { + Y_ASSERT(c); + c->clear(); + AddTo(c); + } + + template <class Container> + inline void AddTo(Container* c) { + Y_ASSERT(c); + TContainerConsumer<Container> consumer(c); + Consume(consumer); + } + + template <class Container> + inline void ParseInto(Container* c) { + Y_ASSERT(c); + TContainerConvertingConsumer<Container> consumer(c); + Consume(consumer); + } + + // TODO: this is actually TryParseInto + /** + * Same as `CollectInto`, just doesn't throw. + * + * \param[out] args Output arguments. + * \returns Whether parsing was successful. + */ + template <typename... Args> + inline bool TryCollectInto(Args*... args) noexcept { + size_t successfullyFilled = 0; + auto it = this->begin(); + + //FIXME: actually, some kind of TryApplyToMany is needed in order to stop iteration upon first failure + ApplyToMany([&](auto&& arg) { + if (it != this->end()) { + if (TryDoFromString(it->Token(), arg)) { + ++successfullyFilled; + } + ++it; + } }, args...); - - return successfullyFilled == sizeof...(args) && it == this->end(); - } - - // TODO: this is actually ParseInto - /** - * Splits and parses everything that's in this splitter into `args`. - * - * Example usage: - * \code - * int l, r; - * StringSplitter("100*200").Split('*').CollectInto(&l, &r); - * \endcode - * - * \param[out] args Output arguments. - * \throws If not all items were parsed, or - * if there were too many items in the split. - */ - template <typename... Args> - inline void CollectInto(Args*... args) { - Y_ENSURE(TryCollectInto<Args...>(args...)); - } - - inline size_t Count() const { - size_t cnt = 0; - for (auto&& it : *this) { - Y_UNUSED(it); - ++cnt; - } - return cnt; - } - }; - - template <class String> - class TStringSplitter { - using TStringType = String; - using TChar = typename TStringType::value_type; - using TIteratorState = TIterState<TStringType>; + + return successfullyFilled == sizeof...(args) && it == this->end(); + } + + // TODO: this is actually ParseInto + /** + * Splits and parses everything that's in this splitter into `args`. + * + * Example usage: + * \code + * int l, r; + * StringSplitter("100*200").Split('*').CollectInto(&l, &r); + * \endcode + * + * \param[out] args Output arguments. + * \throws If not all items were parsed, or + * if there were too many items in the split. + */ + template <typename... Args> + inline void CollectInto(Args*... args) { + Y_ENSURE(TryCollectInto<Args...>(args...)); + } + + inline size_t Count() const { + size_t cnt = 0; + for (auto&& it : *this) { + Y_UNUSED(it); + ++cnt; + } + return cnt; + } + }; + + template <class String> + class TStringSplitter { + using TStringType = String; + using TChar = typename TStringType::value_type; + using TIteratorState = TIterState<TStringType>; using TStringBufType = typename TIteratorState::TStringBufType; using TIterator = typename TIteratorState::TIterator; - - /** - * Base class for all split ranges that actually does the splitting. - */ - template <class DelimStorage> - struct TSplitRangeBase { - template <class OtherString, class... Args> - inline TSplitRangeBase(OtherString&& s, Args&&... args) - : String_(std::forward<OtherString>(s)) - , State_(String_) + + /** + * Base class for all split ranges that actually does the splitting. + */ + template <class DelimStorage> + struct TSplitRangeBase { + template <class OtherString, class... Args> + inline TSplitRangeBase(OtherString&& s, Args&&... args) + : String_(std::forward<OtherString>(s)) + , State_(String_) , Delimiter_(std::forward<Args>(args)...) - { - } - - inline TIteratorState* Next() { + { + } + + inline TIteratorState* Next() { if (State_.DelimiterIsEmpty()) { - return nullptr; - } - + return nullptr; + } + const auto tokenBegin = State_.DelimiterEnd_; const auto tokenEnd = Delimiter_.Ptr()->Find(State_.DelimiterEnd_, State_.OriginEnd_); State_.UpdateParentBuf(tokenBegin, tokenEnd); - - return &State_; - } - - private: - TStringType String_; - TIteratorState State_; + + return &State_; + } + + private: + TStringType String_; + TIteratorState State_; DelimStorage Delimiter_; - }; - - template <class Base, class Filter> + }; + + template <class Base, class Filter> struct TFilterRange: public Base { - template <class... Args> - inline TFilterRange(const Base& base, Args&&... args) - : Base(base) - , Filter_(std::forward<Args>(args)...) - { - } - - inline TIteratorState* Next() { - TIteratorState* ret; - - do { - ret = Base::Next(); - } while (ret && !Filter_.Accept(ret)); - - return ret; - } - - Filter Filter_; - }; - - struct TNonEmptyFilter { - template <class TToken> - inline bool Accept(const TToken* token) noexcept { + template <class... Args> + inline TFilterRange(const Base& base, Args&&... args) + : Base(base) + , Filter_(std::forward<Args>(args)...) + { + } + + inline TIteratorState* Next() { + TIteratorState* ret; + + do { + ret = Base::Next(); + } while (ret && !Filter_.Accept(ret)); + + return ret; + } + + Filter Filter_; + }; + + struct TNonEmptyFilter { + template <class TToken> + inline bool Accept(const TToken* token) noexcept { return !token->empty(); - } - }; - - template <class TIter> - struct TStopIteration; - - template <class Base> + } + }; + + template <class TIter> + struct TStopIteration; + + template <class Base> struct TFilters: public Base { - template <class TFilter> - using TIt = TSplitRange<TStopIteration<TFilters<TFilterRange<Base, TFilter>>>>; - - template <typename... Args> - inline TFilters(Args&&... args) - : Base(std::forward<Args>(args)...) - { - } - - inline TIt<TNonEmptyFilter> SkipEmpty() const { + template <class TFilter> + using TIt = TSplitRange<TStopIteration<TFilters<TFilterRange<Base, TFilter>>>>; + + template <typename... Args> + inline TFilters(Args&&... args) + : Base(std::forward<Args>(args)...) + { + } + + inline TIt<TNonEmptyFilter> SkipEmpty() const { return {*this}; - } - }; - - template <class Base, class Stopper> + } + }; + + template <class Base, class Stopper> struct TStopRange: public Base { - template <typename... Args> - inline TStopRange(const Base& base, Args&&... args) - : Base(base) - , Stopper_(std::forward<Args>(args)...) - { - } - - inline TIteratorState* Next() { - TIteratorState* ret = Base::Next(); - if (!ret || Stopper_.Stop(ret)) { - return nullptr; - } - return ret; - } - - Stopper Stopper_; - }; - - struct TTake { - TTake() = default; - - TTake(size_t count) - : Count(count) - { - } - - template <class TToken> - inline bool Stop(TToken*) noexcept { - if (Count > 0) { - --Count; - return false; - } else { - return true; - } - } - - size_t Count = 0; - }; - - struct TLimit { - TLimit() = default; - - TLimit(size_t count) - : Count(count) - { - Y_ASSERT(Count > 0); - } - - template <class TToken> - inline bool Stop(TToken* token) noexcept { - if (Count > 1) { - --Count; - return false; - } else if (Count == 1) { + template <typename... Args> + inline TStopRange(const Base& base, Args&&... args) + : Base(base) + , Stopper_(std::forward<Args>(args)...) + { + } + + inline TIteratorState* Next() { + TIteratorState* ret = Base::Next(); + if (!ret || Stopper_.Stop(ret)) { + return nullptr; + } + return ret; + } + + Stopper Stopper_; + }; + + struct TTake { + TTake() = default; + + TTake(size_t count) + : Count(count) + { + } + + template <class TToken> + inline bool Stop(TToken*) noexcept { + if (Count > 0) { + --Count; + return false; + } else { + return true; + } + } + + size_t Count = 0; + }; + + struct TLimit { + TLimit() = default; + + TLimit(size_t count) + : Count(count) + { + Y_ASSERT(Count > 0); + } + + template <class TToken> + inline bool Stop(TToken* token) noexcept { + if (Count > 1) { + --Count; + return false; + } else if (Count == 1) { token->DelimiterEnd_ = token->OriginEnd_; token->UpdateParentBuf(token->TokenStart(), token->DelimiterEnd_); - return false; - } - return true; - } - - size_t Count = 0; - }; - - template <class Base> + return false; + } + return true; + } + + size_t Count = 0; + }; + + template <class Base> struct TStopIteration: public Base { - template <class TStopper> - using TIt = TSplitRange<TStopIteration<TFilters<TStopRange<Base, TStopper>>>>; - - template <typename... Args> - inline TStopIteration(Args&&... args) - : Base(std::forward<Args>(args)...) - { - } - - inline TIt<TTake> Take(size_t count) { + template <class TStopper> + using TIt = TSplitRange<TStopIteration<TFilters<TStopRange<Base, TStopper>>>>; + + template <typename... Args> + inline TStopIteration(Args&&... args) + : Base(std::forward<Args>(args)...) + { + } + + inline TIt<TTake> Take(size_t count) { return {*this, count}; - } - - inline TIt<TLimit> Limit(size_t count) { + } + + inline TIt<TLimit> Limit(size_t count) { return {*this, count}; - } - }; - - template <class TPolicy> - using TIt = TSplitRange<TStopIteration<TFilters<TSplitRangeBase<TPolicy>>>>; - - public: + } + }; + + template <class TPolicy> + using TIt = TSplitRange<TStopIteration<TFilters<TSplitRangeBase<TPolicy>>>>; + + public: template <class OtherString> - explicit TStringSplitter(OtherString&& s) - : String_(std::forward<OtherString>(s)) - { - } - - //does not own TDelim - template <class TDelim> - inline TIt<TPtrPolicy<const TDelim>> Split(const TDelim& d) const noexcept { + explicit TStringSplitter(OtherString&& s) + : String_(std::forward<OtherString>(s)) + { + } + + //does not own TDelim + template <class TDelim> + inline TIt<TPtrPolicy<const TDelim>> Split(const TDelim& d) const noexcept { return {String_, &d}; - } - - inline TIt<TEmbedPolicy<TCharDelimiter<const TChar>>> Split(TChar ch) const noexcept { + } + + inline TIt<TEmbedPolicy<TCharDelimiter<const TChar>>> Split(TChar ch) const noexcept { return {String_, ch}; - } - - inline TIt<TSimpleRefPolicy<TSetDelimiter<const TChar>>> SplitBySet(const TChar* set) const noexcept { + } + + inline TIt<TSimpleRefPolicy<TSetDelimiter<const TChar>>> SplitBySet(const TChar* set) const noexcept { return {String_, set}; - } - - inline TIt<TEmbedPolicy<TStringDelimiter<const TChar>>> SplitByString(const TStringBufType& str) const noexcept { + } + + inline TIt<TEmbedPolicy<TStringDelimiter<const TChar>>> SplitByString(const TStringBufType& str) const noexcept { return {String_, str.data(), str.size()}; - } - - template <class TFunc> - inline TIt<TEmbedPolicy<TFuncDelimiter<TIterator, TFunc>>> SplitByFunc(TFunc f) const noexcept { + } + + template <class TFunc> + inline TIt<TEmbedPolicy<TFuncDelimiter<TIterator, TFunc>>> SplitByFunc(TFunc f) const noexcept { return {String_, f}; - } - - private: - TStringType String_; - }; - + } + + private: + TStringType String_; + }; + template <class String> - auto MakeStringSplitter(String&& s) { - return TStringSplitter<std::remove_reference_t<String>>(std::forward<String>(s)); - } -} - -template <class Iterator> -auto StringSplitter(Iterator begin, Iterator end) { + auto MakeStringSplitter(String&& s) { + return TStringSplitter<std::remove_reference_t<String>>(std::forward<String>(s)); + } +} + +template <class Iterator> +auto StringSplitter(Iterator begin, Iterator end) { return ::NStringSplitPrivate::MakeStringSplitter(TIteratorRange<Iterator>(begin, end)); -} - -template <class Char> -auto StringSplitter(const Char* begin, const Char* end) { +} + +template <class Char> +auto StringSplitter(const Char* begin, const Char* end) { return ::NStringSplitPrivate::MakeStringSplitter(TBasicStringBuf<Char>(begin, end)); -} - -template <class Char> -auto StringSplitter(const Char* begin, size_t len) { +} + +template <class Char> +auto StringSplitter(const Char* begin, size_t len) { return ::NStringSplitPrivate::MakeStringSplitter(TBasicStringBuf<Char>(begin, len)); -} - -template <class Char> -auto StringSplitter(const Char* str) { +} + +template <class Char> +auto StringSplitter(const Char* str) { return ::NStringSplitPrivate::MakeStringSplitter(TBasicStringBuf<Char>(str)); -} - -template <class String, std::enable_if_t<!std::is_pointer<std::remove_reference_t<String>>::value, int> = 0> -auto StringSplitter(String& s) { +} + +template <class String, std::enable_if_t<!std::is_pointer<std::remove_reference_t<String>>::value, int> = 0> +auto StringSplitter(String& s) { return ::NStringSplitPrivate::MakeStringSplitter(::NStringSplitPrivate::TStringBufOf<String>(s.data(), s.size())); -} - -template <class String, std::enable_if_t<!std::is_pointer<std::remove_reference_t<String>>::value, int> = 0> -auto StringSplitter(String&& s) { +} + +template <class String, std::enable_if_t<!std::is_pointer<std::remove_reference_t<String>>::value, int> = 0> +auto StringSplitter(String&& s) { return ::NStringSplitPrivate::MakeStringSplitter(std::move(s)); -} +} diff --git a/util/string/split_ut.cpp b/util/string/split_ut.cpp index f8cd78cb88..43e59f2d75 100644 --- a/util/string/split_ut.cpp +++ b/util/string/split_ut.cpp @@ -7,9 +7,9 @@ #include <util/datetime/cputimer.h> #include <util/generic/maybe.h> -#include <string> -#include <string_view> - +#include <string> +#include <string_view> + template <typename T> static inline void OldSplit(char* pszBuf, T* pRes) { pRes->resize(0); @@ -126,8 +126,8 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TVector<TString> good(canonic, canonic + 4); TCharDelimiter<const char> delim(' '); - TestDelimiterOnString<TContainerConsumer>(good, data.data(), delim); - TestDelimiterOnRange<TContainerConsumer>(good, data.data(), data.end(), delim); + TestDelimiterOnString<TContainerConsumer>(good, data.data(), delim); + TestDelimiterOnRange<TContainerConsumer>(good, data.data(), data.end(), delim); } Y_UNIT_TEST(TestWideSingleDelimiter) { @@ -136,8 +136,8 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TVector<TUtf16String> good(canonic, canonic + 4); TCharDelimiter<const wchar16> delim(' '); - TestDelimiterOnString<TContainerConsumer>(good, data.data(), delim); - TestDelimiterOnRange<TContainerConsumer>(good, data.data(), data.end(), delim); + TestDelimiterOnString<TContainerConsumer>(good, data.data(), delim); + TestDelimiterOnRange<TContainerConsumer>(good, data.data(), data.end(), delim); } Y_UNIT_TEST(TestConvertToIntCharSingleDelimiter) { @@ -146,8 +146,8 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TVector<i32> good(canonic, canonic + 4); TCharDelimiter<const char> delim(' '); - TestDelimiterOnString<TContainerConvertingConsumer>(good, data.data(), delim); - TestDelimiterOnRange<TContainerConvertingConsumer>(good, data.data(), data.end(), delim); + TestDelimiterOnString<TContainerConvertingConsumer>(good, data.data(), delim); + TestDelimiterOnRange<TContainerConvertingConsumer>(good, data.data(), data.end(), delim); } Y_UNIT_TEST(TestCharSkipEmpty) { @@ -155,8 +155,8 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TString canonic[] = {"qw", "ab", "qwabcab"}; TVector<TString> good(canonic, canonic + 3); - TestConsumerOnString<TSkipEmptyTokens<TStrokaConsumer>>(good, data.data(), " "); - TestConsumerOnRange<TSkipEmptyTokens<TStrokaConsumer>>(good, data.data(), data.end(), " "); + TestConsumerOnString<TSkipEmptyTokens<TStrokaConsumer>>(good, data.data(), " "); + TestConsumerOnRange<TSkipEmptyTokens<TStrokaConsumer>>(good, data.data(), data.end(), " "); } Y_UNIT_TEST(TestCharKeepDelimiters) { @@ -164,8 +164,8 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TString canonic[] = {"qw", " ", "ab", " ", "", " ", "qwabcab", " ", ""}; TVector<TString> good(canonic, canonic + 9); - TestConsumerOnString<TKeepDelimiters<TStrokaConsumer>>(good, data.data(), " "); - TestConsumerOnRange<TKeepDelimiters<TStrokaConsumer>>(good, data.data(), data.end(), " "); + TestConsumerOnString<TKeepDelimiters<TStrokaConsumer>>(good, data.data(), " "); + TestConsumerOnRange<TKeepDelimiters<TStrokaConsumer>>(good, data.data(), data.end(), " "); } Y_UNIT_TEST(TestCharLimit) { @@ -173,8 +173,8 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TString canonic[] = {"qw", "ab"}; TVector<TString> good(canonic, canonic + 2); - TestLimitingConsumerOnString(good, data.data(), " ", 3, " qwabcab "); - TestLimitingConsumerOnRange(good, data.data(), data.end(), " ", 3, " qwabcab "); + TestLimitingConsumerOnString(good, data.data(), " ", 3, " qwabcab "); + TestLimitingConsumerOnRange(good, data.data(), data.end(), " ", 3, " qwabcab "); } Y_UNIT_TEST(TestCharStringDelimiter) { @@ -183,8 +183,8 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TVector<TString> good(canonic, canonic + 5); TStringDelimiter<const char> delim("ab"); - TestDelimiterOnString<TContainerConsumer>(good, data.data(), delim); - TestDelimiterOnRange<TContainerConsumer>(good, data.data(), data.end(), delim); + TestDelimiterOnString<TContainerConsumer>(good, data.data(), delim); + TestDelimiterOnRange<TContainerConsumer>(good, data.data(), data.end(), delim); } Y_UNIT_TEST(TestWideStringDelimiter) { @@ -194,8 +194,8 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TUtf16String wideDelim(u"ab"); TStringDelimiter<const wchar16> delim(wideDelim.data()); - TestDelimiterOnString<TContainerConsumer>(good, data.data(), delim); - TestDelimiterOnRange<TContainerConsumer>(good, data.data(), data.end(), delim); + TestDelimiterOnString<TContainerConsumer>(good, data.data(), delim); + TestDelimiterOnRange<TContainerConsumer>(good, data.data(), data.end(), delim); } Y_UNIT_TEST(TestCharSetDelimiter) { @@ -204,8 +204,8 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TVector<TString> good(canonic, canonic + 5); TSetDelimiter<const char> delim("wc"); - TestDelimiterOnString<TContainerConsumer>(good, data.data(), delim); - TestDelimiterOnRange<TContainerConsumer>(good, data.data(), data.end(), delim); + TestDelimiterOnString<TContainerConsumer>(good, data.data(), delim); + TestDelimiterOnRange<TContainerConsumer>(good, data.data(), data.end(), delim); } Y_UNIT_TEST(TestWideSetDelimiter) { @@ -215,7 +215,7 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TUtf16String wideDelim(u"wc"); TSetDelimiter<const wchar16> delim(wideDelim.data()); - TestDelimiterOnString<TContainerConsumer>(good, data.data(), delim); + TestDelimiterOnString<TContainerConsumer>(good, data.data(), delim); } Y_UNIT_TEST(TestWideSetDelimiterRange) { @@ -227,18 +227,18 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TVector<TUtf16String> test; TContainerConsumer<TVector<TUtf16String>> consumer(&test); - SplitString(data.data(), data.data(), delim, consumer); // Empty string is still inserted into consumer + SplitString(data.data(), data.data(), delim, consumer); // Empty string is still inserted into consumer Cmp(good, test); good.assign(canonic, canonic + 4); good.push_back(TUtf16String()); test.clear(); - SplitString(data.data(), data.end() - 2, delim, consumer); + SplitString(data.data(), data.end() - 2, delim, consumer); Cmp(good, test); } Y_UNIT_TEST(TestSplit) { - TString data("qw ab qwababcba"); + TString data("qw ab qwababcba"); TString canonic[] = {"qw ", " qw", "c"}; TVector<TString> good(canonic, canonic + 3); TString delim = "ab"; @@ -247,7 +247,7 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { Cmp(good, test); TVector<TStringBuf> test1; - Split(data, delim.data(), test1); + Split(data, delim.data(), test1); Cmp(good, test1); } @@ -302,263 +302,263 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { UNIT_ASSERT_EXCEPTION(Split(data, ' ', s1, s2, m1, m2, m1, m1, m1, m1, s1), yexception); } } - -template <typename I, typename C> -void TestStringSplitterCount(I* str, C delim, size_t good) { - size_t res = StringSplitter(str).Split(delim).Count(); - UNIT_ASSERT_VALUES_EQUAL(res, good); -} - -Y_UNIT_TEST_SUITE(StringSplitter) { - Y_UNIT_TEST(TestSplit) { - int sum = 0; - - for (const auto& it : StringSplitter("1,2,3").Split(',')) { - sum += FromString<int>(it.Token()); - } - - UNIT_ASSERT_VALUES_EQUAL(sum, 6); - } - - Y_UNIT_TEST(TestSplit1) { - int cnt = 0; - - for (const auto& it : StringSplitter(" ").Split(' ')) { - (void)it; - - ++cnt; - } - - UNIT_ASSERT_VALUES_EQUAL(cnt, 2); - } - - Y_UNIT_TEST(TestSplitLimited) { - TVector<TString> expected = {"1", "2", "3,4,5"}; - TVector<TString> actual = StringSplitter("1,2,3,4,5").Split(',').Limit(3).ToList<TString>(); - UNIT_ASSERT_VALUES_EQUAL(expected, actual); - } - - Y_UNIT_TEST(TestSplitLimitedWithEmptySkip) { - TVector<TString> expected = {"1", "2", "3,4,5"}; - TVector<TString> actual = StringSplitter("1,,,2,,,,3,4,5").Split(',').SkipEmpty().Limit(3).ToList<TString>(); - UNIT_ASSERT_VALUES_EQUAL(expected, actual); - - expected = {"1", "2", ",,,3,4,5"}; - actual = StringSplitter("1,2,,,,3,4,5").Split(',').Limit(3).SkipEmpty().ToList<TString>(); - UNIT_ASSERT_VALUES_EQUAL(expected, actual); - } - - Y_UNIT_TEST(TestSplitBySet) { - int sum = 0; - - for (const auto& it : StringSplitter("1,2:3").SplitBySet(",:")) { - sum += FromString<int>(it.Token()); - } - - UNIT_ASSERT_VALUES_EQUAL(sum, 6); - } - - Y_UNIT_TEST(TestSplitBySetLimited) { - TVector<TString> expected = {"1", "2", "3,4:5"}; - TVector<TString> actual = StringSplitter("1,2:3,4:5").SplitBySet(",:").Limit(3).ToList<TString>(); - UNIT_ASSERT_VALUES_EQUAL(expected, actual); - } - - Y_UNIT_TEST(TestSplitBySetLimitedWithEmptySkip) { - TVector<TString> expected = {"1", "2", "3,4:5"}; - TVector<TString> actual = StringSplitter("1,:,2::::,3,4:5").SplitBySet(",:").SkipEmpty().Limit(3).ToList<TString>(); - UNIT_ASSERT_VALUES_EQUAL(expected, actual); - - expected = {"1", ",2::::,3,4:5"}; - actual = StringSplitter("1,:,2::::,3,4:5").SplitBySet(",:").Limit(3).SkipEmpty().ToList<TString>(); - UNIT_ASSERT_VALUES_EQUAL(expected, actual); - } - - Y_UNIT_TEST(TestSplitByString) { - int sum = 0; - - for (const auto& it : StringSplitter("1ab2ab3").SplitByString("ab")) { - sum += FromString<int>(it.Token()); - } - - UNIT_ASSERT_VALUES_EQUAL(sum, 6); - } - - Y_UNIT_TEST(TestSplitByStringLimited) { - TVector<TString> expected = {"1", "2", "3ab4ab5"}; - TVector<TString> actual = StringSplitter("1ab2ab3ab4ab5").SplitByString("ab").Limit(3).ToList<TString>(); - UNIT_ASSERT_VALUES_EQUAL(expected, actual); - } - - Y_UNIT_TEST(TestSplitByStringLimitedWithEmptySkip) { - TVector<TString> expected = {"1", "2", "3ab4ab5"}; - TVector<TString> actual = StringSplitter("1abab2ababababab3ab4ab5").SplitByString("ab").SkipEmpty().Limit(3).ToList<TString>(); - UNIT_ASSERT_VALUES_EQUAL(expected, actual); - } - - Y_UNIT_TEST(TestSplitByFunc) { - TString s = "123 456 \t\n789\n10\t 20"; - TVector<TString> pattern = {"123", "456", "789", "10", "20"}; - - TVector<TString> tokens; - auto f = [](char a) { return a == ' ' || a == '\t' || a == '\n'; }; - for (auto v : StringSplitter(s).SplitByFunc(f)) { + +template <typename I, typename C> +void TestStringSplitterCount(I* str, C delim, size_t good) { + size_t res = StringSplitter(str).Split(delim).Count(); + UNIT_ASSERT_VALUES_EQUAL(res, good); +} + +Y_UNIT_TEST_SUITE(StringSplitter) { + Y_UNIT_TEST(TestSplit) { + int sum = 0; + + for (const auto& it : StringSplitter("1,2,3").Split(',')) { + sum += FromString<int>(it.Token()); + } + + UNIT_ASSERT_VALUES_EQUAL(sum, 6); + } + + Y_UNIT_TEST(TestSplit1) { + int cnt = 0; + + for (const auto& it : StringSplitter(" ").Split(' ')) { + (void)it; + + ++cnt; + } + + UNIT_ASSERT_VALUES_EQUAL(cnt, 2); + } + + Y_UNIT_TEST(TestSplitLimited) { + TVector<TString> expected = {"1", "2", "3,4,5"}; + TVector<TString> actual = StringSplitter("1,2,3,4,5").Split(',').Limit(3).ToList<TString>(); + UNIT_ASSERT_VALUES_EQUAL(expected, actual); + } + + Y_UNIT_TEST(TestSplitLimitedWithEmptySkip) { + TVector<TString> expected = {"1", "2", "3,4,5"}; + TVector<TString> actual = StringSplitter("1,,,2,,,,3,4,5").Split(',').SkipEmpty().Limit(3).ToList<TString>(); + UNIT_ASSERT_VALUES_EQUAL(expected, actual); + + expected = {"1", "2", ",,,3,4,5"}; + actual = StringSplitter("1,2,,,,3,4,5").Split(',').Limit(3).SkipEmpty().ToList<TString>(); + UNIT_ASSERT_VALUES_EQUAL(expected, actual); + } + + Y_UNIT_TEST(TestSplitBySet) { + int sum = 0; + + for (const auto& it : StringSplitter("1,2:3").SplitBySet(",:")) { + sum += FromString<int>(it.Token()); + } + + UNIT_ASSERT_VALUES_EQUAL(sum, 6); + } + + Y_UNIT_TEST(TestSplitBySetLimited) { + TVector<TString> expected = {"1", "2", "3,4:5"}; + TVector<TString> actual = StringSplitter("1,2:3,4:5").SplitBySet(",:").Limit(3).ToList<TString>(); + UNIT_ASSERT_VALUES_EQUAL(expected, actual); + } + + Y_UNIT_TEST(TestSplitBySetLimitedWithEmptySkip) { + TVector<TString> expected = {"1", "2", "3,4:5"}; + TVector<TString> actual = StringSplitter("1,:,2::::,3,4:5").SplitBySet(",:").SkipEmpty().Limit(3).ToList<TString>(); + UNIT_ASSERT_VALUES_EQUAL(expected, actual); + + expected = {"1", ",2::::,3,4:5"}; + actual = StringSplitter("1,:,2::::,3,4:5").SplitBySet(",:").Limit(3).SkipEmpty().ToList<TString>(); + UNIT_ASSERT_VALUES_EQUAL(expected, actual); + } + + Y_UNIT_TEST(TestSplitByString) { + int sum = 0; + + for (const auto& it : StringSplitter("1ab2ab3").SplitByString("ab")) { + sum += FromString<int>(it.Token()); + } + + UNIT_ASSERT_VALUES_EQUAL(sum, 6); + } + + Y_UNIT_TEST(TestSplitByStringLimited) { + TVector<TString> expected = {"1", "2", "3ab4ab5"}; + TVector<TString> actual = StringSplitter("1ab2ab3ab4ab5").SplitByString("ab").Limit(3).ToList<TString>(); + UNIT_ASSERT_VALUES_EQUAL(expected, actual); + } + + Y_UNIT_TEST(TestSplitByStringLimitedWithEmptySkip) { + TVector<TString> expected = {"1", "2", "3ab4ab5"}; + TVector<TString> actual = StringSplitter("1abab2ababababab3ab4ab5").SplitByString("ab").SkipEmpty().Limit(3).ToList<TString>(); + UNIT_ASSERT_VALUES_EQUAL(expected, actual); + } + + Y_UNIT_TEST(TestSplitByFunc) { + TString s = "123 456 \t\n789\n10\t 20"; + TVector<TString> pattern = {"123", "456", "789", "10", "20"}; + + TVector<TString> tokens; + auto f = [](char a) { return a == ' ' || a == '\t' || a == '\n'; }; + for (auto v : StringSplitter(s).SplitByFunc(f)) { if (v) { - tokens.emplace_back(v); + tokens.emplace_back(v); } - } - - UNIT_ASSERT(tokens == pattern); - } - - Y_UNIT_TEST(TestSplitByFuncLimited) { - TVector<TString> expected = {"1", "2", "3a4b5"}; - auto f = [](char a) { return a == 'a' || a == 'b'; }; - TVector<TString> actual = StringSplitter("1a2b3a4b5").SplitByFunc(f).Limit(3).ToList<TString>(); - UNIT_ASSERT_VALUES_EQUAL(expected, actual); - } - - Y_UNIT_TEST(TestSplitByFuncLimitedWithEmptySkip) { - TVector<TString> expected = {"1", "2", "3a4b5"}; - auto f = [](char a) { return a == 'a' || a == 'b'; }; - TVector<TString> actual = StringSplitter("1aaba2bbababa3a4b5").SplitByFunc(f).SkipEmpty().Limit(3).Take(3).ToList<TString>(); - UNIT_ASSERT_VALUES_EQUAL(expected, actual); - } - - Y_UNIT_TEST(TestSkipEmpty) { - int sum = 0; - - for (const auto& it : StringSplitter(" 1 2 3 ").Split(' ').SkipEmpty()) { - sum += FromString<int>(it.Token()); - } - - UNIT_ASSERT_VALUES_EQUAL(sum, 6); - - // double - sum = 0; - for (const auto& it : StringSplitter(" 1 2 3 ").Split(' ').SkipEmpty().SkipEmpty()) { - sum += FromString<int>(it.Token()); - } - UNIT_ASSERT_VALUES_EQUAL(sum, 6); - } - - Y_UNIT_TEST(TestTake) { - TVector<TString> expected = {"1", "2", "3"}; - UNIT_ASSERT_VALUES_EQUAL(expected, StringSplitter("1 2 3 4 5 6 7 8 9 10").Split(' ').Take(3).ToList<TString>()); - - expected = {"1", "2"}; - UNIT_ASSERT_VALUES_EQUAL(expected, StringSplitter(" 1 2 3 ").Split(' ').SkipEmpty().Take(2).ToList<TString>()); - - expected = {"1", "2", "3"}; - UNIT_ASSERT_VALUES_EQUAL(expected, StringSplitter("1 2 3 4 5 6 7 8 9 10").Split(' ').Take(5).Take(3).ToList<TString>()); - UNIT_ASSERT_VALUES_EQUAL(expected, StringSplitter("1 2 3 4 5 6 7 8 9 10").Split(' ').Take(3).Take(5).ToList<TString>()); - - expected = {"1", "2"}; - UNIT_ASSERT_VALUES_EQUAL(expected, StringSplitter(" 1 2 3 ").Split(' ').Take(4).SkipEmpty().ToList<TString>()); - - expected = {"1"}; - UNIT_ASSERT_VALUES_EQUAL(expected, StringSplitter(" 1 2 3 ").Split(' ').Take(4).SkipEmpty().Take(1).ToList<TString>()); - } - - Y_UNIT_TEST(TestCompile) { + } + + UNIT_ASSERT(tokens == pattern); + } + + Y_UNIT_TEST(TestSplitByFuncLimited) { + TVector<TString> expected = {"1", "2", "3a4b5"}; + auto f = [](char a) { return a == 'a' || a == 'b'; }; + TVector<TString> actual = StringSplitter("1a2b3a4b5").SplitByFunc(f).Limit(3).ToList<TString>(); + UNIT_ASSERT_VALUES_EQUAL(expected, actual); + } + + Y_UNIT_TEST(TestSplitByFuncLimitedWithEmptySkip) { + TVector<TString> expected = {"1", "2", "3a4b5"}; + auto f = [](char a) { return a == 'a' || a == 'b'; }; + TVector<TString> actual = StringSplitter("1aaba2bbababa3a4b5").SplitByFunc(f).SkipEmpty().Limit(3).Take(3).ToList<TString>(); + UNIT_ASSERT_VALUES_EQUAL(expected, actual); + } + + Y_UNIT_TEST(TestSkipEmpty) { + int sum = 0; + + for (const auto& it : StringSplitter(" 1 2 3 ").Split(' ').SkipEmpty()) { + sum += FromString<int>(it.Token()); + } + + UNIT_ASSERT_VALUES_EQUAL(sum, 6); + + // double + sum = 0; + for (const auto& it : StringSplitter(" 1 2 3 ").Split(' ').SkipEmpty().SkipEmpty()) { + sum += FromString<int>(it.Token()); + } + UNIT_ASSERT_VALUES_EQUAL(sum, 6); + } + + Y_UNIT_TEST(TestTake) { + TVector<TString> expected = {"1", "2", "3"}; + UNIT_ASSERT_VALUES_EQUAL(expected, StringSplitter("1 2 3 4 5 6 7 8 9 10").Split(' ').Take(3).ToList<TString>()); + + expected = {"1", "2"}; + UNIT_ASSERT_VALUES_EQUAL(expected, StringSplitter(" 1 2 3 ").Split(' ').SkipEmpty().Take(2).ToList<TString>()); + + expected = {"1", "2", "3"}; + UNIT_ASSERT_VALUES_EQUAL(expected, StringSplitter("1 2 3 4 5 6 7 8 9 10").Split(' ').Take(5).Take(3).ToList<TString>()); + UNIT_ASSERT_VALUES_EQUAL(expected, StringSplitter("1 2 3 4 5 6 7 8 9 10").Split(' ').Take(3).Take(5).ToList<TString>()); + + expected = {"1", "2"}; + UNIT_ASSERT_VALUES_EQUAL(expected, StringSplitter(" 1 2 3 ").Split(' ').Take(4).SkipEmpty().ToList<TString>()); + + expected = {"1"}; + UNIT_ASSERT_VALUES_EQUAL(expected, StringSplitter(" 1 2 3 ").Split(' ').Take(4).SkipEmpty().Take(1).ToList<TString>()); + } + + Y_UNIT_TEST(TestCompile) { (void)StringSplitter(TString()); (void)StringSplitter(TStringBuf()); (void)StringSplitter("", 0); - } - - Y_UNIT_TEST(TestStringSplitterCountEmpty) { - TCharDelimiter<const char> delim(' '); - TestStringSplitterCount("", delim, 1); - } - - Y_UNIT_TEST(TestStringSplitterCountOne) { - TCharDelimiter<const char> delim(' '); - TestStringSplitterCount("one", delim, 1); - } - - Y_UNIT_TEST(TestStringSplitterCountWithOneDelimiter) { - TCharDelimiter<const char> delim(' '); - TestStringSplitterCount("one two", delim, 2); - } - - Y_UNIT_TEST(TestStringSplitterCountWithTrailing) { - TCharDelimiter<const char> delim(' '); - TestStringSplitterCount(" one ", delim, 3); - } - - Y_UNIT_TEST(TestStringSplitterConsume) { - TVector<TString> expected = {"1", "2", "3"}; - TVector<TString> actual; - auto func = [&actual](const TBasicStringBuf<char>& token) { - actual.push_back(TString(token)); - }; - StringSplitter("1 2 3").Split(' ').Consume(func); - UNIT_ASSERT_VALUES_EQUAL(expected, actual); - } - - Y_UNIT_TEST(TestStringSplitterConsumeConditional) { + } + + Y_UNIT_TEST(TestStringSplitterCountEmpty) { + TCharDelimiter<const char> delim(' '); + TestStringSplitterCount("", delim, 1); + } + + Y_UNIT_TEST(TestStringSplitterCountOne) { + TCharDelimiter<const char> delim(' '); + TestStringSplitterCount("one", delim, 1); + } + + Y_UNIT_TEST(TestStringSplitterCountWithOneDelimiter) { + TCharDelimiter<const char> delim(' '); + TestStringSplitterCount("one two", delim, 2); + } + + Y_UNIT_TEST(TestStringSplitterCountWithTrailing) { + TCharDelimiter<const char> delim(' '); + TestStringSplitterCount(" one ", delim, 3); + } + + Y_UNIT_TEST(TestStringSplitterConsume) { + TVector<TString> expected = {"1", "2", "3"}; + TVector<TString> actual; + auto func = [&actual](const TBasicStringBuf<char>& token) { + actual.push_back(TString(token)); + }; + StringSplitter("1 2 3").Split(' ').Consume(func); + UNIT_ASSERT_VALUES_EQUAL(expected, actual); + } + + Y_UNIT_TEST(TestStringSplitterConsumeConditional) { TVector<TString> expected = {"1", "2"}; - TVector<TString> actual; - auto func = [&actual](const TBasicStringBuf<char>& token) { + TVector<TString> actual; + auto func = [&actual](const TBasicStringBuf<char>& token) { if (token == "3") { - return false; + return false; } - actual.push_back(TString(token)); - return true; - }; - bool completed = StringSplitter("1 2 3 4 5").Split(' ').Consume(func); - UNIT_ASSERT(!completed); - UNIT_ASSERT_VALUES_EQUAL(expected, actual); - } - - Y_UNIT_TEST(TestStringSplitterToList) { - TVector<TString> expected = {"1", "2", "3"}; - TVector<TString> actual = StringSplitter("1 2 3").Split(' ').ToList<TString>(); - UNIT_ASSERT_VALUES_EQUAL(expected, actual); - } - - Y_UNIT_TEST(TestStringSplitterCollectPushBack) { - TVector<TString> expected = {"1", "2", "3"}; - TVector<TString> actual; - StringSplitter("1 2 3").Split(' ').Collect(&actual); - UNIT_ASSERT_VALUES_EQUAL(expected, actual); - } - - Y_UNIT_TEST(TestStringSplitterCollectInsert) { - TSet<TString> expected = {"1", "2", "3"}; - TSet<TString> actual; - StringSplitter("1 2 3 1 2 3").Split(' ').Collect(&actual); - UNIT_ASSERT_VALUES_EQUAL(expected, actual); - } - - Y_UNIT_TEST(TestStringSplitterCollectClears) { - TVector<TString> v; - StringSplitter("1 2 3").Split(' ').Collect(&v); - UNIT_ASSERT_VALUES_EQUAL(v.size(), 3); - StringSplitter("4 5").Split(' ').Collect(&v); - UNIT_ASSERT_VALUES_EQUAL(v.size(), 2); - } - - Y_UNIT_TEST(TestStringSplitterAddToDoesntClear) { - TVector<TString> v; - StringSplitter("1 2 3").Split(' ').AddTo(&v); - UNIT_ASSERT_VALUES_EQUAL(v.size(), 3); - StringSplitter("4 5").Split(' ').AddTo(&v); - UNIT_ASSERT_VALUES_EQUAL(v.size(), 5); - } - - Y_UNIT_TEST(TestSplitStringInto) { - int a = -1; - TStringBuf s; - double d = -1; - StringSplitter("2 substr 1.02").Split(' ').CollectInto(&a, &s, &d); - UNIT_ASSERT_VALUES_EQUAL(a, 2); - UNIT_ASSERT_VALUES_EQUAL(s, "substr"); - UNIT_ASSERT_DOUBLES_EQUAL(d, 1.02, 0.0001); - UNIT_ASSERT_EXCEPTION(StringSplitter("1").Split(' ').CollectInto(&a, &a), yexception); - UNIT_ASSERT_EXCEPTION(StringSplitter("1 2 3").Split(' ').CollectInto(&a, &a), yexception); - } - + actual.push_back(TString(token)); + return true; + }; + bool completed = StringSplitter("1 2 3 4 5").Split(' ').Consume(func); + UNIT_ASSERT(!completed); + UNIT_ASSERT_VALUES_EQUAL(expected, actual); + } + + Y_UNIT_TEST(TestStringSplitterToList) { + TVector<TString> expected = {"1", "2", "3"}; + TVector<TString> actual = StringSplitter("1 2 3").Split(' ').ToList<TString>(); + UNIT_ASSERT_VALUES_EQUAL(expected, actual); + } + + Y_UNIT_TEST(TestStringSplitterCollectPushBack) { + TVector<TString> expected = {"1", "2", "3"}; + TVector<TString> actual; + StringSplitter("1 2 3").Split(' ').Collect(&actual); + UNIT_ASSERT_VALUES_EQUAL(expected, actual); + } + + Y_UNIT_TEST(TestStringSplitterCollectInsert) { + TSet<TString> expected = {"1", "2", "3"}; + TSet<TString> actual; + StringSplitter("1 2 3 1 2 3").Split(' ').Collect(&actual); + UNIT_ASSERT_VALUES_EQUAL(expected, actual); + } + + Y_UNIT_TEST(TestStringSplitterCollectClears) { + TVector<TString> v; + StringSplitter("1 2 3").Split(' ').Collect(&v); + UNIT_ASSERT_VALUES_EQUAL(v.size(), 3); + StringSplitter("4 5").Split(' ').Collect(&v); + UNIT_ASSERT_VALUES_EQUAL(v.size(), 2); + } + + Y_UNIT_TEST(TestStringSplitterAddToDoesntClear) { + TVector<TString> v; + StringSplitter("1 2 3").Split(' ').AddTo(&v); + UNIT_ASSERT_VALUES_EQUAL(v.size(), 3); + StringSplitter("4 5").Split(' ').AddTo(&v); + UNIT_ASSERT_VALUES_EQUAL(v.size(), 5); + } + + Y_UNIT_TEST(TestSplitStringInto) { + int a = -1; + TStringBuf s; + double d = -1; + StringSplitter("2 substr 1.02").Split(' ').CollectInto(&a, &s, &d); + UNIT_ASSERT_VALUES_EQUAL(a, 2); + UNIT_ASSERT_VALUES_EQUAL(s, "substr"); + UNIT_ASSERT_DOUBLES_EQUAL(d, 1.02, 0.0001); + UNIT_ASSERT_EXCEPTION(StringSplitter("1").Split(' ').CollectInto(&a, &a), yexception); + UNIT_ASSERT_EXCEPTION(StringSplitter("1 2 3").Split(' ').CollectInto(&a, &a), yexception); + } + Y_UNIT_TEST(TestSplitStringWithIgnore) { TStringBuf s; StringSplitter("x y z").Split(' ').CollectInto(&std::ignore, &s, &std::ignore); @@ -567,265 +567,265 @@ Y_UNIT_TEST_SUITE(StringSplitter) { UNIT_ASSERT_EXCEPTION(StringSplitter("ignored != non-requred").Split(':').CollectInto(&s, &std::ignore), yexception); } - Y_UNIT_TEST(TestTryCollectInto) { - int a, b, c; - bool parsingSucceeded; - parsingSucceeded = StringSplitter("100,500,3").Split(',').TryCollectInto(&a, &b, &c); - UNIT_ASSERT(parsingSucceeded); - UNIT_ASSERT_VALUES_EQUAL(a, 100); - UNIT_ASSERT_VALUES_EQUAL(b, 500); - UNIT_ASSERT_VALUES_EQUAL(c, 3); - - //not enough tokens - parsingSucceeded = StringSplitter("3,14").Split(',').TryCollectInto(&a, &b, &c); - UNIT_ASSERT(!parsingSucceeded); - - //too many tokens - parsingSucceeded = StringSplitter("3,14,15,92,6").Split(',').TryCollectInto(&a, &b, &c); - UNIT_ASSERT(!parsingSucceeded); - - //where single TryFromString fails - parsingSucceeded = StringSplitter("ot topota kopyt pyl po polu letit").Split(' ').TryCollectInto(&a, &b, &c); - UNIT_ASSERT(!parsingSucceeded); - } - - Y_UNIT_TEST(TestOwningSplit1) { - int sum = 0; - - for (const auto& it : StringSplitter(TString("1,2,3")).Split(',')) { - sum += FromString<int>(it.Token()); - } - - UNIT_ASSERT_VALUES_EQUAL(sum, 6); - } - - Y_UNIT_TEST(TestOwningSplit2) { - int sum = 0; - - TString str("1,2,3"); - for (const auto& it : StringSplitter(str).Split(',')) { - sum += FromString<int>(it.Token()); - } - - UNIT_ASSERT_VALUES_EQUAL(sum, 6); - } - - Y_UNIT_TEST(TestOwningSplit3) { - int sum = 0; - - const TString str("1,2,3"); - for (const auto& it : StringSplitter(str).Split(',')) { - sum += FromString<int>(it.Token()); - } - - UNIT_ASSERT_VALUES_EQUAL(sum, 6); - } - - Y_UNIT_TEST(TestAssigment) { + Y_UNIT_TEST(TestTryCollectInto) { + int a, b, c; + bool parsingSucceeded; + parsingSucceeded = StringSplitter("100,500,3").Split(',').TryCollectInto(&a, &b, &c); + UNIT_ASSERT(parsingSucceeded); + UNIT_ASSERT_VALUES_EQUAL(a, 100); + UNIT_ASSERT_VALUES_EQUAL(b, 500); + UNIT_ASSERT_VALUES_EQUAL(c, 3); + + //not enough tokens + parsingSucceeded = StringSplitter("3,14").Split(',').TryCollectInto(&a, &b, &c); + UNIT_ASSERT(!parsingSucceeded); + + //too many tokens + parsingSucceeded = StringSplitter("3,14,15,92,6").Split(',').TryCollectInto(&a, &b, &c); + UNIT_ASSERT(!parsingSucceeded); + + //where single TryFromString fails + parsingSucceeded = StringSplitter("ot topota kopyt pyl po polu letit").Split(' ').TryCollectInto(&a, &b, &c); + UNIT_ASSERT(!parsingSucceeded); + } + + Y_UNIT_TEST(TestOwningSplit1) { + int sum = 0; + + for (const auto& it : StringSplitter(TString("1,2,3")).Split(',')) { + sum += FromString<int>(it.Token()); + } + + UNIT_ASSERT_VALUES_EQUAL(sum, 6); + } + + Y_UNIT_TEST(TestOwningSplit2) { + int sum = 0; + + TString str("1,2,3"); + for (const auto& it : StringSplitter(str).Split(',')) { + sum += FromString<int>(it.Token()); + } + + UNIT_ASSERT_VALUES_EQUAL(sum, 6); + } + + Y_UNIT_TEST(TestOwningSplit3) { + int sum = 0; + + const TString str("1,2,3"); + for (const auto& it : StringSplitter(str).Split(',')) { + sum += FromString<int>(it.Token()); + } + + UNIT_ASSERT_VALUES_EQUAL(sum, 6); + } + + Y_UNIT_TEST(TestAssigment) { TVector<TString> expected0 = {"1", "2", "3", "4"}; - TVector<TString> actual0 = StringSplitter("1 2 3 4").Split(' '); - UNIT_ASSERT_VALUES_EQUAL(expected0, actual0); - + TVector<TString> actual0 = StringSplitter("1 2 3 4").Split(' '); + UNIT_ASSERT_VALUES_EQUAL(expected0, actual0); + TSet<TString> expected1 = {"11", "22", "33", "44"}; - TSet<TString> actual1 = StringSplitter("11 22 33 44").Split(' '); - UNIT_ASSERT_VALUES_EQUAL(expected1, actual1); - + TSet<TString> actual1 = StringSplitter("11 22 33 44").Split(' '); + UNIT_ASSERT_VALUES_EQUAL(expected1, actual1); + TSet<TString> expected2 = {"11", "aa"}; - auto actual2 = static_cast<TSet<TString>>(StringSplitter("11 aa 11 11 aa").Split(' ')); - UNIT_ASSERT_VALUES_EQUAL(expected2, actual2); - + auto actual2 = static_cast<TSet<TString>>(StringSplitter("11 aa 11 11 aa").Split(' ')); + UNIT_ASSERT_VALUES_EQUAL(expected2, actual2); + TVector<TString> expected3 = {"dd", "bb"}; - auto actual3 = TVector<TString>(StringSplitter("dd\tbb").Split('\t')); - UNIT_ASSERT_VALUES_EQUAL(expected3, actual3); - } - - Y_UNIT_TEST(TestRangeBasedFor) { + auto actual3 = TVector<TString>(StringSplitter("dd\tbb").Split('\t')); + UNIT_ASSERT_VALUES_EQUAL(expected3, actual3); + } + + Y_UNIT_TEST(TestRangeBasedFor) { TVector<TString> actual0 = {"11", "22", "33", "44"}; - size_t num = 0; - for (TStringBuf elem : StringSplitter("11 22 33 44").Split(' ')) { - UNIT_ASSERT_VALUES_EQUAL(elem, actual0[num++]); - } - + size_t num = 0; + for (TStringBuf elem : StringSplitter("11 22 33 44").Split(' ')) { + UNIT_ASSERT_VALUES_EQUAL(elem, actual0[num++]); + } + TVector<TString> actual1 = {"another", "one,", "and", "another", "one"}; - num = 0; + num = 0; for (TStringBuf elem : StringSplitter(TStringBuf("another one, and \n\n another one")).SplitBySet(" \n").SkipEmpty()) { - UNIT_ASSERT_VALUES_EQUAL(elem, actual1[num++]); - } - + UNIT_ASSERT_VALUES_EQUAL(elem, actual1[num++]); + } + TVector<TUtf16String> actual2 = {u"привет,", u"как", u"дела"}; - num = 0; + num = 0; for (TWtringBuf elem : StringSplitter(u"привет, как дела").Split(wchar16(' '))) { - UNIT_ASSERT_VALUES_EQUAL(elem, actual2[num++]); - } - - TVector<TString> copy(4); - auto v = StringSplitter("11 22 33 44").Split(' '); - Copy(v.begin(), v.end(), copy.begin()); - UNIT_ASSERT_VALUES_EQUAL(actual0, copy); - } - - Y_UNIT_TEST(TestParseInto) { + UNIT_ASSERT_VALUES_EQUAL(elem, actual2[num++]); + } + + TVector<TString> copy(4); + auto v = StringSplitter("11 22 33 44").Split(' '); + Copy(v.begin(), v.end(), copy.begin()); + UNIT_ASSERT_VALUES_EQUAL(actual0, copy); + } + + Y_UNIT_TEST(TestParseInto) { TVector<int> actual0 = {1, 2, 3, 4}; - TVector<int> answer0; - - StringSplitter("1 2 3 4").Split(' ').ParseInto(&answer0); - UNIT_ASSERT_VALUES_EQUAL(actual0, answer0); - + TVector<int> answer0; + + StringSplitter("1 2 3 4").Split(' ').ParseInto(&answer0); + UNIT_ASSERT_VALUES_EQUAL(actual0, answer0); + TVector<int> actual1 = {42, 1, 2, 3, 4}; TVector<int> answer1 = {42}; - StringSplitter("1 2 3 4").Split(' ').ParseInto(&answer1); - UNIT_ASSERT_VALUES_EQUAL(actual1, answer1); - - answer1.clear(); - UNIT_ASSERT_EXCEPTION(StringSplitter("1 2 3 4").Split(' ').ParseInto(&answer1), yexception); - + StringSplitter("1 2 3 4").Split(' ').ParseInto(&answer1); + UNIT_ASSERT_VALUES_EQUAL(actual1, answer1); + + answer1.clear(); + UNIT_ASSERT_EXCEPTION(StringSplitter("1 2 3 4").Split(' ').ParseInto(&answer1), yexception); + answer1 = {42}; - StringSplitter(" 1 2 3 4").Split(' ').SkipEmpty().ParseInto(&answer1); - UNIT_ASSERT_VALUES_EQUAL(actual1, answer1); - - answer1.clear(); - StringSplitter(" \n 1 2 \n\n\n 3 4\n ").SplitBySet(" \n").SkipEmpty().ParseInto(&answer1); - UNIT_ASSERT_VALUES_EQUAL(actual0, answer1); - } - - Y_UNIT_TEST(TestStdString) { - std::vector<std::string_view> r0, r1, answer = {"lol", "zomg"}; - std::string s = "lol zomg"; - for (std::string_view ss : StringSplitter(s).Split(' ')) { - r0.push_back(ss); - } - StringSplitter(s).Split(' ').Collect(&r1); - - UNIT_ASSERT_VALUES_EQUAL(r0, answer); - UNIT_ASSERT_VALUES_EQUAL(r1, answer); - } - - Y_UNIT_TEST(TestStdStringView) { - std::string_view s = "aaacccbbb"; - std::vector<std::string_view> expected = {"aaa", "bbb"}; - std::vector<std::string_view> actual = StringSplitter(s).SplitByString("ccc"); - UNIT_ASSERT_VALUES_EQUAL(expected, actual); - } - - Y_UNIT_TEST(TestStdSplitAfterSplit) { - std::string_view input = "a*b+a*b"; + StringSplitter(" 1 2 3 4").Split(' ').SkipEmpty().ParseInto(&answer1); + UNIT_ASSERT_VALUES_EQUAL(actual1, answer1); + + answer1.clear(); + StringSplitter(" \n 1 2 \n\n\n 3 4\n ").SplitBySet(" \n").SkipEmpty().ParseInto(&answer1); + UNIT_ASSERT_VALUES_EQUAL(actual0, answer1); + } + + Y_UNIT_TEST(TestStdString) { + std::vector<std::string_view> r0, r1, answer = {"lol", "zomg"}; + std::string s = "lol zomg"; + for (std::string_view ss : StringSplitter(s).Split(' ')) { + r0.push_back(ss); + } + StringSplitter(s).Split(' ').Collect(&r1); + + UNIT_ASSERT_VALUES_EQUAL(r0, answer); + UNIT_ASSERT_VALUES_EQUAL(r1, answer); + } + + Y_UNIT_TEST(TestStdStringView) { + std::string_view s = "aaacccbbb"; + std::vector<std::string_view> expected = {"aaa", "bbb"}; + std::vector<std::string_view> actual = StringSplitter(s).SplitByString("ccc"); + UNIT_ASSERT_VALUES_EQUAL(expected, actual); + } + + Y_UNIT_TEST(TestStdSplitAfterSplit) { + std::string_view input = "a*b+a*b"; for (std::string_view summand : StringSplitter(input).Split('+')) { - //FIXME: std::string is used to workaround MSVC ICE - UNIT_ASSERT_VALUES_EQUAL(std::string(summand), "a*b"); - std::string_view multiplier1, multiplier2; - bool splitResult = StringSplitter(summand).Split('*').TryCollectInto(&multiplier1, &multiplier2); - UNIT_ASSERT(splitResult); - UNIT_ASSERT_VALUES_EQUAL(std::string(multiplier1), "a"); - UNIT_ASSERT_VALUES_EQUAL(std::string(multiplier2), "b"); - } - } - - Y_UNIT_TEST(TestStdSplitWithParsing) { - std::string_view input = "1,2,3,4"; - TVector<ui64> numbers; - const TVector<ui64> expected{1, 2, 3, 4}; - StringSplitter(input).Split(',').ParseInto(&numbers); - UNIT_ASSERT_VALUES_EQUAL(numbers, expected); - } - - Y_UNIT_TEST(TestArcadiaStdInterop) { + //FIXME: std::string is used to workaround MSVC ICE + UNIT_ASSERT_VALUES_EQUAL(std::string(summand), "a*b"); + std::string_view multiplier1, multiplier2; + bool splitResult = StringSplitter(summand).Split('*').TryCollectInto(&multiplier1, &multiplier2); + UNIT_ASSERT(splitResult); + UNIT_ASSERT_VALUES_EQUAL(std::string(multiplier1), "a"); + UNIT_ASSERT_VALUES_EQUAL(std::string(multiplier2), "b"); + } + } + + Y_UNIT_TEST(TestStdSplitWithParsing) { + std::string_view input = "1,2,3,4"; + TVector<ui64> numbers; + const TVector<ui64> expected{1, 2, 3, 4}; + StringSplitter(input).Split(',').ParseInto(&numbers); + UNIT_ASSERT_VALUES_EQUAL(numbers, expected); + } + + Y_UNIT_TEST(TestArcadiaStdInterop) { TVector<TString> expected0 = {"a", "b"}; TVector<TStringBuf> expected1 = {"a", "b"}; - std::string src1("a b"); - std::string_view src2("a b"); - TVector<TString> actual0 = StringSplitter(src1).Split(' ').SkipEmpty(); - TVector<TString> actual1 = StringSplitter(src2).Split(' ').SkipEmpty(); - TVector<TStringBuf> actual2 = StringSplitter(src1).Split(' ').SkipEmpty(); - TVector<TStringBuf> actual3 = StringSplitter(src2).Split(' ').SkipEmpty(); - UNIT_ASSERT_VALUES_EQUAL(expected0, actual0); - UNIT_ASSERT_VALUES_EQUAL(expected0, actual1); - UNIT_ASSERT_VALUES_EQUAL(expected1, actual2); - UNIT_ASSERT_VALUES_EQUAL(expected1, actual3); - } - - Y_UNIT_TEST(TestConstCString) { - const char* b = "a;b"; - const char* e = b + 3; - - std::vector<TStringBuf> v; - StringSplitter(b, e).Split(';').AddTo(&v); - + std::string src1("a b"); + std::string_view src2("a b"); + TVector<TString> actual0 = StringSplitter(src1).Split(' ').SkipEmpty(); + TVector<TString> actual1 = StringSplitter(src2).Split(' ').SkipEmpty(); + TVector<TStringBuf> actual2 = StringSplitter(src1).Split(' ').SkipEmpty(); + TVector<TStringBuf> actual3 = StringSplitter(src2).Split(' ').SkipEmpty(); + UNIT_ASSERT_VALUES_EQUAL(expected0, actual0); + UNIT_ASSERT_VALUES_EQUAL(expected0, actual1); + UNIT_ASSERT_VALUES_EQUAL(expected1, actual2); + UNIT_ASSERT_VALUES_EQUAL(expected1, actual3); + } + + Y_UNIT_TEST(TestConstCString) { + const char* b = "a;b"; + const char* e = b + 3; + + std::vector<TStringBuf> v; + StringSplitter(b, e).Split(';').AddTo(&v); + std::vector<TStringBuf> expected = {"a", "b"}; - UNIT_ASSERT_VALUES_EQUAL(v, expected); - } - - Y_UNIT_TEST(TestCStringRef) { - TString s = "lol"; - char* str = s.Detach(); - - std::vector<TStringBuf> v = StringSplitter(str).Split('o'); + UNIT_ASSERT_VALUES_EQUAL(v, expected); + } + + Y_UNIT_TEST(TestCStringRef) { + TString s = "lol"; + char* str = s.Detach(); + + std::vector<TStringBuf> v = StringSplitter(str).Split('o'); std::vector<TStringBuf> expected = {"l", "l"}; - UNIT_ASSERT_VALUES_EQUAL(v, expected); - } - - Y_UNIT_TEST(TestSplitVector) { + UNIT_ASSERT_VALUES_EQUAL(v, expected); + } + + Y_UNIT_TEST(TestSplitVector) { std::vector<char> buffer = {'a', ';', 'b'}; - - std::vector<TStringBuf> v = StringSplitter(buffer).Split(';'); - + + std::vector<TStringBuf> v = StringSplitter(buffer).Split(';'); + std::vector<TStringBuf> expected = {"a", "b"}; - UNIT_ASSERT_VALUES_EQUAL(v, expected); - } - - class TDoubleIterator { - public: - using iterator_category = std::input_iterator_tag; - using value_type = int; - using pointer = void; - using reference = int; - using const_reference = int; - using difference_type = ptrdiff_t; - - TDoubleIterator() = default; - + UNIT_ASSERT_VALUES_EQUAL(v, expected); + } + + class TDoubleIterator { + public: + using iterator_category = std::input_iterator_tag; + using value_type = int; + using pointer = void; + using reference = int; + using const_reference = int; + using difference_type = ptrdiff_t; + + TDoubleIterator() = default; + TDoubleIterator(const char* ptr) : Ptr_(ptr) { } - - TDoubleIterator operator++() { - Ptr_ += 2; - return *this; - } - - TDoubleIterator operator++(int) { - TDoubleIterator tmp = *this; - ++*this; - return tmp; - } - - friend bool operator==(TDoubleIterator l, TDoubleIterator r) { - return l.Ptr_ == r.Ptr_; - } - - friend bool operator!=(TDoubleIterator l, TDoubleIterator r) { - return l.Ptr_ != r.Ptr_; - } - - int operator*() const { - return (*Ptr_ - '0') * 10 + *(Ptr_ + 1) - '0'; - } - - private: - const char* Ptr_ = nullptr; - }; - - Y_UNIT_TEST(TestInputIterator) { - const char* beg = "1213002233000011"; - const char* end = beg + strlen(beg); - + + TDoubleIterator operator++() { + Ptr_ += 2; + return *this; + } + + TDoubleIterator operator++(int) { + TDoubleIterator tmp = *this; + ++*this; + return tmp; + } + + friend bool operator==(TDoubleIterator l, TDoubleIterator r) { + return l.Ptr_ == r.Ptr_; + } + + friend bool operator!=(TDoubleIterator l, TDoubleIterator r) { + return l.Ptr_ != r.Ptr_; + } + + int operator*() const { + return (*Ptr_ - '0') * 10 + *(Ptr_ + 1) - '0'; + } + + private: + const char* Ptr_ = nullptr; + }; + + Y_UNIT_TEST(TestInputIterator) { + const char* beg = "1213002233000011"; + const char* end = beg + strlen(beg); + std::vector<std::vector<int>> expected = {{12, 13}, {22, 33}, {}, {11}}; - int i = 0; - - for (TIteratorRange<TDoubleIterator> part : StringSplitter(TDoubleIterator(beg), TDoubleIterator(end)).SplitByFunc([](int value) { return value == 0; })) { - UNIT_ASSERT(std::equal(part.begin(), part.end(), expected[i].begin(), expected[i].end())); - i++; - } - UNIT_ASSERT_VALUES_EQUAL(i, expected.size()); - } -} + int i = 0; + + for (TIteratorRange<TDoubleIterator> part : StringSplitter(TDoubleIterator(beg), TDoubleIterator(end)).SplitByFunc([](int value) { return value == 0; })) { + UNIT_ASSERT(std::equal(part.begin(), part.end(), expected[i].begin(), expected[i].end())); + i++; + } + UNIT_ASSERT_VALUES_EQUAL(i, expected.size()); + } +} diff --git a/util/string/strip.cpp b/util/string/strip.cpp index f53b9ee896..c921571cf0 100644 --- a/util/string/strip.cpp +++ b/util/string/strip.cpp @@ -10,7 +10,7 @@ bool Collapse(const TString& from, TString& to, size_t maxLen) { void CollapseText(const TString& from, TString& to, size_t maxLen) { Collapse(from, to, maxLen); StripInPlace(to); - if (to.size() >= maxLen) { + if (to.size() >= maxLen) { to.remove(maxLen - 5); // " ..." ReverseInPlace(to); size_t pos = to.find_first_of(" .,;"); diff --git a/util/string/strip.h b/util/string/strip.h index 0769ed5afe..d5ef6da96d 100644 --- a/util/string/strip.h +++ b/util/string/strip.h @@ -218,7 +218,7 @@ size_t CollapseImpl(TChar* s, size_t n, const TWhitespaceFunc& isWhitespace) { template <class TStringType, class TWhitespaceFunc> bool CollapseImpl(const TStringType& from, TStringType& to, size_t maxLen, const TWhitespaceFunc& isWhitespace) { to = from; - maxLen = maxLen ? Min(maxLen, to.size()) : to.size(); + maxLen = maxLen ? Min(maxLen, to.size()) : to.size(); for (size_t i = 0; i < maxLen; ++i) { if (isWhitespace(to[i]) && (to[i] != ' ' || isWhitespace(to[i + 1]))) { size_t tailSize = maxLen - i; diff --git a/util/string/subst.cpp b/util/string/subst.cpp index d86f939e25..b2df328dc1 100644 --- a/util/string/subst.cpp +++ b/util/string/subst.cpp @@ -67,7 +67,7 @@ static inline size_t SubstGlobalImpl(TStringType& s, const TStringViewType from, result.reserve(s.size() + s.size() / 3); } result.append(s.begin() + srcPos, s.begin() + off); - result.append(to.data(), to.size()); + result.append(to.data(), to.size()); srcPos = off + fromSize; ++replacementsCount; } diff --git a/util/string/subst_ut.cpp b/util/string/subst_ut.cpp index a4db704938..21eccef779 100644 --- a/util/string/subst_ut.cpp +++ b/util/string/subst_ut.cpp @@ -26,7 +26,7 @@ Y_UNIT_TEST_SUITE(TStringSubst) { Y_UNIT_TEST(TestSubstGlobalNoSubstA) { for (const auto& from : ALL_FROM) { - const size_t fromSz = from.size(); + const size_t fromSz = from.size(); const size_t minSz = fromSz; const size_t maxSz = fromSz + MIN_FROM_CTX; for (size_t sz = minSz; sz <= maxSz; ++sz) { @@ -42,7 +42,7 @@ Y_UNIT_TEST_SUITE(TStringSubst) { Y_UNIT_TEST(TestSubstGlobalNoSubstB) { for (const auto& from : ALL_FROM) { - const size_t fromSz = from.size(); + const size_t fromSz = from.size(); const size_t minSz = fromSz; const size_t maxSz = fromSz + MIN_FROM_CTX; for (size_t sz = minSz; sz <= maxSz; ++sz) { @@ -64,7 +64,7 @@ Y_UNIT_TEST_SUITE(TStringSubst) { static void DoTestSubstGlobal(TVector<TString>& parts, const size_t minBeg, const size_t sz, const TString& from, const size_t fromPos, const size_t numSubst) { const size_t numLeft = numSubst - parts.size(); - for (size_t fromBeg = minBeg; fromBeg <= sz - numLeft * from.size(); ++fromBeg) { + for (size_t fromBeg = minBeg; fromBeg <= sz - numLeft * from.size(); ++fromBeg) { if (parts.empty()) { parts.emplace_back(fromBeg, '.'); } else { @@ -72,16 +72,16 @@ Y_UNIT_TEST_SUITE(TStringSubst) { } if (numLeft == 1) { - parts.emplace_back(sz - fromBeg - from.size(), '.'); + parts.emplace_back(sz - fromBeg - from.size(), '.'); TString sFrom = JoinSeq(from, parts); - UNIT_ASSERT_VALUES_EQUAL_C(sFrom.size(), sz, sFrom); + UNIT_ASSERT_VALUES_EQUAL_C(sFrom.size(), sz, sFrom); for (const auto& to : ALL_TO) { TString sTo = JoinSeq(to, parts); AssertSubstGlobal(sFrom, sTo, from, to, fromPos, numSubst); } parts.pop_back(); } else { - DoTestSubstGlobal(parts, fromBeg + from.size(), sz, from, fromPos, numSubst); + DoTestSubstGlobal(parts, fromBeg + from.size(), sz, from, fromPos, numSubst); } parts.pop_back(); @@ -91,7 +91,7 @@ Y_UNIT_TEST_SUITE(TStringSubst) { static void DoTestSubstGlobal(size_t numSubst) { TVector<TString> parts; for (const auto& from : ALL_FROM) { - const size_t fromSz = from.size(); + const size_t fromSz = from.size(); const size_t minSz = numSubst * fromSz; const size_t maxSz = numSubst * (fromSz + MIN_FROM_CTX); for (size_t sz = minSz; sz <= maxSz; ++sz) { diff --git a/util/string/type.h b/util/string/type.h index ff6767415f..d6cb29ea58 100644 --- a/util/string/type.h +++ b/util/string/type.h @@ -6,7 +6,7 @@ Y_PURE_FUNCTION bool IsSpace(const char* s, size_t len) noexcept; /// Checks if a string is a set of only space symbols. Y_PURE_FUNCTION static inline bool IsSpace(const TStringBuf s) noexcept { - return IsSpace(s.data(), s.size()); + return IsSpace(s.data(), s.size()); } /// Returns "true" if the given string is an arabic number ([0-9]+) diff --git a/util/string/vector.cpp b/util/string/vector.cpp index 3e78fce9c4..9ba401f0a2 100644 --- a/util/string/vector.cpp +++ b/util/string/vector.cpp @@ -11,12 +11,12 @@ static inline void DoSplit2(TConsumer& c, TDelim& d, const TBasicStringBuf<TChr> template <class TConsumer, class TDelim, typename TChr> static inline void DoSplit1(TConsumer& cc, TDelim& d, const TBasicStringBuf<TChr> str, int opts) { - if (opts & KEEP_EMPTY_TOKENS) { + if (opts & KEEP_EMPTY_TOKENS) { DoSplit2(cc, d, str, opts); } else { TSkipEmptyTokens<TConsumer> sc(&cc); - DoSplit2(sc, d, str, opts); + DoSplit2(sc, d, str, opts); } } @@ -84,8 +84,8 @@ TUtf16String JoinStrings(const TVector<TUtf16String>& v, const TWtringBuf delim) } TUtf16String JoinStrings(const TVector<TUtf16String>& v, size_t index, size_t count, const TWtringBuf delim) { - const size_t f = Min(index, v.size()); - const size_t l = f + Min(count, v.size() - f); + const size_t f = Min(index, v.size()); + const size_t l = f + Min(count, v.size() - f); return JoinStrings(v.begin() + f, v.begin() + l, delim); } diff --git a/util/string/vector.h b/util/string/vector.h index 78e01efa08..e36c348bbe 100644 --- a/util/string/vector.h +++ b/util/string/vector.h @@ -1,7 +1,7 @@ #pragma once #include "cast.h" -#include "split.h" +#include "split.h" #include <util/generic/map.h> #include <util/generic/strbuf.h> @@ -13,7 +13,7 @@ #define KEEP_EMPTY_TOKENS 0x01 // -// NOTE: Check StringSplitter below to get more convenient split string interface. +// NOTE: Check StringSplitter below to get more convenient split string interface. namespace NPrivate { @@ -46,7 +46,7 @@ TVector<typename ::NPrivate::TStringDeducer<C>::type> SplitString(const C* ptr, const C* delimiter, size_t maxFields = 0, int options = 0) { TVector<typename ::NPrivate::TStringDeducer<C>::type> res; - ::NPrivate::SplitStringImpl(&res, ptr, delimiter, maxFields, options); + ::NPrivate::SplitStringImpl(&res, ptr, delimiter, maxFields, options); return res; } @@ -55,7 +55,7 @@ TVector<typename ::NPrivate::TStringDeducer<C>::type> SplitString(const C* ptr, size_t len, const C* delimiter, size_t maxFields = 0, int options = 0) { TVector<typename ::NPrivate::TStringDeducer<C>::type> res; - ::NPrivate::SplitStringImpl(&res, ptr, len, delimiter, maxFields, options); + ::NPrivate::SplitStringImpl(&res, ptr, len, delimiter, maxFields, options); return res; } @@ -63,7 +63,7 @@ template <typename C> TVector<typename ::NPrivate::TStringDeducer<C>::type> SplitString(const typename ::NPrivate::TStringDeducer<C>::type& str, const C* delimiter, size_t maxFields = 0, int options = 0) { - return SplitString(str.data(), str.size(), delimiter, maxFields, options); + return SplitString(str.data(), str.size(), delimiter, maxFields, options); } template <class TIter> |