diff options
author | eeight <eeight@yandex-team.ru> | 2022-02-10 16:46:19 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:19 +0300 |
commit | bd085aee9b4f7a0bee302ce687964ffb7098f986 (patch) | |
tree | 1a2c5ffcf89eb53ecd79dbc9bc0a195c27404d0c /library/cpp/containers/stack_vector/stack_vec.h | |
parent | 475c0a46f28166e83fd263badc7546377cddcabe (diff) | |
download | ydb-bd085aee9b4f7a0bee302ce687964ffb7098f986.tar.gz |
Restoring authorship annotation for <eeight@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/containers/stack_vector/stack_vec.h')
-rw-r--r-- | library/cpp/containers/stack_vector/stack_vec.h | 116 |
1 files changed, 58 insertions, 58 deletions
diff --git a/library/cpp/containers/stack_vector/stack_vec.h b/library/cpp/containers/stack_vector/stack_vec.h index 4fc3f26d89..fcc5d9a2a5 100644 --- a/library/cpp/containers/stack_vector/stack_vec.h +++ b/library/cpp/containers/stack_vector/stack_vec.h @@ -3,23 +3,23 @@ #include <util/generic/vector.h> #include <util/ysaveload.h> -#include <type_traits> - +#include <type_traits> + // A vector preallocated on the stack. // After exceeding the preconfigured stack space falls back to the heap. // Publicly inherits TVector, but disallows swap (and hence shrink_to_fit, also operator= is reimplemented via copying). // // Inspired by: http://qt-project.org/doc/qt-4.8/qvarlengtharray.html#details -template <typename T, size_t CountOnStack = 256, bool UseFallbackAlloc = true, class Alloc = std::allocator<T>> +template <typename T, size_t CountOnStack = 256, bool UseFallbackAlloc = true, class Alloc = std::allocator<T>> class TStackVec; template <typename T, class Alloc = std::allocator<T>> -using TSmallVec = TStackVec<T, 16, true, Alloc>; +using TSmallVec = TStackVec<T, 16, true, Alloc>; + +template <typename T, size_t CountOnStack = 256> +using TStackOnlyVec = TStackVec<T, CountOnStack, false>; -template <typename T, size_t CountOnStack = 256> -using TStackOnlyVec = TStackVec<T, CountOnStack, false>; - namespace NPrivate { template <class Alloc, class StackAlloc, typename T, typename U> struct TRebind { @@ -31,10 +31,10 @@ namespace NPrivate { typedef StackAlloc other; }; - template <typename T, size_t CountOnStack, bool UseFallbackAlloc, class Alloc = std::allocator<T>> + template <typename T, size_t CountOnStack, bool UseFallbackAlloc, class Alloc = std::allocator<T>> class TStackBasedAllocator: public Alloc { public: - typedef TStackBasedAllocator<T, CountOnStack, UseFallbackAlloc, Alloc> TSelf; + typedef TStackBasedAllocator<T, CountOnStack, UseFallbackAlloc, Alloc> TSelf; using typename Alloc::difference_type; using typename Alloc::size_type; @@ -58,14 +58,14 @@ namespace NPrivate { {} T* allocate(size_type n) { - if (!IsStorageUsed && CountOnStack >= n) { - IsStorageUsed = true; + if (!IsStorageUsed && CountOnStack >= n) { + IsStorageUsed = true; return reinterpret_cast<T*>(&StackBasedStorage[0]); } else { - if constexpr (!UseFallbackAlloc) { - Y_FAIL( - "Stack storage overflow. Capacity: %d, requested: %d", (int)CountOnStack, int(n)); - } + if constexpr (!UseFallbackAlloc) { + Y_FAIL( + "Stack storage overflow. Capacity: %d, requested: %d", (int)CountOnStack, int(n)); + } return FallbackAllocator().allocate(n); } } @@ -73,15 +73,15 @@ namespace NPrivate { void deallocate(T* p, size_type n) { if (p >= reinterpret_cast<T*>(&StackBasedStorage[0]) && p < reinterpret_cast<T*>(&StackBasedStorage[CountOnStack])) { - Y_VERIFY(IsStorageUsed); - IsStorageUsed = false; + Y_VERIFY(IsStorageUsed); + IsStorageUsed = false; } else { FallbackAllocator().deallocate(p, n); } } private: - std::aligned_storage_t<sizeof(T), alignof(T)> StackBasedStorage[CountOnStack]; + std::aligned_storage_t<sizeof(T), alignof(T)> StackBasedStorage[CountOnStack]; bool IsStorageUsed = false; private: @@ -91,8 +91,8 @@ namespace NPrivate { }; } -template <typename T, size_t CountOnStack, bool UseFallbackAlloc, class Alloc> -class TStackVec: public TVector<T, ::NPrivate::TStackBasedAllocator<T, CountOnStack, UseFallbackAlloc, TReboundAllocator<Alloc, T>>> { +template <typename T, size_t CountOnStack, bool UseFallbackAlloc, class Alloc> +class TStackVec: public TVector<T, ::NPrivate::TStackBasedAllocator<T, CountOnStack, UseFallbackAlloc, TReboundAllocator<Alloc, T>>> { private: using TBase = TVector<T, ::NPrivate::TStackBasedAllocator<T, CountOnStack, UseFallbackAlloc, TReboundAllocator<Alloc, T>>>; using TAllocator = typename TBase::allocator_type; @@ -131,13 +131,13 @@ public: } TStackVec(const TStackVec& src) - : TStackVec(src.begin(), src.end()) + : TStackVec(src.begin(), src.end()) { } template <class A> - TStackVec(const TVector<T, A>& src) - : TStackVec(src.begin(), src.end()) + TStackVec(const TVector<T, A>& src) + : TStackVec(src.begin(), src.end()) { } @@ -150,20 +150,20 @@ public: TStackVec(TIter first, TIter last, const TAllocator& alloc = TAllocator()) : TBase(alloc) { - // NB(eeight) Since we want to call 'reserve' here, we cannot just delegate to TVector ctor. - // The best way to insert values afterwards is to call TVector::insert. However there is a caveat. - // In order to call this ctor of TVector, T needs to be just move-constructible. Insert however - // requires T to be move-assignable. - TBase::reserve(CountOnStack); - if constexpr (std::is_move_assignable_v<T>) { - // Fast path - TBase::insert(TBase::end(), first, last); - } else { - // Slow path. - for (; first != last; ++first) { - TBase::push_back(*first); - } - } + // NB(eeight) Since we want to call 'reserve' here, we cannot just delegate to TVector ctor. + // The best way to insert values afterwards is to call TVector::insert. However there is a caveat. + // In order to call this ctor of TVector, T needs to be just move-constructible. Insert however + // requires T to be move-assignable. + TBase::reserve(CountOnStack); + if constexpr (std::is_move_assignable_v<T>) { + // Fast path + TBase::insert(TBase::end(), first, last); + } else { + // Slow path. + for (; first != last; ++first) { + TBase::push_back(*first); + } + } } public: @@ -188,25 +188,25 @@ public: }; template <typename T, size_t CountOnStack, class Alloc> -class TSerializer<TStackVec<T, CountOnStack, true, Alloc>>: public TVectorSerializer<TStackVec<T, CountOnStack, true, Alloc>> { +class TSerializer<TStackVec<T, CountOnStack, true, Alloc>>: public TVectorSerializer<TStackVec<T, CountOnStack, true, Alloc>> { +}; + +template <typename T, size_t CountOnStack, class Alloc> +class TSerializer<TStackVec<T, CountOnStack, false, Alloc>> { +public: + static void Save(IOutputStream* rh, const TStackVec<T, CountOnStack, false, Alloc>& v) { + if constexpr (CountOnStack < 256) { + ::Save(rh, (ui8)v.size()); + } else { + ::Save(rh, v.size()); + } + ::SaveArray(rh, v.data(), v.size()); + } + + static void Load(IInputStream* rh, TStackVec<T, CountOnStack, false, Alloc>& v) { + std::conditional_t<CountOnStack < 256, ui8, size_t> size; + ::Load(rh, size); + v.resize(size); + ::LoadPodArray(rh, v.data(), v.size()); + } }; - -template <typename T, size_t CountOnStack, class Alloc> -class TSerializer<TStackVec<T, CountOnStack, false, Alloc>> { -public: - static void Save(IOutputStream* rh, const TStackVec<T, CountOnStack, false, Alloc>& v) { - if constexpr (CountOnStack < 256) { - ::Save(rh, (ui8)v.size()); - } else { - ::Save(rh, v.size()); - } - ::SaveArray(rh, v.data(), v.size()); - } - - static void Load(IInputStream* rh, TStackVec<T, CountOnStack, false, Alloc>& v) { - std::conditional_t<CountOnStack < 256, ui8, size_t> size; - ::Load(rh, size); - v.resize(size); - ::LoadPodArray(rh, v.data(), v.size()); - } -}; |