123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374 |
- #pragma once
- #include "public.h"
- #include "intrusive_ptr.h"
- #include "range.h"
- #include "ref_counted.h"
- #include <library/cpp/yt/assert/assert.h>
- #include <util/ysaveload.h>
- #include <optional>
- namespace NYT {
- ////////////////////////////////////////////////////////////////////////////////
- template <class T, size_t N>
- class TCompactVector;
- ////////////////////////////////////////////////////////////////////////////////
- struct TSharedRangeHolderCloneOptions
- {
- bool KeepMemoryReferenceTracking = true;
- };
- struct TSharedRangeHolder
- : public TRefCounted
- {
- //! Clones the holder possibly adjusting its flavor based on #options.
- /*!
- * The default implementation just returns this.
- */
- virtual TSharedRangeHolderPtr Clone(const TSharedRangeHolderCloneOptions& options);
- //! Returns the (estimated) total number of bytes being held or |null| if unable to estimate.
- /*!
- * The returned value is static and never changes.
- * The default implementation returns |null|.
- */
- virtual std::optional<size_t> GetTotalByteSize() const;
- };
- DEFINE_REFCOUNTED_TYPE(TSharedRangeHolder)
- ////////////////////////////////////////////////////////////////////////////////
- //! TRange with ownership semantics.
- template <class T>
- class TSharedRange
- : public TRange<T>
- {
- public:
- //! Constructs a null TSharedRange.
- TSharedRange()
- { }
- //! Constructs an empty TSharedRange from a nullptr expression.
- TSharedRange(std::nullptr_t)
- : TRange<T>(nullptr, 0UL)
- , Holder_(nullptr)
- { }
- //! Constructs a TSharedRange from TRange.
- TSharedRange(TRange<T> range, TSharedRangeHolderPtr holder)
- : TRange<T>(range)
- , Holder_(std::move(holder))
- { }
- //! Constructs a TSharedRange from a pointer and length.
- TSharedRange(const T* data, size_t length, TSharedRangeHolderPtr holder)
- : TRange<T>(data, length)
- , Holder_(std::move(holder))
- { }
- //! Constructs a TSharedRange from a range.
- TSharedRange(const T* begin, const T* end, TSharedRangeHolderPtr holder)
- : TRange<T>(begin, end)
- , Holder_(std::move(holder))
- { }
- //! Constructs a TSharedRange from a TCompactVector.
- template <size_t N>
- TSharedRange(const TCompactVector<T, N>& elements, TSharedRangeHolderPtr holder)
- : TRange<T>(elements)
- , Holder_(std::move(holder))
- { }
- //! Constructs a TSharedRange from an std::vector.
- TSharedRange(const std::vector<T>& elements, TSharedRangeHolderPtr holder)
- : TRange<T>(elements)
- , Holder_(std::move(holder))
- { }
- //! Constructs a TSharedRange from a C array.
- template <size_t N>
- TSharedRange(const T (& elements)[N], TSharedRangeHolderPtr holder)
- : TRange<T>(elements)
- , Holder_(std::move(holder))
- { }
- TSharedRange(const TSharedRange& other) = default;
- TSharedRange(TSharedRange&& other) noexcept
- : TSharedRange()
- {
- other.Swap(*this);
- }
- TSharedRange& operator=(TSharedRange other) noexcept
- {
- other.Swap(*this);
- return *this;
- }
- void Swap(TSharedRange& other) noexcept
- {
- DoSwap(TRange<T>::Data_, other.Data_);
- DoSwap(TRange<T>::Length_, other.Length_);
- Holder_.Swap(other.Holder_);
- }
- void Reset()
- {
- TRange<T>::Data_ = nullptr;
- TRange<T>::Length_ = 0;
- Holder_.Reset();
- }
- TSharedRange<T> Slice(size_t startOffset, size_t endOffset) const
- {
- YT_ASSERT(startOffset <= this->Size());
- YT_ASSERT(endOffset >= startOffset && endOffset <= this->Size());
- return TSharedRange<T>(this->Begin() + startOffset, endOffset - startOffset, Holder_);
- }
- TSharedRange<T> Slice(const T* begin, const T* end) const
- {
- YT_ASSERT(begin >= this->Begin());
- YT_ASSERT(end <= this->End());
- return TSharedRange<T>(begin, end, Holder_);
- }
- const TSharedRangeHolderPtr& GetHolder() const
- {
- return Holder_;
- }
- TSharedRangeHolderPtr&& ReleaseHolder()
- {
- return std::move(Holder_);
- }
- protected:
- TSharedRangeHolderPtr Holder_;
- };
- ////////////////////////////////////////////////////////////////////////////////
- //! Constructs a combined holder from a vector of typed holders.
- TSharedRangeHolderPtr MakeCompositeSharedRangeHolder(std::vector<TSharedRangeHolderPtr> holders);
- //! Constructs a combined holder instance by taking ownership of a given list of holders.
- template <class... THolders>
- TSharedRangeHolderPtr MakeSharedRangeHolder(THolders&&... holders)
- {
- struct THolder
- : public TSharedRangeHolder
- {
- std::tuple<typename std::decay<THolders>::type...> Holders;
- };
- auto holder = New<THolder>();
- holder->Holders = std::tuple<THolders...>(std::forward<THolders>(holders)...);
- return holder;
- }
- template <class T, class TContainer, class... THolders>
- TSharedRange<T> DoMakeSharedRange(TContainer&& elements, THolders&&... holders)
- {
- struct THolder
- : public TSharedRangeHolder
- {
- typename std::decay<TContainer>::type Elements;
- std::tuple<typename std::decay<THolders>::type...> Holders;
- };
- auto holder = New<THolder>();
- holder->Holders = std::tuple<THolders...>(std::forward<THolders>(holders)...);
- holder->Elements = std::forward<TContainer>(elements);
- auto range = TRange<T>(holder->Elements);
- return TSharedRange<T>(range, std::move(holder));
- }
- //! Constructs a TSharedRange by taking ownership of an std::vector.
- template <class T, class... THolders>
- TSharedRange<T> MakeSharedRange(std::vector<T>&& elements, THolders&&... holders)
- {
- return DoMakeSharedRange<T>(std::move(elements), std::forward<THolders>(holders)...);
- }
- //! Constructs a TSharedRange by taking ownership of an TCompactVector.
- template <class T, size_t N, class... THolders>
- TSharedRange<T> MakeSharedRange(TCompactVector<T, N>&& elements, THolders&&... holders)
- {
- return DoMakeSharedRange<T>(std::move(elements), std::forward<THolders>(holders)...);
- }
- //! Constructs a TSharedRange by copying an std::vector.
- template <class T, class... THolders>
- TSharedRange<T> MakeSharedRange(const std::vector<T>& elements, THolders&&... holders)
- {
- return DoMakeSharedRange<T>(elements, std::forward<THolders>(holders)...);
- }
- template <class T, class... THolders>
- TSharedRange<T> MakeSharedRange(TRange<T> range, THolders&&... holders)
- {
- return TSharedRange<T>(range, MakeSharedRangeHolder(std::forward<THolders>(holders)...));
- }
- template <class T, class THolder>
- TSharedRange<T> MakeSharedRange(TRange<T> range, TSharedRangeHolderPtr holder)
- {
- return TSharedRange<T>(range, std::move(holder));
- }
- template <class U, class T>
- TSharedRange<U> ReinterpretCastRange(const TSharedRange<T>& range)
- {
- static_assert(sizeof(T) == sizeof(U), "T and U must have equal sizes.");
- return TSharedRange<U>(reinterpret_cast<const U*>(range.Begin()), range.Size(), range.GetHolder());
- }
- ////////////////////////////////////////////////////////////////////////////////
- //! TMutableRange with ownership semantics.
- //! Use with caution :)
- template <class T>
- class TSharedMutableRange
- : public TMutableRange<T>
- {
- public:
- //! Constructs a null TSharedMutableRange.
- TSharedMutableRange()
- { }
- //! Constructs a TSharedMutableRange from TMutableRange.
- TSharedMutableRange(TMutableRange<T> range, TSharedRangeHolderPtr holder)
- : TMutableRange<T>(range)
- , Holder_(std::move(holder))
- { }
- //! Constructs a TSharedMutableRange from a pointer and length.
- TSharedMutableRange(T* data, size_t length, TSharedRangeHolderPtr holder)
- : TMutableRange<T>(data, length)
- , Holder_(std::move(holder))
- { }
- //! Constructs a TSharedMutableRange from a range.
- TSharedMutableRange(T* begin, T* end, TSharedRangeHolderPtr holder)
- : TMutableRange<T>(begin, end)
- , Holder_(std::move(holder))
- { }
- //! Constructs a TSharedMutableRange from a TCompactVector.
- template <size_t N>
- TSharedMutableRange(TCompactVector<T, N>& elements, TSharedRangeHolderPtr holder)
- : TMutableRange<T>(elements)
- , Holder_(std::move(holder))
- { }
- //! Constructs a TSharedMutableRange from an std::vector.
- TSharedMutableRange(std::vector<T>& elements, TSharedRangeHolderPtr holder)
- : TMutableRange<T>(elements)
- , Holder_(std::move(holder))
- { }
- //! Constructs a TSharedMutableRange from a C array.
- template <size_t N>
- TSharedMutableRange(T (& elements)[N], TSharedRangeHolderPtr holder)
- : TMutableRange<T>(elements)
- , Holder_(std::move(holder))
- { }
- TSharedMutableRange(const TSharedMutableRange& other) = default;
- TSharedMutableRange(TSharedMutableRange&& other) noexcept
- : TSharedMutableRange()
- {
- other.Swap(*this);
- }
- TSharedMutableRange& operator=(TSharedMutableRange other) noexcept
- {
- other.Swap(*this);
- return *this;
- }
- void Swap(TSharedMutableRange& other) noexcept
- {
- DoSwap(TRange<T>::Data_, other.Data_);
- DoSwap(TRange<T>::Length_, other.Length_);
- Holder_.Swap(other.Holder_);
- }
- void Reset()
- {
- TRange<T>::Data_ = nullptr;
- TRange<T>::Length_ = 0;
- Holder_.Reset();
- }
- TSharedMutableRange<T> Slice(size_t startOffset, size_t endOffset) const
- {
- YT_ASSERT(startOffset <= this->Size());
- YT_ASSERT(endOffset >= startOffset && endOffset <= this->Size());
- return TSharedMutableRange<T>(this->Begin() + startOffset, endOffset - startOffset, Holder_);
- }
- TSharedMutableRange<T> Slice(T* begin, T* end) const
- {
- YT_ASSERT(begin >= this->Begin());
- YT_ASSERT(end <= this->End());
- return TSharedMutableRange<T>(begin, end, Holder_);
- }
- TSharedRangeHolderPtr GetHolder() const
- {
- return Holder_;
- }
- TSharedRangeHolderPtr&& ReleaseHolder()
- {
- return std::move(Holder_);
- }
- protected:
- TSharedRangeHolderPtr Holder_;
- };
- template <class T, class TContainer, class... THolders>
- TSharedMutableRange<T> DoMakeSharedMutableRange(TContainer&& elements, THolders&&... holders)
- {
- struct THolder
- : public TSharedRangeHolder
- {
- typename std::decay<TContainer>::type Elements;
- std::tuple<typename std::decay<THolders>::type...> Holders;
- };
- auto holder = New<THolder>();
- holder->Holders = std::tuple<THolders...>(std::forward<THolders>(holders)...);
- holder->Elements = std::forward<TContainer>(elements);
- auto range = TMutableRange<T>(holder->Elements);
- return TSharedMutableRange<T>(range, holder);
- }
- //! Constructs a TSharedMutableRange by taking ownership of an std::vector.
- template <class T, class... THolders>
- TSharedMutableRange<T> MakeSharedMutableRange(std::vector<T>&& elements, THolders&&... holders)
- {
- return DoMakeSharedMutableRange<T>(std::move(elements), std::forward<THolders>(holders)...);
- }
- ////////////////////////////////////////////////////////////////////////////////
- } // namespace NYT
|