diff options
author | Anton Samokhvalov <pg83@yandex.ru> | 2022-02-10 16:45:17 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:17 +0300 |
commit | d3a398281c6fd1d3672036cb2d63f842d2cb28c5 (patch) | |
tree | dd4bd3ca0f36b817e96812825ffaf10d645803f2 /util/string/split.h | |
parent | 72cb13b4aff9bc9cf22e49251bc8fd143f82538f (diff) | |
download | ydb-d3a398281c6fd1d3672036cb2d63f842d2cb28c5.tar.gz |
Restoring authorship annotation for Anton Samokhvalov <pg83@yandex.ru>. Commit 2 of 2.
Diffstat (limited to 'util/string/split.h')
-rw-r--r-- | util/string/split.h | 454 |
1 files changed, 227 insertions, 227 deletions
diff --git a/util/string/split.h b/util/string/split.h index e568cab618..bc46d9e64c 100644 --- a/util/string/split.h +++ b/util/string/split.h @@ -1,8 +1,8 @@ #pragma once - -#include "strspn.h" + +#include "strspn.h" #include "cast.h" - + #include <util/generic/algorithm.h> #include <util/generic/fwd.h> #include <util/generic/iterator.h> @@ -15,7 +15,7 @@ #include <util/generic/ylimits.h> #include <util/system/compat.h> #include <util/system/defaults.h> - + #include <utility> #include <stlfwd> @@ -24,7 +24,7 @@ namespace NStringSplitPrivate { template <class T, class I, class = void> - struct TIsConsumer: std::false_type {}; + struct TIsConsumer: std::false_type {}; template <class T, class I> struct TIsConsumer< @@ -49,44 +49,44 @@ namespace NStringSplitPrivate { } -template <class I, class TDelim, class TConsumer> +template <class I, class TDelim, class TConsumer> std::enable_if_t<::NStringSplitPrivate::TIsConsumerV<TConsumer, I>> SplitString(I b, I e, const TDelim& d, TConsumer&& c) { - I l, i; - - do { - l = b; - i = d.Find(b, e); - } while (c.Consume(l, i, b) && (b != i)); -} - -template <class I, class TDelim, class TConsumer> + I l, i; + + do { + l = b; + i = d.Find(b, e); + } while (c.Consume(l, i, b) && (b != i)); +} + +template <class I, class TDelim, class TConsumer> std::enable_if_t<::NStringSplitPrivate::TIsConsumerV<TConsumer, I>> SplitString(I b, const TDelim& d, TConsumer&& c) { - I l, i; - - do { - l = b; - i = d.Find(b); - } while (c.Consume(l, i, b) && (b != i)); -} - + I l, i; + + do { + l = b; + i = d.Find(b); + } while (c.Consume(l, i, b) && (b != i)); +} + template <class I1, class I2> static inline I1* FastStrChr(I1* str, I2 f) noexcept { I1* ret = NStringSplitPrivate::Find(str, f); - - if (!ret) { + + if (!ret) { ret = str + std::char_traits<I1>::length(str); - } - - return ret; -} - -template <class I> + } + + return ret; +} + +template <class I> static inline I* FastStrStr(I* str, I* f, size_t l) noexcept { std::basic_string_view<I> strView(str); const auto ret = strView.find(*f); - + if (ret != std::string::npos) { std::basic_string_view<I> fView(f, l); strView = strView.substr(ret); @@ -95,89 +95,89 @@ static inline I* FastStrStr(I* str, I* f, size_t l) noexcept { break; } } - + return strView.size() >= l ? strView.data() : strView.data() + strView.size(); } else { return strView.data() + strView.size(); - } -} - + } +} + template <class Char> -struct TStringDelimiter { +struct TStringDelimiter { inline TStringDelimiter(Char* delim) noexcept - : Delim(delim) + : Delim(delim) , Len(std::char_traits<Char>::length(delim)) - { - } - + { + } + inline TStringDelimiter(Char* delim, size_t len) noexcept - : Delim(delim) - , Len(len) - { + : Delim(delim) + , Len(len) + { } inline Char* Find(Char*& b, Char* e) const noexcept { const auto ret = std::basic_string_view<Char>(b, e - b).find(Delim, 0, Len); - + if (ret != std::string::npos) { const auto result = b + ret; b = result + Len; return result; - } - - return (b = e); - } - + } + + return (b = e); + } + inline Char* Find(Char*& b) const noexcept { Char* ret = FastStrStr(b, Delim, Len); - + b = *ret ? ret + Len : ret; - - return ret; - } - + + return ret; + } + Char* Delim; - const size_t Len; -}; - + const size_t Len; +}; + template <class Char> -struct TCharDelimiter { +struct TCharDelimiter { inline TCharDelimiter(Char ch) noexcept - : Ch(ch) - { - } - + : Ch(ch) + { + } + inline Char* Find(Char*& b, Char* e) const noexcept { const auto ret = std::basic_string_view<Char>(b, e - b).find(Ch); - + if (ret != std::string::npos) { const auto result = b + ret; b = result + 1; return result; - } - - return (b = e); - } - + } + + return (b = e); + } + inline Char* Find(Char*& b) const noexcept { Char* ret = FastStrChr(b, Ch); - - if (*ret) { - b = ret + 1; - } else { - b = ret; - } - - return ret; - } - + + if (*ret) { + b = ret + 1; + } else { + b = ret; + } + + return ret; + } + Char Ch; -}; - +}; + template <class Iterator, class Condition> struct TFuncDelimiter { public: - template <class... Args> + template <class... Args> TFuncDelimiter(Args&&... args) : Fn(std::forward<Args>(args)...) { @@ -196,7 +196,7 @@ private: }; template <class Char> -struct TFindFirstOf { +struct TFindFirstOf { inline TFindFirstOf(Char* set) : Set(set) { @@ -221,17 +221,17 @@ struct TFindFirstOf { }; template <> -struct TFindFirstOf<const char>: public TCompactStrSpn { +struct TFindFirstOf<const char>: public TCompactStrSpn { inline TFindFirstOf(const char* set, const char* e) : TCompactStrSpn(set, e) { } - inline TFindFirstOf(const char* set) - : TCompactStrSpn(set) + inline TFindFirstOf(const char* set) + : TCompactStrSpn(set) { } -}; +}; template <class Char> struct TSetDelimiter: private TFindFirstOf<const Char> { @@ -239,7 +239,7 @@ struct TSetDelimiter: private TFindFirstOf<const Char> { inline Char* Find(Char*& b, Char* e) const noexcept { Char* ret = const_cast<Char*>(this->FindFirstOf(b, e)); - + if (ret != e) { b = ret + 1; return ret; @@ -267,37 +267,37 @@ namespace NSplitTargetHasPushBack { template <class T, class = void> struct TConsumerBackInserter; -template <class T> +template <class T> struct TConsumerBackInserter<T, std::enable_if_t<NSplitTargetHasPushBack::TClassHasPushBack<T>::value>> { - static void DoInsert(T* C, const typename T::value_type& i) { + static void DoInsert(T* C, const typename T::value_type& i) { C->push_back(i); } }; template <class T> struct TConsumerBackInserter<T, std::enable_if_t<!NSplitTargetHasPushBack::TClassHasPushBack<T>::value>> { - static void DoInsert(T* C, const typename T::value_type& i) { + static void DoInsert(T* C, const typename T::value_type& i) { C->insert(C->end(), i); } }; template <class T> -struct TContainerConsumer { +struct TContainerConsumer { inline TContainerConsumer(T* c) noexcept - : C(c) - { - } - - template <class I> - inline bool Consume(I* b, I* d, I* /*e*/) { + : C(c) + { + } + + template <class I> + inline bool Consume(I* b, I* d, I* /*e*/) { TConsumerBackInserter<T>::DoInsert(C, typename T::value_type(b, d)); - - return true; - } - - T* C; -}; - + + return true; + } + + T* C; +}; + template <class T> struct TContainerConvertingConsumer { inline TContainerConvertingConsumer(T* c) noexcept @@ -315,98 +315,98 @@ struct TContainerConvertingConsumer { T* C; }; -template <class S, class I> -struct TLimitingConsumer { +template <class S, class I> +struct TLimitingConsumer { inline TLimitingConsumer(size_t cnt, S* slave) noexcept - : Cnt(cnt ? cnt - 1 : Max<size_t>()) - , Slave(slave) - , Last(nullptr) - { - } - - inline bool Consume(I* b, I* d, I* e) { - if (!Cnt) { - Last = b; - - return false; - } - - --Cnt; - - return Slave->Consume(b, d, e); - } - - size_t Cnt; - S* Slave; - I* Last; -}; - -template <class S> -struct TSkipEmptyTokens { + : Cnt(cnt ? cnt - 1 : Max<size_t>()) + , Slave(slave) + , Last(nullptr) + { + } + + inline bool Consume(I* b, I* d, I* e) { + if (!Cnt) { + Last = b; + + return false; + } + + --Cnt; + + return Slave->Consume(b, d, e); + } + + size_t Cnt; + S* Slave; + I* Last; +}; + +template <class S> +struct TSkipEmptyTokens { inline TSkipEmptyTokens(S* slave) noexcept - : Slave(slave) - { - } - - template <class I> - inline bool Consume(I* b, I* d, I* e) { - if (b != d) { - return Slave->Consume(b, d, e); - } - - return true; - } - - S* Slave; -}; - -template <class S> -struct TKeepDelimiters { + : Slave(slave) + { + } + + template <class I> + inline bool Consume(I* b, I* d, I* e) { + if (b != d) { + return Slave->Consume(b, d, e); + } + + return true; + } + + S* Slave; +}; + +template <class S> +struct TKeepDelimiters { inline TKeepDelimiters(S* slave) noexcept - : Slave(slave) - { - } - - template <class I> - inline bool Consume(I* b, I* d, I* e) { - if (Slave->Consume(b, d, d)) { - if (d != e) { - return Slave->Consume(d, e, e); - } - - return true; - } - - return false; - } - - S* Slave; -}; - -template <class T> -struct TSimplePusher { - inline bool Consume(char* b, char* d, char*) { - *d = 0; - C->push_back(b); - - return true; - } - - T* C; -}; - -template <class T> + : Slave(slave) + { + } + + template <class I> + inline bool Consume(I* b, I* d, I* e) { + if (Slave->Consume(b, d, d)) { + if (d != e) { + return Slave->Consume(d, e, e); + } + + return true; + } + + return false; + } + + S* Slave; +}; + +template <class T> +struct TSimplePusher { + inline bool Consume(char* b, char* d, char*) { + *d = 0; + C->push_back(b); + + return true; + } + + T* C; +}; + +template <class T> static inline void Split(char* buf, char ch, T* res) { - res->resize(0); + res->resize(0); if (*buf == 0) return; TCharDelimiter<char> delim(ch); - TSimplePusher<T> pusher = {res}; - + TSimplePusher<T> pusher = {res}; + SplitString(buf, delim, pusher); -} - +} + /// Split string into res vector. Res vector is cleared before split. /// Old good slow split function. /// Field delimter is any number of symbols specified in delim (no empty strings in res vector) @@ -424,7 +424,7 @@ inline size_t Split(const TStringBuf s, const TSetDelimiter<const char>& delim, return res.size(); } -template <class P, class D> +template <class P, class D> void GetNext(TStringBuf& s, D delim, P& param) { TStringBuf next = s.NextTok(delim); Y_ENSURE(next.IsInited(), TStringBuf("Split: number of fields less than number of Split output arguments")); @@ -443,14 +443,14 @@ void GetNext(TStringBuf& s, D delim, TMaybe<P>& param) { // example: // Split(TStringBuf("Sherlock,2014,36.6"), ',', name, year, temperature); -template <class D, class P1, class P2> +template <class D, class P1, class P2> void Split(TStringBuf s, D delim, P1& p1, P2& p2) { GetNext(s, delim, p1); GetNext(s, delim, p2); Y_ENSURE(!s.IsInited(), TStringBuf("Split: number of fields more than number of Split output arguments")); } -template <class D, class P1, class P2, class... Other> +template <class D, class P1, class P2, class... Other> void Split(TStringBuf s, D delim, P1& p1, P2& p2, Other&... other) { GetNext(s, delim, p1); Split(s, delim, p2, other...); @@ -498,12 +498,12 @@ namespace NStringSplitPrivate { * This one is needed here so that `std::string_view -> std::string_view` * conversion works. */ - template <class Src, class Dst> + template <class Src, class Dst> inline void DoFromString(const Src& src, Dst* dst) { *dst = ::FromString<Dst>(src); } - template <class T> + template <class T> inline void DoFromString(const T& src, T* dst) noexcept { *dst = src; } @@ -513,12 +513,12 @@ namespace NStringSplitPrivate { *dst = src; } - template <class Src, class Dst> + template <class Src, class Dst> inline Y_WARN_UNUSED_RESULT bool TryDoFromString(const Src& src, Dst* dst) noexcept { return ::TryFromString(src, *dst); } - template <class T> + template <class T> inline Y_WARN_UNUSED_RESULT bool TryDoFromString(const T& src, T* dst) noexcept { *dst = src; return true; @@ -544,18 +544,18 @@ namespace NStringSplitPrivate { } // TODO: return bool (continue) - template <class StringBuf> + template <class StringBuf> void operator()(StringBuf e) const { this->operator()(C_, e); } private: - template <class OtherContainer, class StringBuf> + template <class OtherContainer, class StringBuf> auto operator()(OtherContainer* c, StringBuf e) const -> decltype(c->emplace_back()) { return c->emplace_back(value_type(e)); } - template <class OtherContainer, class StringBuf> + template <class OtherContainer, class StringBuf> auto operator()(OtherContainer* c, StringBuf e) const -> decltype(c->emplace()) { return c->emplace(value_type(e)); } @@ -582,14 +582,14 @@ namespace NStringSplitPrivate { } private: - template <class OtherContainer, class StringBuf> + 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)); } - template <class OtherContainer, class StringBuf> + template <class OtherContainer, class StringBuf> auto operator()(OtherContainer* c, StringBuf e) const -> decltype(c->emplace()) { value_type v; DoFromString(e, &v); @@ -604,7 +604,7 @@ namespace NStringSplitPrivate { using type = std::conditional_t< THasData<String>::value, TBasicStringBuf<typename String::value_type>, - TIteratorRange<typename String::const_iterator>>; + TIteratorRange<typename String::const_iterator>>; }; template <class Char, class Traits, class Allocator> @@ -621,36 +621,36 @@ namespace NStringSplitPrivate { * 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> + template <class String> using TStringBufOf = typename TStringBufOfImpl<String>::type; - template <class StringBuf, class Iterator> + template <class StringBuf, class Iterator> StringBuf DoMakeStringBuf(Iterator b, Iterator e, StringBuf*) { return StringBuf(b, e); } - template <class Char, class Traits, class Iterator> + 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); } - template <class StringBuf, class Iterator> + template <class StringBuf, class Iterator> StringBuf MakeStringBuf(Iterator b, Iterator e) { return DoMakeStringBuf(b, e, static_cast<StringBuf*>(nullptr)); } - template <class String> + template <class String> struct TIteratorOfImpl { using type = std::conditional_t< THasData<String>::value, const typename String::value_type*, - typename String::const_iterator>; + typename String::const_iterator>; }; - template <class String> + template <class String> using TIteratorOf = typename TIteratorOfImpl<String>::type; - template <class String> + template <class String> class TStringSplitter; template <class String> @@ -667,7 +667,7 @@ namespace NStringSplitPrivate { { } - template < + template < typename Other, typename = std::enable_if_t< std::is_convertible<Other, TStringBufType>::value>> @@ -706,7 +706,7 @@ namespace NStringSplitPrivate { }; template <class Base> - class TSplitRange: public Base, public TInputRangeAdaptor<TSplitRange<Base>> { + class TSplitRange: public Base, public TInputRangeAdaptor<TSplitRange<Base>> { using TStringBufType = decltype(std::declval<Base>().Next()->Token()); public: @@ -733,7 +733,7 @@ namespace NStringSplitPrivate { return true; } - template <class Container, class = std::enable_if_t<THasInsert<Container>::value || THasPushBack<Container>::value>> + template <class Container, class = std::enable_if_t<THasInsert<Container>::value || THasPushBack<Container>::value>> operator Container() { Container result; AddTo(&result); @@ -790,7 +790,7 @@ namespace NStringSplitPrivate { } ++it; } - }, args...); + }, args...); return successfullyFilled == sizeof...(args) && it == this->end(); } @@ -864,7 +864,7 @@ namespace NStringSplitPrivate { }; template <class Base, class Filter> - struct TFilterRange: public Base { + struct TFilterRange: public Base { template <class... Args> inline TFilterRange(const Base& base, Args&&... args) : Base(base) @@ -896,7 +896,7 @@ namespace NStringSplitPrivate { struct TStopIteration; template <class Base> - struct TFilters: public Base { + struct TFilters: public Base { template <class TFilter> using TIt = TSplitRange<TStopIteration<TFilters<TFilterRange<Base, TFilter>>>>; @@ -907,12 +907,12 @@ namespace NStringSplitPrivate { } inline TIt<TNonEmptyFilter> SkipEmpty() const { - return {*this}; + return {*this}; } }; template <class Base, class Stopper> - struct TStopRange: public Base { + struct TStopRange: public Base { template <typename... Args> inline TStopRange(const Base& base, Args&&... args) : Base(base) @@ -978,7 +978,7 @@ namespace NStringSplitPrivate { }; template <class Base> - struct TStopIteration: public Base { + struct TStopIteration: public Base { template <class TStopper> using TIt = TSplitRange<TStopIteration<TFilters<TStopRange<Base, TStopper>>>>; @@ -989,11 +989,11 @@ namespace NStringSplitPrivate { } inline TIt<TTake> Take(size_t count) { - return {*this, count}; + return {*this, count}; } inline TIt<TLimit> Limit(size_t count) { - return {*this, count}; + return {*this, count}; } }; @@ -1001,7 +1001,7 @@ namespace NStringSplitPrivate { using TIt = TSplitRange<TStopIteration<TFilters<TSplitRangeBase<TPolicy>>>>; public: - template <class OtherString> + template <class OtherString> explicit TStringSplitter(OtherString&& s) : String_(std::forward<OtherString>(s)) { @@ -1010,31 +1010,31 @@ namespace NStringSplitPrivate { //does not own TDelim template <class TDelim> inline TIt<TPtrPolicy<const TDelim>> Split(const TDelim& d) const noexcept { - return {String_, &d}; + return {String_, &d}; } inline TIt<TEmbedPolicy<TCharDelimiter<const TChar>>> Split(TChar ch) const noexcept { - return {String_, ch}; + return {String_, ch}; } inline TIt<TSimpleRefPolicy<TSetDelimiter<const TChar>>> SplitBySet(const TChar* set) const noexcept { - return {String_, set}; + return {String_, set}; } inline TIt<TEmbedPolicy<TStringDelimiter<const TChar>>> SplitByString(const TStringBufType& str) const noexcept { - return {String_, str.data(), str.size()}; + return {String_, str.data(), str.size()}; } template <class TFunc> inline TIt<TEmbedPolicy<TFuncDelimiter<TIterator, TFunc>>> SplitByFunc(TFunc f) const noexcept { - return {String_, f}; + return {String_, f}; } private: TStringType String_; }; - template <class String> + template <class String> auto MakeStringSplitter(String&& s) { return TStringSplitter<std::remove_reference_t<String>>(std::forward<String>(s)); } |