27 inline constexpr
auto dynamicExtent = std::numeric_limits<size_t>::max();
32 template <
typename,
typename =
void>
33 constexpr
auto hasToAddress =
false;
36 constexpr
auto hasToAddress<T, Void<decltype (std::pointer_traits<T>::to_address (std::declval<T>()))>> =
true;
38 template <
typename,
typename =
void>
39 constexpr
auto hasDataAndSize =
false;
42 constexpr
auto hasDataAndSize<T,
43 Void<decltype (std::data (std::declval<T>())),
44 decltype (std::size (std::declval<T>()))>> =
true;
46 template <
size_t Extent>
49 constexpr NumBase() =
default;
51 constexpr
explicit NumBase (
size_t) {}
53 constexpr
size_t size()
const {
return Extent; }
57 struct NumBase<dynamicExtent>
59 constexpr NumBase() =
default;
61 constexpr
explicit NumBase (
size_t arg)
64 constexpr
size_t size()
const {
return num; }
70 constexpr T* toAddress (T* p)
75 template <
typename It>
76 constexpr
auto toAddress (
const It& it)
78 if constexpr (detail::hasToAddress<It>)
79 return std::pointer_traits<It>::to_address (it);
81 return toAddress (it.operator->());
94 template <
typename Value,
size_t Extent = dynamicExtent>
95 class Span :
private detail::NumBase<Extent>
97 using Base = detail::NumBase<Extent>;
100 static constexpr
auto extent = Extent;
102 template <
size_t e = extent, std::enable_if_t<e == 0 || e == dynamicExtent,
int> = 0>
105 template <
typename It>
106 constexpr
Span (It it,
size_t end)
107 : Base (end), ptr (detail::toAddress (it)) {}
109 template <
typename Range, std::enable_if_t<detail::hasDataAndSize<Range>,
int> = 0>
111 : Base (std::size (range)), ptr (std::data (range)) {}
113 constexpr
Span (
const Span&) =
default;
115 constexpr
Span& operator= (
const Span&) =
default;
117 constexpr
Span (
Span&&) noexcept =
default;
119 constexpr
Span& operator= (
Span&&) noexcept =
default;
123 constexpr
Value* begin()
const {
return ptr; }
124 constexpr
Value* end()
const {
return ptr + size(); }
126 constexpr
auto& front()
const {
return ptr[0]; }
127 constexpr
auto& back()
const {
return ptr[size() - 1]; }
129 constexpr
auto& operator[] (
size_t index)
const {
return ptr[index]; }
130 constexpr
Value* data()
const {
return ptr; }
132 constexpr
bool empty()
const {
return size() == 0; }
135 Value* ptr =
nullptr;
138 template <
typename T,
typename End>
141 template <
typename T,
size_t N>
144 template <
typename T,
size_t N>
147 template <
typename T,
size_t N>
150 template <
typename Range>
151 Span (
Range&& r) ->
Span<std::remove_pointer_t<decltype (std::data (r))>>;