HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
span.h
Go to the documentation of this file.
1 // OpenImageIO Copyright 2018 Larry Gritz, et al. All Rights Reserved.
2 // https://github.com/OpenImageIO/oiio
3 // BSD 3-clause license:
4 // https://github.com/OpenImageIO/oiio/blob/master/LICENSE
5 
6 // clang-format off
7 
8 #pragma once
9 
10 #include <array>
11 #include <cstddef>
12 #include <initializer_list>
13 #include <iostream>
14 #include <stdexcept>
15 #include <type_traits>
16 #include <vector>
17 
18 #include <OpenImageIO/dassert.h>
20 #include <OpenImageIO/platform.h>
21 
23 
24 
25 constexpr ptrdiff_t dynamic_extent = -1;
26 
27 
28 /// span<T> : a non-owning reference to a contiguous array with known
29 /// length. An span<T> is mutable (the values in the array may be
30 /// modified), whereas an span<const T> is not mutable.
31 ///
32 /// Background: Functions whose input requires a set of contiguous values
33 /// (an array) are faced with a dilemma. If the caller passes just a
34 /// pointer, the function has no inherent way to determine how many elements
35 /// may safely be accessed. Passing a std::vector& is "safe", but the caller
36 /// may not have the data in a vector. The function could require an
37 /// explicit length to be passed (or a begin/end pair of iterators or
38 /// pointers). Any way you shake it, there is some awkwardness.
39 ///
40 /// The span template tries to address this problem by providing
41 /// a way to pass array parameters that are non-owning, non-copying,
42 /// non-allocating, and contain a length reference (which in many cases
43 /// is transparently and automatically computed without additional user
44 /// code).
45 
46 template <typename T, ptrdiff_t Extent = dynamic_extent>
47 class span {
48  static_assert (std::is_array<T>::value == false, "can't have span of an array");
49 public:
50  using element_type = T;
52  using index_type = ptrdiff_t;
53  using difference_type = ptrdiff_t;
54  using size_type = ptrdiff_t;
58  using const_iterator = const element_type*;
59  using reverse_iterator = std::reverse_iterator<iterator>;
60  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
61  static constexpr index_type extent = Extent;
62 
63  /// Default ctr -- points to nothing
64  constexpr span () noexcept { }
65 
66  /// Copy constructor
67  template<class U, ptrdiff_t N>
68  constexpr span (const span<U,N> &copy) noexcept
69  : m_data(copy.data()), m_size(copy.size()) { }
70  constexpr span (const span &copy) noexcept = default;
71 
72  /// Construct from T* and length.
73  constexpr span (pointer data, index_type size) noexcept
74  : m_data(data), m_size(size) { }
75 
76  /// Construct from begin and end pointers
77  constexpr span (pointer b, pointer e) noexcept
78  : m_data(b), m_size(e-b) { }
79 
80  /// Construct from a single T&.
81  constexpr span (T &data) : m_data(&data), m_size(1) { }
82 
83  /// Construct from a fixed-length C array. Template magic automatically
84  /// finds the length from the declared type of the array.
85  template<size_t N>
86  constexpr span (T (&data)[N]) : m_data(data), m_size(N) { }
87 
88  /// Construct from std::vector<T>.
89  constexpr span (std::vector<T> &v)
90  : m_data(v.size() ? &v[0] : nullptr), m_size(v.size()) {
91  }
92 
93  /// Construct from const std::vector<T>.
94  /// This turns const std::vector<T> into an span<const T> (the
95  /// span isn't const, but the data it points to will be).
96  span (const std::vector<value_type> &v)
97  : m_data(v.size() ? &v[0] : nullptr), m_size(v.size()) { }
98 
99  /// Construct from mutable element std::array
100  template <size_t N>
101  constexpr span (std::array<value_type, N> &arr)
102  : m_data(arr.data()), m_size(N) {}
103 
104  /// Construct from read-only element std::array
105  template <size_t N>
106  constexpr span (const std::array<value_type, N>& arr)
107  : m_data(arr.data()), m_size(N) {}
108 
109  /// Construct an span from an initializer_list.
110  constexpr span (std::initializer_list<T> il)
111  : span (il.begin(), il.size()) { }
112 
113  // assignments
115  m_data = copy.data();
116  m_size = copy.size();
117  return *this;
118  }
119 
120  // Subviews
121  template<index_type Count>
122  constexpr span<element_type, Count> first () const {
123  return { m_data, Count };
124  }
125  template<index_type Count>
126  constexpr span<element_type, Count> last () const {
127  return { m_data + m_size - Count, Count };
128  }
129 
130  template<index_type Offset, index_type Count = dynamic_extent>
131  constexpr span<element_type, Count> subspan () const {
132  return { m_data + Offset, Count != dynamic_extent ? Count : (Extent != dynamic_extent ? Extent - Offset : m_size - Offset) };
133  }
134 
136  return { m_data, count };
137  }
138 
140  return { m_data + ( m_size - count ), count };
141  }
142 
145  return { m_data + offset, count == dynamic_extent ? m_size - offset : count };
146  }
147 
148  constexpr index_type size() const noexcept { return m_size; }
149  constexpr index_type size_bytes() const noexcept { return m_size*sizeof(T); }
150  constexpr bool empty() const noexcept { return m_size == 0; }
151 
152  constexpr pointer data() const noexcept { return m_data; }
153 
154  constexpr reference operator[] (index_type idx) const { return m_data[idx]; }
155  constexpr reference operator() (index_type idx) const { return m_data[idx]; }
156  reference at (index_type idx) const {
157  if (idx >= size())
158  throw (std::out_of_range ("OpenImageIO::span::at"));
159  return m_data[idx];
160  }
161 
162  constexpr reference front() const noexcept { return m_data[0]; }
163  constexpr reference back() const noexcept { return m_data[size()-1]; }
164 
165  constexpr iterator begin() const noexcept { return m_data; }
166  constexpr iterator end() const noexcept { return m_data + m_size; }
167 
168  constexpr const_iterator cbegin() const noexcept { return m_data; }
169  constexpr const_iterator cend() const noexcept { return m_data + m_size; }
170 
171  constexpr reverse_iterator rbegin() const noexcept { return m_data + m_size - 1; }
172  constexpr reverse_iterator rend() const noexcept { return m_data - 1; }
173 
174  constexpr const_reverse_iterator crbegin() const noexcept { return m_data + m_size - 1; }
175  constexpr const_reverse_iterator crend() const noexcept { return m_data - 1; }
176 
177 private:
178  pointer m_data = nullptr;
179  index_type m_size = 0;
180 };
181 
182 
183 
184 /// cspan<T> is a synonym for a non-mutable span<const T>.
185 template <typename T>
187 
188 
189 
190 /// Compare all elements of two spans for equality
191 template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
192 OIIO_CONSTEXPR14 bool operator== (span<T,X> l, span<U,Y> r) {
193 #if OIIO_CPLUSPLUS_VERSION >= 20
194  return std::equal (l.begin(), l.end(), r.begin(), r.end());
195 #else
196  auto lsize = l.size();
197  bool same = (lsize == r.size());
198  for (ptrdiff_t i = 0; same && i < lsize; ++i)
199  same &= (l[i] == r[i]);
200  return same;
201 #endif
202 }
203 
204 /// Compare all elements of two spans for inequality
205 template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
206 OIIO_CONSTEXPR14 bool operator!= (span<T,X> l, span<U,Y> r) {
207  return !(l == r);
208 }
209 
210 
211 
212 /// span_strided<T> : a non-owning, mutable reference to a contiguous
213 /// array with known length and optionally non-default strides through the
214 /// data. An span_strided<T> is mutable (the values in the array may
215 /// be modified), whereas an span_strided<const T> is not mutable.
216 template <typename T, ptrdiff_t Extent = dynamic_extent>
218  static_assert (std::is_array<T>::value == false,
219  "can't have span_strided of an array");
220 public:
221  using element_type = T;
223  using index_type = ptrdiff_t;
224  using difference_type = ptrdiff_t;
225  using stride_type = ptrdiff_t;
229  using const_iterator = const element_type*;
230  using reverse_iterator = std::reverse_iterator<iterator>;
231  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
232  static constexpr index_type extent = Extent;
233 
234  /// Default ctr -- points to nothing
235  constexpr span_strided () noexcept {}
236 
237  /// Copy constructor
238  constexpr span_strided (const span_strided &copy)
239  : m_data(copy.data()), m_size(copy.size()), m_stride(copy.stride()) {}
240 
241  /// Construct from T* and size, and optionally stride.
243  : m_data(data), m_size(size), m_stride(stride) { }
244 
245  /// Construct from a single T&.
246  constexpr span_strided (T &data) : span_strided(&data,1,1) { }
247 
248  /// Construct from a fixed-length C array. Template magic automatically
249  /// finds the length from the declared type of the array.
250  template<size_t N>
251  constexpr span_strided (T (&data)[N]) : span_strided(data,N,1) {}
252 
253  /// Construct from std::vector<T>.
254  OIIO_CONSTEXPR14 span_strided (std::vector<T> &v)
255  : span_strided(v.size() ? &v[0] : nullptr, v.size(), 1) {}
256 
257  /// Construct from const std::vector<T>. This turns const std::vector<T>
258  /// into an span_strided<const T> (the span_strided isn't
259  /// const, but the data it points to will be).
260  constexpr span_strided (const std::vector<value_type> &v)
261  : span_strided(v.size() ? &v[0] : nullptr, v.size(), 1) {}
262 
263  /// Construct an span from an initializer_list.
264  constexpr span_strided (std::initializer_list<T> il)
265  : span_strided (il.begin(), il.size()) { }
266 
267  /// Initialize from an span (stride will be 1).
268  constexpr span_strided (span<T> av)
269  : span_strided(av.data(), av.size(), 1) { }
270 
271  // assignments
273  m_data = copy.data();
274  m_size = copy.size();
275  m_stride = copy.stride();
276  return *this;
277  }
278 
279  constexpr index_type size() const noexcept { return m_size; }
280  constexpr stride_type stride() const noexcept { return m_stride; }
281 
282  constexpr reference operator[] (index_type idx) const {
283  return m_data[m_stride*idx];
284  }
285  constexpr reference operator() (index_type idx) const {
286  return m_data[m_stride*idx];
287  }
288  reference at (index_type idx) const {
289  if (idx >= size())
290  throw (std::out_of_range ("OpenImageIO::span_strided::at"));
291  return m_data[m_stride*idx];
292  }
293  constexpr reference front() const noexcept { return m_data[0]; }
294  constexpr reference back() const noexcept { return (*this)[size()-1]; }
295  constexpr pointer data() const noexcept { return m_data; }
296 
297 private:
298  pointer m_data = nullptr;
299  index_type m_size = 0;
300  stride_type m_stride = 1;
301 };
302 
303 
304 
305 /// cspan_strided<T> is a synonym for a non-mutable span_strided<const T>.
306 template <typename T>
308 
309 
310 
311 /// Compare all elements of two spans for equality
312 template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
314  auto lsize = l.size();
315  if (lsize != r.size())
316  return false;
317  for (ptrdiff_t i = 0; i < lsize; ++i)
318  if (l[i] != r[i])
319  return false;
320  return true;
321 }
322 
323 /// Compare all elements of two spans for inequality
324 template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
326  return !(l == r);
327 }
328 
329 
constexpr span(std::array< value_type, N > &arr)
Construct from mutable element std::array.
Definition: span.h:101
constexpr reference operator()(index_type idx) const
Definition: span.h:155
constexpr const_iterator cend() const noexcept
Definition: span.h:169
typename std::remove_cv< T >::type value_type
Definition: span.h:222
GLsizeiptr size
Definition: glew.h:1681
constexpr iterator end() const noexcept
Definition: span.h:166
constexpr span_strided(const span_strided &copy)
Copy constructor.
Definition: span.h:238
constexpr index_type size() const noexcept
Definition: span.h:148
ptrdiff_t difference_type
Definition: span.h:224
constexpr span< element_type, Count > first() const
Definition: span.h:122
span & operator=(const span &copy)
Definition: span.h:114
OIIO_NAMESPACE_BEGIN constexpr ptrdiff_t dynamic_extent
Definition: span.h:25
element_type * iterator
Definition: span.h:228
constexpr span_strided(T(&data)[N])
Definition: span.h:251
constexpr span< element_type, Count > subspan() const
Definition: span.h:131
typename std::remove_cv< unsigned char >::type value_type
Definition: span.h:51
Definition: span.h:47
constexpr span< element_type, dynamic_extent > first(index_type count) const
Definition: span.h:135
ptrdiff_t index_type
Definition: span.h:223
T element_type
Definition: span.h:221
GLdouble l
Definition: glew.h:9122
const GLdouble * v
Definition: glew.h:1391
Platform-related macros.
constexpr span_strided() noexcept
Default ctr – points to nothing.
Definition: span.h:235
constexpr span(std::vector< T > &v)
Construct from std::vector<T>.
Definition: span.h:89
constexpr span_strided(span< T > av)
Initialize from an span (stride will be 1).
Definition: span.h:268
std::reverse_iterator< iterator > reverse_iterator
Definition: span.h:230
constexpr span(pointer data, index_type size) noexcept
Construct from T* and length.
Definition: span.h:73
reference at(index_type idx) const
Definition: span.h:288
constexpr span_strided(const std::vector< value_type > &v)
Definition: span.h:260
ptrdiff_t difference_type
Definition: span.h:53
constexpr const_iterator cbegin() const noexcept
Definition: span.h:168
constexpr reference back() const noexcept
Definition: span.h:163
constexpr span(std::initializer_list< T > il)
Construct an span from an initializer_list.
Definition: span.h:110
ptrdiff_t stride_type
Definition: span.h:225
span(const std::vector< value_type > &v)
Definition: span.h:96
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: span.h:60
OIIO_CONSTEXPR14 bool operator==(span< T, X > l, span< U, Y > r)
Compare all elements of two spans for equality.
Definition: span.h:192
OIIO_CONSTEXPR14 bool operator!=(span< T, X > l, span< U, Y > r)
Compare all elements of two spans for inequality.
Definition: span.h:206
reference at(index_type idx) const
Definition: span.h:156
constexpr iterator begin() const noexcept
Definition: span.h:165
constexpr span< element_type, Count > last() const
Definition: span.h:126
constexpr pointer data() const noexcept
Definition: span.h:295
element_type * iterator
Definition: span.h:57
GLint GLenum GLsizei GLint GLsizei const void * data
Definition: glew.h:1379
const element_type * const_iterator
Definition: span.h:229
ptrdiff_t index_type
Definition: span.h:52
constexpr const_reverse_iterator crend() const noexcept
Definition: span.h:175
element_type & reference
Definition: span.h:56
const element_type * const_iterator
Definition: span.h:58
constexpr span(T &data)
Construct from a single T&.
Definition: span.h:81
OIIO_CONSTEXPR14 span_strided(std::vector< T > &v)
Construct from std::vector<T>.
Definition: span.h:254
constexpr reverse_iterator rbegin() const noexcept
Definition: span.h:171
constexpr span_strided(std::initializer_list< T > il)
Construct an span from an initializer_list.
Definition: span.h:264
GLint GLenum GLsizei GLsizei GLsizei GLsizei extent
Definition: glew.h:15538
constexpr span(const std::array< value_type, N > &arr)
Construct from read-only element std::array.
Definition: span.h:106
unsigned char element_type
Definition: span.h:50
GLsizei stride
Definition: glew.h:1523
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: span.h:231
GLdouble GLdouble GLdouble b
Definition: glew.h:9122
constexpr span(const span< U, N > &copy) noexcept
Copy constructor.
Definition: span.h:68
constexpr reference back() const noexcept
Definition: span.h:294
constexpr span(T(&data)[N])
Definition: span.h:86
GLsizei const void * pointer
Definition: glew.h:1523
constexpr span_strided(pointer data, index_type size, stride_type stride=1)
Construct from T* and size, and optionally stride.
Definition: span.h:242
constexpr index_type size() const noexcept
Definition: span.h:279
ptrdiff_t size_type
Definition: span.h:54
GLdouble GLdouble GLdouble r
Definition: glew.h:1406
constexpr reference front() const noexcept
Definition: span.h:162
OIIO_API bool copy(string_view from, string_view to, std::string &err)
GLuint GLuint GLsizei count
Definition: glew.h:1253
constexpr span_strided(T &data)
Construct from a single T&.
Definition: span.h:246
GA_API const UT_StringHolder N
bool equal(T1 a, T2 b, T3 t)
Definition: ImathFun.h:143
constexpr bool empty() const noexcept
Definition: span.h:150
constexpr span(pointer b, pointer e) noexcept
Construct from begin and end pointers.
Definition: span.h:77
element_type * pointer
Definition: span.h:226
element_type * pointer
Definition: span.h:55
constexpr reference front() const noexcept
Definition: span.h:293
#define const
Definition: zconf.h:214
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:66
element_type & reference
Definition: span.h:227
constexpr span() noexcept
Default ctr – points to nothing.
Definition: span.h:64
constexpr reverse_iterator rend() const noexcept
Definition: span.h:172
GLsizei const GLfloat * value
Definition: glew.h:1849
constexpr pointer data() const noexcept
Definition: span.h:152
constexpr index_type size_bytes() const noexcept
Definition: span.h:149
constexpr const_reverse_iterator crbegin() const noexcept
Definition: span.h:174
constexpr span< element_type, dynamic_extent > last(index_type count) const
Definition: span.h:139
type
Definition: core.h:528
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:65
constexpr stride_type stride() const noexcept
Definition: span.h:280
constexpr span< element_type, dynamic_extent > subspan(index_type offset, index_type count=dynamic_extent) const
Definition: span.h:144
std::reverse_iterator< iterator > reverse_iterator
Definition: span.h:59
constexpr reference operator[](index_type idx) const
Definition: span.h:154
GLintptr offset
Definition: glew.h:1682