xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/debug/array (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj// Debugging array implementation -*- C++ -*-
2*38fd1498Szrj
3*38fd1498Szrj// Copyright (C) 2012-2018 Free Software Foundation, Inc.
4*38fd1498Szrj//
5*38fd1498Szrj// This file is part of the GNU ISO C++ Library.  This library is free
6*38fd1498Szrj// software; you can redistribute it and/or modify it under the
7*38fd1498Szrj// terms of the GNU General Public License as published by the
8*38fd1498Szrj// Free Software Foundation; either version 3, or (at your option)
9*38fd1498Szrj// any later version.
10*38fd1498Szrj
11*38fd1498Szrj// This library is distributed in the hope that it will be useful,
12*38fd1498Szrj// but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*38fd1498Szrj// GNU General Public License for more details.
15*38fd1498Szrj
16*38fd1498Szrj// Under Section 7 of GPL version 3, you are granted additional
17*38fd1498Szrj// permissions described in the GCC Runtime Library Exception, version
18*38fd1498Szrj// 3.1, as published by the Free Software Foundation.
19*38fd1498Szrj
20*38fd1498Szrj// You should have received a copy of the GNU General Public License and
21*38fd1498Szrj// a copy of the GCC Runtime Library Exception along with this program;
22*38fd1498Szrj// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*38fd1498Szrj// <http://www.gnu.org/licenses/>.
24*38fd1498Szrj
25*38fd1498Szrj/** @file debug/array
26*38fd1498Szrj *  This is a Standard C++ Library header.
27*38fd1498Szrj */
28*38fd1498Szrj
29*38fd1498Szrj#ifndef _GLIBCXX_DEBUG_ARRAY
30*38fd1498Szrj#define _GLIBCXX_DEBUG_ARRAY 1
31*38fd1498Szrj
32*38fd1498Szrj#pragma GCC system_header
33*38fd1498Szrj
34*38fd1498Szrj#include <array>
35*38fd1498Szrj
36*38fd1498Szrj#include <debug/formatter.h>
37*38fd1498Szrj#include <debug/macros.h>
38*38fd1498Szrj
39*38fd1498Szrjnamespace std _GLIBCXX_VISIBILITY(default)
40*38fd1498Szrj{
41*38fd1498Szrjnamespace __debug
42*38fd1498Szrj{
43*38fd1498Szrj  template<typename _Tp, std::size_t _Nm>
44*38fd1498Szrj    struct array
45*38fd1498Szrj    {
46*38fd1498Szrj      typedef _Tp 	    			      value_type;
47*38fd1498Szrj      typedef value_type*			      pointer;
48*38fd1498Szrj      typedef const value_type*                       const_pointer;
49*38fd1498Szrj      typedef value_type&                   	      reference;
50*38fd1498Szrj      typedef const value_type&             	      const_reference;
51*38fd1498Szrj      typedef value_type*                             iterator;
52*38fd1498Szrj      typedef const value_type*                       const_iterator;
53*38fd1498Szrj      typedef std::size_t                    	      size_type;
54*38fd1498Szrj      typedef std::ptrdiff_t                   	      difference_type;
55*38fd1498Szrj      typedef std::reverse_iterator<iterator>	      reverse_iterator;
56*38fd1498Szrj      typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
57*38fd1498Szrj
58*38fd1498Szrj      // Support for zero-sized arrays mandatory.
59*38fd1498Szrj      typedef _GLIBCXX_STD_C::__array_traits<_Tp, _Nm> _AT_Type;
60*38fd1498Szrj      typename _AT_Type::_Type                         _M_elems;
61*38fd1498Szrj
62*38fd1498Szrj      template<std::size_t _Size>
63*38fd1498Szrj	struct _Array_check_subscript
64*38fd1498Szrj 	{
65*38fd1498Szrj	  std::size_t size() { return _Size; }
66*38fd1498Szrj
67*38fd1498Szrj	  _Array_check_subscript(std::size_t __index)
68*38fd1498Szrj	  { __glibcxx_check_subscript(__index); }
69*38fd1498Szrj        };
70*38fd1498Szrj
71*38fd1498Szrj      template<std::size_t _Size>
72*38fd1498Szrj	struct _Array_check_nonempty
73*38fd1498Szrj 	{
74*38fd1498Szrj	  bool empty() { return _Size == 0; }
75*38fd1498Szrj
76*38fd1498Szrj	  _Array_check_nonempty()
77*38fd1498Szrj	  { __glibcxx_check_nonempty(); }
78*38fd1498Szrj        };
79*38fd1498Szrj
80*38fd1498Szrj      // No explicit construct/copy/destroy for aggregate type.
81*38fd1498Szrj
82*38fd1498Szrj      // DR 776.
83*38fd1498Szrj      void
84*38fd1498Szrj      fill(const value_type& __u)
85*38fd1498Szrj      { std::fill_n(begin(), size(), __u); }
86*38fd1498Szrj
87*38fd1498Szrj      void
88*38fd1498Szrj      swap(array& __other)
89*38fd1498Szrj      noexcept(_AT_Type::_Is_nothrow_swappable::value)
90*38fd1498Szrj      { std::swap_ranges(begin(), end(), __other.begin()); }
91*38fd1498Szrj
92*38fd1498Szrj      // Iterators.
93*38fd1498Szrj      _GLIBCXX17_CONSTEXPR iterator
94*38fd1498Szrj      begin() noexcept
95*38fd1498Szrj      { return iterator(data()); }
96*38fd1498Szrj
97*38fd1498Szrj      _GLIBCXX17_CONSTEXPR const_iterator
98*38fd1498Szrj      begin() const noexcept
99*38fd1498Szrj      { return const_iterator(data()); }
100*38fd1498Szrj
101*38fd1498Szrj      _GLIBCXX17_CONSTEXPR iterator
102*38fd1498Szrj      end() noexcept
103*38fd1498Szrj      { return iterator(data() + _Nm); }
104*38fd1498Szrj
105*38fd1498Szrj      _GLIBCXX17_CONSTEXPR const_iterator
106*38fd1498Szrj      end() const noexcept
107*38fd1498Szrj      { return const_iterator(data() + _Nm); }
108*38fd1498Szrj
109*38fd1498Szrj      _GLIBCXX17_CONSTEXPR reverse_iterator
110*38fd1498Szrj      rbegin() noexcept
111*38fd1498Szrj      { return reverse_iterator(end()); }
112*38fd1498Szrj
113*38fd1498Szrj      _GLIBCXX17_CONSTEXPR const_reverse_iterator
114*38fd1498Szrj      rbegin() const noexcept
115*38fd1498Szrj      { return const_reverse_iterator(end()); }
116*38fd1498Szrj
117*38fd1498Szrj      _GLIBCXX17_CONSTEXPR reverse_iterator
118*38fd1498Szrj      rend() noexcept
119*38fd1498Szrj      { return reverse_iterator(begin()); }
120*38fd1498Szrj
121*38fd1498Szrj      _GLIBCXX17_CONSTEXPR const_reverse_iterator
122*38fd1498Szrj      rend() const noexcept
123*38fd1498Szrj      { return const_reverse_iterator(begin()); }
124*38fd1498Szrj
125*38fd1498Szrj      _GLIBCXX17_CONSTEXPR const_iterator
126*38fd1498Szrj      cbegin() const noexcept
127*38fd1498Szrj      { return const_iterator(data()); }
128*38fd1498Szrj
129*38fd1498Szrj      _GLIBCXX17_CONSTEXPR const_iterator
130*38fd1498Szrj      cend() const noexcept
131*38fd1498Szrj      { return const_iterator(data() + _Nm); }
132*38fd1498Szrj
133*38fd1498Szrj      _GLIBCXX17_CONSTEXPR const_reverse_iterator
134*38fd1498Szrj      crbegin() const noexcept
135*38fd1498Szrj      { return const_reverse_iterator(end()); }
136*38fd1498Szrj
137*38fd1498Szrj      _GLIBCXX17_CONSTEXPR const_reverse_iterator
138*38fd1498Szrj      crend() const noexcept
139*38fd1498Szrj      { return const_reverse_iterator(begin()); }
140*38fd1498Szrj
141*38fd1498Szrj      // Capacity.
142*38fd1498Szrj      constexpr size_type
143*38fd1498Szrj      size() const noexcept { return _Nm; }
144*38fd1498Szrj
145*38fd1498Szrj      constexpr size_type
146*38fd1498Szrj      max_size() const noexcept { return _Nm; }
147*38fd1498Szrj
148*38fd1498Szrj      constexpr bool
149*38fd1498Szrj      empty() const noexcept { return size() == 0; }
150*38fd1498Szrj
151*38fd1498Szrj      // Element access.
152*38fd1498Szrj      _GLIBCXX17_CONSTEXPR reference
153*38fd1498Szrj      operator[](size_type __n) noexcept
154*38fd1498Szrj      {
155*38fd1498Szrj	__glibcxx_check_subscript(__n);
156*38fd1498Szrj	return _AT_Type::_S_ref(_M_elems, __n);
157*38fd1498Szrj      }
158*38fd1498Szrj
159*38fd1498Szrj      constexpr const_reference
160*38fd1498Szrj      operator[](size_type __n) const noexcept
161*38fd1498Szrj      {
162*38fd1498Szrj	return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
163*38fd1498Szrj	 : (_GLIBCXX_THROW_OR_ABORT(_Array_check_subscript<_Nm>(__n)),
164*38fd1498Szrj	    _AT_Type::_S_ref(_M_elems, 0));
165*38fd1498Szrj      }
166*38fd1498Szrj
167*38fd1498Szrj      _GLIBCXX17_CONSTEXPR reference
168*38fd1498Szrj      at(size_type __n)
169*38fd1498Szrj      {
170*38fd1498Szrj	if (__n >= _Nm)
171*38fd1498Szrj	  std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
172*38fd1498Szrj					    ">= _Nm (which is %zu)"),
173*38fd1498Szrj					__n, _Nm);
174*38fd1498Szrj	return _AT_Type::_S_ref(_M_elems, __n);
175*38fd1498Szrj      }
176*38fd1498Szrj
177*38fd1498Szrj      constexpr const_reference
178*38fd1498Szrj      at(size_type __n) const
179*38fd1498Szrj      {
180*38fd1498Szrj	// Result of conditional expression must be an lvalue so use
181*38fd1498Szrj	// boolean ? lvalue : (throw-expr, lvalue)
182*38fd1498Szrj	return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
183*38fd1498Szrj	  : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
184*38fd1498Szrj					       ">= _Nm (which is %zu)"),
185*38fd1498Szrj					   __n, _Nm),
186*38fd1498Szrj	     _AT_Type::_S_ref(_M_elems, 0));
187*38fd1498Szrj      }
188*38fd1498Szrj
189*38fd1498Szrj      _GLIBCXX17_CONSTEXPR reference
190*38fd1498Szrj      front() noexcept
191*38fd1498Szrj      {
192*38fd1498Szrj	__glibcxx_check_nonempty();
193*38fd1498Szrj	return *begin();
194*38fd1498Szrj      }
195*38fd1498Szrj
196*38fd1498Szrj      constexpr const_reference
197*38fd1498Szrj      front() const noexcept
198*38fd1498Szrj      {
199*38fd1498Szrj	return _Nm ? _AT_Type::_S_ref(_M_elems, 0)
200*38fd1498Szrj	  : (_GLIBCXX_THROW_OR_ABORT(_Array_check_nonempty<_Nm>()),
201*38fd1498Szrj	     _AT_Type::_S_ref(_M_elems, 0));
202*38fd1498Szrj      }
203*38fd1498Szrj
204*38fd1498Szrj      _GLIBCXX17_CONSTEXPR reference
205*38fd1498Szrj      back() noexcept
206*38fd1498Szrj      {
207*38fd1498Szrj	__glibcxx_check_nonempty();
208*38fd1498Szrj	return _Nm ? *(end() - 1) : *end();
209*38fd1498Szrj      }
210*38fd1498Szrj
211*38fd1498Szrj      constexpr const_reference
212*38fd1498Szrj      back() const noexcept
213*38fd1498Szrj      {
214*38fd1498Szrj	return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1)
215*38fd1498Szrj	  : (_GLIBCXX_THROW_OR_ABORT(_Array_check_nonempty<_Nm>()),
216*38fd1498Szrj	     _AT_Type::_S_ref(_M_elems, 0));
217*38fd1498Szrj      }
218*38fd1498Szrj
219*38fd1498Szrj      _GLIBCXX17_CONSTEXPR pointer
220*38fd1498Szrj      data() noexcept
221*38fd1498Szrj      { return _AT_Type::_S_ptr(_M_elems); }
222*38fd1498Szrj
223*38fd1498Szrj      _GLIBCXX17_CONSTEXPR const_pointer
224*38fd1498Szrj      data() const noexcept
225*38fd1498Szrj      { return _AT_Type::_S_ptr(_M_elems); }
226*38fd1498Szrj    };
227*38fd1498Szrj
228*38fd1498Szrj#if __cpp_deduction_guides >= 201606
229*38fd1498Szrj  template<typename _Tp, typename... _Up>
230*38fd1498Szrj    array(_Tp, _Up...)
231*38fd1498Szrj      -> array<std::enable_if_t<(std::is_same_v<_Tp, _Up> && ...), _Tp>,
232*38fd1498Szrj	       1 + sizeof...(_Up)>;
233*38fd1498Szrj#endif
234*38fd1498Szrj
235*38fd1498Szrj  // Array comparisons.
236*38fd1498Szrj  template<typename _Tp, std::size_t _Nm>
237*38fd1498Szrj    inline bool
238*38fd1498Szrj    operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
239*38fd1498Szrj    { return std::equal(__one.begin(), __one.end(), __two.begin()); }
240*38fd1498Szrj
241*38fd1498Szrj  template<typename _Tp, std::size_t _Nm>
242*38fd1498Szrj    inline bool
243*38fd1498Szrj    operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
244*38fd1498Szrj    { return !(__one == __two); }
245*38fd1498Szrj
246*38fd1498Szrj  template<typename _Tp, std::size_t _Nm>
247*38fd1498Szrj    inline bool
248*38fd1498Szrj    operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
249*38fd1498Szrj    {
250*38fd1498Szrj      return std::lexicographical_compare(__a.begin(), __a.end(),
251*38fd1498Szrj					  __b.begin(), __b.end());
252*38fd1498Szrj    }
253*38fd1498Szrj
254*38fd1498Szrj  template<typename _Tp, std::size_t _Nm>
255*38fd1498Szrj    inline bool
256*38fd1498Szrj    operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
257*38fd1498Szrj    { return __two < __one; }
258*38fd1498Szrj
259*38fd1498Szrj  template<typename _Tp, std::size_t _Nm>
260*38fd1498Szrj    inline bool
261*38fd1498Szrj    operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
262*38fd1498Szrj    { return !(__one > __two); }
263*38fd1498Szrj
264*38fd1498Szrj  template<typename _Tp, std::size_t _Nm>
265*38fd1498Szrj    inline bool
266*38fd1498Szrj    operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
267*38fd1498Szrj    { return !(__one < __two); }
268*38fd1498Szrj
269*38fd1498Szrj  // Specialized algorithms.
270*38fd1498Szrj
271*38fd1498Szrj#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
272*38fd1498Szrj  template<typename _Tp, size_t _Nm>
273*38fd1498Szrj    typename enable_if<
274*38fd1498Szrj      !_GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::_Is_swappable::value>::type
275*38fd1498Szrj    swap(array<_Tp, _Nm>&, array<_Tp, _Nm>&) = delete;
276*38fd1498Szrj#endif
277*38fd1498Szrj
278*38fd1498Szrj  template<typename _Tp, std::size_t _Nm>
279*38fd1498Szrj    inline void
280*38fd1498Szrj    swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
281*38fd1498Szrj    noexcept(noexcept(__one.swap(__two)))
282*38fd1498Szrj    { __one.swap(__two); }
283*38fd1498Szrj
284*38fd1498Szrj  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
285*38fd1498Szrj    constexpr _Tp&
286*38fd1498Szrj    get(array<_Tp, _Nm>& __arr) noexcept
287*38fd1498Szrj    {
288*38fd1498Szrj      static_assert(_Int < _Nm, "index is out of bounds");
289*38fd1498Szrj      return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
290*38fd1498Szrj	_S_ref(__arr._M_elems, _Int);
291*38fd1498Szrj    }
292*38fd1498Szrj
293*38fd1498Szrj  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
294*38fd1498Szrj    constexpr _Tp&&
295*38fd1498Szrj    get(array<_Tp, _Nm>&& __arr) noexcept
296*38fd1498Szrj    {
297*38fd1498Szrj      static_assert(_Int < _Nm, "index is out of bounds");
298*38fd1498Szrj      return std::move(__debug::get<_Int>(__arr));
299*38fd1498Szrj    }
300*38fd1498Szrj
301*38fd1498Szrj  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
302*38fd1498Szrj    constexpr const _Tp&
303*38fd1498Szrj    get(const array<_Tp, _Nm>& __arr) noexcept
304*38fd1498Szrj    {
305*38fd1498Szrj      static_assert(_Int < _Nm, "index is out of bounds");
306*38fd1498Szrj      return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
307*38fd1498Szrj	_S_ref(__arr._M_elems, _Int);
308*38fd1498Szrj    }
309*38fd1498Szrj
310*38fd1498Szrj  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
311*38fd1498Szrj    constexpr const _Tp&&
312*38fd1498Szrj    get(const array<_Tp, _Nm>&& __arr) noexcept
313*38fd1498Szrj    {
314*38fd1498Szrj      static_assert(_Int < _Nm, "index is out of bounds");
315*38fd1498Szrj      return std::move(__debug::get<_Int>(__arr));
316*38fd1498Szrj    }
317*38fd1498Szrj} // namespace __debug
318*38fd1498Szrj
319*38fd1498Szrj_GLIBCXX_BEGIN_NAMESPACE_VERSION
320*38fd1498Szrj  // Tuple interface to class template array.
321*38fd1498Szrj
322*38fd1498Szrj  /// tuple_size
323*38fd1498Szrj  template<typename _Tp, std::size_t _Nm>
324*38fd1498Szrj    struct tuple_size<std::__debug::array<_Tp, _Nm>>
325*38fd1498Szrj    : public integral_constant<std::size_t, _Nm> { };
326*38fd1498Szrj
327*38fd1498Szrj  /// tuple_element
328*38fd1498Szrj  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
329*38fd1498Szrj    struct tuple_element<_Int, std::__debug::array<_Tp, _Nm>>
330*38fd1498Szrj    {
331*38fd1498Szrj      static_assert(_Int < _Nm, "index is out of bounds");
332*38fd1498Szrj      typedef _Tp type;
333*38fd1498Szrj    };
334*38fd1498Szrj
335*38fd1498Szrj  template<typename _Tp, std::size_t _Nm>
336*38fd1498Szrj    struct __is_tuple_like_impl<std::__debug::array<_Tp, _Nm>> : true_type
337*38fd1498Szrj    { };
338*38fd1498Szrj
339*38fd1498Szrj_GLIBCXX_END_NAMESPACE_VERSION
340*38fd1498Szrj} // namespace std
341*38fd1498Szrj
342*38fd1498Szrj#endif // _GLIBCXX_DEBUG_ARRAY
343