All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
span.h
Go to the documentation of this file.
1 //
2 // Copyright 2019 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_BASE_TF_SPAN_H
25 #define PXR_BASE_TF_SPAN_H
26 
28 
29 #include "pxr/pxr.h"
30 #include "pxr/base/tf/api.h"
31 #include "pxr/base/tf/diagnostic.h"
32 
33 #include <cstddef>
34 #include <iterator>
35 #include <type_traits>
36 
37 
38 PXR_NAMESPACE_OPEN_SCOPE
39 
40 
86 template <typename T>
87 class TfSpan
88 {
89 public:
90  using element_type = T;
91  using value_type = typename std::remove_cv<T>::type;
92  using pointer = T*;
93  using reference = T&;
94  using index_type = std::size_t;
95  using difference_type = std::ptrdiff_t;
96 
97  using iterator = T*;
98  using const_iterator = const T*;
99  using reverse_iterator = std::reverse_iterator<iterator>;
100  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
101 
102  TfSpan() noexcept = default;
103 
107  TfSpan(pointer ptr, index_type count)
108  : _data(ptr), _size(count)
109  {
110  TF_DEV_AXIOM(count == 0 || ptr);
111  }
112 
114  TfSpan(pointer first, pointer last)
115  : TfSpan(first, index_type(last-first))
116  {
117  TF_DEV_AXIOM(last >= first);
118  }
119 
123  template <class Container>
124  TfSpan(Container& cont,
125  typename std::enable_if<
126  !std::is_const<element_type>::value &&
127  std::is_same<typename Container::value_type, value_type
128  >::value, Container
129  >::type* = 0)
130  : _data(cont.data()), _size(cont.size())
131  {
132  TF_DEV_AXIOM(_size == 0 || _data);
133  }
134 
138  template <class Container>
139  TfSpan(const Container& cont,
140  typename std::enable_if<
141  std::is_same<typename Container::value_type, value_type
142  >::value, Container
143  >::type* = 0)
144  : _data(cont.data()), _size(cont.size())
145  {
146  TF_DEV_AXIOM(_size == 0 || _data);
147  }
148 
150  pointer data() const noexcept { return _data; }
151 
153  index_type size() const noexcept { return _size; }
154 
156  bool empty() const noexcept { return _size == 0; }
157 
161  reference operator[](index_type idx) const {
162  TF_DEV_AXIOM(idx < _size);
163  return _data[idx];
164  }
165 
167  reference front() const {
168  TF_DEV_AXIOM(!empty());
169  return *begin();
170  }
171 
173  reference back() const {
174  TF_DEV_AXIOM(!empty());
175  return *(end() - 1);
176  }
177 
179  iterator begin() const noexcept { return _data; }
180 
182  const_iterator cbegin() const noexcept { return _data; }
183 
185  iterator end() const noexcept { return _data + _size; }
186 
188  const_iterator cend() const noexcept { return _data + _size; }
189 
191  reverse_iterator rbegin() const noexcept
192  { return reverse_iterator(end()); }
193 
195  const_reverse_iterator crbegin() const noexcept
196  { return const_reverse_iterator(cend()); }
197 
199  reverse_iterator rend() const noexcept
200  { return reverse_iterator(begin()); }
201 
203  const_reverse_iterator crend() const noexcept
204  { return const_reverse_iterator(cbegin()); }
205 
210  TfSpan<T> subspan(difference_type offset, difference_type count=-1) const {
211  TF_DEV_AXIOM(offset >= 0 && (index_type)offset < _size);
212  if (count == -1) {
213  return TfSpan<T>(_data + offset, _size - offset);
214  } else {
215  TF_DEV_AXIOM(count >= 0);
216  TF_DEV_AXIOM(((index_type)offset+(index_type)count) <= _size);
217  return TfSpan<T>(_data + offset, count);
218  }
219  }
220 
222  TfSpan<T> first(size_t count) const {
223  return subspan(0, count);
224  }
225 
227  TfSpan<T> last(size_t count) const {
228  TF_DEV_AXIOM(_size >= count);
229  return TfSpan<T>(end() - count, count);
230  }
231 
232 private:
233  pointer _data = nullptr;
234  index_type _size = 0;
235 };
236 
237 
239 template <typename Container>
241 TfMakeSpan(Container& cont)
242 {
244 }
245 
246 
248 template <typename Container>
250 TfMakeConstSpan(const Container& cont)
251 {
253 }
254 
255 PXR_NAMESPACE_CLOSE_SCOPE
256 
257 #endif // PXR_BASE_TF_SPAN_H
#define TF_DEV_AXIOM(cond)
The same as TF_AXIOM, but compiled only in dev builds.
Definition: diagnostic.h:222
reverse_iterator rbegin() const noexcept
Returns a non-const reverse iterator the start of the span.
Definition: span.h:191
TfSpan(pointer first, pointer last)
Construct a span over the range [first, last).
Definition: span.h:114
TfSpan< T > first(size_t count) const
Return a subspan consisting of the first count elements of this span.
Definition: span.h:222
TfSpan(pointer ptr, index_type count)
Construct a span over the range of [ptr, ptr+count).
Definition: span.h:107
TfSpan< T > last(size_t count) const
Return a subspan consisting of the last count elements of this span.
Definition: span.h:227
const_reverse_iterator crbegin() const noexcept
Returns a cons reverse iterator to the start of the span.
Definition: span.h:195
iterator end() const noexcept
Returns a non-const iterator to the end of the span.
Definition: span.h:185
reference back() const
Return a reference to the last element in the span.
Definition: span.h:173
reference operator[](index_type idx) const
Returns a reference to the idx&#39;th element of the span.
Definition: span.h:161
Low-level utilities for informing users of various internal and external diagnostic conditions...
const_iterator cend() const noexcept
Returns a const iterator to the end of the span.
Definition: span.h:188
iterator begin() const noexcept
Returns a non-const iterator the start of the span.
Definition: span.h:179
index_type size() const noexcept
Return the total number of elements in the span.
Definition: span.h:153
Represents a range of contiguous elements.
Definition: span.h:87
bool empty() const noexcept
Returns true if this span contains no elements, false otherwise.
Definition: span.h:156
const_iterator cbegin() const noexcept
Returns a cons iterator to the start of the span.
Definition: span.h:182
TfSpan< const typename Container::value_type > TfMakeConstSpan(const Container &cont)
Helper for constructing a const TfSpan from a container.
Definition: span.h:250
reference front() const
Return a reference to the first element in the span.
Definition: span.h:167
const_reverse_iterator crend() const noexcept
Returns a const reverse iterator to the end of the span.
Definition: span.h:203
TfSpan(Container &cont, typename std::enable_if< !std::is_const< element_type >::value &&std::is_same< typename Container::value_type, value_type >::value, Container >::type *=0)
Construct a span from a container.
Definition: span.h:124
TfSpan(const Container &cont, typename std::enable_if< std::is_same< typename Container::value_type, value_type >::value, Container >::type *=0)
Construct a span from a container.
Definition: span.h:139
TfSpan< typename Container::value_type > TfMakeSpan(Container &cont)
Helper for constructing a non-const TfSpan from a container.
Definition: span.h:241
reverse_iterator rend() const noexcept
Returns a non-const reverse iterator to the end of the span.
Definition: span.h:199
pointer data() const noexcept
Return a pointer to the first element of the span.
Definition: span.h:150
TfSpan< T > subspan(difference_type offset, difference_type count=-1) const
Returns a new span referencing a sub-range of this span.
Definition: span.h:210