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 TF_SPAN_H
25 #define 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  iterator begin() const noexcept { return _data; }
168 
170  const_iterator cbegin() const noexcept { return _data; }
171 
173  iterator end() const noexcept { return _data + _size; }
174 
176  const_iterator cend() const noexcept { return _data + _size; }
177 
179  reverse_iterator rbegin() const noexcept
180  { return reverse_iterator(end()); }
181 
183  const_reverse_iterator crbegin() const noexcept
184  { return const_reverse_iterator(cend()); }
185 
187  reverse_iterator rend() const noexcept
188  { return reverse_iterator(begin()); }
189 
191  const_reverse_iterator crend() const noexcept
192  { return const_reverse_iterator(cbegin()); }
193 
198  TfSpan<T> subspan(difference_type offset, difference_type count=-1) const {
199  TF_DEV_AXIOM(offset >= 0 && (index_type)offset < _size);
200  if (count == -1) {
201  return TfSpan<T>(_data + offset, _size - offset);
202  } else {
203  TF_DEV_AXIOM(count >= 0);
204  TF_DEV_AXIOM(((index_type)offset+(index_type)count) <= _size);
205  return TfSpan<T>(_data + offset, count);
206  }
207  }
208 
209 private:
210  pointer _data = nullptr;
211  index_type _size = 0;
212 };
213 
214 
216 template <typename Container>
218 TfMakeSpan(Container& cont)
219 {
221 }
222 
223 
225 template <typename Container>
227 TfMakeConstSpan(const Container& cont)
228 {
230 }
231 
232 PXR_NAMESPACE_CLOSE_SCOPE
233 
234 #endif // TF_SPAN_H
#define TF_DEV_AXIOM(cond)
The same as TF_AXIOM, but compiled only in dev builds.
Definition: diagnostic.h:227
reverse_iterator rbegin() const noexcept
Returns a non-const reverse iterator the start of the span.
Definition: span.h:179
TfSpan(pointer first, pointer last)
Construct a span over the range [first, last).
Definition: span.h:114
TfSpan(pointer ptr, index_type count)
Construct a span over the range of [ptr, ptr+count).
Definition: span.h:107
const_reverse_iterator crbegin() const noexcept
Returns a cons reverse iterator to the start of the span.
Definition: span.h:183
iterator end() const noexcept
Returns a non-const iterator to the end of 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
const_iterator cend() const noexcept
Returns a const iterator to the end of the span.
Definition: span.h:176
iterator begin() const noexcept
Returns a non-const iterator the start of the span.
Definition: span.h:167
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:170
TfSpan< const typename Container::value_type > TfMakeConstSpan(const Container &cont)
Helper for constructing a const TfSpan from a container.
Definition: span.h:227
const_reverse_iterator crend() const noexcept
Returns a const reverse iterator to the end of the span.
Definition: span.h:191
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:218
reverse_iterator rend() const noexcept
Returns a non-const reverse iterator to the end of the span.
Definition: span.h:187
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:198