/* This file is part of TON Blockchain Library. TON Blockchain Library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. TON Blockchain Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . Copyright 2017-2019 Telegram Systems LLP */ #pragma once #include "td/utils/common.h" #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 *data() const { return data_; } InnerT *begin() const { return data_; } InnerT *end() const { return data_ + size_; } size_t size() const { return size_; } bool empty() const { return size() == 0; } SpanImpl &truncate(size_t size) { CHECK(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 span(const T *ptr, size_t size) { return Span(ptr, size); } template MutableSpan mutable_span(T *ptr, size_t size) { return MutableSpan(ptr, size); } } // namespace td