OTB  9.0.0
Orfeo Toolbox
otbSpan.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2022 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef Span_h
22 #define Span_h
23 
24 #include <type_traits>
25 #include <iterator>
26 #include <limits>
27 #include <cassert>
28 
29 namespace otb
30 {
31 #if defined(__cpp_constexpr) && __cpp_constexpr >= 201304
32  // In C++ (only; fixed in C++14), constexpr implies const on member
33  // functions, and OTB support VC++14 which is not C++14 compliant on this
34  // topic.
35  // Hence the workaround...
36  // TODO: get rid with this hack along VC++14
37 # define OTB_MB_CSTXPR constexpr
38 #else
39 # define OTB_MB_CSTXPR
40 #endif
41 
60 template <typename T> struct Span
61 {
62 
65  using element_type = T;
66  using value_type = std::remove_cv_t<T>;
67  using index_type = std::size_t;
68  using difference_type = std::ptrdiff_t;
69  using pointer = T*;
70  using const_pointer = T const*;
71  using reference = T&;
72  using const_reference = T const&;
73  using iterator = T*;
74  using const_iterator = T const*;
75  using reverse_iterator = std::reverse_iterator<iterator>;
76  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
78 
81  constexpr Span() noexcept = default;
82  constexpr Span(pointer ptr, index_type count) noexcept
83  : m_buffer(ptr), m_size(count)
84  {
85  assert(! (!ptr) xor (!count));
86  }
87  constexpr Span(pointer first, pointer last) noexcept
88  : Span(first, last - first)
89  {
90  assert(! (!first) xor (!last));
91  assert(first <= last);
92  }
93  template <std::size_t N> constexpr Span(element_type (&arr)[N]) noexcept
94  : Span(arr, N)
95  {}
97 
114  template <class Container> constexpr Span(Container&& cont) noexcept
115  : Span(cont.data(), cont.size())
116  {
117  // We cannot use op[] which has an assertion sometimes.
118  // assert(&const[size()] == (&cont[0] + size()));
119  // Beside, it's not noexcept.
120  }
121  template <class U> constexpr Span(const otb::Span<U>& s) noexcept
122  : Span(s.data(), s.size())
123  {}
124  constexpr Span(const Span& other) noexcept = default;
126 
127 
129  Span& operator=(Span const&) noexcept = default;
130 
132  ~Span() = default;
133 
136  OTB_MB_CSTXPR iterator begin () noexcept { return data(); }
137  OTB_MB_CSTXPR iterator end () noexcept { return data()+size(); }
138  constexpr const_iterator begin () const noexcept { return data(); }
139  constexpr const_iterator end () const noexcept { return data()+size(); }
140  constexpr const_iterator cbegin() const noexcept { return data(); }
141  constexpr const_iterator cend () const noexcept { return data()+size(); }
143 
146  constexpr const_reverse_iterator crbegin() const noexcept { return reverse_const_iterator(cend()); }
147  constexpr const_reverse_iterator crend () const noexcept { return reverse_const_iterator(cbegin()); }
149 
152  OTB_MB_CSTXPR pointer data () noexcept { return m_buffer; }
153  constexpr const_pointer data () const noexcept { return m_buffer; }
154  OTB_MB_CSTXPR reference front() noexcept { assert(!empty()); return *data(); }
155  constexpr const_reference front() const noexcept { assert(!empty()); return *data(); }
156  OTB_MB_CSTXPR reference back () noexcept { assert(!empty()); return *data()+size()-1; }
157  constexpr const_reference back () const noexcept { assert(!empty()); return *data()+size()-1; }
159 
161  {
162  assert(p < size());
163  return data()[p];
164  }
165  constexpr const_reference operator[](index_type p) const noexcept
166  {
167  assert(p < size());
168  return data()[p];
169  }
171 
174  constexpr index_type size () const noexcept { return m_size; }
175  constexpr bool empty() const noexcept { return size() == 0; }
177 
178 
181  constexpr Span first(index_type n) const noexcept
182  { assert(n < size()); return Span(data(), n);}
183  constexpr Span last(index_type n) const noexcept
184  { assert(n < size()); return Span(data()-n, n);}
186 
187  constexpr Span subspan(index_type offset, index_type count = std::numeric_limits<index_type>::max()) const noexcept
188  {
189  assert(offset <= size());
190  if (count == std::numeric_limits<index_type>::max())
191  {
192  count = size() - offset;
193  }
194 
195  assert(count <= (size() - offset));
196  return Span(data()+offset, count);
197 
198  }
200 
201 private:
202  pointer m_buffer = nullptr;
204 };
205 
222 template <typename T>
223 inline
224 auto make_span(T* first, T* last) noexcept
225 {
226  return Span<T>(first, last);
227 }
229 
245 template <typename T>
246 inline
247 auto make_span(T* first, std::size_t count) noexcept
248 {
249  return Span<T>(first, count);
250 }
252 
266 template <typename T, std::size_t N>
267 inline
268 auto make_span(T (&arr)[N]) noexcept
269 {
270  return Span<T>(arr);
271 }
273 
286 template <typename ContiguousContainer>
287 inline
288 auto make_span(ContiguousContainer & c) noexcept
289 {
290  return Span<decltype(*c.data())>(c);
291 }
293 
294 }
295 // otb namespace
296 
297 
298 #endif // Span_h
otb::Span::difference_type
std::ptrdiff_t difference_type
Definition: otbSpan.h:68
otb::Span::m_buffer
pointer m_buffer
Definition: otbSpan.h:202
otb::Span::const_pointer
T const * const_pointer
Definition: otbSpan.h:70
otb::Span::m_size
index_type m_size
Definition: otbSpan.h:203
otb::Span::~Span
~Span()=default
No-op destructor.
otb::Span::back
constexpr const_reference back() const noexcept
Definition: otbSpan.h:157
otb::Span::operator[]
OTB_MB_CSTXPR reference operator[](index_type p) noexcept
Definition: otbSpan.h:160
otb::Span::element_type
T element_type
Definition: otbSpan.h:65
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::Span::const_iterator
T const * const_iterator
Definition: otbSpan.h:74
otb::Span::last
constexpr Span last(index_type n) const noexcept
Definition: otbSpan.h:183
otb::Span::back
OTB_MB_CSTXPR reference back() noexcept
Definition: otbSpan.h:156
otb::Span::empty
constexpr bool empty() const noexcept
Definition: otbSpan.h:175
otb::Span::crbegin
constexpr const_reverse_iterator crbegin() const noexcept
Definition: otbSpan.h:146
otb::Span::value_type
std::remove_cv_t< T > value_type
Definition: otbSpan.h:66
otb::Span::crend
constexpr const_reverse_iterator crend() const noexcept
Definition: otbSpan.h:147
otb::make_span
auto make_span(T *first, T *last) noexcept
Definition: otbSpan.h:224
otb::Span::Span
constexpr Span(const otb::Span< U > &s) noexcept
Definition: otbSpan.h:121
otb::Span::begin
constexpr const_iterator begin() const noexcept
Definition: otbSpan.h:138
otb::Span::data
constexpr const_pointer data() const noexcept
Definition: otbSpan.h:153
otb::Span::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: otbSpan.h:76
otb::Span::begin
OTB_MB_CSTXPR iterator begin() noexcept
Definition: otbSpan.h:136
otb::Span::end
constexpr const_iterator end() const noexcept
Definition: otbSpan.h:139
otb::Span::subspan
constexpr Span subspan(index_type offset, index_type count=std::numeric_limits< index_type >::max()) const noexcept
Definition: otbSpan.h:187
otb::Span::Span
constexpr Span(element_type(&arr)[N]) noexcept
Definition: otbSpan.h:93
otb::Span::cend
constexpr const_iterator cend() const noexcept
Definition: otbSpan.h:141
otb::Span::first
constexpr Span first(index_type n) const noexcept
Definition: otbSpan.h:181
otb::Span::Span
constexpr Span() noexcept=default
otb::Span::rend
OTB_MB_CSTXPR reverse_iterator rend() noexcept
Definition: otbSpan.h:145
otb::Span::index_type
std::vcl_size_t index_type
Definition: otbSpan.h:67
otb::Span::rbegin
OTB_MB_CSTXPR reverse_iterator rbegin() noexcept
Definition: otbSpan.h:144
otb::Span
Definition: otbSpan.h:60
otb::Span::const_reference
T const & const_reference
Definition: otbSpan.h:72
otb::Span::operator=
Span & operator=(Span const &) noexcept=default
shallow assignment
otb::Span::pointer
T * pointer
Definition: otbSpan.h:69
otb::Span::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: otbSpan.h:75
otb::Span::size
constexpr index_type size() const noexcept
Definition: otbSpan.h:174
otb::Span::data
OTB_MB_CSTXPR pointer data() noexcept
Definition: otbSpan.h:152
otb::Span::front
OTB_MB_CSTXPR reference front() noexcept
Definition: otbSpan.h:154
otb::Span::Span
constexpr Span(pointer first, pointer last) noexcept
Definition: otbSpan.h:87
otb::Span::reference
T & reference
Definition: otbSpan.h:71
otb::Span::Span
constexpr Span(Container &&cont) noexcept
Definition: otbSpan.h:114
otb::Span::iterator
T * iterator
Definition: otbSpan.h:73
otb::Span::end
OTB_MB_CSTXPR iterator end() noexcept
Definition: otbSpan.h:137
otb::Span::operator[]
constexpr const_reference operator[](index_type p) const noexcept
Definition: otbSpan.h:165
otb::Span::cbegin
constexpr const_iterator cbegin() const noexcept
Definition: otbSpan.h:140
OTB_MB_CSTXPR
#define OTB_MB_CSTXPR
Definition: otbSpan.h:39
otb::Span::front
constexpr const_reference front() const noexcept
Definition: otbSpan.h:155