aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/deprecated/split/delim_string_iter.h
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/deprecated/split/delim_string_iter.h
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/deprecated/split/delim_string_iter.h')
-rw-r--r--library/cpp/deprecated/split/delim_string_iter.h185
1 files changed, 185 insertions, 0 deletions
diff --git a/library/cpp/deprecated/split/delim_string_iter.h b/library/cpp/deprecated/split/delim_string_iter.h
new file mode 100644
index 0000000000..8e4ca171a0
--- /dev/null
+++ b/library/cpp/deprecated/split/delim_string_iter.h
@@ -0,0 +1,185 @@
+#pragma once
+
+#include <util/generic/algorithm.h>
+#include <util/generic/strbuf.h>
+#include <util/generic/yexception.h>
+#include <util/string/cast.h>
+#include <util/system/yassert.h>
+
+#include <iterator>
+
+class TDelimStringIter {
+public:
+ using value_type = TStringBuf;
+ using difference_type = ptrdiff_t;
+ using pointer = const TStringBuf*;
+ using reference = const TStringBuf&;
+ using iterator_category = std::forward_iterator_tag;
+
+ inline TDelimStringIter(const char* begin, const char* strEnd, TStringBuf delim)
+ : TDelimStringIter(TStringBuf(begin, strEnd), delim)
+ {
+ }
+
+ inline TDelimStringIter(TStringBuf str, TStringBuf delim)
+ : IsValid(true)
+ , Str(str)
+ , Delim(delim)
+ {
+ UpdateCurrent();
+ }
+
+ inline TDelimStringIter()
+ : IsValid(false)
+ {
+ }
+
+ inline explicit operator bool() const {
+ return IsValid;
+ }
+
+ // NOTE: this is a potentially unsafe operation (no overrun check)
+ inline TDelimStringIter& operator++() {
+ if (Current.end() != Str.end()) {
+ Str.Skip(Current.length() + Delim.length());
+ UpdateCurrent();
+ } else {
+ Str.Clear();
+ Current.Clear();
+ IsValid = false;
+ }
+ return *this;
+ }
+
+ inline void operator+=(size_t n) {
+ for (; n > 0; --n) {
+ ++(*this);
+ }
+ }
+
+ inline bool operator==(const TDelimStringIter& rhs) const {
+ return (IsValid == rhs.IsValid) && (!IsValid || (Current.begin() == rhs.Current.begin()));
+ }
+
+ inline bool operator!=(const TDelimStringIter& rhs) const {
+ return !(*this == rhs);
+ }
+
+ inline TStringBuf operator*() const {
+ return Current;
+ }
+
+ inline const TStringBuf* operator->() const {
+ return &Current;
+ }
+
+ // Get & advance
+ template <class T>
+ inline bool TryNext(T& t) {
+ if (IsValid) {
+ t = FromString<T>(Current);
+ operator++();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ template <class T>
+ inline TDelimStringIter& Next(T& t) // Get & advance
+ {
+ if (!TryNext(t))
+ ythrow yexception() << "No valid field";
+ return *this;
+ }
+
+ template <class T>
+ inline T GetNext() {
+ T res;
+ Next(res);
+ return res;
+ }
+
+ inline const char* GetBegin() const {
+ return Current.begin();
+ }
+
+ inline const char* GetEnd() const {
+ return Current.end();
+ }
+
+ inline bool Valid() const {
+ return IsValid;
+ }
+
+ // contents from next token to the end of string
+ inline TStringBuf Cdr() const {
+ return Str.SubStr(Current.length() + Delim.length());
+ }
+
+ inline TDelimStringIter IterEnd() const {
+ return TDelimStringIter();
+ }
+
+private:
+ inline void UpdateCurrent() {
+ // it is much faster than TStringBuf::find
+ size_t pos = std::search(Str.begin(), Str.end(), Delim.begin(), Delim.end()) - Str.begin();
+ Current = Str.Head(pos);
+ }
+
+private:
+ bool IsValid;
+
+ TStringBuf Str;
+ TStringBuf Current;
+ TStringBuf Delim;
+};
+
+//example: for (TStringBuf field: TDelimStroka(line, "@@")) { ... }
+struct TDelimStroka {
+ TStringBuf S;
+ TStringBuf Delim;
+
+ inline TDelimStroka(TStringBuf s, TStringBuf delim)
+ : S(s)
+ , Delim(delim)
+ {
+ }
+
+ inline TDelimStringIter begin() const {
+ return TDelimStringIter(S, Delim);
+ }
+
+ inline TDelimStringIter end() const {
+ return TDelimStringIter();
+ }
+};
+
+inline TDelimStringIter begin_delim(const TString& str, TStringBuf delim) {
+ return TDelimStringIter(str, delim);
+}
+
+inline TDelimStringIter begin_delim(TStringBuf str, TStringBuf delim) {
+ return TDelimStringIter(str.begin(), str.end(), delim);
+}
+
+inline TDelimStringIter end_delim(const TString& /*str*/, TStringBuf /*delim*/) {
+ return TDelimStringIter();
+}
+
+class TKeyValueDelimStringIter {
+public:
+ TKeyValueDelimStringIter(const TStringBuf str, const TStringBuf delim);
+ bool Valid() const;
+ TKeyValueDelimStringIter& operator++();
+ const TStringBuf& Key() const;
+ const TStringBuf& Value() const;
+
+private:
+ TDelimStringIter DelimIter;
+ TStringBuf ChunkKey, ChunkValue;
+
+private:
+ void ReadKeyAndValue();
+};