1#ifndef MILLICAST_API_SPAN_H
2#define MILLICAST_API_SPAN_H
15template <
typename T,
typename E,
typename =
void>
17struct is_container_element_type_compatible : std::false_type {};
19template <
typename T,
typename E>
20struct is_container_element_type_compatible<
23 typename std::enable_if<
24 !std::is_same<typename std::remove_cv<decltype(std::data(
25 std::declval<T>()))>::type,
28 std::remove_pointer_t<decltype(std::declval<T>().data())> (*)[],
29 E (*)[]>::value>::type> : std::true_type {};
35 using element_type = T;
36 using pointer = element_type*;
37 using reference = element_type&;
39 constexpr Span() noexcept = default;
40 constexpr Span(pointer ptr,
size_t size) noexcept : _ptr(ptr), _size(size) {}
43 constexpr Span(T (&arr)[N]) noexcept : Span(arr, N) {}
44 constexpr Span(
const Span&)
noexcept =
default;
48 typename std::enable_if<
49 std::is_same_v<typename C::value_type, T> ||
50 detail::is_container_element_type_compatible<const C&, T>::value,
52 constexpr Span(
const C& container) noexcept
53 : _ptr(std::data(container)), _size(std::size(container)) {}
56 typename std::enable_if<
57 std::is_same_v<typename C::value_type, T> ||
58 detail::is_container_element_type_compatible<C&, T>::value,
60 constexpr Span(C& container) noexcept
61 : _ptr(std::data(container)), _size(std::size(container)) {}
64 typename OtherElementType,
65 typename std::enable_if<!std::is_same_v<OtherElementType, T> &&
66 detail::is_container_element_type_compatible<
67 const Span<OtherElementType>&,
70 constexpr Span(
const Span<OtherElementType>& other) noexcept
71 : _ptr(other._ptr), _size(other._size) {}
73 constexpr T* data()
const {
return _ptr; }
74 constexpr T* begin()
const {
return data(); }
75 constexpr T* end()
const {
return data() + size(); }
77 [[nodiscard]]
constexpr size_t size()
const {
return _size; }
78 [[nodiscard]]
constexpr size_t size_bytes()
const {
79 return size() *
sizeof(T);
81 [[nodiscard]]
constexpr bool empty()
const {
return size() == 0; }
#define MILLICAST_TEMPLATE_API
Definition exports.h:46