DATAKIT SDK  V2026.1
span.hpp
Go to the documentation of this file.
1 #ifndef HPP_DTK_SPAN_INCLUDED
2 # define HPP_DTK_SPAN_INCLUDED
3 
4 # include <array>
5 # include <limits>
6 #
7 # include <dtk/config.hpp>
8 
9 namespace dtk
10 {
13  struct DynamicExtent : std::integral_constant<std::size_t, static_cast< std::size_t >( -1 )>{};
14 
15  template <class T, std::size_t Extent = DynamicExtent::value> class Span;
16 
26  template <class T> class Span<T, DynamicExtent::value>
27  {
28  public:
29  typedef T* Pointer;
30  typedef T const* ConstPointer;
31  typedef T Element;
32  public:
33  static auto const extent = DynamicExtent::value;
34  public:
36  : m_data( nullptr ), m_size( 0u )
37  {
38  }
39  Span( T * data, std::size_t n ) DTK_NOEXCEPT
40  : m_data( data ), m_size( n )
41  {
42  }
43  template <class Iterator> Span( Iterator begin, Iterator end )
44  : m_data( &( *begin ) )
45  , m_size( static_cast< std::size_t >( end - begin ) )
46  {
47  }
48  template <class Range> Span( Range&& range )
49  : m_data( std::forward<Range>( range ).data() )
50  , m_size( std::forward<Range>( range ).size() )
51  {
52  }
53  public:
55  {
56  return m_data;
57  }
59  {
60  return m_data;
61  }
63  {
64  return m_data + m_size;
65  }
67  {
68  return m_data;
69  }
71  {
72  return m_data + m_size;
73  }
74  public:
75  Span subspan( std::size_t offset, std::size_t count = static_cast< std::size_t >( -1 ) ) const DTK_NOEXCEPT
76  {
77  auto const off = offset > m_size ? m_size : offset;
78  return Span( m_data + off, ( count > m_size - off ? ( m_size - off ) : count ) );
79  }
80  Span& operator+=( std::size_t n ) DTK_NOEXCEPT
81  {
82  *this = subspan( n );
83  return *this;
84  }
85  public:
86  std::size_t size() const DTK_NOEXCEPT
87  {
88  return m_size;
89  }
90  bool empty() const DTK_NOEXCEPT
91  {
92  return !m_size;
93  }
94  public:
95  friend Span operator+( Span const& s, std::size_t n ) DTK_NOEXCEPT
96  {
97  return s.subspan( n );
98  }
99  private:
100  Pointer m_data;
101  std::size_t m_size;
102  };
103 
104  template <class Range> auto as_const_span( Range&& range ) -> Span<typename std::add_const<typename std::remove_pointer<decltype( std::forward<Range>( range ).data() )>::type>::type>
105  {
106  return Span<typename std::add_const<typename std::remove_pointer<decltype( std::forward<Range>( range ).data() )>::type>::type>( std::forward<Range>( range ) );
107  }
108  template <class T> auto as_const_span( T* data, std::size_t n ) DTK_NOEXCEPT -> Span<T const>
109  {
110  return Span<T const>( data, n );
111  }
112  template <class T> auto as_const_span( T const* data, std::size_t n ) DTK_NOEXCEPT -> Span<T const>
113  {
114  return Span<T const>( data, n );
115  }
116  template <class Range> auto as_span( Range&& range ) -> Span<typename std::remove_pointer<decltype( std::forward<Range>( range ).data() )>::type>
117  {
118  return Span<typename std::remove_pointer<decltype( std::forward<Range>( range ).data() )>::type>( std::forward<Range>( range ) );
119  }
120  template <class T> auto as_span( T* data, std::size_t n ) DTK_NOEXCEPT -> Span<T>
121  {
122  return Span<T>( data, n );
123  }
124  template <class T> auto as_span( T const* data, std::size_t n ) DTK_NOEXCEPT -> Span<T const>
125  {
126  return Span<T const>( data, n );
127  }
128 
131 
132  template <class T> auto as_const_buffer( T * data, std::size_t n ) DTK_NOEXCEPT -> ConstBuffer
133  {
134  return ConstBuffer( reinterpret_cast< char const* >( data ), n * sizeof( T ) );
135  }
136  template <class T> auto as_const_buffer( T const* data, std::size_t n ) DTK_NOEXCEPT -> ConstBuffer
137  {
138  return ConstBuffer( reinterpret_cast< char const* >( data ), n * sizeof( T ) );
139  }
140  template <class Range> auto as_const_buffer( Range&& range ) -> ConstBuffer
141  {
142  typedef typename std::remove_pointer<decltype( std::forward<Range>( range ).data() )>::type Element;
143  return ConstBuffer( reinterpret_cast< char const* >( std::forward<Range>( range ).data() ), std::forward<Range>( range ).size() * sizeof( Element ) );
144  }
145  template <class T> auto as_buffer( T* data, std::size_t n ) DTK_NOEXCEPT -> MutableBuffer
146  {
147  return MutableBuffer( reinterpret_cast<char*>( data ), n * sizeof( T ) );
148  }
149  template <class T> auto as_buffer( T const* data, std::size_t n ) DTK_NOEXCEPT -> ConstBuffer
150  {
151  return ConstBuffer( reinterpret_cast<char const*>( data ), n * sizeof( T ) );
152  }
153  template <class Range> auto as_buffer( Range&& range ) -> decltype( as_buffer( std::forward<Range>( range ).data(), std::forward<Range>( range ).size() ) )
154  {
155  return as_buffer( std::forward<Range>( range ).data(), std::forward<Range>( range ).size() );
156  }
157 }
158 
159 #endif
dtk::as_const_buffer
auto as_const_buffer(T *data, std::size_t n) DTK_NOEXCEPT -> ConstBuffer
Definition: span.hpp:132
dtk::Span< T, DynamicExtent::value >::Pointer
T * Pointer
Definition: span.hpp:29
dtk::Span< T, DynamicExtent::value >::cend
ConstPointer cend() const DTK_NOEXCEPT
Definition: span.hpp:70
config.hpp
dtk::as_const_span
auto as_const_span(Range &&range) -> Span< typename std::add_const< typename std::remove_pointer< decltype(std::forward< Range >(range).data())>::type >::type >
Definition: span.hpp:104
dtk::Span< T, DynamicExtent::value >::Span
Span(T *data, std::size_t n) DTK_NOEXCEPT
Definition: span.hpp:39
dtk::Span< T, DynamicExtent::value >::Span
Span() DTK_NOEXCEPT
Definition: span.hpp:35
dtk::Span< T, DynamicExtent::value >::operator+
friend Span operator+(Span const &s, std::size_t n) DTK_NOEXCEPT
Definition: span.hpp:95
dtk::Span< T, DynamicExtent::value >::cbegin
ConstPointer cbegin() const DTK_NOEXCEPT
Definition: span.hpp:66
dtk::MutableBuffer
Span< char > MutableBuffer
Definition: span.hpp:129
dtk::Span< T, DynamicExtent::value >::ConstPointer
T const * ConstPointer
Definition: span.hpp:30
dtk::DynamicExtent
Numeric wrapping type denoting the dynamic nature of a size.
Definition: span.hpp:13
dtk::ConstBuffer
Span< char const > ConstBuffer
Definition: span.hpp:130
dtk::Span< T, DynamicExtent::value >::begin
Pointer begin() const DTK_NOEXCEPT
Definition: span.hpp:58
dtk::as_buffer
auto as_buffer(T *data, std::size_t n) DTK_NOEXCEPT -> MutableBuffer
Definition: span.hpp:145
dtk::Span< T, DynamicExtent::value >::end
Pointer end() const DTK_NOEXCEPT
Definition: span.hpp:62
dtk::Span< T, DynamicExtent::value >::size
std::size_t size() const DTK_NOEXCEPT
Definition: span.hpp:86
dtk::Span< T, DynamicExtent::value >::subspan
Span subspan(std::size_t offset, std::size_t count=static_cast< std::size_t >(-1)) const DTK_NOEXCEPT
Definition: span.hpp:75
dtk::Span< T, DynamicExtent::value >::Span
Span(Iterator begin, Iterator end)
Definition: span.hpp:43
dtk::as_span
auto as_span(Range &&range) -> Span< typename std::remove_pointer< decltype(std::forward< Range >(range).data())>::type >
Definition: span.hpp:116
dtk
Definition: span.hpp:10
dtk::Span< T, DynamicExtent::value >::Element
T Element
Definition: span.hpp:31
dtk::Span< T, DynamicExtent::value >::data
Pointer data() const DTK_NOEXCEPT
Definition: span.hpp:54
dtk::Span< T, DynamicExtent::value >::empty
bool empty() const DTK_NOEXCEPT
Definition: span.hpp:90
dtk::Span< T, DynamicExtent::value >::Span
Span(Range &&range)
Definition: span.hpp:48
dtk::Span
Definition: span.hpp:15
dtk::Span< T, DynamicExtent::value >::operator+=
Span & operator+=(std::size_t n) DTK_NOEXCEPT
Definition: span.hpp:80
DTK_NOEXCEPT
#define DTK_NOEXCEPT
Definition: config.hpp:30