Embedded Template Library  1.0
span.h
Go to the documentation of this file.
1 
3 /******************************************************************************
4 The MIT License(MIT)
5 
6 Embedded Template Library.
7 https://github.com/ETLCPP/etl
8 https://www.etlcpp.com
9 
10 Copyright(c) 2020 jwellbelove
11 
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files(the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions :
18 
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21 
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29 ******************************************************************************/
30 
31 #ifndef ETL_SPAN_INCLUDED
32 #define ETL_SPAN_INCLUDED
33 
34 #include "platform.h"
35 #include "iterator.h"
36 #include "nullptr.h"
37 #include "hash.h"
38 #include "type_traits.h"
39 #include "integral_limits.h"
40 #include "memory.h"
41 #include "array.h"
42 
46 
47 #undef ETL_FILE
48 #define ETL_FILE "41"
49 
50 namespace etl
51 {
52  static ETL_CONSTANT size_t dynamic_extent = etl::integral_limits<size_t>::max;
53 
54  //***************************************************************************
56  //***************************************************************************
57  template <typename T, const size_t EXTENT = etl::dynamic_extent>
58  class span
59  {
60  public:
61 
62  typedef T element_type;
63  typedef typename etl::remove_cv<T>::type value_type;
64  typedef size_t size_type;
65  typedef T& reference;
66  typedef const T& const_reference;
67  typedef T* pointer;
68  typedef const T* const_pointer;
69  typedef T* iterator;
70  typedef const T* const_iterator;
71  typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
72  typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
73 
74  static ETL_CONSTANT size_t extent = EXTENT;
75 
76  //*************************************************************************
78  //*************************************************************************
79  ETL_CONSTEXPR span() ETL_NOEXCEPT
80  : mbegin(ETL_NULLPTR)
81  , mend(ETL_NULLPTR)
82  {
83  }
84 
85  //*************************************************************************
88  //*************************************************************************
89  template <typename TSpan>
90  ETL_CONSTEXPR span(TSpan& a) ETL_NOEXCEPT
91  : mbegin(a.data())
92  , mend(a.data() + a.size())
93  {
94  }
95 
96  //*************************************************************************
99  //*************************************************************************
100  template <typename TSpan>
101  ETL_CONSTEXPR span(const TSpan& a) ETL_NOEXCEPT
102  : mbegin(a.data())
103  , mend(a.data() + a.size())
104  {
105  }
106 
107  //*************************************************************************
109  //*************************************************************************
110  template <typename TIterator>
111  ETL_CONSTEXPR span(const TIterator begin_, const TIterator end_)
112  : mbegin(etl::addressof(*begin_))
113  , mend(etl::addressof(*begin_) + etl::distance(begin_, end_))
114  {
115  }
116 
117  //*************************************************************************
119  //*************************************************************************
120  template <typename TIterator, typename TSize>
121  ETL_CONSTEXPR span(const TIterator begin_, const TSize size_) ETL_NOEXCEPT
122  : mbegin(etl::addressof(*begin_))
123  , mend(etl::addressof(*begin_) + size_)
124  {
125  }
126 
127  //*************************************************************************
129  //*************************************************************************
130  template<const size_t ARRAY_SIZE>
131  ETL_CONSTEXPR span(element_type(&begin_)[ARRAY_SIZE]) ETL_NOEXCEPT
132  : mbegin(begin_)
133  , mend(begin_ + ARRAY_SIZE)
134  {
135  }
136 
137  //*************************************************************************
139  //*************************************************************************
140  ETL_CONSTEXPR span(const span& other) ETL_NOEXCEPT
141  : mbegin(other.mbegin)
142  , mend(other.mend)
143  {
144  }
145 
146  //*************************************************************************
148  //*************************************************************************
149  ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
150  {
151  return *mbegin;
152  }
153 
154  //*************************************************************************
156  //*************************************************************************
157  ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
158  {
159  return *(mend - 1);
160  }
161 
162  //*************************************************************************
164  //*************************************************************************
165  ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
166  {
167  return mbegin;
168  }
169 
170  //*************************************************************************
172  //*************************************************************************
173  ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
174  {
175  return mbegin;
176  }
177 
178  //*************************************************************************
180  //*************************************************************************
181  ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
182  {
183  return mend;
184  }
185 
186  //*************************************************************************
187  // Returns an reverse iterator to the reverse beginning of the span.
188  //*************************************************************************
189  ETL_CONSTEXPR reverse_iterator rbegin() const ETL_NOEXCEPT
190  {
191  return reverse_iterator(mend);
192  }
193 
194  //*************************************************************************
196  //*************************************************************************
197  ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
198  {
199  return reverse_iterator(mbegin);
200  }
201 
202  //*************************************************************************
204  //*************************************************************************
205  ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
206  {
207  return (mbegin == mend);
208  }
209 
210  //*************************************************************************
212  //*************************************************************************
213  ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
214  {
215  return (mend - mbegin);
216  }
217 
218  //*************************************************************************
220  //*************************************************************************
221  ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
222  {
223  return sizeof(element_type) * (mend - mbegin);
224  }
225 
226  //*************************************************************************
228  //*************************************************************************
229  ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT
230  {
231  return size();
232  }
233 
234  //*************************************************************************
236  //*************************************************************************
237  ETL_CONSTEXPR14 span& operator =(const span& other) ETL_NOEXCEPT
238  {
239  mbegin = other.mbegin;
240  mend = other.mend;
241  return *this;
242  }
243 
244  //*************************************************************************
246  //*************************************************************************
247  ETL_CONSTEXPR reference operator[](const size_t i) const
248  {
249  return mbegin[i];
250  }
251 
252  //*************************************************************************
254  //*************************************************************************
255  template <const size_t COUNT>
256  ETL_CONSTEXPR etl::span<element_type, COUNT> first() const
257  {
258  return etl::span<element_type, COUNT>(mbegin, mbegin + COUNT);
259  }
260 
261  //*************************************************************************
263  //*************************************************************************
264  ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> first(size_t count) const
265  {
266  return etl::span<element_type, etl::dynamic_extent>(mbegin, mbegin + count);
267  }
268 
269  //*************************************************************************
271  //*************************************************************************
272  template <const size_t COUNT>
273  ETL_CONSTEXPR etl::span<element_type, COUNT> last() const
274  {
275  return etl::span<element_type, COUNT>(mend - COUNT, mend);
276  }
277 
278  //*************************************************************************
280  //*************************************************************************
281  ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> last(size_t count) const
282  {
283  return etl::span<element_type, etl::dynamic_extent>(mend - count, mend);
284  }
285 
286  //*************************************************************************
289  //*************************************************************************
290  template <const size_t OFFSET, const size_t COUNT = etl::dynamic_extent>
291  ETL_CONSTEXPR
292  typename etl::enable_if<COUNT == etl::dynamic_extent, etl::span<element_type, ((EXTENT != etl::dynamic_extent) ? EXTENT - OFFSET : etl::dynamic_extent)> >::type
293  subspan() const
294  {
295  return etl::span<element_type, ((EXTENT != etl::dynamic_extent) ? EXTENT - OFFSET : etl::dynamic_extent)>(mbegin + OFFSET, mend);
296  }
297 
298  //*************************************************************************
301  //*************************************************************************
302  template <const size_t OFFSET, const size_t COUNT = etl::dynamic_extent>
303  ETL_CONSTEXPR
305  subspan() const
306  {
307  return etl::span<element_type, COUNT>(mbegin + OFFSET, mbegin + OFFSET + COUNT);
308  }
309 
310  //*************************************************************************
312  //*************************************************************************
313  ETL_CONSTEXPR14 etl::span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const
314  {
315  if (count == etl::dynamic_extent)
316  {
317  return etl::span<element_type, etl::dynamic_extent>(mbegin + offset, mend);
318  }
319  return etl::span<element_type, etl::dynamic_extent>(mbegin + offset, mbegin + offset + count);
320  }
321 
322  private:
323 
324  element_type* mbegin;
325  element_type* mend;
326  };
327 
328  //*************************************************************************
330 //*************************************************************************
331 #if ETL_CPP17_SUPPORTED
332  template <typename TArray>
333  span(TArray& a)
334  ->span<typename TArray::value_type>;
335 
336  template <typename TIterator>
337  span(const TIterator begin_, const TIterator end_)
338  ->span<etl::remove_pointer_t<TIterator>>;
339 
340  template <typename TIterator,
341  typename TSize>
342  span(const TIterator begin_, const TSize size_)
343  ->span<etl::remove_pointer_t<TIterator>>;
344 #endif
345 
346  //*************************************************************************
348  //*************************************************************************
349 #if ETL_8BIT_SUPPORT
350  template <typename T>
351  struct hash<etl::span<T> >
352  {
353  size_t operator()(const etl::span<T>& view) const
354  {
355  return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(&view[0]),
356  reinterpret_cast<const uint8_t*>(&view[view.size()]));
357  }
358  };
359 #endif
360 }
361 
362 #undef ETL_FILE
363 
364 #endif
365 
Definition: iterator.h:251
Array view.
Definition: span.h:59
ETL_CONSTEXPR14 span & operator=(const span &other) ETL_NOEXCEPT
Assign from a span.
Definition: span.h:237
ETL_CONSTEXPR etl::enable_if< COUNT !=etl::dynamic_extent, etl::span< element_type, COUNT > >::type subspan() const
Definition: span.h:305
ETL_CONSTEXPR span() ETL_NOEXCEPT
Default constructor.
Definition: span.h:79
ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
Returns a reference to the last element.
Definition: span.h:157
ETL_CONSTEXPR etl::span< element_type, COUNT > last() const
Obtains a span that is a view over the last COUNT elements of this span.
Definition: span.h:273
ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
Returns an iterator to the end of the span.
Definition: span.h:181
ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
Returns an iterator to the beginning of the span.
Definition: span.h:173
ETL_CONSTEXPR etl::span< element_type, COUNT > first() const
Obtains a span that is a view over the first COUNT elements of this span.
Definition: span.h:256
ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
Returns a pointer to the first element of the internal storage.
Definition: span.h:165
ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
Returns true if the span size is zero.
Definition: span.h:205
ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
Returns a reference to the first element.
Definition: span.h:149
ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
Returns the size of the span in bytes.
Definition: span.h:221
ETL_CONSTEXPR etl::enable_if< COUNT==etl::dynamic_extent, etl::span< element_type,((EXTENT !=etl::dynamic_extent) ? EXTENT - OFFSET :etl::dynamic_extent)> >::type subspan() const
Definition: span.h:293
ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT
Returns the maximum possible size of the span.
Definition: span.h:229
ETL_CONSTEXPR reference operator[](const size_t i) const
Returns a reference to the indexed value.
Definition: span.h:247
ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
Returns the size of the span.
Definition: span.h:213
ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
Returns a reverse iterator to the end of the span.
Definition: span.h:197
Definition: integral_limits.h:54
T * addressof(T &t)
Definition: memory.h:61
enable_if
Definition: type_traits_generator.h:1228
extent
Definition: type_traits_generator.h:1239
Definition: absolute.h:37