aboutsummaryrefslogtreecommitdiffstats
path: root/util/string/split.h
diff options
context:
space:
mode:
authorAnton Samokhvalov <pg83@yandex.ru>2022-02-10 16:45:17 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:17 +0300
commitd3a398281c6fd1d3672036cb2d63f842d2cb28c5 (patch)
treedd4bd3ca0f36b817e96812825ffaf10d645803f2 /util/string/split.h
parent72cb13b4aff9bc9cf22e49251bc8fd143f82538f (diff)
downloadydb-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.h454
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));
}