6#include <initializer_list>
30 template <
typename,
typename =
void>
31 struct HasSize : std::false_type {};
34 struct HasSize<C, std::void_t<decltype(std::size(std::declval<C>()))>> : std::true_type {};
36 template <
typename,
typename =
void>
37 struct HasData : std::false_type {};
40 struct HasData<C, std::void_t<decltype(std::data(std::declval<C>()))>> : std::true_type {};
43 using EnableIfHasSizeAndData =
44 typename std::enable_if_t<HasSize<C>::value && HasData<C>::value>;
62 constexpr Span() noexcept = default;
71 template <
typename Container,
typename = EnableIfHasSizeAndData<Container>>
72 constexpr Span(Container& container)
noexcept
73 :
Span(std::data(container), std::size(container)) {}
78 template <
typename Container,
typename = EnableIfHasSizeAndData<Container>>
79 constexpr Span(
const Container& container)
noexcept
80 :
Span(std::data(container), std::size(container)) {}
95 constexpr Span(std::initializer_list<value_type> values) noexcept
96 :
Span(values.begin(), values.size()) {}
99 std::swap(data_, other.data_);
100 std::swap(size_, other.size_);
103 [[nodiscard]]
constexpr size_t size() const noexcept {
107 [[nodiscard]]
constexpr bool empty() const noexcept {
117 assert(index <
size());
118 return data()[index];
124 if (index >=
size()) {
125 throw std::out_of_range(
126 std::string(
"index (") + std::to_string(index) +
") >= size() (" +
127 std::to_string(
size()) +
")"
130 return data()[index];
177 size_t offset,
size_t count = (std::numeric_limits<std::size_t>::max)()
179 if (offset >=
size()) {
182 if (count >
size() - offset) {
183 count =
size() - offset;
185 return {
data() + offset, count};
189 [[nodiscard]]
constexpr Span first(
size_t count)
const noexcept {
190 if (count >=
size()) {
193 return {
data(), count};
197 [[nodiscard]]
constexpr Span last(
size_t count)
const noexcept {
198 if (count >=
size()) {
201 return {
data() + (
size() - count), count};
212template <
typename Container>
216template <
typename Container>
224struct IsSpan : std::false_type {};
227struct IsSpan<
Span<T>> : std::true_type {};
235template <
typename T,
typename U>
236using EnableIfEqualityComparable =
typename std::enable_if_t<
237 std::is_invocable_v<std::equal_to<>,
const T&,
const U&> &&
238 std::is_invocable_v<std::not_equal_to<>,
const T&,
const U&>>;
243template <
typename T,
typename U,
typename = detail::EnableIfEqualityComparable<T, U>>
249template <
typename T,
typename U,
typename = detail::EnableIfEqualityComparable<T, U>>
251 return !(lhs == rhs);
View to a contiguous sequence of objects, similar to std::span in C++20.
constexpr const_reverse_iterator crend() const noexcept
std::remove_cv_t< T > value_type
const T & const_reference
constexpr Span last(size_t count) const noexcept
Obtain a view over the last count elements of this Span.
constexpr reverse_iterator rend() const noexcept
constexpr reference operator[](size_t index) const noexcept
Access element by index.
constexpr reference at(size_t index) const
Access element by index with bounds checking.
constexpr const_iterator cbegin() const noexcept
constexpr iterator begin() const noexcept
constexpr Span() noexcept=default
constexpr bool operator==(Span< T > lhs, Span< U > rhs)
constexpr Span(std::initializer_list< value_type > values) noexcept
Implicit constructor from an initializer list.
constexpr bool empty() const noexcept
constexpr bool operator!=(Span< T > lhs, Span< U > rhs)
constexpr void swap(Span &other) noexcept
constexpr Span subview(size_t offset, size_t count=(std::numeric_limits< std::size_t >::max)()) const noexcept
Obtain a view over count elements of this Span starting at offset offset.
std::reverse_iterator< const_iterator > const_reverse_iterator
constexpr const_reverse_iterator crbegin() const noexcept
constexpr size_t size() const noexcept
Span(Container &) -> Span< typename Container::value_type >
constexpr reference front() const noexcept
constexpr Span(Container &container) noexcept
Implicit constructor from a container like std::array or std::vector.
std::reverse_iterator< iterator > reverse_iterator
Span(const Container &) -> Span< const typename Container::value_type >
constexpr reverse_iterator rbegin() const noexcept
constexpr reference back() const noexcept
const_pointer const_iterator
std::ptrdiff_t difference_type
constexpr iterator end() const noexcept
constexpr const_iterator cend() const noexcept
constexpr pointer data() const noexcept
constexpr Span(const Container &container) noexcept
Implicit constructor from a container like std::array or std::vector (const).
constexpr Span first(size_t count) const noexcept
Obtain a view over the first count elements of this Span.