diff options
author | thegeorg <thegeorg@yandex-team.ru> | 2022-02-10 16:45:12 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:12 +0300 |
commit | 49116032d905455a7b1c994e4a696afc885c1e71 (patch) | |
tree | be835aa92c6248212e705f25388ebafcf84bc7a1 /util/generic | |
parent | 4e839db24a3bbc9f1c610c43d6faaaa99824dcca (diff) | |
download | ydb-49116032d905455a7b1c994e4a696afc885c1e71.tar.gz |
Restoring authorship annotation for <thegeorg@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'util/generic')
30 files changed, 1069 insertions, 1069 deletions
diff --git a/util/generic/array_ref.h b/util/generic/array_ref.h index 1c4fd140cb..1ac60ac7d3 100644 --- a/util/generic/array_ref.h +++ b/util/generic/array_ref.h @@ -1,10 +1,10 @@ #pragma once -#include <util/generic/yexception.h> +#include <util/generic/yexception.h> #include <algorithm> #include <initializer_list> -#include <iterator> +#include <iterator> /** * `TArrayRef` works pretty much like `std::span` with dynamic extent, presenting @@ -25,16 +25,16 @@ * - `const TArrayRef<const T>` is a const reference to const data (like `const T* const`). */ template <class T> -class TArrayRef { +class TArrayRef { public: - using iterator = T*; - using const_iterator = const T*; - using reference = T&; - using const_reference = const T&; - using value_type = T; - using reverse_iterator = std::reverse_iterator<iterator>; - using const_reverse_iterator = std::reverse_iterator<const_iterator>; - + using iterator = T*; + using const_iterator = const T*; + using reference = T&; + using const_reference = const T&; + using value_type = T; + using reverse_iterator = std::reverse_iterator<iterator>; + using const_reverse_iterator = std::reverse_iterator<const_iterator>; + constexpr inline TArrayRef() noexcept : T_(nullptr) , S_(0) @@ -75,180 +75,180 @@ public: template <class TT, typename = std::enable_if_t<std::is_same<std::remove_const_t<T>, std::remove_const_t<TT>>::value>> bool operator==(const TArrayRef<TT>& other) const noexcept { - return (S_ == other.size()) && std::equal(begin(), end(), other.begin()); + return (S_ == other.size()) && std::equal(begin(), end(), other.begin()); } - constexpr inline T* data() const noexcept { + constexpr inline T* data() const noexcept { return T_; } - constexpr inline size_t size() const noexcept { + constexpr inline size_t size() const noexcept { return S_; } - constexpr size_t size_bytes() const noexcept { - return (size() * sizeof(T)); - } - - constexpr inline bool empty() const noexcept { - return (S_ == 0); - } - + constexpr size_t size_bytes() const noexcept { + return (size() * sizeof(T)); + } + + constexpr inline bool empty() const noexcept { + return (S_ == 0); + } + constexpr inline iterator begin() const noexcept { - return T_; - } - + return T_; + } + constexpr inline iterator end() const noexcept { - return (T_ + S_); - } - + return (T_ + S_); + } + constexpr inline const_iterator cbegin() const noexcept { - return T_; - } - + return T_; + } + constexpr inline const_iterator cend() const noexcept { - return (T_ + S_); - } - + return (T_ + S_); + } + constexpr inline reverse_iterator rbegin() const noexcept { - return reverse_iterator(T_ + S_); - } - + return reverse_iterator(T_ + S_); + } + constexpr inline reverse_iterator rend() const noexcept { - return reverse_iterator(T_); - } - + return reverse_iterator(T_); + } + constexpr inline const_reverse_iterator crbegin() const noexcept { - return const_reverse_iterator(T_ + S_); - } - + return const_reverse_iterator(T_ + S_); + } + constexpr inline const_reverse_iterator crend() const noexcept { - return const_reverse_iterator(T_); - } - + return const_reverse_iterator(T_); + } + constexpr inline reference front() const noexcept { - return *T_; - } - - inline reference back() const noexcept { - Y_ASSERT(S_ > 0); - - return *(end() - 1); - } - - inline reference operator[](size_t n) const noexcept { - Y_ASSERT(n < S_); - - return *(T_ + n); - } - - inline reference at(size_t n) const { - if (n >= S_) { - throw std::out_of_range("array ref range error"); - } - - return (*this)[n]; - } - + return *T_; + } + + inline reference back() const noexcept { + Y_ASSERT(S_ > 0); + + return *(end() - 1); + } + + inline reference operator[](size_t n) const noexcept { + Y_ASSERT(n < S_); + + return *(T_ + n); + } + + inline reference at(size_t n) const { + if (n >= S_) { + throw std::out_of_range("array ref range error"); + } + + return (*this)[n]; + } + constexpr inline explicit operator bool() const noexcept { - return (S_ > 0); - } + return (S_ > 0); + } + + /** + * Obtains a ref that is a view over the first `count` elements of this TArrayRef. + * + * The behavior is undefined if count > size(). + */ + TArrayRef first(size_t count) const { + Y_ASSERT(count <= size()); + return TArrayRef(data(), count); + } - /** - * Obtains a ref that is a view over the first `count` elements of this TArrayRef. - * + /** + * Obtains a ref that is a view over the last `count` elements of this TArrayRef. + * * The behavior is undefined if count > size(). - */ - TArrayRef first(size_t count) const { - Y_ASSERT(count <= size()); - return TArrayRef(data(), count); - } - - /** - * Obtains a ref that is a view over the last `count` elements of this TArrayRef. - * - * The behavior is undefined if count > size(). - */ - TArrayRef last(size_t count) const { - Y_ASSERT(count <= size()); - return TArrayRef(end() - count, end()); - } - - /** - * Obtains a ref that is a view over the `count` elements of this TArrayRef starting at `offset`. - * - * The behavior is undefined in either offset or count is out of range. - */ - TArrayRef subspan(size_t offset) const { - Y_ASSERT(offset <= size()); - return TArrayRef(data() + offset, size() - offset); - } - - TArrayRef subspan(size_t offset, size_t count) const { - Y_ASSERT(offset + count <= size()); - return TArrayRef(data() + offset, count); - } - - TArrayRef Slice(size_t offset) const { - return subspan(offset); - } - - TArrayRef Slice(size_t offset, size_t size) const { - return subspan(offset, size); - } - - /* FIXME: - * This method is placed here for backward compatibility only and should be removed. - * Keep in mind that it's behavior is different from Slice(): - * SubRegion() never throws. It returns empty TArrayRef in case of invalid input. - * - * DEPRECATED. DO NOT USE. - */ - TArrayRef SubRegion(size_t offset, size_t size) const { - if (size == 0 || offset >= S_) { - return TArrayRef(); - } - - if (size > S_ - offset) { - size = S_ - offset; - } - - return TArrayRef(T_ + offset, size); - } - + */ + TArrayRef last(size_t count) const { + Y_ASSERT(count <= size()); + return TArrayRef(end() - count, end()); + } + + /** + * Obtains a ref that is a view over the `count` elements of this TArrayRef starting at `offset`. + * + * The behavior is undefined in either offset or count is out of range. + */ + TArrayRef subspan(size_t offset) const { + Y_ASSERT(offset <= size()); + return TArrayRef(data() + offset, size() - offset); + } + + TArrayRef subspan(size_t offset, size_t count) const { + Y_ASSERT(offset + count <= size()); + return TArrayRef(data() + offset, count); + } + + TArrayRef Slice(size_t offset) const { + return subspan(offset); + } + + TArrayRef Slice(size_t offset, size_t size) const { + return subspan(offset, size); + } + + /* FIXME: + * This method is placed here for backward compatibility only and should be removed. + * Keep in mind that it's behavior is different from Slice(): + * SubRegion() never throws. It returns empty TArrayRef in case of invalid input. + * + * DEPRECATED. DO NOT USE. + */ + TArrayRef SubRegion(size_t offset, size_t size) const { + if (size == 0 || offset >= S_) { + return TArrayRef(); + } + + if (size > S_ - offset) { + size = S_ - offset; + } + + return TArrayRef(T_ + offset, size); + } + constexpr inline yssize_t ysize() const noexcept { - return static_cast<yssize_t>(this->size()); - } - + return static_cast<yssize_t>(this->size()); + } + private: T* T_; size_t S_; }; -/** - * Obtains a view to the object representation of the elements of the TArrayRef arrayRef. - * - * Named as its std counterparts, std::as_bytes. - */ +/** + * Obtains a view to the object representation of the elements of the TArrayRef arrayRef. + * + * Named as its std counterparts, std::as_bytes. + */ template <typename T> -TArrayRef<const char> as_bytes(TArrayRef<T> arrayRef) noexcept { - return TArrayRef<const char>( - reinterpret_cast<const char*>(arrayRef.data()), +TArrayRef<const char> as_bytes(TArrayRef<T> arrayRef) noexcept { + return TArrayRef<const char>( + reinterpret_cast<const char*>(arrayRef.data()), arrayRef.size_bytes()); -} - -/** - * Obtains a view to the writable object representation of the elements of the TArrayRef arrayRef. - * - * Named as its std counterparts, std::as_writable_bytes. - */ +} + +/** + * Obtains a view to the writable object representation of the elements of the TArrayRef arrayRef. + * + * Named as its std counterparts, std::as_writable_bytes. + */ template <typename T> -TArrayRef<char> as_writable_bytes(TArrayRef<T> arrayRef) noexcept { - return TArrayRef<char>( - reinterpret_cast<char*>(arrayRef.data()), +TArrayRef<char> as_writable_bytes(TArrayRef<T> arrayRef) noexcept { + return TArrayRef<char>( + reinterpret_cast<char*>(arrayRef.data()), arrayRef.size_bytes()); -} - +} + template <class Range> constexpr TArrayRef<const typename Range::value_type> MakeArrayRef(const Range& range) { return TArrayRef<const typename Range::value_type>(range); diff --git a/util/generic/array_ref_ut.cpp b/util/generic/array_ref_ut.cpp index a26e57e803..4c8eaf7135 100644 --- a/util/generic/array_ref_ut.cpp +++ b/util/generic/array_ref_ut.cpp @@ -3,173 +3,173 @@ #include <library/cpp/testing/unittest/registar.h> Y_UNIT_TEST_SUITE(TestArrayRef) { - Y_UNIT_TEST(TestDefaultConstructor) { - TArrayRef<int> defaulted; - UNIT_ASSERT_VALUES_EQUAL(defaulted.data(), nullptr); - UNIT_ASSERT_VALUES_EQUAL(defaulted.size(), 0u); - } - - Y_UNIT_TEST(TestConstructorFromArray) { - int x[] = {10, 20, 30}; - TArrayRef<int> ref(x); - UNIT_ASSERT_VALUES_EQUAL(3u, ref.size()); - UNIT_ASSERT_VALUES_EQUAL(30, ref[2]); - ref[2] = 50; - UNIT_ASSERT_VALUES_EQUAL(50, x[2]); - - TArrayRef<const int> constRef(x); - UNIT_ASSERT_VALUES_EQUAL(3u, constRef.size()); - UNIT_ASSERT_VALUES_EQUAL(50, constRef[2]); - ref[0] = 100; - UNIT_ASSERT_VALUES_EQUAL(constRef[0], 100); - } - - Y_UNIT_TEST(TestAccessingElements) { - int a[]{1, 2, 3}; - TArrayRef<int> ref(a); - - UNIT_ASSERT_VALUES_EQUAL(ref[0], 1); - UNIT_ASSERT_VALUES_EQUAL(ref.at(0), 1); - - ref[0] = 5; - UNIT_ASSERT_VALUES_EQUAL(a[0], 5); - - //FIXME: size checks are implemented via Y_ASSERT, hence there is no way to test them - } - - Y_UNIT_TEST(TestFrontBack) { - const int x[] = {1, 2, 3}; - const TArrayRef<const int> rx{x}; - UNIT_ASSERT_VALUES_EQUAL(rx.front(), 1); - UNIT_ASSERT_VALUES_EQUAL(rx.back(), 3); - - int y[] = {1, 2, 3}; - TArrayRef<int> ry{y}; - UNIT_ASSERT_VALUES_EQUAL(ry.front(), 1); - UNIT_ASSERT_VALUES_EQUAL(ry.back(), 3); - - ry.front() = 100; - ry.back() = 500; - UNIT_ASSERT_VALUES_EQUAL(ry.front(), 100); - UNIT_ASSERT_VALUES_EQUAL(ry.back(), 500); - UNIT_ASSERT_VALUES_EQUAL(y[0], 100); - UNIT_ASSERT_VALUES_EQUAL(y[2], 500); - } - - Y_UNIT_TEST(TestIterator) { - int array[] = {17, 19, 21}; - TArrayRef<int> r(array, 3); - - TArrayRef<int>::iterator iterator = r.begin(); - for (auto& i : array) { - UNIT_ASSERT(iterator != r.end()); - UNIT_ASSERT_VALUES_EQUAL(i, *iterator); - ++iterator; + Y_UNIT_TEST(TestDefaultConstructor) { + TArrayRef<int> defaulted; + UNIT_ASSERT_VALUES_EQUAL(defaulted.data(), nullptr); + UNIT_ASSERT_VALUES_EQUAL(defaulted.size(), 0u); + } + + Y_UNIT_TEST(TestConstructorFromArray) { + int x[] = {10, 20, 30}; + TArrayRef<int> ref(x); + UNIT_ASSERT_VALUES_EQUAL(3u, ref.size()); + UNIT_ASSERT_VALUES_EQUAL(30, ref[2]); + ref[2] = 50; + UNIT_ASSERT_VALUES_EQUAL(50, x[2]); + + TArrayRef<const int> constRef(x); + UNIT_ASSERT_VALUES_EQUAL(3u, constRef.size()); + UNIT_ASSERT_VALUES_EQUAL(50, constRef[2]); + ref[0] = 100; + UNIT_ASSERT_VALUES_EQUAL(constRef[0], 100); + } + + Y_UNIT_TEST(TestAccessingElements) { + int a[]{1, 2, 3}; + TArrayRef<int> ref(a); + + UNIT_ASSERT_VALUES_EQUAL(ref[0], 1); + UNIT_ASSERT_VALUES_EQUAL(ref.at(0), 1); + + ref[0] = 5; + UNIT_ASSERT_VALUES_EQUAL(a[0], 5); + + //FIXME: size checks are implemented via Y_ASSERT, hence there is no way to test them + } + + Y_UNIT_TEST(TestFrontBack) { + const int x[] = {1, 2, 3}; + const TArrayRef<const int> rx{x}; + UNIT_ASSERT_VALUES_EQUAL(rx.front(), 1); + UNIT_ASSERT_VALUES_EQUAL(rx.back(), 3); + + int y[] = {1, 2, 3}; + TArrayRef<int> ry{y}; + UNIT_ASSERT_VALUES_EQUAL(ry.front(), 1); + UNIT_ASSERT_VALUES_EQUAL(ry.back(), 3); + + ry.front() = 100; + ry.back() = 500; + UNIT_ASSERT_VALUES_EQUAL(ry.front(), 100); + UNIT_ASSERT_VALUES_EQUAL(ry.back(), 500); + UNIT_ASSERT_VALUES_EQUAL(y[0], 100); + UNIT_ASSERT_VALUES_EQUAL(y[2], 500); + } + + Y_UNIT_TEST(TestIterator) { + int array[] = {17, 19, 21}; + TArrayRef<int> r(array, 3); + + TArrayRef<int>::iterator iterator = r.begin(); + for (auto& i : array) { + UNIT_ASSERT(iterator != r.end()); + UNIT_ASSERT_VALUES_EQUAL(i, *iterator); + ++iterator; } - UNIT_ASSERT(iterator == r.end()); - } - - Y_UNIT_TEST(TestReverseIterators) { - const int x[] = {1, 2, 3}; - const TArrayRef<const int> rx{x}; - auto i = rx.crbegin(); - UNIT_ASSERT_VALUES_EQUAL(*i, 3); - ++i; - UNIT_ASSERT_VALUES_EQUAL(*i, 2); - ++i; - UNIT_ASSERT_VALUES_EQUAL(*i, 1); - ++i; - UNIT_ASSERT_EQUAL(i, rx.crend()); + UNIT_ASSERT(iterator == r.end()); + } + + Y_UNIT_TEST(TestReverseIterators) { + const int x[] = {1, 2, 3}; + const TArrayRef<const int> rx{x}; + auto i = rx.crbegin(); + UNIT_ASSERT_VALUES_EQUAL(*i, 3); + ++i; + UNIT_ASSERT_VALUES_EQUAL(*i, 2); + ++i; + UNIT_ASSERT_VALUES_EQUAL(*i, 1); + ++i; + UNIT_ASSERT_EQUAL(i, rx.crend()); + } + + Y_UNIT_TEST(TestConstIterators) { + int x[] = {1, 2, 3}; + TArrayRef<int> rx{x}; + UNIT_ASSERT_EQUAL(rx.begin(), rx.cbegin()); + UNIT_ASSERT_EQUAL(rx.end(), rx.cend()); + UNIT_ASSERT_EQUAL(rx.rbegin(), rx.crbegin()); + UNIT_ASSERT_EQUAL(rx.rend(), rx.crend()); + + int w[] = {1, 2, 3}; + const TArrayRef<int> rw{w}; + UNIT_ASSERT_EQUAL(rw.begin(), rw.cbegin()); + UNIT_ASSERT_EQUAL(rw.end(), rw.cend()); + UNIT_ASSERT_EQUAL(rw.rbegin(), rw.crbegin()); + UNIT_ASSERT_EQUAL(rw.rend(), rw.crend()); + + int y[] = {1, 2, 3}; + TArrayRef<const int> ry{y}; + UNIT_ASSERT_EQUAL(ry.begin(), ry.cbegin()); + UNIT_ASSERT_EQUAL(ry.end(), ry.cend()); + UNIT_ASSERT_EQUAL(ry.rbegin(), ry.crbegin()); + UNIT_ASSERT_EQUAL(ry.rend(), ry.crend()); + + const int z[] = {1, 2, 3}; + TArrayRef<const int> rz{z}; + UNIT_ASSERT_EQUAL(rz.begin(), rz.cbegin()); + UNIT_ASSERT_EQUAL(rz.end(), rz.cend()); + UNIT_ASSERT_EQUAL(rz.rbegin(), rz.crbegin()); + UNIT_ASSERT_EQUAL(rz.rend(), rz.crend()); + + const int q[] = {1, 2, 3}; + const TArrayRef<const int> rq{q}; + UNIT_ASSERT_EQUAL(rq.begin(), rq.cbegin()); + UNIT_ASSERT_EQUAL(rq.end(), rq.cend()); + UNIT_ASSERT_EQUAL(rq.rbegin(), rq.crbegin()); + UNIT_ASSERT_EQUAL(rq.rend(), rq.crend()); } - Y_UNIT_TEST(TestConstIterators) { - int x[] = {1, 2, 3}; - TArrayRef<int> rx{x}; - UNIT_ASSERT_EQUAL(rx.begin(), rx.cbegin()); - UNIT_ASSERT_EQUAL(rx.end(), rx.cend()); - UNIT_ASSERT_EQUAL(rx.rbegin(), rx.crbegin()); - UNIT_ASSERT_EQUAL(rx.rend(), rx.crend()); - - int w[] = {1, 2, 3}; - const TArrayRef<int> rw{w}; - UNIT_ASSERT_EQUAL(rw.begin(), rw.cbegin()); - UNIT_ASSERT_EQUAL(rw.end(), rw.cend()); - UNIT_ASSERT_EQUAL(rw.rbegin(), rw.crbegin()); - UNIT_ASSERT_EQUAL(rw.rend(), rw.crend()); - - int y[] = {1, 2, 3}; - TArrayRef<const int> ry{y}; - UNIT_ASSERT_EQUAL(ry.begin(), ry.cbegin()); - UNIT_ASSERT_EQUAL(ry.end(), ry.cend()); - UNIT_ASSERT_EQUAL(ry.rbegin(), ry.crbegin()); - UNIT_ASSERT_EQUAL(ry.rend(), ry.crend()); - - const int z[] = {1, 2, 3}; - TArrayRef<const int> rz{z}; - UNIT_ASSERT_EQUAL(rz.begin(), rz.cbegin()); - UNIT_ASSERT_EQUAL(rz.end(), rz.cend()); - UNIT_ASSERT_EQUAL(rz.rbegin(), rz.crbegin()); - UNIT_ASSERT_EQUAL(rz.rend(), rz.crend()); - - const int q[] = {1, 2, 3}; - const TArrayRef<const int> rq{q}; - UNIT_ASSERT_EQUAL(rq.begin(), rq.cbegin()); - UNIT_ASSERT_EQUAL(rq.end(), rq.cend()); - UNIT_ASSERT_EQUAL(rq.rbegin(), rq.crbegin()); - UNIT_ASSERT_EQUAL(rq.rend(), rq.crend()); - } - - Y_UNIT_TEST(TestCreatingFromStringLiteral) { - TConstArrayRef<char> knownSizeRef("123", 3); + Y_UNIT_TEST(TestCreatingFromStringLiteral) { + TConstArrayRef<char> knownSizeRef("123", 3); size_t ret = 0; - for (char ch : knownSizeRef) { + for (char ch : knownSizeRef) { ret += ch - '0'; } UNIT_ASSERT_VALUES_EQUAL(ret, 6); - UNIT_ASSERT_VALUES_EQUAL(knownSizeRef.size(), 3); - UNIT_ASSERT_VALUES_EQUAL(knownSizeRef.at(0), '1'); - - /* - * When TArrayRef is being constructed from string literal, - * trailing zero will be added into it. - */ - TConstArrayRef<char> autoSizeRef("456"); - UNIT_ASSERT_VALUES_EQUAL(autoSizeRef[0], '4'); - UNIT_ASSERT_VALUES_EQUAL(autoSizeRef[3], '\0'); + UNIT_ASSERT_VALUES_EQUAL(knownSizeRef.size(), 3); + UNIT_ASSERT_VALUES_EQUAL(knownSizeRef.at(0), '1'); + + /* + * When TArrayRef is being constructed from string literal, + * trailing zero will be added into it. + */ + TConstArrayRef<char> autoSizeRef("456"); + UNIT_ASSERT_VALUES_EQUAL(autoSizeRef[0], '4'); + UNIT_ASSERT_VALUES_EQUAL(autoSizeRef[3], '\0'); } - Y_UNIT_TEST(TestEqualityOperator) { + Y_UNIT_TEST(TestEqualityOperator) { static constexpr size_t size = 5; int a[size]{1, 2, 3, 4, 5}; int b[size]{5, 4, 3, 2, 1}; int c[size - 1]{5, 4, 3, 2}; float d[size]{1.f, 2.f, 3.f, 4.f, 5.f}; - TArrayRef<int> aRef(a); - TConstArrayRef<int> aConstRef(a, size); + TArrayRef<int> aRef(a); + TConstArrayRef<int> aConstRef(a, size); - TArrayRef<int> bRef(b); + TArrayRef<int> bRef(b); - TArrayRef<int> cRef(c, size - 1); + TArrayRef<int> cRef(c, size - 1); - TArrayRef<float> dRef(d, size); - TConstArrayRef<float> dConstRef(d, size); + TArrayRef<float> dRef(d, size); + TConstArrayRef<float> dConstRef(d, size); - UNIT_ASSERT_EQUAL(aRef, aConstRef); - UNIT_ASSERT_EQUAL(dRef, dConstRef); + UNIT_ASSERT_EQUAL(aRef, aConstRef); + UNIT_ASSERT_EQUAL(dRef, dConstRef); - UNIT_ASSERT_UNEQUAL(aRef, cRef); - UNIT_ASSERT_UNEQUAL(aRef, bRef); - - TArrayRef<int> bSubRef(b, size - 1); - - //Testing if operator== compares values, not pointers - UNIT_ASSERT_EQUAL(cRef, bSubRef); + UNIT_ASSERT_UNEQUAL(aRef, cRef); + UNIT_ASSERT_UNEQUAL(aRef, bRef); + + TArrayRef<int> bSubRef(b, size - 1); + + //Testing if operator== compares values, not pointers + UNIT_ASSERT_EQUAL(cRef, bSubRef); } - Y_UNIT_TEST(TestImplicitConstructionFromContainer) { + Y_UNIT_TEST(TestImplicitConstructionFromContainer) { /* Just test compilation. */ auto fc = [](TArrayRef<const int>) {}; auto fm = [](TArrayRef<int>) {}; @@ -185,16 +185,16 @@ Y_UNIT_TEST_SUITE(TestArrayRef) { // fm(ac); // This one shouldn't compile. } - Y_UNIT_TEST(TestFirstLastSubspan) { - const int arr[] = {1, 2, 3, 4, 5}; - TArrayRef<const int> aRef(arr); - - UNIT_ASSERT_EQUAL(aRef.first(2), MakeArrayRef(std::vector<int>{1, 2})); - UNIT_ASSERT_EQUAL(aRef.last(2), MakeArrayRef(std::vector<int>{4, 5})); - UNIT_ASSERT_EQUAL(aRef.subspan(2), MakeArrayRef(std::vector<int>{3, 4, 5})); - UNIT_ASSERT_EQUAL(aRef.subspan(1, 3), MakeArrayRef(std::vector<int>{2, 3, 4})); - } - + Y_UNIT_TEST(TestFirstLastSubspan) { + const int arr[] = {1, 2, 3, 4, 5}; + TArrayRef<const int> aRef(arr); + + UNIT_ASSERT_EQUAL(aRef.first(2), MakeArrayRef(std::vector<int>{1, 2})); + UNIT_ASSERT_EQUAL(aRef.last(2), MakeArrayRef(std::vector<int>{4, 5})); + UNIT_ASSERT_EQUAL(aRef.subspan(2), MakeArrayRef(std::vector<int>{3, 4, 5})); + UNIT_ASSERT_EQUAL(aRef.subspan(1, 3), MakeArrayRef(std::vector<int>{2, 3, 4})); + } + Y_UNIT_TEST(TestSlice) { const int a0[] = {1, 2, 3}; TArrayRef<const int> r0(a0); @@ -209,71 +209,71 @@ Y_UNIT_TEST_SUITE(TestArrayRef) { UNIT_ASSERT_VALUES_EQUAL(s1.size(), 1); UNIT_ASSERT_VALUES_EQUAL(s1[0], 3); - - //FIXME: size checks are implemented via Y_ASSERT, hence there is no way to test them + + //FIXME: size checks are implemented via Y_ASSERT, hence there is no way to test them } - Y_UNIT_TEST(SubRegion) { - TVector<char> x; - for (size_t i = 0; i < 42; ++i) { - x.push_back('a' + (i * 42424243) % 13); - } - TArrayRef<const char> ref(x.data(), 42); - for (size_t i = 0; i <= 50; ++i) { - TVector<char> expected; - for (size_t j = 0; j <= 100; ++j) { - UNIT_ASSERT(MakeArrayRef(expected) == ref.SubRegion(i, j)); - if (i + j < 42) { - expected.push_back(x[i + j]); - } - } - } - } - - Y_UNIT_TEST(TestAsBytes) { - const int16_t constArr[] = {1, 2, 3}; - TArrayRef<const int16_t> constRef(constArr); - auto bytesRef = as_bytes(constRef); - - UNIT_ASSERT_VALUES_EQUAL(bytesRef.size(), sizeof(int16_t) * constRef.size()); - UNIT_ASSERT_EQUAL( - bytesRef, + Y_UNIT_TEST(SubRegion) { + TVector<char> x; + for (size_t i = 0; i < 42; ++i) { + x.push_back('a' + (i * 42424243) % 13); + } + TArrayRef<const char> ref(x.data(), 42); + for (size_t i = 0; i <= 50; ++i) { + TVector<char> expected; + for (size_t j = 0; j <= 100; ++j) { + UNIT_ASSERT(MakeArrayRef(expected) == ref.SubRegion(i, j)); + if (i + j < 42) { + expected.push_back(x[i + j]); + } + } + } + } + + Y_UNIT_TEST(TestAsBytes) { + const int16_t constArr[] = {1, 2, 3}; + TArrayRef<const int16_t> constRef(constArr); + auto bytesRef = as_bytes(constRef); + + UNIT_ASSERT_VALUES_EQUAL(bytesRef.size(), sizeof(int16_t) * constRef.size()); + UNIT_ASSERT_EQUAL( + bytesRef, MakeArrayRef(std::vector<char>{0x01, 0x00, 0x02, 0x00, 0x03, 0x00})); - - //should not compile - //as_writable_bytes(constRef); - } - - Y_UNIT_TEST(TestAsWritableBytes) { - uint32_t uintArr[] = {0x0c'00'0d'0e}; - TArrayRef<uint32_t> uintRef(uintArr); - auto writableBytesRef = as_writable_bytes(uintRef); - - UNIT_ASSERT_VALUES_EQUAL(writableBytesRef.size(), sizeof(uint32_t)); - UNIT_ASSERT_EQUAL( - writableBytesRef, + + //should not compile + //as_writable_bytes(constRef); + } + + Y_UNIT_TEST(TestAsWritableBytes) { + uint32_t uintArr[] = {0x0c'00'0d'0e}; + TArrayRef<uint32_t> uintRef(uintArr); + auto writableBytesRef = as_writable_bytes(uintRef); + + UNIT_ASSERT_VALUES_EQUAL(writableBytesRef.size(), sizeof(uint32_t)); + UNIT_ASSERT_EQUAL( + writableBytesRef, MakeArrayRef(std::vector<char>{0x0e, 0x0d, 0x00, 0x0c})); - - uint32_t newVal = 0xde'ad'be'ef; - std::memcpy(writableBytesRef.data(), &newVal, writableBytesRef.size()); - UNIT_ASSERT_VALUES_EQUAL(uintArr[0], newVal); - } - - Y_UNIT_TEST(TestTypeDeductionViaMakeArrayRef) { - TVector<int> vec{17, 19, 21}; - TArrayRef<int> ref = MakeArrayRef(vec); - UNIT_ASSERT_VALUES_EQUAL(21, ref[2]); - ref[1] = 23; - UNIT_ASSERT_VALUES_EQUAL(23, vec[1]); - - const TVector<int>& constVec(vec); - TArrayRef<const int> constRef = MakeArrayRef(constVec); - UNIT_ASSERT_VALUES_EQUAL(21, constRef[2]); - - TArrayRef<const int> constRefFromNonConst = MakeArrayRef(vec); - UNIT_ASSERT_VALUES_EQUAL(23, constRefFromNonConst[1]); - } - + + uint32_t newVal = 0xde'ad'be'ef; + std::memcpy(writableBytesRef.data(), &newVal, writableBytesRef.size()); + UNIT_ASSERT_VALUES_EQUAL(uintArr[0], newVal); + } + + Y_UNIT_TEST(TestTypeDeductionViaMakeArrayRef) { + TVector<int> vec{17, 19, 21}; + TArrayRef<int> ref = MakeArrayRef(vec); + UNIT_ASSERT_VALUES_EQUAL(21, ref[2]); + ref[1] = 23; + UNIT_ASSERT_VALUES_EQUAL(23, vec[1]); + + const TVector<int>& constVec(vec); + TArrayRef<const int> constRef = MakeArrayRef(constVec); + UNIT_ASSERT_VALUES_EQUAL(21, constRef[2]); + + TArrayRef<const int> constRefFromNonConst = MakeArrayRef(vec); + UNIT_ASSERT_VALUES_EQUAL(23, constRefFromNonConst[1]); + } + static void Do(const TArrayRef<int> a) { a[0] = 8; } @@ -287,16 +287,16 @@ Y_UNIT_TEST_SUITE(TestArrayRef) { Y_UNIT_TEST(TestConstexpr) { static constexpr const int a[] = {1, 2, -3, -4}; static constexpr const auto r0 = MakeArrayRef(a, 1); - static_assert(r0.size() == 1, "r0.size() is not equal 1"); - static_assert(r0.data()[0] == 1, "r0.data()[0] is not equal to 1"); - + static_assert(r0.size() == 1, "r0.size() is not equal 1"); + static_assert(r0.data()[0] == 1, "r0.data()[0] is not equal to 1"); + static constexpr const TArrayRef<const int> r1{a}; - static_assert(r1.size() == 4, "r1.size() is not equal to 4"); - static_assert(r1.data()[3] == -4, "r1.data()[3] is not equal to -4"); - + static_assert(r1.size() == 4, "r1.size() is not equal to 4"); + static_assert(r1.data()[3] == -4, "r1.data()[3] is not equal to -4"); + static constexpr const TArrayRef<const int> r2 = r1; - static_assert(r2.size() == 4, "r2.size() is not equal to 4"); - static_assert(r2.data()[2] == -3, "r2.data()[2] is not equal to -3"); + static_assert(r2.size() == 4, "r2.size() is not equal to 4"); + static_assert(r2.data()[2] == -3, "r2.data()[2] is not equal to -3"); } template <typename T> diff --git a/util/generic/bitops.h b/util/generic/bitops.h index a66fcf4a00..2db15fc59b 100644 --- a/util/generic/bitops.h +++ b/util/generic/bitops.h @@ -216,7 +216,7 @@ static inline T FastClp2(T t) noexcept { * Check if integer is a power of 2. */ template <typename T> -Y_CONST_FUNCTION constexpr bool IsPowerOf2(T v) noexcept { +Y_CONST_FUNCTION constexpr bool IsPowerOf2(T v) noexcept { return v > 0 && (v & (v - 1)) == 0; } diff --git a/util/generic/buffer.h b/util/generic/buffer.h index 864828c889..9576467404 100644 --- a/util/generic/buffer.h +++ b/util/generic/buffer.h @@ -2,7 +2,7 @@ #include "utility.h" -#include <util/generic/fwd.h> +#include <util/generic/fwd.h> #include <util/system/align.h> #include <util/system/yassert.h> diff --git a/util/generic/deque.h b/util/generic/deque.h index 8717de8183..2dabaf3177 100644 --- a/util/generic/deque.h +++ b/util/generic/deque.h @@ -8,12 +8,12 @@ #include <memory> #include <initializer_list> -template <class T, class A> +template <class T, class A> class TDeque: public std::deque<T, TReboundAllocator<A, T>> { - using TBase = std::deque<T, TReboundAllocator<A, T>>; + using TBase = std::deque<T, TReboundAllocator<A, T>>; public: - using TBase::TBase; + using TBase::TBase; inline yssize_t ysize() const noexcept { return (yssize_t)this->size(); diff --git a/util/generic/fwd.h b/util/generic/fwd.h index 246947bc7a..5cc2da40e5 100644 --- a/util/generic/fwd.h +++ b/util/generic/fwd.h @@ -5,19 +5,19 @@ #include <stlfwd> template <typename TCharType, typename TTraits = std::char_traits<TCharType>> -class TBasicString; - -using TString = TBasicString<char>; -using TUtf16String = TBasicString<wchar16>; -using TUtf32String = TBasicString<wchar32>; - +class TBasicString; + +using TString = TBasicString<char>; +using TUtf16String = TBasicString<wchar16>; +using TUtf32String = TBasicString<wchar32>; + template <typename TCharType, typename TTraits = std::char_traits<TCharType>> -class TBasicStringBuf; - -using TStringBuf = TBasicStringBuf<char>; -using TWtringBuf = TBasicStringBuf<wchar16>; -using TUtf32StringBuf = TBasicStringBuf<wchar32>; - +class TBasicStringBuf; + +using TStringBuf = TBasicStringBuf<char>; +using TWtringBuf = TBasicStringBuf<wchar16>; +using TUtf32StringBuf = TBasicStringBuf<wchar32>; + //misc class TBuffer; diff --git a/util/generic/hash_ut.cpp b/util/generic/hash_ut.cpp index 2322ed4d9d..0551d58770 100644 --- a/util/generic/hash_ut.cpp +++ b/util/generic/hash_ut.cpp @@ -160,9 +160,9 @@ void THashTest::TestHMapConstructorsAndAssignments() { UNIT_ASSERT_VALUES_EQUAL(2, c4.at("two")); UNIT_ASSERT_VALUES_EQUAL(3, c4.at("three")); UNIT_ASSERT_VALUES_EQUAL(4, c4.at("four")); - - // non-existent values must be zero-initialized - UNIT_ASSERT_VALUES_EQUAL(c1["nonexistent"], 0); + + // non-existent values must be zero-initialized + UNIT_ASSERT_VALUES_EQUAL(c1["nonexistent"], 0); } void THashTest::TestHMap1() { @@ -807,18 +807,18 @@ public: { } - T* allocate(size_type n) { - auto result = base_type::allocate(n); + T* allocate(size_type n) { + auto result = base_type::allocate(n); if (Counters_) { ++Counters_->Allocations; - Counters_->Chunks.emplace(result, n * sizeof(T)); + Counters_->Chunks.emplace(result, n * sizeof(T)); } return result; } - void deallocate(T* p, size_type n) { + void deallocate(T* p, size_type n) { if (Counters_) { ++Counters_->Deallocations; Counters_->Chunks.erase(std::make_pair(p, n * sizeof(T))); diff --git a/util/generic/list.h b/util/generic/list.h index cb23527624..7b0b8ffc72 100644 --- a/util/generic/list.h +++ b/util/generic/list.h @@ -13,8 +13,8 @@ template <class T, class A> class TList: public std::list<T, TReboundAllocator<A, T>> { using TBase = std::list<T, TReboundAllocator<A, T>>; -public: - using TBase::TBase; +public: + using TBase::TBase; inline explicit operator bool() const noexcept { return !this->empty(); diff --git a/util/generic/map.h b/util/generic/map.h index 7690f82636..b5001b56c0 100644 --- a/util/generic/map.h +++ b/util/generic/map.h @@ -16,7 +16,7 @@ class TMap: public std::map<K, V, Less, TReboundAllocator<A, std::pair<const K, using TBase = std::map<K, V, Less, TReboundAllocator<A, std::pair<const K, V>>>; public: - using TBase::TBase; + using TBase::TBase; inline explicit operator bool() const noexcept { return !this->empty(); @@ -32,7 +32,7 @@ class TMultiMap: public std::multimap<K, V, Less, TReboundAllocator<A, std::pair using TBase = std::multimap<K, V, Less, TReboundAllocator<A, std::pair<const K, V>>>; public: - using TBase::TBase; + using TBase::TBase; inline explicit operator bool() const noexcept { return !this->empty(); diff --git a/util/generic/ptr.h b/util/generic/ptr.h index 10b54f0054..19db0e3ec5 100644 --- a/util/generic/ptr.h +++ b/util/generic/ptr.h @@ -213,10 +213,10 @@ public: } #ifdef __cpp_impl_three_way_comparison - template <class Other> - inline bool operator==(const Other& p) const noexcept { - return (p == Get()); - } + template <class Other> + inline bool operator==(const Other& p) const noexcept { + return (p == Get()); + } #endif private: inline void DoDestroy() noexcept { @@ -328,10 +328,10 @@ public: } #ifdef __cpp_impl_three_way_comparison - template <class Other> - inline bool operator==(const Other& p) const noexcept { - return (p == Get()); - } + template <class Other> + inline bool operator==(const Other& p) const noexcept { + return (p == Get()); + } #endif private: inline void DoDestroy() noexcept { @@ -580,10 +580,10 @@ public: } #ifdef __cpp_impl_three_way_comparison - template <class Other> - inline bool operator==(const Other& p) const noexcept { - return (p == Get()); - } + template <class Other> + inline bool operator==(const Other& p) const noexcept { + return (p == Get()); + } #endif private: inline void Ref() noexcept { @@ -691,10 +691,10 @@ public: } #ifdef __cpp_impl_three_way_comparison - template <class Other> - inline bool operator==(const Other& p) const noexcept { - return (p == Get()); - } + template <class Other> + inline bool operator==(const Other& p) const noexcept { + return (p == Get()); + } #endif private: inline void Ref() noexcept { @@ -895,10 +895,10 @@ public: } #ifdef __cpp_impl_three_way_comparison - template <class Other> - inline bool operator==(const Other& p) const noexcept { - return (p == Get()); - } + template <class Other> + inline bool operator==(const Other& p) const noexcept { + return (p == Get()); + } #endif private: template <class X> @@ -1039,10 +1039,10 @@ public: } #ifdef __cpp_impl_three_way_comparison - template <class Other> - inline bool operator==(const Other& p) const noexcept { - return (p == Get()); - } + template <class Other> + inline bool operator==(const Other& p) const noexcept { + return (p == Get()); + } #endif private: inline void DoDestroy() noexcept { @@ -1103,10 +1103,10 @@ public: } #ifdef __cpp_impl_three_way_comparison - template <class Other> - inline bool operator==(const Other& p) const noexcept { - return (p == Get()); - } + template <class Other> + inline bool operator==(const Other& p) const noexcept { + return (p == Get()); + } #endif private: inline void Unshare() { diff --git a/util/generic/queue.h b/util/generic/queue.h index f3c8bc0898..f5959f68f2 100644 --- a/util/generic/queue.h +++ b/util/generic/queue.h @@ -14,7 +14,7 @@ class TQueue: public std::queue<T, S> { using TBase = std::queue<T, S>; public: - using TBase::TBase; + using TBase::TBase; inline explicit operator bool() const noexcept { return !this->empty(); @@ -35,10 +35,10 @@ public: template <class T, class S, class C> class TPriorityQueue: public std::priority_queue<T, S, C> { - using TBase = std::priority_queue<T, S, C>; + using TBase = std::priority_queue<T, S, C>; public: - using TBase::TBase; + using TBase::TBase; inline explicit operator bool() const noexcept { return !this->empty(); diff --git a/util/generic/set.h b/util/generic/set.h index 4ca2916064..4c437ca26f 100644 --- a/util/generic/set.h +++ b/util/generic/set.h @@ -11,9 +11,9 @@ template <class K, class L, class A> class TSet: public std::set<K, L, TReboundAllocator<A, K>> { -public: +public: using TBase = std::set<K, L, TReboundAllocator<A, K>>; - using TBase::TBase; + using TBase::TBase; inline explicit operator bool() const noexcept { return !this->empty(); @@ -27,9 +27,9 @@ public: template <class K, class L, class A> class TMultiSet: public std::multiset<K, L, TReboundAllocator<A, K>> { -public: +public: using TBase = std::multiset<K, L, TReboundAllocator<A, K>>; - using TBase::TBase; + using TBase::TBase; inline explicit operator bool() const noexcept { return !this->empty(); diff --git a/util/generic/stack.h b/util/generic/stack.h index 6d67d3a703..dbcbf2b5c9 100644 --- a/util/generic/stack.h +++ b/util/generic/stack.h @@ -10,7 +10,7 @@ class TStack: public std::stack<T, S> { using TBase = std::stack<T, S>; public: - using TBase::TBase; + using TBase::TBase; inline explicit operator bool() const noexcept { return !this->empty(); diff --git a/util/generic/strbase.h b/util/generic/strbase.h index f4b303e058..ab39fc7537 100644 --- a/util/generic/strbase.h +++ b/util/generic/strbase.h @@ -45,11 +45,11 @@ public: using TSelf = TStringBase<TDerived, TChar, TTraits>; using size_type = size_t; - using difference_type = ptrdiff_t; + using difference_type = ptrdiff_t; static constexpr size_t npos = size_t(-1); using const_iterator = const TCharType*; - using const_reference = const TCharType&; + using const_reference = const TCharType&; template <typename TBase> struct TReverseIteratorBase { @@ -106,21 +106,21 @@ public: }; using const_reverse_iterator = TReverseIteratorBase<const_iterator>; - static constexpr size_t StrLen(const TCharType* s) noexcept { + static constexpr size_t StrLen(const TCharType* s) noexcept { if (Y_LIKELY(s)) { - return TTraits::length(s); + return TTraits::length(s); } return 0; } - template <class TCharTraits> - inline constexpr operator std::basic_string_view<TCharType, TCharTraits>() const { + template <class TCharTraits> + inline constexpr operator std::basic_string_view<TCharType, TCharTraits>() const { return std::basic_string_view<TCharType, TCharTraits>(data(), size()); - } - - template <class TCharTraits, class Allocator> + } + + template <class TCharTraits, class Allocator> inline explicit operator std::basic_string<TCharType, TCharTraits, Allocator>() const { - return std::basic_string<TCharType, TCharTraits, Allocator>(Ptr(), Len()); + return std::basic_string<TCharType, TCharTraits, Allocator>(Ptr(), Len()); } /** @@ -327,16 +327,16 @@ public: } template <typename TDerived2, typename TTraits2> - bool operator==(const TStringBase<TDerived2, TChar, TTraits2>& s2) const noexcept { - return equal(*this, s2); + bool operator==(const TStringBase<TDerived2, TChar, TTraits2>& s2) const noexcept { + return equal(*this, s2); + } + + bool operator==(TStringView s2) const noexcept { + return equal(*this, s2); } - bool operator==(TStringView s2) const noexcept { - return equal(*this, s2); - } - - bool operator==(const TCharType* pc) const noexcept { - return equal(*this, pc); + bool operator==(const TCharType* pc) const noexcept { + return equal(*this, pc); } #ifndef __cpp_impl_three_way_comparison @@ -349,10 +349,10 @@ public: return !(s1 == s2); } - friend bool operator!=(const TSelf& s1, TStringView s2) noexcept { - return !(s1 == s2); - } - + friend bool operator!=(const TSelf& s1, TStringView s2) noexcept { + return !(s1 == s2); + } + friend bool operator!=(const TSelf& s, const TCharType* pc) noexcept { return !(s == pc); } @@ -367,10 +367,10 @@ public: return compare(s1, s2) < 0; } - friend bool operator<(const TSelf& s1, TStringView s2) noexcept { - return compare(s1, s2) < 0; - } - + friend bool operator<(const TSelf& s1, TStringView s2) noexcept { + return compare(s1, s2) < 0; + } + friend bool operator<(const TSelf& s, const TCharType* pc) noexcept { return compare(s, pc) < 0; } @@ -384,10 +384,10 @@ public: return compare(s1, s2) <= 0; } - friend bool operator<=(const TSelf& s1, TStringView s2) noexcept { - return compare(s1, s2) <= 0; - } - + friend bool operator<=(const TSelf& s1, TStringView s2) noexcept { + return compare(s1, s2) <= 0; + } + friend bool operator<=(const TSelf& s, const TCharType* pc) noexcept { return compare(s, pc) <= 0; } @@ -401,10 +401,10 @@ public: return compare(s1, s2) > 0; } - friend bool operator>(const TSelf& s1, TStringView s2) noexcept { - return compare(s1, s2) > 0; - } - + friend bool operator>(const TSelf& s1, TStringView s2) noexcept { + return compare(s1, s2) > 0; + } + friend bool operator>(const TSelf& s, const TCharType* pc) noexcept { return compare(s, pc) > 0; } @@ -418,10 +418,10 @@ public: return compare(s1, s2) >= 0; } - friend bool operator>=(const TSelf& s1, TStringView s2) noexcept { - return compare(s1, s2) >= 0; - } - + friend bool operator>=(const TSelf& s1, TStringView s2) noexcept { + return compare(s1, s2) >= 0; + } + friend bool operator>=(const TSelf& s, const TCharType* pc) noexcept { return compare(s, pc) >= 0; } @@ -452,10 +452,10 @@ public: return find(s.data(), pos, s.size()); } - inline size_t find(const TCharType* s, size_t pos, size_t count) const noexcept { + inline size_t find(const TCharType* s, size_t pos, size_t count) const noexcept { return AsStringView().find(s, pos, count); - } - + } + inline size_t find(TCharType c, size_t pos = 0) const noexcept { return AsStringView().find(c, pos); } @@ -550,7 +550,7 @@ public: inline size_t copy(TCharType* pc, size_t n, size_t pos) const { if (pos > Len()) { - throw std::out_of_range("TStringBase::copy"); + throw std::out_of_range("TStringBase::copy"); } return CopyImpl(pc, n, pos); @@ -600,7 +600,7 @@ private: inline size_t CopyImpl(TCharType* pc, size_t n, size_t pos) const noexcept { const size_t toCopy = Min(Len() - pos, n); - TTraits::copy(pc, Ptr() + pos, toCopy); + TTraits::copy(pc, Ptr() + pos, toCopy); return toCopy; } diff --git a/util/generic/strbuf.cpp b/util/generic/strbuf.cpp index affb7b3d1e..668602ca16 100644 --- a/util/generic/strbuf.cpp +++ b/util/generic/strbuf.cpp @@ -1,9 +1,9 @@ #include "strbuf.h" #include <util/stream/output.h> -#include <ostream> +#include <ostream> std::ostream& operator<<(std::ostream& os, TStringBuf buf) { - os.write(buf.data(), buf.size()); - return os; -} + os.write(buf.data(), buf.size()); + return os; +} diff --git a/util/generic/strbuf.h b/util/generic/strbuf.h index 8d6483f72c..70b9360d58 100644 --- a/util/generic/strbuf.h +++ b/util/generic/strbuf.h @@ -5,144 +5,144 @@ #include "utility.h" #include "typetraits.h" -#include <string_view> - -using namespace std::string_view_literals; - -template <typename TCharType, typename TTraits> +#include <string_view> + +using namespace std::string_view_literals; + +template <typename TCharType, typename TTraits> class TBasicStringBuf: public std::basic_string_view<TCharType>, public TStringBase<TBasicStringBuf<TCharType, TTraits>, TCharType, TTraits> { -private: +private: using TdSelf = TBasicStringBuf; - using TBase = TStringBase<TdSelf, TCharType, TTraits>; - using TStringView = std::basic_string_view<TCharType>; + using TBase = TStringBase<TdSelf, TCharType, TTraits>; + using TStringView = std::basic_string_view<TCharType>; public: - using char_type = TCharType; // TODO: DROP + using char_type = TCharType; // TODO: DROP using traits_type = TTraits; - //Resolving some ambiguity between TStringBase and std::basic_string_view - //for typenames - using typename TStringView::const_iterator; + //Resolving some ambiguity between TStringBase and std::basic_string_view + //for typenames + using typename TStringView::const_iterator; using typename TStringView::const_reference; - using typename TStringView::const_reverse_iterator; + using typename TStringView::const_reverse_iterator; using typename TStringView::iterator; - using typename TStringView::reference; + using typename TStringView::reference; using typename TStringView::reverse_iterator; using typename TStringView::size_type; using typename TStringView::value_type; - - //for constants - using TStringView::npos; - - //for methods and operators - using TStringView::begin; - using TStringView::cbegin; - using TStringView::cend; + + //for constants + using TStringView::npos; + + //for methods and operators + using TStringView::begin; + using TStringView::cbegin; + using TStringView::cend; using TStringView::crbegin; using TStringView::crend; using TStringView::end; - using TStringView::rbegin; - using TStringView::rend; - + using TStringView::rbegin; + using TStringView::rend; + using TStringView::data; using TStringView::empty; - using TStringView::size; - - using TStringView::operator[]; - - /* - * WARN: - * TBase::at silently return 0 in case of range error, - * while std::string_view throws std::out_of_range. - */ - using TBase::at; + using TStringView::size; + + using TStringView::operator[]; + + /* + * WARN: + * TBase::at silently return 0 in case of range error, + * while std::string_view throws std::out_of_range. + */ + using TBase::at; using TStringView::back; - using TStringView::front; - - using TStringView::find; - /* - * WARN: - * TBase::*find* methods take into account TCharTraits, - * while TTStringView::*find* would use default std::char_traits. - */ + using TStringView::front; + + using TStringView::find; + /* + * WARN: + * TBase::*find* methods take into account TCharTraits, + * while TTStringView::*find* would use default std::char_traits. + */ using TBase::find_first_not_of; - using TBase::find_first_of; + using TBase::find_first_of; using TBase::find_last_not_of; - using TBase::find_last_of; + using TBase::find_last_of; using TBase::rfind; - - using TStringView::copy; - /* - * WARN: - * TBase::compare takes into account TCharTraits, - * thus making it possible to implement case-insensitive string buffers, - * if it is using TStringBase::compare - */ - using TBase::compare; - - /* - * WARN: - * TBase::substr properly checks boundary cases and clamps them with maximum valid values, - * while TStringView::substr throws std::out_of_range error. - */ - using TBase::substr; - - /* - * WARN: - * Constructing std::string_view(nullptr, non_zero_size) ctor - * results in undefined behavior according to the standard. - * In libc++ this UB results in runtime assertion, though it is better - * to generate compilation error instead. - */ - constexpr inline TBasicStringBuf(std::nullptr_t begin, size_t size) = delete; - - constexpr inline TBasicStringBuf(const TCharType* data, size_t size) noexcept - : TStringView(data, size) + + using TStringView::copy; + /* + * WARN: + * TBase::compare takes into account TCharTraits, + * thus making it possible to implement case-insensitive string buffers, + * if it is using TStringBase::compare + */ + using TBase::compare; + + /* + * WARN: + * TBase::substr properly checks boundary cases and clamps them with maximum valid values, + * while TStringView::substr throws std::out_of_range error. + */ + using TBase::substr; + + /* + * WARN: + * Constructing std::string_view(nullptr, non_zero_size) ctor + * results in undefined behavior according to the standard. + * In libc++ this UB results in runtime assertion, though it is better + * to generate compilation error instead. + */ + constexpr inline TBasicStringBuf(std::nullptr_t begin, size_t size) = delete; + + constexpr inline TBasicStringBuf(const TCharType* data, size_t size) noexcept + : TStringView(data, size) { } - constexpr TBasicStringBuf(const TCharType* data) noexcept - /* - * WARN: TBase::StrLen properly handles nullptr, - * while std::string_view (using std::char_traits) will abort in such case - */ - : TStringView(data, TBase::StrLen(data)) + constexpr TBasicStringBuf(const TCharType* data) noexcept + /* + * WARN: TBase::StrLen properly handles nullptr, + * while std::string_view (using std::char_traits) will abort in such case + */ + : TStringView(data, TBase::StrLen(data)) { } constexpr inline TBasicStringBuf(const TCharType* beg, const TCharType* end) noexcept - : TStringView(beg, end - beg) + : TStringView(beg, end - beg) { } template <typename D, typename T> - inline TBasicStringBuf(const TStringBase<D, TCharType, T>& str) noexcept - : TStringView(str.data(), str.size()) + inline TBasicStringBuf(const TStringBase<D, TCharType, T>& str) noexcept + : TStringView(str.data(), str.size()) { } template <typename T, typename A> - inline TBasicStringBuf(const std::basic_string<TCharType, T, A>& str) noexcept - : TStringView(str) + inline TBasicStringBuf(const std::basic_string<TCharType, T, A>& str) noexcept + : TStringView(str) + { + } + + template <typename TCharTraits> + constexpr TBasicStringBuf(std::basic_string_view<TCharType, TCharTraits> view) noexcept + : TStringView(view) { } - template <typename TCharTraits> - constexpr TBasicStringBuf(std::basic_string_view<TCharType, TCharTraits> view) noexcept - : TStringView(view) - { - } - constexpr inline TBasicStringBuf() noexcept { - /* - * WARN: - * This ctor can not be defaulted due to the following feature of default initialization: - * If T is a const-qualified type, it must be a class type with a user-provided default constructor. - * (see https://en.cppreference.com/w/cpp/language/default_initialization). - * - * This means, that a class with default ctor can not be a constant member of another class with default ctor. - */ + /* + * WARN: + * This ctor can not be defaulted due to the following feature of default initialization: + * If T is a const-qualified type, it must be a class type with a user-provided default constructor. + * (see https://en.cppreference.com/w/cpp/language/default_initialization). + * + * This means, that a class with default ctor can not be a constant member of another class with default ctor. + */ } inline TBasicStringBuf(const TBasicStringBuf& src, size_t pos, size_t n) noexcept @@ -157,9 +157,9 @@ public: } Y_PURE_FUNCTION inline TBasicStringBuf SubString(size_t pos, size_t n) const noexcept { - pos = Min(pos, size()); - n = Min(n, size() - pos); - return TBasicStringBuf(data() + pos, n); + pos = Min(pos, size()); + n = Min(n, size() - pos); + return TBasicStringBuf(data() + pos, n); } public: @@ -168,7 +168,7 @@ public: } constexpr bool IsInited() const noexcept { - return data() != nullptr; + return data() != nullptr; } public: @@ -183,7 +183,7 @@ public: * @param[out] r The second part of split result. * @returns Whether the split was actually performed. */ - inline bool TrySplit(TCharType delim, TdSelf& l, TdSelf& r) const noexcept { + inline bool TrySplit(TCharType delim, TdSelf& l, TdSelf& r) const noexcept { return TrySplitOn(TBase::find(delim), l, r); } @@ -198,7 +198,7 @@ public: * @param[out] r The second part of split result. * @returns Whether the split was actually performed. */ - inline bool TryRSplit(TCharType delim, TdSelf& l, TdSelf& r) const noexcept { + inline bool TryRSplit(TCharType delim, TdSelf& l, TdSelf& r) const noexcept { return TrySplitOn(TBase::rfind(delim), l, r); } @@ -232,11 +232,11 @@ public: return TrySplitOn(TBase::rfind(delim), l, r, delim.size()); } - inline void Split(TCharType delim, TdSelf& l, TdSelf& r) const noexcept { + inline void Split(TCharType delim, TdSelf& l, TdSelf& r) const noexcept { SplitTemplate(delim, l, r); } - inline void RSplit(TCharType delim, TdSelf& l, TdSelf& r) const noexcept { + inline void RSplit(TCharType delim, TdSelf& l, TdSelf& r) const noexcept { RSplitTemplate(delim, l, r); } @@ -262,7 +262,7 @@ private: public: // In all methods below with @pos parameter, @pos is supposed to be // a result of string find()/rfind()/find_first() or other similiar functions, - // returning either position within string length [0..size()) or npos. + // returning either position within string length [0..size()) or npos. // For all other @pos values (out of string index range) the behaviour isn't well defined // For example, for TStringBuf s("abc"): // s.TrySplitOn(s.find('z'), ...) is false, but s.TrySplitOn(100500, ...) is true. @@ -328,7 +328,7 @@ public: inline bool BeforeSuffix(const TdSelf& suffix, TdSelf& result) const noexcept { if (this->EndsWith(suffix)) { - result = Head(size() - suffix.size()); + result = Head(size() - suffix.size()); return true; } return false; @@ -377,19 +377,19 @@ public: */ public: - TdSelf SplitOff(TCharType delim) { + TdSelf SplitOff(TCharType delim) { TdSelf tok; Split(delim, *this, tok); return tok; } - TdSelf RSplitOff(TCharType delim) { + TdSelf RSplitOff(TCharType delim) { TdSelf tok; RSplit(delim, tok, *this); return tok; } - bool NextTok(TCharType delim, TdSelf& tok) { + bool NextTok(TCharType delim, TdSelf& tok) { return NextTokTemplate(delim, tok); } @@ -397,7 +397,7 @@ public: return NextTokTemplate(delim, tok); } - bool RNextTok(TCharType delim, TdSelf& tok) { + bool RNextTok(TCharType delim, TdSelf& tok) { return RNextTokTemplate(delim, tok); } @@ -408,7 +408,7 @@ public: bool ReadLine(TdSelf& tok) { if (NextTok('\n', tok)) { while (!tok.empty() && tok.back() == '\r') { - tok.remove_suffix(1); + tok.remove_suffix(1); } return true; @@ -417,11 +417,11 @@ public: return false; } - TdSelf NextTok(TCharType delim) { + TdSelf NextTok(TCharType delim) { return NextTokTemplate(delim); } - TdSelf RNextTok(TCharType delim) { + TdSelf RNextTok(TCharType delim) { return RNextTokTemplate(delim); } @@ -436,28 +436,28 @@ public: public: // string subsequences /// Cut last @c shift characters (or less if length is less than @c shift) inline TdSelf& Chop(size_t shift) noexcept { - this->remove_suffix(std::min(shift, size())); + this->remove_suffix(std::min(shift, size())); return *this; } /// Cut first @c shift characters (or less if length is less than @c shift) inline TdSelf& Skip(size_t shift) noexcept { - this->remove_prefix(std::min(shift, size())); + this->remove_prefix(std::min(shift, size())); return *this; } /// Sets the start pointer to a position relative to the end - inline TdSelf& RSeek(size_t tailSize) noexcept { - if (size() > tailSize) { - //WARN: removing TStringView:: will lead to an infinite recursion - *this = TStringView::substr(size() - tailSize, tailSize); + inline TdSelf& RSeek(size_t tailSize) noexcept { + if (size() > tailSize) { + //WARN: removing TStringView:: will lead to an infinite recursion + *this = TStringView::substr(size() - tailSize, tailSize); } return *this; } // coverity[exn_spec_violation] - inline TdSelf& Trunc(size_t targetSize) noexcept { + inline TdSelf& Trunc(size_t targetSize) noexcept { // Coverity false positive issue // exn_spec_violation: An exception of type "std::out_of_range" is thrown but the exception specification "noexcept" doesn't allow it to be thrown. This will result in a call to terminate(). // fun_call_w_exception: Called function TStringView::substr throws an exception of type "std::out_of_range". @@ -503,7 +503,7 @@ private: template <typename TDelimiterType> bool NextTokTemplate(TDelimiterType delim, TdSelf& tok) { - if (!empty()) { + if (!empty()) { tok = NextTokTemplate(delim); return true; } @@ -512,7 +512,7 @@ private: template <typename TDelimiterType> bool RNextTokTemplate(TDelimiterType delim, TdSelf& tok) { - if (!empty()) { + if (!empty()) { tok = RNextTokTemplate(delim); return true; } diff --git a/util/generic/strbuf_ut.cpp b/util/generic/strbuf_ut.cpp index fa7d961408..69cde785af 100644 --- a/util/generic/strbuf_ut.cpp +++ b/util/generic/strbuf_ut.cpp @@ -2,10 +2,10 @@ #include <library/cpp/testing/unittest/registar.h> -#include <string_view> - +#include <string_view> + Y_UNIT_TEST_SUITE(TStrBufTest) { - Y_UNIT_TEST(TestConstructorsAndOperators) { + Y_UNIT_TEST(TestConstructorsAndOperators) { TStringBuf str("qwerty"); UNIT_ASSERT_EQUAL(*str.data(), 'q'); @@ -16,14 +16,14 @@ Y_UNIT_TEST_SUITE(TStrBufTest) { UNIT_ASSERT_VALUES_UNEQUAL(str1, str2); UNIT_ASSERT_VALUES_EQUAL(str1.size(), 7); UNIT_ASSERT_VALUES_EQUAL(str2.size(), 3); - - std::string_view helloWorld("Hello, World!"); - TStringBuf fromStringView(helloWorld); - UNIT_ASSERT_EQUAL(fromStringView.data(), helloWorld.data()); + + std::string_view helloWorld("Hello, World!"); + TStringBuf fromStringView(helloWorld); + UNIT_ASSERT_EQUAL(fromStringView.data(), helloWorld.data()); UNIT_ASSERT_EQUAL(fromStringView.size(), helloWorld.size()); - - std::string_view fromStringBuf = fromStringView; - UNIT_ASSERT_EQUAL(helloWorld.data(), fromStringBuf.data()); + + std::string_view fromStringBuf = fromStringView; + UNIT_ASSERT_EQUAL(helloWorld.data(), fromStringBuf.data()); UNIT_ASSERT_EQUAL(helloWorld.size(), fromStringBuf.size()); } @@ -54,7 +54,7 @@ Y_UNIT_TEST_SUITE(TStrBufTest) { UNIT_ASSERT_VALUES_EQUAL(str.After('w'), TStringBuf("erty")); UNIT_ASSERT_VALUES_EQUAL(str.After('x'), TStringBuf("qwerty")); - UNIT_ASSERT_VALUES_EQUAL(str.After('y'), TStringBuf()); + UNIT_ASSERT_VALUES_EQUAL(str.After('y'), TStringBuf()); UNIT_ASSERT_STRINGS_EQUAL(str.After('='), str); // Also works properly on empty strings @@ -68,7 +68,7 @@ Y_UNIT_TEST_SUITE(TStrBufTest) { UNIT_ASSERT_VALUES_EQUAL(str.Before('w'), TStringBuf("q")); UNIT_ASSERT_VALUES_EQUAL(str.Before('x'), TStringBuf("qwerty")); UNIT_ASSERT_VALUES_EQUAL(str.Before('y'), TStringBuf("qwert")); - UNIT_ASSERT_VALUES_EQUAL(str.Before('q'), TStringBuf()); + UNIT_ASSERT_VALUES_EQUAL(str.Before('q'), TStringBuf()); } Y_UNIT_TEST(TestRAfterBefore) { @@ -207,18 +207,18 @@ Y_UNIT_TEST_SUITE(TStrBufTest) { TStringBuf buf("12\n45\r\n\r\n23"); TStringBuf tok; - buf.ReadLine(tok); - UNIT_ASSERT_VALUES_EQUAL(tok, "12"); - - buf.ReadLine(tok); - UNIT_ASSERT_VALUES_EQUAL(tok, "45"); - - buf.ReadLine(tok); - UNIT_ASSERT_VALUES_EQUAL(tok, ""); - - buf.ReadLine(tok); - UNIT_ASSERT_VALUES_EQUAL(tok, "23"); - + buf.ReadLine(tok); + UNIT_ASSERT_VALUES_EQUAL(tok, "12"); + + buf.ReadLine(tok); + UNIT_ASSERT_VALUES_EQUAL(tok, "45"); + + buf.ReadLine(tok); + UNIT_ASSERT_VALUES_EQUAL(tok, ""); + + buf.ReadLine(tok); + UNIT_ASSERT_VALUES_EQUAL(tok, "23"); + UNIT_ASSERT(!buf.ReadLine(tok)); } @@ -323,7 +323,7 @@ Y_UNIT_TEST_SUITE(TStrBufTest) { template <class T> void PassByConstReference(const T& val) { // In https://st.yandex-team.ru/IGNIETFERRO-294 was assumed that `const char[]` types are compile time strings - // and that CharTraits::Length may not be called for them. Unfortunately that is not true, `char[]` types + // and that CharTraits::Length may not be called for them. Unfortunately that is not true, `char[]` types // are easily converted to `const char[]` if they are passed to a function accepting `const T&`. UNIT_ASSERT(TStringBuf(val).size() == 5); } diff --git a/util/generic/strfcpy.cpp b/util/generic/strfcpy.cpp index f842b0219d..19b4da493e 100644 --- a/util/generic/strfcpy.cpp +++ b/util/generic/strfcpy.cpp @@ -1,35 +1,35 @@ -/* $OpenBSD: strlcpy.c,v 1.16 2019/01/25 00:19:25 millert Exp $ */ - +/* $OpenBSD: strlcpy.c,v 1.16 2019/01/25 00:19:25 millert Exp $ */ + /* - * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org> + * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org> * * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Modified version is + * Copyright (c) Alexey Galakhov */ -/* - * Modified version is - * Copyright (c) Alexey Galakhov - */ - #include "strfcpy.h" /* - * Copy string src to buffer dst of size dsize. At most dsize-1 - * chars will be copied. Always NUL terminates (unless dsize == 0). + * Copy string src to buffer dst of size dsize. At most dsize-1 + * chars will be copied. Always NUL terminates (unless dsize == 0). */ void strfcpy(char* dst, const char* src, size_t dsize) -{ +{ size_t nleft = dsize; /* Copy as many bytes as will fit. */ diff --git a/util/generic/strfcpy.h b/util/generic/strfcpy.h index 1955a18b6e..8a95bc3df2 100644 --- a/util/generic/strfcpy.h +++ b/util/generic/strfcpy.h @@ -1,11 +1,11 @@ #pragma once /* - * strfcpy is a faster version of strlcpy(). - * It returns void thus does not wastes time computing - * (most likely, unneeded) strlen(str) + * strfcpy is a faster version of strlcpy(). + * It returns void thus does not wastes time computing + * (most likely, unneeded) strlen(str) * - * Comparison with other copying functions: + * Comparison with other copying functions: * strcpy() - buffer overflow ready * strncpy() - wastes time filling exactly n bytes with 0 * strlcpy() - wastes time searching for the length of src diff --git a/util/generic/string.cpp b/util/generic/string.cpp index b8d3af544c..3c655f1f66 100644 --- a/util/generic/string.cpp +++ b/util/generic/string.cpp @@ -14,10 +14,10 @@ std::ostream& operator<<(std::ostream& os, const TString& s) { return os.write(s.data(), s.size()); } -std::istream& operator>>(std::istream& is, TString& s) { +std::istream& operator>>(std::istream& is, TString& s) { return is >> s.MutRef(); -} - +} + template <> bool TBasicString<char, std::char_traits<char>>::to_lower(size_t pos, size_t n) { return Transform([](size_t, char c) { return AsciiToLower(c); }, pos, n); @@ -38,7 +38,7 @@ bool TBasicString<char, std::char_traits<char>>::to_title(size_t pos, size_t n) } template <> -TUtf16String& +TUtf16String& TBasicString<wchar16, std::char_traits<wchar16>>::AppendAscii(const ::TStringBuf& s) { ReserveAndResize(size() + s.size()); @@ -48,53 +48,53 @@ TBasicString<wchar16, std::char_traits<wchar16>>::AppendAscii(const ::TStringBuf *dst = static_cast<wchar16>(*src); } - return *this; + return *this; } template <> -TUtf16String& +TUtf16String& TBasicString<wchar16, std::char_traits<wchar16>>::AppendUtf8(const ::TStringBuf& s) { - size_t oldSize = size(); + size_t oldSize = size(); ReserveAndResize(size() + s.size() * 4); - size_t written = 0; + size_t written = 0; size_t pos = UTF8ToWideImpl(s.data(), s.size(), begin() + oldSize, written); if (pos != s.size()) { ythrow yexception() << "failed to decode UTF-8 string at pos " << pos << ::NDetail::InStringMsg(s.data(), s.size()); } resize(oldSize + written); - - return *this; -} - + + return *this; +} + template <> bool TBasicString<wchar16, std::char_traits<wchar16>>::to_lower(size_t pos, size_t n) { - return ToLower(*this, pos, n); + return ToLower(*this, pos, n); } template <> bool TBasicString<wchar16, std::char_traits<wchar16>>::to_upper(size_t pos, size_t n) { - return ToUpper(*this, pos, n); + return ToUpper(*this, pos, n); } template <> bool TBasicString<wchar16, std::char_traits<wchar16>>::to_title(size_t pos, size_t n) { - return ToTitle(*this, pos, n); + return ToTitle(*this, pos, n); } template <> -TUtf32String& +TUtf32String& TBasicString<wchar32, std::char_traits<wchar32>>::AppendAscii(const ::TStringBuf& s) { ReserveAndResize(size() + s.size()); - + auto dst = begin() + size() - s.size(); - + for (const char* src = s.data(); dst != end(); ++dst, ++src) { - *dst = static_cast<wchar32>(*src); - } - - return *this; -} - + *dst = static_cast<wchar32>(*src); + } + + return *this; +} + template <> TBasicString<char, std::char_traits<char>>& TBasicString<char, std::char_traits<char>>::AppendUtf16(const ::TWtringBuf& s) { @@ -110,7 +110,7 @@ TBasicString<char, std::char_traits<char>>::AppendUtf16(const ::TWtringBuf& s) { } template <> -TUtf32String& +TUtf32String& TBasicString<wchar32, std::char_traits<wchar32>>::AppendUtf8(const ::TStringBuf& s) { size_t oldSize = size(); ReserveAndResize(size() + s.size() * 4); @@ -120,12 +120,12 @@ TBasicString<wchar32, std::char_traits<wchar32>>::AppendUtf8(const ::TStringBuf& ythrow yexception() << "failed to decode UTF-8 string at pos " << pos << ::NDetail::InStringMsg(s.data(), s.size()); } resize(oldSize + written); - - return *this; + + return *this; } template <> -TUtf32String& +TUtf32String& TBasicString<wchar32, std::char_traits<wchar32>>::AppendUtf16(const ::TWtringBuf& s) { size_t oldSize = size(); ReserveAndResize(size() + s.size() * 2); @@ -137,20 +137,20 @@ TBasicString<wchar32, std::char_traits<wchar32>>::AppendUtf16(const ::TWtringBuf resize(oldSize + written); - return *this; + return *this; } template <> bool TBasicString<wchar32, std::char_traits<wchar32>>::to_lower(size_t pos, size_t n) { - return ToLower(*this, pos, n); + return ToLower(*this, pos, n); } template <> bool TBasicString<wchar32, std::char_traits<wchar32>>::to_upper(size_t pos, size_t n) { - return ToUpper(*this, pos, n); + return ToUpper(*this, pos, n); } template <> bool TBasicString<wchar32, std::char_traits<wchar32>>::to_title(size_t pos, size_t n) { - return ToTitle(*this, pos, n); + return ToTitle(*this, pos, n); } diff --git a/util/generic/string.h b/util/generic/string.h index e7ff1c7f5f..8cd8aa6917 100644 --- a/util/generic/string.h +++ b/util/generic/string.h @@ -3,9 +3,9 @@ #include <cstddef> #include <cstring> #include <stlfwd> -#include <stdexcept> +#include <stdexcept> #include <string> -#include <string_view> +#include <string_view> #include <util/system/yassert.h> #include <util/system/atomic.h> @@ -15,7 +15,7 @@ #include "bitops.h" #include "explicit_type.h" #include "reserve.h" -#include "singleton.h" +#include "singleton.h" #include "strbase.h" #include "strbuf.h" #include "string_hash.h" @@ -82,12 +82,12 @@ struct TStdString: public TRefCountHolder, public B { #ifdef _LIBCPP_VERSION return (TStdString*)NULL_STRING_REPR; #else - return Singleton<TStdString>(); + return Singleton<TStdString>(); #endif } -private: - friend TStringPtrOps<TStdString>; +private: + friend TStringPtrOps<TStdString>; inline void Ref() noexcept { C.Inc(); } @@ -138,36 +138,36 @@ public: return this->operator=(static_cast<TChar>(other)); } - /* - * WARN: - * Though references are copyable types according to the standard, - * the behavior of this explicit default specification is different from the one - * implemented by the assignment operator above. - * - * An attempt to explicitly delete it will break valid invocations like - * auto c = flag ? s[i] : s[j]; - */ - TBasicCharRef(const TBasicCharRef&) = default; - + /* + * WARN: + * Though references are copyable types according to the standard, + * the behavior of this explicit default specification is different from the one + * implemented by the assignment operator above. + * + * An attempt to explicitly delete it will break valid invocations like + * auto c = flag ? s[i] : s[j]; + */ + TBasicCharRef(const TBasicCharRef&) = default; + private: TStringType& S_; size_t Pos_; }; #endif -template <typename TCharType, typename TTraits> -class TBasicString: public TStringBase<TBasicString<TCharType, TTraits>, TCharType, TTraits> { +template <typename TCharType, typename TTraits> +class TBasicString: public TStringBase<TBasicString<TCharType, TTraits>, TCharType, TTraits> { public: // TODO: Move to private section - using TBase = TStringBase<TBasicString, TCharType, TTraits>; + using TBase = TStringBase<TBasicString, TCharType, TTraits>; using TStringType = std::basic_string<TCharType, TTraits>; #ifdef TSTRING_IS_STD_STRING using TStorage = TStringType; - using reference = typename TStorage::reference; + using reference = typename TStorage::reference; #else using TStdStr = TStdString<TStringType>; using TStorage = TIntrusivePtr<TStdStr, TStringPtrOps<TStdStr>>; - using reference = TBasicCharRef<TBasicString>; + using reference = TBasicCharRef<TBasicString>; #endif using char_type = TCharType; // TODO: DROP using value_type = TCharType; @@ -175,9 +175,9 @@ public: using iterator = TCharType*; using reverse_iterator = typename TBase::template TReverseIteratorBase<iterator>; - using typename TBase::const_iterator; + using typename TBase::const_iterator; using typename TBase::const_reference; - using typename TBase::const_reverse_iterator; + using typename TBase::const_reverse_iterator; struct TUninitialized { explicit TUninitialized(size_t size) @@ -227,7 +227,7 @@ protected: } size_t RefCount() const noexcept { - return S_.RefCount(); + return S_.RefCount(); } #endif @@ -250,47 +250,47 @@ public: #endif } - inline const_reference operator[](size_t pos) const noexcept { + inline const_reference operator[](size_t pos) const noexcept { Y_ASSERT(pos <= length()); return this->data()[pos]; } - inline reference operator[](size_t pos) noexcept { + inline reference operator[](size_t pos) noexcept { Y_ASSERT(pos <= length()); #ifdef TSTRING_IS_STD_STRING return Storage_[pos]; #else - return reference(*this, pos); + return reference(*this, pos); #endif } using TBase::back; - inline reference back() noexcept { + inline reference back() noexcept { Y_ASSERT(!this->empty()); #ifdef TSTRING_IS_STD_STRING return Storage_.back(); #else if (Y_UNLIKELY(this->empty())) { - return reference(*this, 0); + return reference(*this, 0); } - return reference(*this, length() - 1); + return reference(*this, length() - 1); #endif } using TBase::front; - inline reference front() noexcept { + inline reference front() noexcept { Y_ASSERT(!this->empty()); #ifdef TSTRING_IS_STD_STRING return Storage_.front(); #else - return reference(*this, 0); + return reference(*this, 0); #endif } @@ -332,7 +332,7 @@ public: using TBase::rbegin; //!< const_reverse_iterator TStringBase::rbegin() const using TBase::rend; //!< const_reverse_iterator TStringBase::rend() const - inline size_t capacity() const noexcept { + inline size_t capacity() const noexcept { #ifdef TSTRING_IS_STD_STRING return Storage_.capacity(); #else @@ -365,7 +365,7 @@ public: } // ~~~ Size and capacity ~~~ - TBasicString& resize(size_t n, TCharType c = ' ') { // remove or append + TBasicString& resize(size_t n, TCharType c = ' ') { // remove or append MutRef().resize(n, c); return *this; @@ -383,11 +383,11 @@ public: #ifndef TSTRING_IS_STD_STRING : S_(Construct()) #endif - { - reserve(rt.Capacity); - } - - inline TBasicString(const TBasicString& s) + { + reserve(rt.Capacity); + } + + inline TBasicString(const TBasicString& s) #ifdef TSTRING_IS_STD_STRING : Storage_(s.Storage_) #else @@ -396,19 +396,19 @@ public: { } - inline TBasicString(TBasicString&& s) noexcept + inline TBasicString(TBasicString&& s) noexcept #ifdef TSTRING_IS_STD_STRING : Storage_(std::move(s.Storage_)) #else : S_(Construct()) #endif - { + { #ifdef TSTRING_IS_STD_STRING #else s.swap(*this); #endif - } - + } + template <typename T, typename A> explicit inline TBasicString(const std::basic_string<TCharType, T, A>& s) : TBasicString(s.data(), s.size()) @@ -438,8 +438,8 @@ public: : TBasicString(pc, TBase::StrLen(pc)) { } - // TODO thegeorg@: uncomment and fix clients - // TBasicString(std::nullptr_t) = delete; + // TODO thegeorg@: uncomment and fix clients + // TBasicString(std::nullptr_t) = delete; TBasicString(const TCharType* pc, size_t n) #ifdef TSTRING_IS_STD_STRING @@ -449,17 +449,17 @@ public: #endif { } - TBasicString(std::nullptr_t, size_t) = delete; + TBasicString(std::nullptr_t, size_t) = delete; TBasicString(const TCharType* pc, size_t pos, size_t n) : TBasicString(pc + pos, n) { } -#ifdef TSTRING_IS_STD_STRING +#ifdef TSTRING_IS_STD_STRING explicit TBasicString(TExplicitType<TCharType> c) { Storage_.push_back(c); - } + } #else explicit TBasicString(TExplicitType<TCharType> c) : TBasicString(&c.Value(), 1) @@ -509,25 +509,25 @@ public: { } - /** + /** * WARN: * Certain invocations of this method will result in link-time error. - * You are free to implement corresponding methods in string.cpp if you need them. - */ + * You are free to implement corresponding methods in string.cpp if you need them. + */ static TBasicString FromAscii(const ::TStringBuf& s) { - return TBasicString().AppendAscii(s); - } - + return TBasicString().AppendAscii(s); + } + static TBasicString FromUtf8(const ::TStringBuf& s) { - return TBasicString().AppendUtf8(s); - } - + return TBasicString().AppendUtf8(s); + } + static TBasicString FromUtf16(const ::TWtringBuf& s) { - return TBasicString().AppendUtf16(s); - } - - static TBasicString Uninitialized(size_t n) { - return TBasicString(TUninitialized(n)); + return TBasicString().AppendUtf16(s); + } + + static TBasicString Uninitialized(size_t n) { + return TBasicString(TUninitialized(n)); } private: @@ -547,7 +547,7 @@ private: template <typename... R> static void CopyAll(TCharType* p, const TBasicStringBuf<TCharType, TTraits> s, const R&... r) { - TTraits::copy(p, s.data(), s.size()); + TTraits::copy(p, s.data(), s.size()); CopyAll(p + s.size(), r...); } @@ -576,7 +576,7 @@ public: } template <typename... R> - static inline TBasicString Join(const R&... r) { + static inline TBasicString Join(const R&... r) { TBasicString s{TUninitialized{SumLength(r...)}}; TBasicString::CopyAll((TCharType*)s.data(), r...); @@ -585,31 +585,31 @@ public: } // ~~~ Assignment ~~~ : FAMILY0(TBasicString&, assign); - TBasicString& assign(size_t size, TCharType ch) { - ReserveAndResize(size); - std::fill(begin(), vend(), ch); - return *this; - } - - TBasicString& assign(const TBasicString& s) { - TBasicString(s).swap(*this); + TBasicString& assign(size_t size, TCharType ch) { + ReserveAndResize(size); + std::fill(begin(), vend(), ch); + return *this; + } + + TBasicString& assign(const TBasicString& s) { + TBasicString(s).swap(*this); - return *this; + return *this; } - TBasicString& assign(const TBasicString& s, size_t pos, size_t n) { - return assign(TBasicString(s, pos, n)); + TBasicString& assign(const TBasicString& s, size_t pos, size_t n) { + return assign(TBasicString(s, pos, n)); } - TBasicString& assign(const TCharType* pc) { + TBasicString& assign(const TCharType* pc) { return assign(pc, TBase::StrLen(pc)); } - TBasicString& assign(TCharType ch) { + TBasicString& assign(TCharType ch) { return assign(&ch, 1); } - TBasicString& assign(const TCharType* pc, size_t len) { + TBasicString& assign(const TCharType* pc, size_t len) { #if defined(address_sanitizer_enabled) || defined(thread_sanitizer_enabled) pc = (const TCharType*)HidePointerOrigin((void*)pc); #endif @@ -619,14 +619,14 @@ public: TBasicString(pc, len).swap(*this); } - return *this; + return *this; } - TBasicString& assign(const TCharType* first, const TCharType* last) { + TBasicString& assign(const TCharType* first, const TCharType* last) { return assign(first, last - first); } - TBasicString& assign(const TCharType* pc, size_t pos, size_t n) { + TBasicString& assign(const TCharType* pc, size_t pos, size_t n) { return assign(pc + pos, n); } @@ -654,35 +654,35 @@ public: return AssignNoAlias(s.SubString(spos, sn)); } - /** + /** * WARN: * Certain invocations of this method will result in link-time error. - * You are free to implement corresponding methods in string.cpp if you need them. - */ + * You are free to implement corresponding methods in string.cpp if you need them. + */ auto AssignAscii(const ::TStringBuf& s) { - clear(); - return AppendAscii(s); - } - + clear(); + return AppendAscii(s); + } + auto AssignUtf8(const ::TStringBuf& s) { - clear(); - return AppendUtf8(s); - } - + clear(); + return AppendUtf8(s); + } + auto AssignUtf16(const ::TWtringBuf& s) { - clear(); - return AppendUtf16(s); - } - - TBasicString& operator=(const TBasicString& s) { + clear(); + return AppendUtf16(s); + } + + TBasicString& operator=(const TBasicString& s) { return assign(s); } - TBasicString& operator=(TBasicString&& s) noexcept { - swap(s); - return *this; - } - + TBasicString& operator=(TBasicString&& s) noexcept { + swap(s); + return *this; + } + template <typename T, typename A> TBasicString& operator=(std::basic_string<TCharType, T, A>&& s) noexcept { TBasicString(std::move(s)).swap(*this); @@ -694,16 +694,16 @@ public: return assign(s); } - TBasicString& operator=(std::initializer_list<TCharType> il) { - return assign(il.begin(), il.end()); - } - - TBasicString& operator=(const TCharType* s) { + TBasicString& operator=(std::initializer_list<TCharType> il) { + return assign(il.begin(), il.end()); + } + + TBasicString& operator=(const TCharType* s) { return assign(s); } - TBasicString& operator=(std::nullptr_t) = delete; + TBasicString& operator=(std::nullptr_t) = delete; - TBasicString& operator=(TExplicitType<TCharType> ch) { + TBasicString& operator=(TExplicitType<TCharType> ch) { return assign(ch); } @@ -712,19 +712,19 @@ public: } // ~~~ Appending ~~~ : FAMILY0(TBasicString&, append); - inline TBasicString& append(size_t count, TCharType ch) { + inline TBasicString& append(size_t count, TCharType ch) { MutRef().append(count, ch); - return *this; + return *this; } - inline TBasicString& append(const TBasicString& s) { + inline TBasicString& append(const TBasicString& s) { MutRef().append(s.ConstRef()); return *this; } - inline TBasicString& append(const TBasicString& s, size_t pos, size_t n) { + inline TBasicString& append(const TBasicString& s, size_t pos, size_t n) { MutRef().append(s.ConstRef(), pos, n); return *this; @@ -736,19 +736,19 @@ public: return *this; } - inline TBasicString& append(TCharType c) { + inline TBasicString& append(TCharType c) { MutRef().push_back(c); - return *this; + return *this; } - inline TBasicString& append(const TCharType* first, const TCharType* last) { + inline TBasicString& append(const TCharType* first, const TCharType* last) { MutRef().append(first, last); return *this; } - inline TBasicString& append(const TCharType* pc, size_t len) { + inline TBasicString& append(const TCharType* pc, size_t len) { MutRef().append(pc, len); return *this; @@ -766,7 +766,7 @@ public: memcpy(&*(begin() + s), pc, len * sizeof(*pc)); } - return *this; + return *this; } TBasicString& AppendNoAlias(const TBasicStringBuf<TCharType, TTraits> s) { @@ -789,30 +789,30 @@ public: return append(pc + pos, Min(n, pc_len - pos)); } - /** + /** * WARN: * Certain invocations of this method will result in link-time error. - * You are free to implement corresponding methods in string.cpp if you need them. - */ + * You are free to implement corresponding methods in string.cpp if you need them. + */ TBasicString& AppendAscii(const ::TStringBuf& s); - + TBasicString& AppendUtf8(const ::TStringBuf& s); - + TBasicString& AppendUtf16(const ::TWtringBuf& s); - + inline void push_back(TCharType c) { // TODO append(c); } template <class T> - TBasicString& operator+=(const T& s) { + TBasicString& operator+=(const T& s) { return append(s); } template <class T> - friend TBasicString operator*(const TBasicString& s, T count) { - TBasicString result; + friend TBasicString operator*(const TBasicString& s, T count) { + TBasicString result; for (T i = 0; i < count; ++i) { result += s; @@ -822,16 +822,16 @@ public: } template <class T> - TBasicString& operator*=(T count) { - TBasicString temp; + TBasicString& operator*=(T count) { + TBasicString temp; for (T i = 0; i < count; ++i) { - temp += *this; + temp += *this; } swap(temp); - return *this; + return *this; } operator const TStringType&() const noexcept { @@ -863,17 +863,17 @@ public: * malloc + memcpy + memcpy. */ - friend TBasicString operator+(TBasicString&& s1, const TBasicString& s2) Y_WARN_UNUSED_RESULT { + friend TBasicString operator+(TBasicString&& s1, const TBasicString& s2) Y_WARN_UNUSED_RESULT { s1 += s2; return std::move(s1); } - friend TBasicString operator+(const TBasicString& s1, TBasicString&& s2) Y_WARN_UNUSED_RESULT { + friend TBasicString operator+(const TBasicString& s1, TBasicString&& s2) Y_WARN_UNUSED_RESULT { s2.prepend(s1); return std::move(s2); } - friend TBasicString operator+(TBasicString&& s1, TBasicString&& s2) Y_WARN_UNUSED_RESULT { + friend TBasicString operator+(TBasicString&& s1, TBasicString&& s2) Y_WARN_UNUSED_RESULT { #if 0 && !defined(TSTRING_IS_STD_STRING) if (!s1.IsDetached() && s2.IsDetached()) { s2.prepend(s1); @@ -889,21 +889,21 @@ public: return std::move(s1); } - friend TBasicString operator+(TBasicString&& s1, const TCharType* s2) Y_WARN_UNUSED_RESULT { + friend TBasicString operator+(TBasicString&& s1, const TCharType* s2) Y_WARN_UNUSED_RESULT { s1 += s2; return std::move(s1); } - friend TBasicString operator+(TBasicString&& s1, TCharType s2) Y_WARN_UNUSED_RESULT { + friend TBasicString operator+(TBasicString&& s1, TCharType s2) Y_WARN_UNUSED_RESULT { s1 += s2; return std::move(s1); } friend TBasicString operator+(TExplicitType<TCharType> ch, const TBasicString& s) Y_WARN_UNUSED_RESULT { - return Join(TCharType(ch), s); - } - - friend TBasicString operator+(const TBasicString& s1, const TBasicString& s2) Y_WARN_UNUSED_RESULT { + return Join(TCharType(ch), s); + } + + friend TBasicString operator+(const TBasicString& s1, const TBasicString& s2) Y_WARN_UNUSED_RESULT { return Join(s1, s2); } @@ -911,15 +911,15 @@ public: return Join(s1, s2); } - friend TBasicString operator+(const TBasicString& s1, const TCharType* s2) Y_WARN_UNUSED_RESULT { + friend TBasicString operator+(const TBasicString& s1, const TCharType* s2) Y_WARN_UNUSED_RESULT { return Join(s1, s2); } - friend TBasicString operator+(const TBasicString& s1, TCharType s2) Y_WARN_UNUSED_RESULT { + friend TBasicString operator+(const TBasicString& s1, TCharType s2) Y_WARN_UNUSED_RESULT { return Join(s1, TBasicStringBuf<TCharType, TTraits>(&s2, 1)); } - friend TBasicString operator+(const TCharType* s1, TBasicString&& s2) Y_WARN_UNUSED_RESULT { + friend TBasicString operator+(const TCharType* s1, TBasicString&& s2) Y_WARN_UNUSED_RESULT { s2.prepend(s1); return std::move(s2); } @@ -933,7 +933,7 @@ public: return Join(s1, s2); } - friend TBasicString operator+(const TCharType* s1, const TBasicString& s2) Y_WARN_UNUSED_RESULT { + friend TBasicString operator+(const TCharType* s1, const TBasicString& s2) Y_WARN_UNUSED_RESULT { return Join(s1, s2); } @@ -945,32 +945,32 @@ public: return l.ConstRef() + r; } - // ~~~ Prepending ~~~ : FAMILY0(TBasicString&, prepend); - TBasicString& prepend(const TBasicString& s) { + // ~~~ Prepending ~~~ : FAMILY0(TBasicString&, prepend); + TBasicString& prepend(const TBasicString& s) { MutRef().insert(0, s.ConstRef()); return *this; } - TBasicString& prepend(const TBasicString& s, size_t pos, size_t n) { + TBasicString& prepend(const TBasicString& s, size_t pos, size_t n) { MutRef().insert(0, s.ConstRef(), pos, n); return *this; } - TBasicString& prepend(const TCharType* pc) { + TBasicString& prepend(const TCharType* pc) { MutRef().insert(0, pc); return *this; } - TBasicString& prepend(size_t n, TCharType c) { + TBasicString& prepend(size_t n, TCharType c) { MutRef().insert(size_t(0), n, c); return *this; } - TBasicString& prepend(TCharType c) { + TBasicString& prepend(TCharType c) { MutRef().insert(size_t(0), 1, c); return *this; @@ -980,32 +980,32 @@ public: return insert(0, s, spos, sn); } - // ~~~ Insertion ~~~ : FAMILY1(TBasicString&, insert, size_t pos); - TBasicString& insert(size_t pos, const TBasicString& s) { + // ~~~ Insertion ~~~ : FAMILY1(TBasicString&, insert, size_t pos); + TBasicString& insert(size_t pos, const TBasicString& s) { MutRef().insert(pos, s.ConstRef()); return *this; } - TBasicString& insert(size_t pos, const TBasicString& s, size_t pos1, size_t n1) { + TBasicString& insert(size_t pos, const TBasicString& s, size_t pos1, size_t n1) { MutRef().insert(pos, s.ConstRef(), pos1, n1); return *this; } - TBasicString& insert(size_t pos, const TCharType* pc) { + TBasicString& insert(size_t pos, const TCharType* pc) { MutRef().insert(pos, pc); return *this; } - TBasicString& insert(size_t pos, const TCharType* pc, size_t len) { + TBasicString& insert(size_t pos, const TCharType* pc, size_t len) { MutRef().insert(pos, pc, len); return *this; } - TBasicString& insert(const_iterator pos, const_iterator b, const_iterator e) { + TBasicString& insert(const_iterator pos, const_iterator b, const_iterator e) { #ifdef TSTRING_IS_STD_STRING Storage_.insert(Storage_.begin() + this->off(pos), b, e); @@ -1015,17 +1015,17 @@ public: #endif } - TBasicString& insert(size_t pos, size_t n, TCharType c) { + TBasicString& insert(size_t pos, size_t n, TCharType c) { MutRef().insert(pos, n, c); return *this; } - TBasicString& insert(const_iterator pos, size_t len, TCharType ch) { + TBasicString& insert(const_iterator pos, size_t len, TCharType ch) { return this->insert(this->off(pos), len, ch); } - TBasicString& insert(const_iterator pos, TCharType ch) { + TBasicString& insert(const_iterator pos, TCharType ch) { return this->insert(pos, 1, ch); } @@ -1045,11 +1045,11 @@ public: } TBasicString& remove(size_t pos = 0) Y_NOEXCEPT { - if (pos < length()) { + if (pos < length()) { MutRef().erase(pos); } - return *this; + return *this; } TBasicString& erase(size_t pos = 0, size_t n = TBase::npos) Y_NOEXCEPT { @@ -1074,7 +1074,7 @@ public: return *this; } - // ~~~ replacement ~~~ : FAMILY2(TBasicString&, replace, size_t pos, size_t n); + // ~~~ replacement ~~~ : FAMILY2(TBasicString&, replace, size_t pos, size_t n); TBasicString& replace(size_t pos, size_t n, const TBasicString& s) Y_NOEXCEPT { MutRef().replace(pos, n, s.ConstRef()); @@ -1114,10 +1114,10 @@ public: TBasicString& replace(size_t pos, size_t n, const TBasicStringBuf<TCharType, TTraits> s, size_t spos = 0, size_t sn = TBase::npos) Y_NOEXCEPT { MutRef().replace(pos, n, s, spos, sn); - return *this; + return *this; } - void swap(TBasicString& s) noexcept { + void swap(TBasicString& s) noexcept { #ifdef TSTRING_IS_STD_STRING std::swap(Storage_, s.Storage_); #else @@ -1129,43 +1129,43 @@ public: * @returns String suitable for debug printing (like Python's `repr()`). * Format of the string is unspecified and may be changed over time. */ - TBasicString Quote() const { - extern TBasicString EscapeC(const TBasicString&); - - return TBasicString() + '"' + EscapeC(*this) + '"'; - } - - /** - * Modifies the case of the string, depending on the operation. - * @return false if no changes have been made. - * - * @warning when the value_type is char, these methods will not work with non-ASCII letters. - */ - bool to_lower(size_t pos = 0, size_t n = TBase::npos); - bool to_upper(size_t pos = 0, size_t n = TBase::npos); - bool to_title(size_t pos = 0, size_t n = TBase::npos); - -public: - /** - * Modifies the substring of length `n` starting from `pos`, applying `f` to each position and symbol. - * - * @return false if no changes have been made. - */ - template <typename T> - bool Transform(T&& f, size_t pos = 0, size_t n = TBase::npos) { - size_t len = length(); - - if (pos > len) { - pos = len; - } - - if (n > len - pos) { - n = len - pos; - } - - bool changed = false; - - for (size_t i = pos; i != pos + n; ++i) { + TBasicString Quote() const { + extern TBasicString EscapeC(const TBasicString&); + + return TBasicString() + '"' + EscapeC(*this) + '"'; + } + + /** + * Modifies the case of the string, depending on the operation. + * @return false if no changes have been made. + * + * @warning when the value_type is char, these methods will not work with non-ASCII letters. + */ + bool to_lower(size_t pos = 0, size_t n = TBase::npos); + bool to_upper(size_t pos = 0, size_t n = TBase::npos); + bool to_title(size_t pos = 0, size_t n = TBase::npos); + +public: + /** + * Modifies the substring of length `n` starting from `pos`, applying `f` to each position and symbol. + * + * @return false if no changes have been made. + */ + template <typename T> + bool Transform(T&& f, size_t pos = 0, size_t n = TBase::npos) { + size_t len = length(); + + if (pos > len) { + pos = len; + } + + if (n > len - pos) { + n = len - pos; + } + + bool changed = false; + + for (size_t i = pos; i != pos + n; ++i) { #ifdef TSTRING_IS_STD_STRING auto c = f(i, Storage_[i]); @@ -1177,44 +1177,44 @@ public: #else auto c = f(i, data()[i]); if (c != data()[i]) { - if (!changed) { - Detach(); - changed = true; - } - + if (!changed) { + Detach(); + changed = true; + } + begin()[i] = c; - } + } #endif - } - - return changed; - } + } + + return changed; + } }; -std::ostream& operator<<(std::ostream&, const TString&); -std::istream& operator>>(std::istream&, TString&); +std::ostream& operator<<(std::ostream&, const TString&); +std::istream& operator>>(std::istream&, TString&); template <typename TCharType, typename TTraits> -TBasicString<TCharType> to_lower(const TBasicString<TCharType, TTraits>& s) { - TBasicString<TCharType> ret(s); - ret.to_lower(); - return ret; -} - +TBasicString<TCharType> to_lower(const TBasicString<TCharType, TTraits>& s) { + TBasicString<TCharType> ret(s); + ret.to_lower(); + return ret; +} + template <typename TCharType, typename TTraits> -TBasicString<TCharType> to_upper(const TBasicString<TCharType, TTraits>& s) { - TBasicString<TCharType> ret(s); - ret.to_upper(); - return ret; -} - +TBasicString<TCharType> to_upper(const TBasicString<TCharType, TTraits>& s) { + TBasicString<TCharType> ret(s); + ret.to_upper(); + return ret; +} + template <typename TCharType, typename TTraits> -TBasicString<TCharType> to_title(const TBasicString<TCharType, TTraits>& s) { - TBasicString<TCharType> ret(s); - ret.to_title(); - return ret; -} - +TBasicString<TCharType> to_title(const TBasicString<TCharType, TTraits>& s) { + TBasicString<TCharType> ret(s); + ret.to_title(); + return ret; +} + namespace std { template <> struct hash<TString> { diff --git a/util/generic/string_ut.cpp b/util/generic/string_ut.cpp index 9cb0b7aeee..ac82e9091d 100644 --- a/util/generic/string_ut.cpp +++ b/util/generic/string_ut.cpp @@ -304,7 +304,7 @@ protected: // ISO/IEC 14882:1998(E), ISO/IEC 14882:2003(E), 21.3.4 ('... the const version') const TStringType s(Data_._123456()); - UNIT_ASSERT(s[s.size()] == 0); + UNIT_ASSERT(s[s.size()] == 0); } // Allowed since C++17, see http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2475 @@ -474,15 +474,15 @@ protected: void capacity() { TStringType s; - UNIT_ASSERT(s.capacity() < s.max_size()); - UNIT_ASSERT(s.capacity() >= s.size()); + UNIT_ASSERT(s.capacity() < s.max_size()); + UNIT_ASSERT(s.capacity() >= s.size()); for (int i = 0; i < 18; ++i) { s += ' '; - UNIT_ASSERT(s.capacity() > 0); - UNIT_ASSERT(s.capacity() < s.max_size()); - UNIT_ASSERT(s.capacity() >= s.size()); + UNIT_ASSERT(s.capacity() > 0); + UNIT_ASSERT(s.capacity() < s.max_size()); + UNIT_ASSERT(s.capacity() >= s.size()); } } @@ -610,13 +610,13 @@ protected: TStringType test(Data.aba()); - UNIT_ASSERT(test.rfind(Data.a(), 2, 1) == 2); - UNIT_ASSERT(test.rfind(Data.a(), 1, 1) == 0); - UNIT_ASSERT(test.rfind(Data.a(), 0, 1) == 0); + UNIT_ASSERT(test.rfind(Data.a(), 2, 1) == 2); + UNIT_ASSERT(test.rfind(Data.a(), 1, 1) == 0); + UNIT_ASSERT(test.rfind(Data.a(), 0, 1) == 0); - UNIT_ASSERT(test.rfind(*Data.a(), 2) == 2); - UNIT_ASSERT(test.rfind(*Data.a(), 1) == 0); - UNIT_ASSERT(test.rfind(*Data.a(), 0) == 0); + UNIT_ASSERT(test.rfind(*Data.a(), 2) == 2); + UNIT_ASSERT(test.rfind(*Data.a(), 1) == 0); + UNIT_ASSERT(test.rfind(*Data.a(), 0) == 0); } #endif void find_last_not_of() { @@ -682,7 +682,7 @@ protected: i = s.begin(); ci = s.begin() + 1; s.replace(i, i, ci, ci + 1); - UNIT_ASSERT(s == Data._2123456()); + UNIT_ASSERT(s == Data._2123456()); s = Data._123456(); s.replace(s.begin() + 4, s.end(), cs.begin(), cs.end()); @@ -749,36 +749,36 @@ public: UNIT_TEST(TestIterators); UNIT_TEST(TestReverseIterators); UNIT_TEST(TestAppendUtf16) - UNIT_TEST(TestFillingAssign) - UNIT_TEST(TestStdStreamApi) + UNIT_TEST(TestFillingAssign) + UNIT_TEST(TestStdStreamApi) //UNIT_TEST(TestOperatorsCI); must fail UNIT_TEST_SUITE_END(); void TestAppendUtf16() { - TString appended = TString("А роза упала").AppendUtf16(u" на лапу Азора"); - UNIT_ASSERT(appended == "А роза упала на лапу Азора"); + TString appended = TString("А роза упала").AppendUtf16(u" на лапу Азора"); + UNIT_ASSERT(appended == "А роза упала на лапу Азора"); + } + + void TestFillingAssign() { + TString s("abc"); + s.assign(5, 'a'); + UNIT_ASSERT_VALUES_EQUAL(s, "aaaaa"); } - - void TestFillingAssign() { - TString s("abc"); - s.assign(5, 'a'); - UNIT_ASSERT_VALUES_EQUAL(s, "aaaaa"); - } - - void TestStdStreamApi() { - const TString data = "abracadabra"; - std::stringstream ss; - ss << data; - - UNIT_ASSERT_VALUES_EQUAL(data, ss.str()); - + + void TestStdStreamApi() { + const TString data = "abracadabra"; + std::stringstream ss; + ss << data; + + UNIT_ASSERT_VALUES_EQUAL(data, ss.str()); + ss << '\n' << data << std::endl; - + TString read = "xxx"; - ss >> read; - UNIT_ASSERT_VALUES_EQUAL(read, data); - } + ss >> read; + UNIT_ASSERT_VALUES_EQUAL(read, data); + } }; UNIT_TEST_SUITE_REGISTRATION(TStringTest); @@ -885,7 +885,7 @@ private: void TestLetOperator() { TUtf16String str; - str = wchar16('X'); + str = wchar16('X'); UNIT_ASSERT(str == TUtf16String::FromAscii("X")); const TUtf16String hello = TUtf16String::FromAscii("hello"); @@ -1083,7 +1083,7 @@ private: void TestLetOperator() { TUtf32String str; - str = wchar32('X'); + str = wchar32('X'); UNIT_ASSERT(str == TUtf32String::FromAscii("X")); const TUtf32String hello = TUtf32String::FromAscii("hello"); @@ -1176,20 +1176,20 @@ public: }; UNIT_TEST_SUITE_REGISTRATION(TWideStringStdTest); - -Y_UNIT_TEST_SUITE(TStringConversionTest) { - Y_UNIT_TEST(ConversionToStdStringTest) { - TString abra = "cadabra"; - std::string stdAbra = abra; - UNIT_ASSERT_VALUES_EQUAL(stdAbra, "cadabra"); - } - - Y_UNIT_TEST(ConversionToStdStringViewTest) { - TString abra = "cadabra"; - std::string_view stdAbra = abra; - UNIT_ASSERT_VALUES_EQUAL(stdAbra, "cadabra"); - } -} + +Y_UNIT_TEST_SUITE(TStringConversionTest) { + Y_UNIT_TEST(ConversionToStdStringTest) { + TString abra = "cadabra"; + std::string stdAbra = abra; + UNIT_ASSERT_VALUES_EQUAL(stdAbra, "cadabra"); + } + + Y_UNIT_TEST(ConversionToStdStringViewTest) { + TString abra = "cadabra"; + std::string_view stdAbra = abra; + UNIT_ASSERT_VALUES_EQUAL(stdAbra, "cadabra"); + } +} Y_UNIT_TEST_SUITE(HashFunctorTests) { Y_UNIT_TEST(TestTransparency) { diff --git a/util/generic/string_ut.h b/util/generic/string_ut.h index 4a8faeb137..44bb10bdeb 100644 --- a/util/generic/string_ut.h +++ b/util/generic/string_ut.h @@ -534,13 +534,13 @@ public: TStringType s2(Data._0()); UNIT_ASSERT(s1 == s2); - TStringType fromZero(0); - UNIT_ASSERT_VALUES_EQUAL(fromZero.size(), 0u); - - TStringType fromChar(char_type('a')); - UNIT_ASSERT_VALUES_EQUAL(fromChar.size(), 1u); - UNIT_ASSERT_VALUES_EQUAL(fromChar[0], char_type('a')); - + TStringType fromZero(0); + UNIT_ASSERT_VALUES_EQUAL(fromZero.size(), 0u); + + TStringType fromChar(char_type('a')); + UNIT_ASSERT_VALUES_EQUAL(fromChar.size(), 1u); + UNIT_ASSERT_VALUES_EQUAL(fromChar[0], char_type('a')); + #ifndef TSTRING_IS_STD_STRING TStringType s3 = TStringType::Uninitialized(10); UNIT_ASSERT(s3.size() == 10); @@ -824,7 +824,7 @@ public: // length() UNIT_ASSERT(s.length() == s.size()); - UNIT_ASSERT(s.length() == traits_type::length(s.data())); + UNIT_ASSERT(s.length() == traits_type::length(s.data())); // is_null() TStringType s1(Data.Empty()); @@ -909,7 +909,7 @@ public: //s2.reserve(); TStringType s5(Data.abcde()); - s5.clear(); + s5.clear(); UNIT_ASSERT(s5 == Data.Empty()); } diff --git a/util/generic/typetraits.h b/util/generic/typetraits.h index 9ac70d3d1c..d165bd1a06 100644 --- a/util/generic/typetraits.h +++ b/util/generic/typetraits.h @@ -270,28 +270,28 @@ template <template <class...> class T, class... Ts> struct TIsSpecializationOf<T, T<Ts...>>: std::true_type {}; /* - * TDependentFalse is a constant dependent on a template parameter. - * Use it in static_assert in a false branch of if constexpr to produce a compile error. + * TDependentFalse is a constant dependent on a template parameter. + * Use it in static_assert in a false branch of if constexpr to produce a compile error. * See an example with dependent_false at https://en.cppreference.com/w/cpp/language/if * * if constexpr (std::is_same<T, someType1>) { * } else if constexpr (std::is_same<T, someType2>) { * } else { - * static_assert(TDependentFalse<T>, "unknown type"); + * static_assert(TDependentFalse<T>, "unknown type"); * } */ template <typename... T> constexpr bool TDependentFalse = false; -// FIXME: neither nvcc10 nor nvcc11 support using auto in this context -#if defined(__NVCC__) -template <size_t Value> +// FIXME: neither nvcc10 nor nvcc11 support using auto in this context +#if defined(__NVCC__) +template <size_t Value> constexpr bool TValueDependentFalse = false; -#else +#else template <auto... Values> -constexpr bool TValueDependentFalse = false; -#endif - +constexpr bool TValueDependentFalse = false; +#endif + /* * shortcut for std::enable_if_t<...> which checks that T is std::tuple or std::pair */ diff --git a/util/generic/vector.h b/util/generic/vector.h index bc3020e3c2..a5b258955a 100644 --- a/util/generic/vector.h +++ b/util/generic/vector.h @@ -110,20 +110,20 @@ public: return (yssize_t)TBase::size(); } -#ifdef _YNDX_LIBCXX_ENABLE_VECTOR_POD_RESIZE_UNINITIALIZED - void yresize(size_type newSize) { - if (std::is_pod<T>::value) { - TBase::resize_uninitialized(newSize); - } else { - TBase::resize(newSize); - } - } -#else - void yresize(size_type newSize) { - TBase::resize(newSize); - } -#endif - +#ifdef _YNDX_LIBCXX_ENABLE_VECTOR_POD_RESIZE_UNINITIALIZED + void yresize(size_type newSize) { + if (std::is_pod<T>::value) { + TBase::resize_uninitialized(newSize); + } else { + TBase::resize(newSize); + } + } +#else + void yresize(size_type newSize) { + TBase::resize(newSize); + } +#endif + inline void crop(size_type size) { if (this->size() > size) { this->erase(this->begin() + size, this->end()); diff --git a/util/generic/vector_ut.cpp b/util/generic/vector_ut.cpp index 0119ef35c7..0f6b4037a0 100644 --- a/util/generic/vector_ut.cpp +++ b/util/generic/vector_ut.cpp @@ -473,10 +473,10 @@ private: struct TPod { int x; - - operator int() { - return x; - } + + operator int() { + return x; + } }; struct TNonPod { @@ -484,10 +484,10 @@ private: TNonPod() { x = 0; } - - operator int() { - return x; - } + + operator int() { + return x; + } }; template <typename T> @@ -495,8 +495,8 @@ private: public: using TBase = std::allocator<T>; - T* allocate(typename TBase::size_type n) { - auto p = TBase::allocate(n); + T* allocate(typename TBase::size_type n) { + auto p = TBase::allocate(n); for (size_t i = 0; i < n; ++i) { memset(p + i, 0xab, sizeof(T)); } @@ -510,28 +510,28 @@ private: }; template <typename T> - void TestYResize() { -#ifdef _YNDX_LIBCXX_ENABLE_VECTOR_POD_RESIZE_UNINITIALIZED - constexpr bool ALLOW_UNINITIALIZED = std::is_pod_v<T>; -#else - constexpr bool ALLOW_UNINITIALIZED = false; -#endif - + void TestYResize() { +#ifdef _YNDX_LIBCXX_ENABLE_VECTOR_POD_RESIZE_UNINITIALIZED + constexpr bool ALLOW_UNINITIALIZED = std::is_pod_v<T>; +#else + constexpr bool ALLOW_UNINITIALIZED = false; +#endif + TVector<T, TDebugAlloc<T>> v; v.reserve(5); - auto firstBegin = v.begin(); + auto firstBegin = v.begin(); - v.yresize(5); // No realloc, no initialization if allowed + v.yresize(5); // No realloc, no initialization if allowed UNIT_ASSERT(firstBegin == v.begin()); for (int i = 0; i < 5; ++i) { - UNIT_ASSERT_VALUES_EQUAL(bool(v[i]), ALLOW_UNINITIALIZED); + UNIT_ASSERT_VALUES_EQUAL(bool(v[i]), ALLOW_UNINITIALIZED); } - v.yresize(20); // Realloc, still no initialization + v.yresize(20); // Realloc, still no initialization UNIT_ASSERT(firstBegin != v.begin()); for (int i = 0; i < 20; ++i) { - UNIT_ASSERT_VALUES_EQUAL(bool(v[i]), ALLOW_UNINITIALIZED); + UNIT_ASSERT_VALUES_EQUAL(bool(v[i]), ALLOW_UNINITIALIZED); } } @@ -559,9 +559,9 @@ private: } void TestYResize() { - TestYResize<int>(); - TestYResize<TPod>(); - TestYResize<TNonPod>(); + TestYResize<int>(); + TestYResize<TPod>(); + TestYResize<TNonPod>(); } void CheckInitializeList(const TVector<int>& v) { diff --git a/util/generic/xrange.h b/util/generic/xrange.h index 57c6f89a9c..5fc8c82912 100644 --- a/util/generic/xrange.h +++ b/util/generic/xrange.h @@ -60,11 +60,11 @@ namespace NPrivate { return *this; } - TIterator& operator--() noexcept { - --Value; - return *this; - } - + TIterator& operator--() noexcept { + --Value; + return *this; + } + constexpr TDiff operator-(const TIterator& b) const noexcept { return Value - b.Value; } @@ -169,11 +169,11 @@ namespace NPrivate { return *this; } - TIterator& operator--() noexcept { - Value_ -= Parent_->Step_; - return *this; - } - + TIterator& operator--() noexcept { + Value_ -= Parent_->Step_; + return *this; + } + constexpr TDiff operator-(const TIterator& b) const noexcept { return (Value_ - b.Value_) / Parent_->Step_; } diff --git a/util/generic/yexception.cpp b/util/generic/yexception.cpp index 4e87dda6a9..2ce6c4369d 100644 --- a/util/generic/yexception.cpp +++ b/util/generic/yexception.cpp @@ -39,12 +39,12 @@ TString CurrentExceptionMessage() { } bool UncaughtException() noexcept { -// FIXME: use std::uncaught_exceptions() unconditionally after DEVTOOLS-8811 -#if defined(__cpp_lib_uncaught_exceptions) && !defined(_LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS) - return std::uncaught_exceptions() > 0; -#else +// FIXME: use std::uncaught_exceptions() unconditionally after DEVTOOLS-8811 +#if defined(__cpp_lib_uncaught_exceptions) && !defined(_LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS) + return std::uncaught_exceptions() > 0; +#else return std::uncaught_exception(); -#endif +#endif } std::string CurrentExceptionTypeName() { diff --git a/util/generic/yexception.h b/util/generic/yexception.h index d4162f9822..b0c604e8c4 100644 --- a/util/generic/yexception.h +++ b/util/generic/yexception.h @@ -155,22 +155,22 @@ namespace NPrivate { void fputs(const std::exception& e, FILE* f = stderr); TString CurrentExceptionMessage(); - -/* - * A neat method that detects wrether stack unwinding is in progress. - * As its std counterpart (that is std::uncaught_exception()) - * was removed from the standard, this method uses std::uncaught_exceptions() internally. - * - * If you are struggling to use this method, please, consider reading - * - * http://www.gotw.ca/gotw/047.htm - * and - * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4152.pdf - * - * DO NOT USE THIS METHOD IN DESTRUCTORS. - */ + +/* + * A neat method that detects wrether stack unwinding is in progress. + * As its std counterpart (that is std::uncaught_exception()) + * was removed from the standard, this method uses std::uncaught_exceptions() internally. + * + * If you are struggling to use this method, please, consider reading + * + * http://www.gotw.ca/gotw/047.htm + * and + * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4152.pdf + * + * DO NOT USE THIS METHOD IN DESTRUCTORS. + */ bool UncaughtException() noexcept; - + std::string CurrentExceptionTypeName(); TString FormatExc(const std::exception& exception); diff --git a/util/generic/yexception_ut.cpp b/util/generic/yexception_ut.cpp index 860ba90949..cb3e29fed8 100644 --- a/util/generic/yexception_ut.cpp +++ b/util/generic/yexception_ut.cpp @@ -330,7 +330,7 @@ private: try { throw int(1); } catch (...) { -#if defined(LIBCXX_BUILDING_LIBCXXRT) || defined(LIBCXX_BUILDING_LIBGCC) +#if defined(LIBCXX_BUILDING_LIBCXXRT) || defined(LIBCXX_BUILDING_LIBGCC) UNIT_ASSERT_VALUES_EQUAL(CurrentExceptionTypeName(), "int"); #else UNIT_ASSERT_VALUES_EQUAL(CurrentExceptionTypeName(), "unknown type"); @@ -357,7 +357,7 @@ private: UNIT_ASSERT_STRING_CONTAINS(CurrentExceptionTypeName(), "std::bad_alloc"); } } - // For exceptions thrown by std::rethrow_exception() a nullptr will be returned by libcxxrt's __cxa_current_exception_type(). + // For exceptions thrown by std::rethrow_exception() a nullptr will be returned by libcxxrt's __cxa_current_exception_type(). // Adding an explicit test for the case. try { throw int(1); @@ -365,7 +365,7 @@ private: try { std::rethrow_exception(std::current_exception()); } catch (...) { -#if defined(LIBCXX_BUILDING_LIBGCC) +#if defined(LIBCXX_BUILDING_LIBGCC) UNIT_ASSERT_VALUES_EQUAL(CurrentExceptionTypeName(), "int"); #else UNIT_ASSERT_VALUES_EQUAL(CurrentExceptionTypeName(), "unknown type"); @@ -379,7 +379,7 @@ private: try { throw; } catch (...) { -#if defined(LIBCXX_BUILDING_LIBCXXRT) || defined(LIBCXX_BUILDING_LIBGCC) +#if defined(LIBCXX_BUILDING_LIBCXXRT) || defined(LIBCXX_BUILDING_LIBGCC) UNIT_ASSERT_VALUES_EQUAL(CurrentExceptionTypeName(), "int"); #else UNIT_ASSERT_VALUES_EQUAL(CurrentExceptionTypeName(), "unknown type"); |