GEOSX
Span.hpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2018-2020 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2020 The Board of Trustees of the Leland Stanford Junior University
7  * Copyright (c) 2018-2020 TotalEnergies
8  * Copyright (c) 2019- GEOSX Contributors
9  * All rights reserved
10  *
11  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
12  * ------------------------------------------------------------------------------------------------------------
13  */
14 
19 #ifndef GEOS_COMMON_SPAN_HPP
20 #define GEOS_COMMON_SPAN_HPP
21 
22 #include "codingUtilities/traits.hpp"
23 #include "common/Logger.hpp"
24 
25 #include <memory>
26 #include <iterator>
27 #include <type_traits>
28 
29 namespace geos
30 {
31 
39 template< typename T >
40 class Span
41 {
42 public:
43 
45  using element_type = T;
46 
48  using value_type = std::remove_cv_t< T >;
49 
52 
54  using difference_type = std::ptrdiff_t;
55 
59  constexpr Span() noexcept = default;
60 
66  Span( T * const ptr, size_type const size ) noexcept
67  : m_data( ptr ),
68  m_size( size )
69  {}
70 
77  template< typename ITER >
78  constexpr Span( ITER const begin, ITER const end ) noexcept
79  : Span( std::addressof( *begin ), std::distance( begin, end ) )
80  {}
81 
87  template< int N >
88  constexpr Span( T (& arr)[N] ) noexcept
89  : Span( std::addressof( arr[0] ), N )
90  {}
91 
98  template< typename R, typename std::enable_if_t< traits::is_range_like< R > > * = nullptr >
99  constexpr Span( R const & range )
100  : Span( range.begin(), range.end() )
101  {}
102 
106  constexpr size_type size() const noexcept
107  {
108  return m_size;
109  }
110 
114  constexpr size_type size_bytes() const noexcept
115  {
116  return size() * sizeof( element_type );
117  }
118 
122  constexpr bool empty() const noexcept
123  {
124  return m_size == 0;
125  }
126 
130  constexpr T * data() const noexcept
131  {
132  return m_data;
133  }
134 
138  constexpr T * begin() const noexcept
139  {
140  return m_data;
141  }
142 
146  constexpr T * end() const noexcept
147  {
148  return m_data + m_size;
149  }
150 
154  constexpr std::reverse_iterator< T * > rbegin() const noexcept
155  {
156  return std::reverse_iterator< T * >( m_data + m_size - 1 );
157  }
158 
162  constexpr std::reverse_iterator< T * > rend() const noexcept
163  {
164  return std::reverse_iterator< T * >( m_data - 1 );
165  }
166 
171  T & front() const
172  {
173  GEOS_ASSERT_GT( m_size, 0 );
174  return m_data[0];
175  }
176 
181  T & back() const
182  {
183  GEOS_ASSERT_GT( m_size, 0 );
184  return m_data[m_size-1];
185  }
186 
192  T & operator[]( size_type const i ) const
193  {
194  GEOS_ASSERT_GT( m_size, i );
195  return m_data[i];
196  }
197 
202  Span< element_type > first( size_type const count ) const
203  {
204  GEOS_ASSERT_GE( m_size, count );
205  return { m_data, count };
206  }
207 
212  Span< element_type > last( size_type const count ) const
213  {
214  GEOS_ASSERT_GE( m_size, count );
215  return { m_data + (m_size - count), count };
216  }
217 
223  Span< element_type > subspan( size_type const offset, size_type const count ) const
224  {
225  GEOS_ASSERT_GE( m_size, offset + count );
226  return { m_data + offset, count };
227  }
228 
229 private:
230 
232  T * m_data{};
233 
235  size_type m_size{};
236 
237 };
238 
239 }
240 
241 #endif //GEOS_COMMON_SPAN_HPP
#define GEOS_ASSERT_GT(lhs, rhs)
Assert that one value compares greater than the other in debug builds.
Definition: Logger.hpp:405
#define GEOS_ASSERT_GE(lhs, rhs)
Assert that one value compares greater than or equal to the other in debug builds.
Definition: Logger.hpp:420
Lightweight non-owning wrapper over a contiguous range of elements.
Definition: Span.hpp:41
Span< element_type > last(size_type const count) const
Definition: Span.hpp:212
constexpr bool empty() const noexcept
Definition: Span.hpp:122
constexpr Span(R const &range)
Construct a span from a range-like object (anything that has begin() and end()).
Definition: Span.hpp:99
constexpr T * data() const noexcept
Definition: Span.hpp:130
std::remove_cv_t< T > value_type
Type of underlying value.
Definition: Span.hpp:48
constexpr std::reverse_iterator< T * > rend() const noexcept
Definition: Span.hpp:162
constexpr Span() noexcept=default
Construct an empty span.
T & front() const
Definition: Span.hpp:171
T & operator[](size_type const i) const
Definition: Span.hpp:192
constexpr T * begin() const noexcept
Definition: Span.hpp:138
constexpr size_type size_bytes() const noexcept
Definition: Span.hpp:114
constexpr Span(T(&arr)[N]) noexcept
Construct a span from a c-array.
Definition: Span.hpp:88
constexpr T * end() const noexcept
Definition: Span.hpp:146
T element_type
Type of range element.
Definition: Span.hpp:45
constexpr std::reverse_iterator< T * > rbegin() const noexcept
Definition: Span.hpp:154
std::ptrdiff_t difference_type
Type used for indexing the range.
Definition: Span.hpp:54
Span< element_type > subspan(size_type const offset, size_type const count) const
Definition: Span.hpp:223
constexpr size_type size() const noexcept
Definition: Span.hpp:106
T & back() const
Definition: Span.hpp:181
constexpr Span(ITER const begin, ITER const end) noexcept
Construct a span from pair of iterators.
Definition: Span.hpp:78
Span< element_type > first(size_type const count) const
Definition: Span.hpp:202
std::size_t size_type
Type used for indexing the range.
Definition: Span.hpp:51
std::size_t size_t
Unsigned size type.
Definition: DataTypes.hpp:119