27inline 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->());
94template <
typename Value,
size_t Extent = dynamicExtent>
95class 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;
138template <
typename T,
typename End>
141template <
typename T,
size_t N>
144template <
typename T,
size_t N>
147template <
typename T,
size_t N>
150template <
typename Range>
151Span (
Range&& r) ->
Span<std::remove_pointer_t<
decltype (std::data (r))>>;