GDB (xrefs)
array-view.h
Go to the documentation of this file.
1 /* Copyright (C) 2017-2018 Free Software Foundation, Inc.
2 
3  This file is part of GDB.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 
18 #ifndef COMMON_ARRAY_VIEW_H
19 #define COMMON_ARRAY_VIEW_H
20 
21 #include "traits.h"
22 #include <type_traits>
23 
24 /* An array_view is an abstraction that provides a non-owning view
25  over a sequence of contiguous objects.
26 
27  A way to put it is that array_view is to std::vector (and
28  std::array and built-in arrays with rank==1) like std::string_view
29  is to std::string.
30 
31  The main intent of array_view is to use it as function input
32  parameter type, making it possible to pass in any sequence of
33  contiguous objects, irrespective of whether the objects live on the
34  stack or heap and what actual container owns them. Implicit
35  construction from the element type is supported too, making it easy
36  to call functions that expect an array of elements when you only
37  have one element (usually on the stack). For example:
38 
39  struct A { .... };
40  void function (gdb::array_view<A> as);
41 
42  std::vector<A> std_vec = ...;
43  std::array<A, N> std_array = ...;
44  A array[] = {...};
45  A elem;
46 
47  function (std_vec);
48  function (std_array);
49  function (array);
50  function (elem);
51 
52  Views can be either mutable or const. A const view is simply
53  created by specifying a const T as array_view template parameter,
54  in which case operator[] of non-const array_view objects ends up
55  returning const references. Making the array_view itself const is
56  analogous to making a pointer itself be const. I.e., disables
57  re-seating the view/pointer.
58 
59  Since array_view objects are small (pointer plus size), and
60  designed to be trivially copyable, they should generally be passed
61  around by value.
62 
63  You can find unit tests covering the whole API in
64  unittests/array-view-selftests.c. */
65 
66 namespace gdb {
67 
68 template <typename T>
70 {
71  /* True iff decayed T is the same as decayed U. E.g., we want to
72  say that 'T&' is the same as 'const T'. */
73  template <typename U>
76 
77  /* True iff decayed T is the same as decayed U, and 'U *' is
78  implicitly convertible to 'T *'. This is a requirement for
79  several methods. */
80  template <typename U>
82  std::is_convertible<U *, T *>>;
83 
84 public:
85  using value_type = T;
86  using reference = T &;
87  using const_reference = const T &;
88  using size_type = size_t;
89 
90  /* Default construction creates an empty view. */
91  constexpr array_view () noexcept
92  : m_array (nullptr), m_size (0)
93  {}
94 
95  /* Create an array view over a single object of the type of an
96  array_view element. The created view as size==1. This is
97  templated on U to allow constructing a array_view<const T> over a
98  (non-const) T. The "convertible" requirement makes sure that you
99  can't create an array_view<T> over a const T. */
100  template<typename U,
101  typename = Requires<DecayedConvertible<U>>>
102  constexpr array_view (U &elem) noexcept
103  : m_array (&elem), m_size (1)
104  {}
105 
106  /* Same as above, for rvalue references. */
107  template<typename U,
108  typename = Requires<DecayedConvertible<U>>>
109  constexpr array_view (U &&elem) noexcept
110  : m_array (&elem), m_size (1)
111  {}
112 
113  /* Create an array view from a pointer to an array and an element
114  count. */
115  template<typename U,
116  typename = Requires<DecayedConvertible<U>>>
117  constexpr array_view (U *array, size_t size) noexcept
118  : m_array (array), m_size (size)
119  {}
120 
121  /* Create an array view from a range. This is templated on both U
122  an V to allow passing in a mix of 'const T *' and 'T *'. */
123  template<typename U, typename V,
124  typename = Requires<DecayedConvertible<U>>,
125  typename = Requires<DecayedConvertible<V>>>
126  constexpr array_view (U *begin, V *end) noexcept
127  : m_array (begin), m_size (end - begin)
128  {}
129 
130  /* Create an array view from an array. */
131  template<typename U, size_t Size,
132  typename = Requires<DecayedConvertible<U>>>
133  constexpr array_view (U (&array)[Size]) noexcept
134  : m_array (array), m_size (Size)
135  {}
136 
137  /* Create an array view from a contiguous container. E.g.,
138  std::vector and std::array. */
139  template<typename Container,
141  typename
143  <decltype (std::declval<Container> ().data ()),
144  T *>>,
145  typename
147  <decltype (std::declval<Container> ().size ()),
148  size_type>>>
149  constexpr array_view (Container &&c) noexcept
150  : m_array (c.data ()), m_size (c.size ())
151  {}
152 
153  /* Observer methods. Some of these can't be constexpr until we
154  require C++14. */
155  /*constexpr14*/ T *data () noexcept { return m_array; }
156  constexpr const T *data () const noexcept { return m_array; }
157 
158  /*constexpr14*/ T *begin () noexcept { return m_array; }
159  constexpr const T *begin () const noexcept { return m_array; }
160 
161  /*constexpr14*/ T *end () noexcept { return m_array + m_size; }
162  constexpr const T *end () const noexcept { return m_array + m_size; }
163 
164  /*constexpr14*/ reference operator[] (size_t index) noexcept
165  { return m_array[index]; }
166  constexpr const_reference operator[] (size_t index) const noexcept
167  { return m_array[index]; }
168 
169  constexpr size_type size () const noexcept { return m_size; }
170  constexpr bool empty () const noexcept { return m_size == 0; }
171 
172 private:
175 };
176 
177 } /* namespace gdb */
178 
179 #endif
constexpr array_view(U &&elem) noexcept
Definition: array-view.h:109
constexpr array_view(U(&array)[Size]) noexcept
Definition: array-view.h:133
constexpr size_type size() const noexcept
Definition: array-view.h:169
constexpr const T * end() const noexcept
Definition: array-view.h:162
constexpr array_view(U *array, size_t size) noexcept
Definition: array-view.h:117
T * data() noexcept
Definition: array-view.h:155
size_type m_size
Definition: array-view.h:174
constexpr array_view(U &elem) noexcept
Definition: array-view.h:102
reference operator[](size_t index) noexcept
Definition: array-view.h:164
typename std::is_same< typename std::decay< T >::type, typename std::decay< U >::type > IsDecayedT
Definition: array-view.h:75
static const char * type
Definition: language.c:113
constexpr array_view(U *begin, V *end) noexcept
Definition: array-view.h:126
Definition: array-view.h:66
constexpr array_view(Container &&c) noexcept
Definition: array-view.h:149
typename std::enable_if< Condition::value, void >::type Requires
Definition: traits.h:98
constexpr const T * data() const noexcept
Definition: array-view.h:156
constexpr bool empty() const noexcept
Definition: array-view.h:170
T * end() noexcept
Definition: array-view.h:161
T * begin() noexcept
Definition: array-view.h:158
constexpr array_view() noexcept
Definition: array-view.h:91
constexpr const T * begin() const noexcept
Definition: array-view.h:159
static constexpr bool is_convertible()