// // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once #include "td/utils/common.h" #include #include namespace td { namespace detail { template class SpanImpl { InnerT *data_{nullptr}; size_t size_{0}; public: SpanImpl() = default; SpanImpl(InnerT *data, size_t size) : data_(data), size_(size) { } SpanImpl(InnerT &data) : SpanImpl(&data, 1) { } template SpanImpl(const SpanImpl &other) : SpanImpl(other.data(), other.size()) { } template SpanImpl(const std::array &arr) : SpanImpl(arr.data(), arr.size()) { } template SpanImpl(std::array &arr) : SpanImpl(arr.data(), arr.size()) { } template SpanImpl(const T (&arr)[N]) : SpanImpl(arr, N) { } template SpanImpl(T (&arr)[N]) : SpanImpl(arr, N) { } SpanImpl(const vector &v) : SpanImpl(v.data(), v.size()) { } SpanImpl(vector &v) : SpanImpl(v.data(), v.size()) { } template SpanImpl &operator=(const SpanImpl &other) { SpanImpl copy{other}; *this = copy; } template bool operator==(const SpanImpl &other) const { if (size() != other.size()) { return false; } for (size_t i = 0; i < size(); i++) { if (!((*this)[i] == other[i])) { return false; } } return true; } InnerT &operator[](size_t i) { DCHECK(i < size()); return data_[i]; } const InnerT &operator[](size_t i) const { DCHECK(i < size()); return data_[i]; } InnerT &back() { DCHECK(!empty()); return data_[size() - 1]; } const InnerT &back() const { DCHECK(!empty()); return data_[size() - 1]; } InnerT &front() { DCHECK(!empty()); return data_[0]; } const InnerT &front() const { DCHECK(!empty()); return data_[0]; } InnerT *data() const { return data_; } InnerT *begin() const { return data_; } InnerT *end() const { return data_ + size_; } std::reverse_iterator rbegin() const { return std::reverse_iterator(end()); } std::reverse_iterator rend() const { return std::reverse_iterator(begin()); } size_t size() const { return size_; } bool empty() const { return size() == 0; } SpanImpl &truncate(size_t size) { if (size < size_) { size_ = size; } return *this; } SpanImpl substr(size_t offset) const { CHECK(offset <= size_); return SpanImpl(begin() + offset, size_ - offset); } SpanImpl substr(size_t offset, size_t size) const { CHECK(offset <= size_); CHECK(size_ - offset >= size); return SpanImpl(begin() + offset, size); } }; } // namespace detail template using Span = detail::SpanImpl; template using MutableSpan = detail::SpanImpl; template Span as_span(const std::vector &vec) { return Span(vec); } template MutableSpan as_mutable_span(std::vector &vec) { return MutableSpan(vec); } } // namespace td