1 #ifndef MATIOCPP_SPAN_H
2 #define MATIOCPP_SPAN_H
81 template<
class,
typename =
void >
89 template <
typename T,
typename =
void>
98 using type =
typename T::value_type;
102 template <
typename T>
109 template <
typename T>
112 using type =
typename std::remove_all_extents_t<T>;
116 template <
typename Class,
typename =
void>
120 template <
typename Class>
122 typename
std::enable_if<
123 std::is_constructible<Span<typename container_data<Class>::type>, Class&>::value>::type>
137 template <
class ElementType, std::ptrdiff_t Extent>
152 template <
class ElementType, std::
size_t Extent>
162 template <std::ptrdiff_t From, std::ptrdiff_t To>
165 To == matioCpp::dynamic_extent>
169 template <
class From,
class To>
175 template <
class Span,
bool IsConst>
186 using reference = std::conditional_t<IsConst, const element_type_, element_type_>&;
187 using pointer = std::add_pointer_t<reference>;
196 template<
bool B, std::enable_if_t<!B && IsConst>* =
nullptr>
230 assert(
index_ != 0 && index_ <= span_->size());
277 return lhs.span_ == rhs.span_ && lhs.index_ == rhs.index_;
283 return !(lhs == rhs);
289 return lhs.index_ < rhs.index_;
315 template <
class Span,
bool IsConst>
323 template <
class Span,
bool IsConst>
331 template <std::ptrdiff_t Ext>
337 static_assert(Ext >= 0,
"A fixed-size span must be >= 0 in size.");
341 template <index_type Other>
345 "Mismatch between fixed-size extent and size of initializing data.");
346 assert(ext.
size() == Ext);
360 template <index_type Other>
373 template <
class ElementType, std::ptrdiff_t Extent, std::ptrdiff_t Offset, std::ptrdiff_t Count>
381 template <
class ElementType, std::ptrdiff_t Extent>
400 #if defined(MATIOCPP_USE_STATIC_CONSTEXPR_WORKAROUND)
408 template <
bool Dependent =
false,
411 class = std::enable_if_t<(Dependent || Extent <= 0)>>
420 : storage_(firstElem,
std::distance(firstElem, lastElem))
424 template <std::
size_t N>
430 template <std::
size_t N,
class ArrayElementType = std::remove_const_t<element_type>>
436 template <std::
size_t N>
445 template <
class Container,
447 class = std::enable_if_t<
454 template <
class Container,
456 class = std::enable_if_t<
469 class = std::enable_if_t<
473 : storage_(other.
data(), details::extent_type<OtherExtent>(other.
size()))
482 template <
std::ptrdiff_t Count>
485 assert(Count >= 0 && Count <=
size());
486 return {
data(), Count};
489 template <std::ptrdiff_t Count>
492 assert(Count >= 0 &&
size() - Count >= 0);
493 return {
data() + (
size() - Count), Count};
497 template <std::ptrdiff_t Offset, std::ptrdiff_t Count = dynamic_extent>
500 assert((Offset >= 0 &&
size() - Offset >= 0) &&
509 assert(count >= 0 && count <=
size());
510 return {
data(), count};
521 return make_subspan(offset, count, subspan_selector<Extent>{});
536 assert(idx >= 0 && idx < storage_.size());
543 assert(idx >= 0 && idx < storage_.size());
576 template <
class ExtentType>
577 class storage_type :
public ExtentType
582 template <
class OtherExtentType>
585 assert(ExtentType::size() >= 0);
589 template <
class OtherExtentType>
592 assert(ExtentType::size() >= 0);
593 assert(
data || ExtentType::size() == 0);
602 storage_type<details::extent_type<Extent>> storage_;
608 template <std::ptrdiff_t CallerExtent>
609 class subspan_selector {};
611 template <std::ptrdiff_t CallerExtent>
612 Span<element_type, dynamic_extent> make_subspan(
index_type offset,
614 subspan_selector<CallerExtent>)
const
616 Span<element_type, dynamic_extent> tmp(*
this);
617 return tmp.subspan(offset, count);
620 Span<element_type, dynamic_extent> make_subspan(
index_type offset,
622 subspan_selector<dynamic_extent>)
const
624 assert(offset >= 0 &&
size() - offset >= 0);
627 return { KnownNotNull{
data() + offset },
size() - offset };
630 assert(count >= 0 &&
size() - offset >= count);
631 return { KnownNotNull{
data() + offset },
count };
635 #if defined(MATIOCPP_USE_STATIC_CONSTEXPR_WORKAROUND)
636 template <
class ElementType, std::ptrdiff_t Extent>
642 template <
class ElementType, std::ptrdiff_t FirstExtent, std::ptrdiff_t SecondExtent>
649 template <
class ElementType, std::ptrdiff_t Extent>
656 template <
class ElementType, std::ptrdiff_t Extent>
663 template <
class ElementType, std::ptrdiff_t Extent>
670 template <
class ElementType, std::ptrdiff_t Extent>
677 template <
class ElementType, std::ptrdiff_t Extent>
693 template <
class ElementType, std::ptrdiff_t Extent>
696 static_cast<std::ptrdiff_t>(sizeof(ElementType) *
697 static_cast<std::size_t>(Extent))>
701 template <
class ElementType>
713 template <
class ElementType>
719 template <
class ElementType>
725 template <
class ElementType, std::
size_t N>
731 template <class Container, typename = typename std::enable_if<SpanUtils::is_value_defined<Container>::value>::type>
737 template <class Container, typename = typename std::enable_if<SpanUtils::is_value_defined<Container>::value>::type>
749 template <class Ptr, typename = typename std::enable_if<!SpanUtils::is_value_defined<Ptr>::value && SpanUtils::is_element_defined<Ptr>::value>::type>
755 template <class Container, typename = typename std::enable_if<!SpanUtils::is_value_defined<Container>::value &&
756 !SpanUtils::is_element_defined<Container>::value &&
757 SpanUtils::has_data_method<Container>::value>::type>
763 template <class Container, typename = typename std::enable_if<!SpanUtils::is_value_defined<Container>::value &&
764 !SpanUtils::is_element_defined<Container>::value &&
765 SpanUtils::has_data_method<Container>::value>::type>
771 namespace SpanUtils {
773 template <
typename Class,
typename =
void>
777 template <
typename Class>
789 #pragma pop_macro("constexpr")
#define MATIOCPP_CONSTEXPR
MATIOCPP_CONSTEXPR reverse_iterator rend() const noexcept
MATIOCPP_CONSTEXPR Span(pointer ptr, index_type count)
MATIOCPP_CONSTEXPR bool setVal(index_type idx, const_reference val)
MATIOCPP_CONSTEXPR Span() noexcept
MATIOCPP_CONSTEXPR Span(const Span< OtherElementType, OtherExtent > &other)
MATIOCPP_CONSTEXPR const_reverse_iterator crbegin() const noexcept
MATIOCPP_CONSTEXPR reference operator[](index_type idx) const
std::remove_cv_t< ElementType > value_type
MATIOCPP_CONSTEXPR Span< element_type, dynamic_extent > subspan(index_type offset, index_type count=dynamic_extent) const
MATIOCPP_CONSTEXPR const_reverse_iterator crend() const noexcept
MATIOCPP_CONSTEXPR reference operator()(index_type idx) const
MATIOCPP_CONSTEXPR Span(element_type(&arr)[N]) noexcept
MATIOCPP_CONSTEXPR auto subspan() const -> typename details::calculate_subspan_type< ElementType, Extent, Offset, Count >::type
MATIOCPP_CONSTEXPR Span< element_type, Count > first() const
MATIOCPP_CONSTEXPR Span(std::array< ArrayElementType, N > &arr) noexcept
MATIOCPP_CONSTEXPR index_type size_bytes() const noexcept
MATIOCPP_CONSTEXPR reverse_iterator rbegin() const noexcept
MATIOCPP_CONSTEXPR const_iterator cend() const noexcept
MATIOCPP_CONSTEXPR iterator begin() const noexcept
MATIOCPP_CONSTEXPR Span(pointer firstElem, pointer lastElem)
MATIOCPP_CONSTEXPR Span< element_type, dynamic_extent > last(index_type count) const
MATIOCPP_CONSTEXPR index_type size() const noexcept
MATIOCPP_CONSTEXPR Span< element_type, Count > last() const
MATIOCPP_CONSTEXPR Span< element_type, dynamic_extent > first(index_type count) const
MATIOCPP_CONSTEXPR reference at(index_type idx) const
MATIOCPP_CONSTEXPR bool empty() const noexcept
MATIOCPP_CONSTEXPR Span(const std::array< std::remove_const_t< element_type >, N > &arr) noexcept
MATIOCPP_CONSTEXPR Span(const Span &other) noexcept=default
std::ptrdiff_t index_type
MATIOCPP_CONSTEXPR const_reference getVal(index_type idx) const
MATIOCPP_CONSTEXPR iterator end() const noexcept
static constexpr index_type extent
MATIOCPP_CONSTEXPR const_iterator cbegin() const noexcept
MATIOCPP_CONSTEXPR pointer data() const noexcept
const element_type & const_reference
MATIOCPP_CONSTEXPR extent_type(extent_type< Other > ext)
MATIOCPP_CONSTEXPR index_type size() const noexcept
MATIOCPP_CONSTEXPR extent_type(index_type size)
MATIOCPP_CONSTEXPR extent_type(extent_type< Other > ext)
MATIOCPP_CONSTEXPR extent_type(index_type size)
MATIOCPP_CONSTEXPR index_type size() const noexcept
MATIOCPP_CONSTEXPR extent_type() noexcept
std::ptrdiff_t index_type
MATIOCPP_CONSTEXPR friend bool operator>=(span_iterator lhs, span_iterator rhs) noexcept
typename Span::index_type difference_type
MATIOCPP_CONSTEXPR reference operator[](difference_type n) const
MATIOCPP_CONSTEXPR span_iterator & operator-=(difference_type n)
MATIOCPP_CONSTEXPR friend bool operator>(span_iterator lhs, span_iterator rhs) noexcept
MATIOCPP_CONSTEXPR difference_type operator-(span_iterator rhs) const
MATIOCPP_CONSTEXPR span_iterator operator-(difference_type n) const
MATIOCPP_CONSTEXPR friend bool operator<=(span_iterator lhs, span_iterator rhs) noexcept
MATIOCPP_CONSTEXPR span_iterator & operator++()
MATIOCPP_CONSTEXPR reference operator*() const
MATIOCPP_CONSTEXPR pointer operator->() const
MATIOCPP_CONSTEXPR friend bool operator<(span_iterator lhs, span_iterator rhs) noexcept
MATIOCPP_CONSTEXPR span_iterator operator+(difference_type n) const
MATIOCPP_CONSTEXPR span_iterator & operator+=(difference_type n)
MATIOCPP_CONSTEXPR span_iterator(const span_iterator< Span, B > &other) noexcept
MATIOCPP_CONSTEXPR span_iterator operator--(int)
MATIOCPP_CONSTEXPR friend bool operator==(span_iterator lhs, span_iterator rhs) noexcept
MATIOCPP_CONSTEXPR span_iterator(const Span *span, typename Span::index_type idx) noexcept
std::remove_cv_t< element_type_ > value_type
MATIOCPP_CONSTEXPR span_iterator operator++(int)
std::add_pointer_t< reference > pointer
MATIOCPP_CONSTEXPR span_iterator & operator--()
MATIOCPP_CONSTEXPR friend bool operator!=(span_iterator lhs, span_iterator rhs) noexcept
std::conditional_t< IsConst, const element_type_, element_type_ > & reference
T lexicographical_compare(T... args)
typename make_void< Ts... >::type void_t
MATIOCPP_CONSTEXPR span_iterator< Span, IsConst > operator-(typename span_iterator< Span, IsConst >::difference_type n, span_iterator< Span, IsConst > rhs)
MATIOCPP_CONSTEXPR span_iterator< Span, IsConst > operator+(typename span_iterator< Span, IsConst >::difference_type n, span_iterator< Span, IsConst > rhs)
MATIOCPP_CONSTEXPR Span< ElementType > make_span(ElementType *ptr, typename Span< ElementType >::index_type count)
MATIOCPP_CONSTEXPR bool operator!=(Span< ElementType, Extent > l, Span< ElementType, Extent > r)
MATIOCPP_CONSTEXPR const std::ptrdiff_t dynamic_extent
MATIOCPP_CONSTEXPR bool operator<(Span< ElementType, Extent > l, Span< ElementType, Extent > r)
MATIOCPP_CONSTEXPR bool operator>=(Span< ElementType, Extent > l, Span< ElementType, Extent > r)
MATIOCPP_CONSTEXPR bool operator>(Span< ElementType, Extent > l, Span< ElementType, Extent > r)
MATIOCPP_CONSTEXPR bool operator<=(Span< ElementType, Extent > l, Span< ElementType, Extent > r)
MATIOCPP_CONSTEXPR bool operator==(Span< ElementType, FirstExtent > l, Span< ElementType, SecondExtent > r)
typename T::value_type type
typename std::remove_all_extents_t< T > type
typename std::remove_pointer< decltype(std::declval< T >().data())>::type type
dependent_false is a type-dependent expression that is always false.