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)