base/include/base/span/span.h¶
Provides a C++17 implementation of std::span (C++20). More...
Namespaces¶
| Name |
|---|
| cf |
Classes¶
| Name | |
|---|---|
| class | cf::span A non-owning view into a contiguous sequence of elements. |
Detailed Description¶
Provides a C++17 implementation of std::span (C++20).
Author: Charliechen114514
Version: 0.1
Since: 0.1
Date: 2026-02-22
Offers a zero-overhead view into contiguous sequences of elements. Supports C arrays, std::vector, and std::array as underlying storage.
Source code¶
#pragma once
#include <array>
#include <cstddef>
#include <vector>
namespace cf {
template <typename T> class span {
T* data_;
size_t size_;
public:
constexpr span() noexcept : data_(nullptr), size_(0) {}
constexpr span(T* data, size_t size) noexcept : data_(data), size_(size) {}
template <size_t N> constexpr span(T (&arr)[N]) noexcept : data_(arr), size_(N) {}
constexpr span(std::vector<T>& vec) noexcept : data_(vec.data()), size_(vec.size()) {}
template <typename U = T, std::enable_if_t<std::is_const<U>::value, int> = 0>
constexpr span(const std::vector<std::remove_const_t<T>>& vec) noexcept
: data_(vec.data()), size_(vec.size()) {}
template <size_t N> constexpr span(std::array<T, N>& arr) noexcept
: data_(arr.data()), size_(N) {}
template <size_t N, typename U = T, std::enable_if_t<std::is_const<U>::value, int> = 0>
constexpr span(const std::array<std::remove_const_t<T>, N>& arr) noexcept
: data_(arr.data()), size_(N) {}
constexpr span(const span& other) noexcept = default;
constexpr span& operator=(const span& other) noexcept = default;
constexpr T* data() const noexcept { return data_; }
constexpr size_t size() const noexcept { return size_; }
constexpr bool empty() const noexcept { return size_ == 0; }
constexpr T& operator[](size_t index) const noexcept { return data_[index]; }
constexpr T& front() const noexcept { return data_[0]; }
constexpr T& back() const noexcept { return data_[size_ - 1]; }
constexpr T* begin() const noexcept { return data_; }
constexpr T* end() const noexcept { return data_ + size_; }
constexpr span<T> first(size_t count) const noexcept { return span<T>(data_, count); }
constexpr span<T> last(size_t count) const noexcept {
return span<T>(data_ + size_ - count, count);
}
constexpr span<T> subspan(size_t offset,
size_t count = static_cast<size_t>(-1)) const noexcept {
if (count == static_cast<size_t>(-1)) {
count = size_ - offset;
}
return span<T>(data_ + offset, count);
}
};
// Type deduction guides
template <typename T> span(T*, size_t) -> span<T>;
template <typename T, size_t N> span(T (&)[N]) -> span<T>;
template <typename T> span(std::vector<T>&) -> span<T>;
template <typename T> span(const std::vector<T>&) -> span<const T>;
template <typename T, size_t N> span(std::array<T, N>&) -> span<T>;
template <typename T, size_t N> span(const std::array<T, N>&) -> span<const T>;
} // namespace cf
Updated on 2026-03-09 at 10:14:01 +0000