94 lines
2.9 KiB
Plaintext
94 lines
2.9 KiB
Plaintext
|
|
#pragma once
|
|
|
|
#if !defined(BAD_APPLE_OS_SPAN_HPP_INCLUDED)
|
|
#define BAD_APPLE_OS_SPAN_HPP_INCLUDED
|
|
|
|
#include <array>
|
|
#include <cstddef>
|
|
#include <initializer_list>
|
|
#include <stdexcept>
|
|
#include <type_traits>
|
|
|
|
namespace std
|
|
{
|
|
inline constexpr size_t dynamic_extent = size_t(-1);
|
|
|
|
template<typename T, size_t Extent = dynamic_extent> // TODO: use the extent?
|
|
class span
|
|
{
|
|
public:
|
|
using element_type = T;
|
|
using value_type = remove_cv_t<T>;
|
|
using size_type = size_t;
|
|
using difference_type = ptrdiff_t;
|
|
using reference = element_type&;
|
|
using const_reference = const element_type&;
|
|
using pointer = element_type*;
|
|
using const_pointer = const element_type*;
|
|
using iterator = pointer;
|
|
using const_iterator = const_pointer;
|
|
|
|
static constexpr size_t extent = Extent;
|
|
private:
|
|
pointer _first = nullptr;
|
|
pointer _last = nullptr;
|
|
public:
|
|
constexpr span() noexcept = default;
|
|
constexpr span(const span&) noexcept = default;
|
|
|
|
template<typename It>
|
|
explicit(extent != dynamic_extent)
|
|
constexpr span(It first, size_type count) : _first(&*first), _last(&*(_first + count)) {}
|
|
|
|
template<typename It>
|
|
explicit(extent != dynamic_extent)
|
|
constexpr span(It first, It last) : _first(&*first), _last(&*last) {}
|
|
|
|
template<size_t N>
|
|
constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept : span(&arr[0], N) {}
|
|
|
|
template<typename U, size_t N>
|
|
constexpr span(array<U, N>& arr) noexcept : span(&arr[0], N) {}
|
|
|
|
template<typename U, size_t N>
|
|
constexpr span(const array<U, N>& arr) noexcept : span(&arr[0], N) {}
|
|
|
|
explicit(Extent != dynamic_extent)
|
|
constexpr span(initializer_list<value_type> il) noexcept : span(il.begin(), il.size()) {}
|
|
|
|
template<typename U, size_t N>
|
|
explicit(extent != dynamic_extent && N != dynamic_extent)
|
|
constexpr span(const span<U, N>& source) noexcept : span(source.begin(), source.end()) {}
|
|
|
|
constexpr span& operator=(const span&) noexcept = default;
|
|
|
|
constexpr reference operator[](size_type idx) const { return _first[idx]; }
|
|
|
|
constexpr iterator begin() const noexcept { return _first; }
|
|
constexpr const_iterator cbegin() const noexcept { return _first; }
|
|
constexpr iterator end() const noexcept { return _last; }
|
|
constexpr const_iterator cend() const noexcept { return _last; }
|
|
|
|
constexpr reference front() const { return *_first; }
|
|
constexpr reference back() const { return *(_last - 1); }
|
|
|
|
constexpr reference at(size_type pos) const
|
|
{
|
|
if (pos >= size()) {
|
|
__ba_throw std::out_of_range();
|
|
}
|
|
return (*this)[pos];
|
|
}
|
|
constexpr pointer data() const noexcept { return _first; }
|
|
|
|
constexpr size_type size() const noexcept { return _last - _first; }
|
|
constexpr size_type size_bytes() const noexcept { return size() * sizeof(element_type); }
|
|
constexpr bool empty() const noexcept { return size() == 0; }
|
|
|
|
// TODO: subspans
|
|
};
|
|
}
|
|
|
|
#endif // !defined(BAD_APPLE_OS_SPAN_HPP_INCLUDED)
|