Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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