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 /library/cpp/deprecated/split | |
parent | 72cb13b4aff9bc9cf22e49251bc8fd143f82538f (diff) | |
download | ydb-d3a398281c6fd1d3672036cb2d63f842d2cb28c5.tar.gz |
Restoring authorship annotation for Anton Samokhvalov <pg83@yandex.ru>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/deprecated/split')
-rw-r--r-- | library/cpp/deprecated/split/delim_string_iter.h | 32 | ||||
-rw-r--r-- | library/cpp/deprecated/split/delim_string_iter_ut.cpp | 22 | ||||
-rw-r--r-- | library/cpp/deprecated/split/split_iterator.cpp | 128 | ||||
-rw-r--r-- | library/cpp/deprecated/split/split_iterator.h | 120 | ||||
-rw-r--r-- | library/cpp/deprecated/split/split_iterator_ut.cpp | 32 |
5 files changed, 167 insertions, 167 deletions
diff --git a/library/cpp/deprecated/split/delim_string_iter.h b/library/cpp/deprecated/split/delim_string_iter.h index 9ef4bada93..8e4ca171a0 100644 --- a/library/cpp/deprecated/split/delim_string_iter.h +++ b/library/cpp/deprecated/split/delim_string_iter.h @@ -3,10 +3,10 @@ #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 <util/string/cast.h> +#include <util/system/yassert.h> -#include <iterator> +#include <iterator> class TDelimStringIter { public: @@ -18,8 +18,8 @@ public: inline TDelimStringIter(const char* begin, const char* strEnd, TStringBuf delim) : TDelimStringIter(TStringBuf(begin, strEnd), delim) - { - } + { + } inline TDelimStringIter(TStringBuf str, TStringBuf delim) : IsValid(true) @@ -31,10 +31,10 @@ public: inline TDelimStringIter() : IsValid(false) - { - } + { + } - inline explicit operator bool() const { + inline explicit operator bool() const { return IsValid; } @@ -52,7 +52,7 @@ public: } inline void operator+=(size_t n) { - for (; n > 0; --n) { + for (; n > 0; --n) { ++(*this); } } @@ -74,7 +74,7 @@ public: } // Get & advance - template <class T> + template <class T> inline bool TryNext(T& t) { if (IsValid) { t = FromString<T>(Current); @@ -85,7 +85,7 @@ public: } } - template <class T> + template <class T> inline TDelimStringIter& Next(T& t) // Get & advance { if (!TryNext(t)) @@ -93,7 +93,7 @@ public: return *this; } - template <class T> + template <class T> inline T GetNext() { T res; Next(res); @@ -124,7 +124,7 @@ public: 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(); + size_t pos = std::search(Str.begin(), Str.end(), Delim.begin(), Delim.end()) - Str.begin(); Current = Str.Head(pos); } @@ -137,15 +137,15 @@ private: }; //example: for (TStringBuf field: TDelimStroka(line, "@@")) { ... } -struct TDelimStroka { +struct TDelimStroka { TStringBuf S; TStringBuf Delim; inline TDelimStroka(TStringBuf s, TStringBuf delim) : S(s) , Delim(delim) - { - } + { + } inline TDelimStringIter begin() const { return TDelimStringIter(S, Delim); diff --git a/library/cpp/deprecated/split/delim_string_iter_ut.cpp b/library/cpp/deprecated/split/delim_string_iter_ut.cpp index 72ba1c4f69..18a8b2a160 100644 --- a/library/cpp/deprecated/split/delim_string_iter_ut.cpp +++ b/library/cpp/deprecated/split/delim_string_iter_ut.cpp @@ -43,7 +43,7 @@ Y_UNIT_TEST_SUITE(TDelimStrokaIterTestSuite) { TVector<TStringBuf> expected = {"1", "", "3@4", ""}; TVector<TStringBuf> got; - for (TStringBuf x : TDelimStroka("1@@@@3@4@@", "@@")) { + for (TStringBuf x : TDelimStroka("1@@@@3@4@@", "@@")) { got.push_back(x); } @@ -70,30 +70,30 @@ Y_UNIT_TEST_SUITE(TKeyValueDelimStringIterTestSuite) { Y_UNIT_TEST(SingleCharacterAsDelimiter) { AssertKeyValueStringSplit( "abc=123,cde=qwer", ",", - {{"abc", "123"}, - {"cde", "qwer"}}); + {{"abc", "123"}, + {"cde", "qwer"}}); } Y_UNIT_TEST(MultipleCharactersAsDelimiter) { AssertKeyValueStringSplit( "abc=xyz@@qwerty=zxcv", "@@", - {{"abc", "xyz"}, - {"qwerty", "zxcv"}}); + {{"abc", "xyz"}, + {"qwerty", "zxcv"}}); } Y_UNIT_TEST(NoDelimiters) { AssertKeyValueStringSplit( "abc=zz", ",", - {{"abc", "zz"}}); + {{"abc", "zz"}}); } Y_UNIT_TEST(EmptyElements) { AssertKeyValueStringSplit( "@@abc=zxy@@@@qwerty=y@@", "@@", - {{"", ""}, - {"abc", "zxy"}, - {"", ""}, - {"qwerty", "y"}, - {"", ""}}); + {{"", ""}, + {"abc", "zxy"}, + {"", ""}, + {"qwerty", "y"}, + {"", ""}}); } } diff --git a/library/cpp/deprecated/split/split_iterator.cpp b/library/cpp/deprecated/split/split_iterator.cpp index b1fe9a5f15..32262d25bd 100644 --- a/library/cpp/deprecated/split/split_iterator.cpp +++ b/library/cpp/deprecated/split/split_iterator.cpp @@ -1,23 +1,23 @@ -#include "split_iterator.h" - -#include <util/system/yassert.h> - -#include <cctype> -#include <cstring> -#include <cstdlib> - +#include "split_iterator.h" + +#include <util/system/yassert.h> + +#include <cctype> +#include <cstring> +#include <cstdlib> + /****************** TSplitDelimiters2 ******************/ -TSplitDelimiters::TSplitDelimiters(const char* s) { +TSplitDelimiters::TSplitDelimiters(const char* s) { memset(Delims, 0, sizeof(Delims)); while (*s) - Delims[(ui8) * (s++)] = true; + Delims[(ui8) * (s++)] = true; } /****************** TSplitBase ******************/ -TSplitBase::TSplitBase(const char* str, size_t length) - : Str(str) - , Len(length) +TSplitBase::TSplitBase(const char* str, size_t length) + : Str(str) + , Len(length) { } @@ -29,62 +29,62 @@ TSplitBase::TSplitBase(const TString& s) /****************** TDelimitersSplit ******************/ -TDelimitersSplit::TDelimitersSplit(const char* str, size_t length, const TSplitDelimiters& delimiters) - : TSplitBase(str, length) - , Delimiters(delimiters) +TDelimitersSplit::TDelimitersSplit(const char* str, size_t length, const TSplitDelimiters& delimiters) + : TSplitBase(str, length) + , Delimiters(delimiters) { } TDelimitersSplit::TDelimitersSplit(const TString& s, const TSplitDelimiters& delimiters) - : TSplitBase(s) - , Delimiters(delimiters) + : TSplitBase(s) + , Delimiters(delimiters) { } -size_t TDelimitersSplit::Begin() const { +size_t TDelimitersSplit::Begin() const { size_t pos = 0; - while ((pos < Len) && Delimiters.IsDelimiter(Str[pos])) + while ((pos < Len) && Delimiters.IsDelimiter(Str[pos])) ++pos; return pos; } -TSizeTRegion TDelimitersSplit::Next(size_t& pos) const { +TSizeTRegion TDelimitersSplit::Next(size_t& pos) const { size_t begin = pos; - while ((pos < Len) && !Delimiters.IsDelimiter(Str[pos])) + while ((pos < Len) && !Delimiters.IsDelimiter(Str[pos])) ++pos; TSizeTRegion result(begin, pos); - while ((pos < Len) && Delimiters.IsDelimiter(Str[pos])) + while ((pos < Len) && Delimiters.IsDelimiter(Str[pos])) ++pos; - + return result; } -TDelimitersSplit::TIterator TDelimitersSplit::Iterator() const { +TDelimitersSplit::TIterator TDelimitersSplit::Iterator() const { return TIterator(*this); } /****************** TDelimitersStrictSplit ******************/ -TDelimitersStrictSplit::TDelimitersStrictSplit(const char* str, size_t length, const TSplitDelimiters& delimiters) - : TSplitBase(str, length) - , Delimiters(delimiters) +TDelimitersStrictSplit::TDelimitersStrictSplit(const char* str, size_t length, const TSplitDelimiters& delimiters) + : TSplitBase(str, length) + , Delimiters(delimiters) { } TDelimitersStrictSplit::TDelimitersStrictSplit(const TString& s, const TSplitDelimiters& delimiters) - : TSplitBase(s) - , Delimiters(delimiters) + : TSplitBase(s) + , Delimiters(delimiters) { } -TDelimitersStrictSplit::TIterator TDelimitersStrictSplit::Iterator() const { +TDelimitersStrictSplit::TIterator TDelimitersStrictSplit::Iterator() const { return TIterator(*this); } -TSizeTRegion TDelimitersStrictSplit::Next(size_t& pos) const { +TSizeTRegion TDelimitersStrictSplit::Next(size_t& pos) const { size_t begin = pos; - while ((pos < Len) && !Delimiters.IsDelimiter(Str[pos])) + while ((pos < Len) && !Delimiters.IsDelimiter(Str[pos])) ++pos; TSizeTRegion result(begin, pos); @@ -94,7 +94,7 @@ TSizeTRegion TDelimitersStrictSplit::Next(size_t& pos) const { return result; } -size_t TDelimitersStrictSplit::Begin() const { +size_t TDelimitersStrictSplit::Begin() const { return 0; } @@ -142,84 +142,84 @@ size_t TScreenedDelimitersSplit::Begin() const { /****************** TDelimitersSplitWithoutTags ******************/ -TDelimitersSplitWithoutTags::TDelimitersSplitWithoutTags(const char* str, size_t length, const TSplitDelimiters& delimiters) - : TSplitBase(str, length) - , Delimiters(delimiters) +TDelimitersSplitWithoutTags::TDelimitersSplitWithoutTags(const char* str, size_t length, const TSplitDelimiters& delimiters) + : TSplitBase(str, length) + , Delimiters(delimiters) { } TDelimitersSplitWithoutTags::TDelimitersSplitWithoutTags(const TString& s, const TSplitDelimiters& delimiters) - : TSplitBase(s) - , Delimiters(delimiters) + : TSplitBase(s) + , Delimiters(delimiters) { } -size_t TDelimitersSplitWithoutTags::SkipTag(size_t pos) const { +size_t TDelimitersSplitWithoutTags::SkipTag(size_t pos) const { Y_ASSERT('<' == Str[pos]); while ((pos < Len) && ('>' != Str[pos])) ++pos; return pos + 1; } -size_t TDelimitersSplitWithoutTags::SkipDelimiters(size_t pos) const { - while (true) { - while ((pos < Len) && Delimiters.IsDelimiter(Str[pos]) && ('<' != Str[pos])) +size_t TDelimitersSplitWithoutTags::SkipDelimiters(size_t pos) const { + while (true) { + while ((pos < Len) && Delimiters.IsDelimiter(Str[pos]) && ('<' != Str[pos])) ++pos; - if (pos < Len) { + if (pos < Len) { if ('<' != Str[pos]) break; else pos = SkipTag(pos); - } else + } else break; } return pos; } -size_t TDelimitersSplitWithoutTags::Begin() const { +size_t TDelimitersSplitWithoutTags::Begin() const { size_t pos = 0; pos = SkipDelimiters(pos); return pos; } -TSizeTRegion TDelimitersSplitWithoutTags::Next(size_t& pos) const { +TSizeTRegion TDelimitersSplitWithoutTags::Next(size_t& pos) const { size_t begin = pos; - while ((pos < Len) && !Delimiters.IsDelimiter(Str[pos]) && ('<' != Str[pos])) + while ((pos < Len) && !Delimiters.IsDelimiter(Str[pos]) && ('<' != Str[pos])) ++pos; TSizeTRegion result(begin, pos); - + pos = SkipDelimiters(pos); return result; } -TDelimitersSplitWithoutTags::TIterator TDelimitersSplitWithoutTags::Iterator() const { +TDelimitersSplitWithoutTags::TIterator TDelimitersSplitWithoutTags::Iterator() const { return TIterator(*this); } /****************** TCharSplit ******************/ -TCharSplit::TCharSplit(const char* str, size_t length) - : TSplitBase(str, length) +TCharSplit::TCharSplit(const char* str, size_t length) + : TSplitBase(str, length) { } TCharSplit::TCharSplit(const TString& s) - : TSplitBase(s) + : TSplitBase(s) { } -TCharSplit::TIterator TCharSplit::Iterator() const { +TCharSplit::TIterator TCharSplit::Iterator() const { return TIterator(*this); } -TSizeTRegion TCharSplit::Next(size_t& pos) const { +TSizeTRegion TCharSplit::Next(size_t& pos) const { TSizeTRegion result(pos, pos + 1); ++pos; return result; } -size_t TCharSplit::Begin() const { +size_t TCharSplit::Begin() const { return 0; } @@ -235,33 +235,33 @@ TCharSplitWithoutTags::TCharSplitWithoutTags(const TString& s) { } -size_t TCharSplitWithoutTags::SkipTag(size_t pos) const { +size_t TCharSplitWithoutTags::SkipTag(size_t pos) const { Y_ASSERT('<' == Str[pos]); while ((pos < Len) && ('>' != Str[pos])) ++pos; return pos + 1; } -size_t TCharSplitWithoutTags::SkipDelimiters(size_t pos) const { - while (true) { - if (pos < Len) { +size_t TCharSplitWithoutTags::SkipDelimiters(size_t pos) const { + while (true) { + if (pos < Len) { if ('<' != Str[pos]) break; else pos = SkipTag(pos); - } else + } else break; } return pos; } -size_t TCharSplitWithoutTags::Begin() const { +size_t TCharSplitWithoutTags::Begin() const { size_t pos = 0; pos = SkipDelimiters(pos); return pos; } -TSizeTRegion TCharSplitWithoutTags::Next(size_t& pos) const { +TSizeTRegion TCharSplitWithoutTags::Next(size_t& pos) const { size_t begin = pos++; TSizeTRegion result(begin, pos); @@ -270,7 +270,7 @@ TSizeTRegion TCharSplitWithoutTags::Next(size_t& pos) const { return result; } -TCharSplitWithoutTags::TIterator TCharSplitWithoutTags::Iterator() const { +TCharSplitWithoutTags::TIterator TCharSplitWithoutTags::Iterator() const { return TIterator(*this); } diff --git a/library/cpp/deprecated/split/split_iterator.h b/library/cpp/deprecated/split/split_iterator.h index 73f3693564..0eacc29228 100644 --- a/library/cpp/deprecated/split/split_iterator.h +++ b/library/cpp/deprecated/split/split_iterator.h @@ -4,74 +4,74 @@ #include <util/string/cast.h> #include <util/string/util.h> #include <util/string/builder.h> - -#include <util/system/yassert.h> + +#include <util/system/yassert.h> #include <util/system/defaults.h> #include <util/generic/strbuf.h> #include <util/generic/string.h> #include <util/generic/vector.h> #include <util/generic/yexception.h> -#include <cstdio> - -template <typename T> -struct TNumPair { - T Begin; - T End; - +#include <cstdio> + +template <typename T> +struct TNumPair { + T Begin; + T End; + TNumPair() = default; - - TNumPair(T begin, T end) - : Begin(begin) - , End(end) - { + + TNumPair(T begin, T end) + : Begin(begin) + , End(end) + { Y_ASSERT(begin <= end); - } - - T Length() const { - return End - Begin + 1; - } - - bool operator==(const TNumPair& r) const { - return (Begin == r.Begin) && (End == r.End); - } - - bool operator!=(const TNumPair& r) const { - return (Begin != r.Begin) || (End != r.End); - } -}; - + } + + T Length() const { + return End - Begin + 1; + } + + bool operator==(const TNumPair& r) const { + return (Begin == r.Begin) && (End == r.End); + } + + bool operator!=(const TNumPair& r) const { + return (Begin != r.Begin) || (End != r.End); + } +}; + using TSizeTRegion = TNumPair<size_t>; using TUi32Region = TNumPair<ui32>; - -template <> + +template <> inline TString ToString(const TUi32Region& r) { - return TStringBuilder() << "(" << r.Begin << ", " << r.End << ")"; -} - -template <> + return TStringBuilder() << "(" << r.Begin << ", " << r.End << ")"; +} + +template <> inline TUi32Region FromString(const TString& s) { - TUi32Region result; + TUi32Region result; sscanf(s.data(), "(%" PRIu32 ", %" PRIu32 ")", &result.Begin, &result.End); - return result; -} - -class TSplitDelimiters { + return result; +} + +class TSplitDelimiters { private: bool Delims[256]; public: explicit TSplitDelimiters(const char* s); - + Y_FORCE_INLINE bool IsDelimiter(ui8 ch) const { return Delims[ch]; } }; -template <class Split> +template <class Split> class TSplitIterator; -class TSplitBase { +class TSplitBase { protected: const char* Str; size_t Len; @@ -94,11 +94,11 @@ private: }; #ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4512) +#pragma warning(push) +#pragma warning(disable : 4512) #endif -class TDelimitersSplit: public TSplitBase { +class TDelimitersSplit: public TSplitBase { private: const TSplitDelimiters& Delimiters; @@ -119,7 +119,7 @@ private: TDelimitersSplit(TString&&, const TSplitDelimiters&) = delete; }; -class TDelimitersStrictSplit: public TSplitBase { +class TDelimitersStrictSplit: public TSplitBase { private: const TSplitDelimiters& Delimiters; @@ -140,7 +140,7 @@ private: TDelimitersStrictSplit(TString&&, const TSplitDelimiters&) = delete; }; -class TScreenedDelimitersSplit: public TSplitBase { +class TScreenedDelimitersSplit: public TSplitBase { private: const TSplitDelimiters& Delimiters; const TSplitDelimiters& Screens; @@ -162,7 +162,7 @@ private: TScreenedDelimitersSplit(const TString&, const TSplitDelimiters&, TSplitDelimiters&&) = delete; }; -class TDelimitersSplitWithoutTags: public TSplitBase { +class TDelimitersSplitWithoutTags: public TSplitBase { private: const TSplitDelimiters& Delimiters; size_t SkipTag(size_t pos) const; @@ -185,7 +185,7 @@ private: TDelimitersSplitWithoutTags(TString&&, const TSplitDelimiters&) = delete; }; -class TCharSplit: public TSplitBase { +class TCharSplit: public TSplitBase { public: using TIterator = TSplitIterator<TCharSplit>; friend class TSplitIterator<TCharSplit>; @@ -202,10 +202,10 @@ private: }; #ifdef _MSC_VER -#pragma warning(pop) +#pragma warning(pop) #endif -class TCharSplitWithoutTags: public TSplitBase { +class TCharSplitWithoutTags: public TSplitBase { private: size_t SkipTag(size_t pos) const; size_t SkipDelimiters(size_t pos) const; @@ -225,7 +225,7 @@ private: TCharSplitWithoutTags(TString&&) = delete; }; -class TSubstringSplitDelimiter { +class TSubstringSplitDelimiter { public: TKMPMatcher Matcher; size_t Len; @@ -233,7 +233,7 @@ public: TSubstringSplitDelimiter(const TString& s); }; -class TSubstringSplit: public TSplitBase { +class TSubstringSplit: public TSplitBase { private: const TSubstringSplitDelimiter& Delimiter; @@ -253,8 +253,8 @@ private: TSubstringSplit(const TString&, TSubstringSplitDelimiter&&) = delete; }; -template <class TSplit> -class TSplitIterator { +template <class TSplit> +class TSplitIterator { protected: const TSplit& Split; size_t Pos; @@ -271,12 +271,12 @@ public: virtual ~TSplitIterator() { delete CurrentStroka; } - + inline TSizeTRegion Next() { Y_ENSURE(!Eof(), TStringBuf("eof reached")); return Split.Next(Pos); } - + TStringBuf NextTok() { if (Eof()) return TStringBuf(); @@ -308,8 +308,8 @@ public: using TSplitTokens = TVector<TString>; -template <typename TSplit> -void Split(const TSplit& split, TSplitTokens* words) { +template <typename TSplit> +void Split(const TSplit& split, TSplitTokens* words) { words->clear(); TSplitIterator<TSplit> it(split); while (!it.Eof()) diff --git a/library/cpp/deprecated/split/split_iterator_ut.cpp b/library/cpp/deprecated/split/split_iterator_ut.cpp index c4df3b2d13..be5069c4be 100644 --- a/library/cpp/deprecated/split/split_iterator_ut.cpp +++ b/library/cpp/deprecated/split/split_iterator_ut.cpp @@ -1,15 +1,15 @@ -#include "split_iterator.h" +#include "split_iterator.h" #include <library/cpp/testing/unittest/registar.h> -class TSplitIteratorTest: public TTestBase { +class TSplitIteratorTest: public TTestBase { UNIT_TEST_SUITE(TSplitIteratorTest); - UNIT_TEST(TestDelimiters); - UNIT_TEST(TestDelimitersSplit); - UNIT_TEST(TestDelimitersStrictSplit); - UNIT_TEST(TestTail); - UNIT_TEST(TestScreenedDelimitersSplit); - UNIT_TEST(TestSubstringDelimiter); + UNIT_TEST(TestDelimiters); + UNIT_TEST(TestDelimitersSplit); + UNIT_TEST(TestDelimitersStrictSplit); + UNIT_TEST(TestTail); + UNIT_TEST(TestScreenedDelimitersSplit); + UNIT_TEST(TestSubstringDelimiter); UNIT_TEST_SUITE_END(); public: @@ -21,17 +21,17 @@ public: void TestSubstringDelimiter(); }; -void TSplitIteratorTest::TestDelimiters() { +void TSplitIteratorTest::TestDelimiters() { TSplitDelimiters delims("@"); for (int i = 0; i < 256; ++i) - if ('@' != i) { + if ('@' != i) { UNIT_ASSERT(!delims.IsDelimiter((ui8)i)); - } else { + } else { UNIT_ASSERT(delims.IsDelimiter((ui8)i)); } } -void TSplitIteratorTest::TestDelimitersSplit() { +void TSplitIteratorTest::TestDelimitersSplit() { { TString s = "1a3b45cd"; TSplitDelimiters delims("abcd"); @@ -52,7 +52,7 @@ void TSplitIteratorTest::TestDelimitersSplit() { } } -void TSplitIteratorTest::TestDelimitersStrictSplit() { +void TSplitIteratorTest::TestDelimitersStrictSplit() { { TString s = "grp@2"; TSplitDelimiters delims("@"); @@ -74,7 +74,7 @@ void TSplitIteratorTest::TestDelimitersStrictSplit() { } } -void TSplitIteratorTest::TestTail() { +void TSplitIteratorTest::TestTail() { TString s = "grp@2@4"; TSplitDelimiters delims("@"); TDelimitersSplit split(s, delims); @@ -88,7 +88,7 @@ void TSplitIteratorTest::TestTail() { UNIT_ASSERT_EQUAL(it.GetTail(), ""); } -void TSplitIteratorTest::TestScreenedDelimitersSplit() { +void TSplitIteratorTest::TestScreenedDelimitersSplit() { { const TString s = "77.88.58.91 - - [28/Aug/2008:00:08:07 +0400] \"GET /export/mordashka.tgz HTTP/1.1\" 304 - \"-\" \"libwww-perl/5.805\" \"news.yandex.ru,80\" \"-\" \"-\" 1219867687 \"0\" 3283 2"; const TSplitDelimiters delims(" "); @@ -137,7 +137,7 @@ void TSplitIteratorTest::TestScreenedDelimitersSplit() { } } -void TSplitIteratorTest::TestSubstringDelimiter() { +void TSplitIteratorTest::TestSubstringDelimiter() { const TString s = "a@@bb@@cc@c.d@@r"; static const TSubstringSplitDelimiter delimiter("@@"); const TSubstringSplit splitter(s, delimiter); |