/*
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