Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6554 serge 1
// Debugging support implementation -*- C++ -*-
2
 
3
// Copyright (C) 2003-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/macros.h
26
 *  This file is a GNU debug extension to the Standard C++ Library.
27
 */
28
 
29
#ifndef _GLIBCXX_DEBUG_MACROS_H
30
#define _GLIBCXX_DEBUG_MACROS_H 1
31
 
32
/**
33
 * Macros used by the implementation to verify certain
34
 * properties. These macros may only be used directly by the debug
35
 * wrappers. Note that these are macros (instead of the more obviously
36
 * @a correct choice of making them functions) because we need line and
37
 * file information at the call site, to minimize the distance between
38
 * the user error and where the error is reported.
39
 *
40
 */
41
#define _GLIBCXX_DEBUG_VERIFY_AT(_Condition,_ErrorMessage,_File,_Line)	\
42
  do									\
43
  {									\
44
    if (! (_Condition))							\
45
      __gnu_debug::_Error_formatter::_M_at(_File, _Line)		\
46
	  ._ErrorMessage._M_error();					\
47
  } while (false)
48
 
49
#define _GLIBCXX_DEBUG_VERIFY(_Condition,_ErrorMessage)			\
50
  _GLIBCXX_DEBUG_VERIFY_AT(_Condition,_ErrorMessage,__FILE__,__LINE__)
51
 
52
// Verify that [_First, _Last) forms a valid iterator range.
53
#define __glibcxx_check_valid_range(_First,_Last)			\
54
_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__valid_range(_First, _Last),	\
55
		      _M_message(__gnu_debug::__msg_valid_range)	\
56
		      ._M_iterator(_First, #_First)			\
57
		      ._M_iterator(_Last, #_Last))
58
 
59
// Verify that [_First, _Last) forms a non-empty iterator range.
60
#define __glibcxx_check_non_empty_range(_First,_Last)			\
61
_GLIBCXX_DEBUG_VERIFY(_First != _Last,					\
62
		      _M_message(__gnu_debug::__msg_non_empty_range)	\
63
		      ._M_iterator(_First, #_First)			\
64
		      ._M_iterator(_Last, #_Last))
65
 
66
/** Verify that we can insert into *this with the iterator _Position.
67
 *  Insertion into a container at a specific position requires that
68
 *  the iterator be nonsingular, either dereferenceable or past-the-end,
69
 *  and that it reference the sequence we are inserting into. Note that
70
 *  this macro is only valid when the container is a_Safe_sequence and
71
 *  the iterator is a _Safe_iterator.
72
*/
73
#define __glibcxx_check_insert(_Position)				\
74
_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(),				\
75
		      _M_message(__gnu_debug::__msg_insert_singular)	\
76
		      ._M_sequence(*this, "this")			\
77
		      ._M_iterator(_Position, #_Position));		\
78
_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this),			\
79
		      _M_message(__gnu_debug::__msg_insert_different)	\
80
		      ._M_sequence(*this, "this")			\
81
		      ._M_iterator(_Position, #_Position))
82
 
83
/** Verify that we can insert into *this after the iterator _Position.
84
 *  Insertion into a container after a specific position requires that
85
 *  the iterator be nonsingular, either dereferenceable or before-begin,
86
 *  and that it reference the sequence we are inserting into. Note that
87
 *  this macro is only valid when the container is a_Safe_sequence and
88
 *  the iterator is a _Safe_iterator.
89
*/
90
#define __glibcxx_check_insert_after(_Position)				\
91
__glibcxx_check_insert(_Position);					\
92
_GLIBCXX_DEBUG_VERIFY(!_Position._M_is_end(),				\
93
		      _M_message(__gnu_debug::__msg_insert_after_end)	\
94
		      ._M_sequence(*this, "this")			\
95
		      ._M_iterator(_Position, #_Position))
96
 
97
/** Verify that we can insert the values in the iterator range
98
 *  [_First, _Last) into *this with the iterator _Position.  Insertion
99
 *  into a container at a specific position requires that the iterator
100
 *  be nonsingular (i.e., either dereferenceable or past-the-end),
101
 *  that it reference the sequence we are inserting into, and that the
102
 *  iterator range [_First, _Last) is a valid (possibly empty)
103
 *  range which does not reference the sequence we are inserting into.
104
 *  Note that this macro is only valid when the container is a
105
 *  _Safe_sequence and the _Position iterator is a _Safe_iterator.
106
*/
107
#define __glibcxx_check_insert_range(_Position,_First,_Last)		\
108
__glibcxx_check_valid_range(_First,_Last);				\
109
__glibcxx_check_insert(_Position);					\
110
_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__foreign_iterator(_Position,_First,_Last),\
111
		      _M_message(__gnu_debug::__msg_insert_range_from_self)\
112
		      ._M_iterator(_First, #_First)			\
113
		      ._M_iterator(_Last, #_Last)			\
114
		      ._M_sequence(*this, "this"))
115
 
116
/** Verify that we can insert the values in the iterator range
117
 *  [_First, _Last) into *this after the iterator _Position.  Insertion
118
 *  into a container after a specific position requires that the iterator
119
 *  be nonsingular (i.e., either dereferenceable or past-the-end),
120
 *  that it reference the sequence we are inserting into, and that the
121
 *  iterator range [_First, _Last) is a valid (possibly empty)
122
 *  range which does not reference the sequence we are inserting into.
123
 *  Note that this macro is only valid when the container is a
124
 *  _Safe_sequence and the _Position iterator is a _Safe_iterator.
125
*/
126
#define __glibcxx_check_insert_range_after(_Position,_First,_Last)	\
127
__glibcxx_check_valid_range(_First,_Last);				\
128
__glibcxx_check_insert_after(_Position);				\
129
_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__foreign_iterator(_Position,_First,_Last),\
130
		      _M_message(__gnu_debug::__msg_insert_range_from_self)\
131
		      ._M_iterator(_First, #_First)			\
132
		      ._M_iterator(_Last, #_Last)			\
133
		      ._M_sequence(*this, "this"))
134
 
135
/** Verify that we can erase the element referenced by the iterator
136
 * _Position. We can erase the element if the _Position iterator is
137
 * dereferenceable and references this sequence.
138
*/
139
#define __glibcxx_check_erase(_Position)				\
140
_GLIBCXX_DEBUG_VERIFY(_Position._M_dereferenceable(),			\
141
		      _M_message(__gnu_debug::__msg_erase_bad)	        \
142
                      ._M_sequence(*this, "this")			\
143
		      ._M_iterator(_Position, #_Position));		\
144
_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this),			\
145
		      _M_message(__gnu_debug::__msg_erase_different)    \
146
		      ._M_sequence(*this, "this")			\
147
		      ._M_iterator(_Position, #_Position))
148
 
149
/** Verify that we can erase the element after the iterator
150
 * _Position. We can erase the element if the _Position iterator is
151
 * before a dereferenceable one and references this sequence.
152
*/
153
#define __glibcxx_check_erase_after(_Position)				\
154
_GLIBCXX_DEBUG_VERIFY(_Position._M_before_dereferenceable(),		\
155
		      _M_message(__gnu_debug::__msg_erase_after_bad)	\
156
		      ._M_sequence(*this, "this")			\
157
		      ._M_iterator(_Position, #_Position));		\
158
_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this),			\
159
		      _M_message(__gnu_debug::__msg_erase_different)	\
160
		      ._M_sequence(*this, "this")			\
161
		      ._M_iterator(_Position, #_Position))
162
 
163
/** Verify that we can erase the elements in the iterator range
164
 *  [_First, _Last). We can erase the elements if [_First, _Last) is a
165
 *  valid iterator range within this sequence.
166
*/
167
#define __glibcxx_check_erase_range(_First,_Last)			\
168
__glibcxx_check_valid_range(_First,_Last);				\
169
_GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this),			\
170
		      _M_message(__gnu_debug::__msg_erase_different)    \
171
                      ._M_sequence(*this, "this")			\
172
		      ._M_iterator(_First, #_First)			\
173
		      ._M_iterator(_Last, #_Last))
174
 
175
/** Verify that we can erase the elements in the iterator range
176
 *  (_First, _Last). We can erase the elements if (_First, _Last) is a
177
 *  valid iterator range within this sequence.
178
*/
179
#define __glibcxx_check_erase_range_after(_First,_Last)			\
180
_GLIBCXX_DEBUG_VERIFY(_First._M_can_compare(_Last),			\
181
		      _M_message(__gnu_debug::__msg_erase_different)	\
182
		      ._M_sequence(*this, "this")			\
183
		      ._M_iterator(_First, #_First)			\
184
		      ._M_iterator(_Last, #_Last));			\
185
_GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this),			\
186
		      _M_message(__gnu_debug::__msg_erase_different)	\
187
		      ._M_sequence(*this, "this")			\
188
		      ._M_iterator(_First, #_First));			\
189
_GLIBCXX_DEBUG_VERIFY(_First != _Last,					\
190
		      _M_message(__gnu_debug::__msg_valid_range2)	\
191
		      ._M_sequence(*this, "this")			\
192
		      ._M_iterator(_First, #_First)			\
193
		      ._M_iterator(_Last, #_Last));			\
194
_GLIBCXX_DEBUG_VERIFY(_First._M_incrementable(),			\
195
		      _M_message(__gnu_debug::__msg_valid_range2)	\
196
		      ._M_sequence(*this, "this")			\
197
		      ._M_iterator(_First, #_First)			\
198
		      ._M_iterator(_Last, #_Last));			\
199
_GLIBCXX_DEBUG_VERIFY(!_Last._M_is_before_begin(),			\
200
		      _M_message(__gnu_debug::__msg_valid_range2)	\
201
		      ._M_sequence(*this, "this")			\
202
		      ._M_iterator(_First, #_First)			\
203
		      ._M_iterator(_Last, #_Last))			\
204
 
205
// Verify that the subscript _N is less than the container's size.
206
#define __glibcxx_check_subscript(_N)					\
207
_GLIBCXX_DEBUG_VERIFY(_N < this->size(),				\
208
		      _M_message(__gnu_debug::__msg_subscript_oob)	\
209
                      ._M_sequence(*this, "this")			\
210
		      ._M_integer(_N, #_N)				\
211
		      ._M_integer(this->size(), "size"))
212
 
213
// Verify that the bucket _N is less than the container's buckets count.
214
#define __glibcxx_check_bucket_index(_N)				\
215
_GLIBCXX_DEBUG_VERIFY(_N < this->bucket_count(),			\
216
		      _M_message(__gnu_debug::__msg_bucket_index_oob)	\
217
                      ._M_sequence(*this, "this")			\
218
		      ._M_integer(_N, #_N)				\
219
		      ._M_integer(this->bucket_count(), "size"))
220
 
221
// Verify that the container is nonempty
222
#define __glibcxx_check_nonempty()					\
223
_GLIBCXX_DEBUG_VERIFY(! this->empty(),					\
224
		      _M_message(__gnu_debug::__msg_empty)	        \
225
                      ._M_sequence(*this, "this"))
226
 
227
// Verify that the iterator range [_First, _Last) is sorted
228
#define __glibcxx_check_sorted(_First,_Last)				\
229
__glibcxx_check_valid_range(_First,_Last);				\
230
 _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(			\
231
			__gnu_debug::__base(_First),			\
232
			__gnu_debug::__base(_Last)),			\
233
		      _M_message(__gnu_debug::__msg_unsorted)	        \
234
                      ._M_iterator(_First, #_First)			\
235
		      ._M_iterator(_Last, #_Last))
236
 
237
/** Verify that the iterator range [_First, _Last) is sorted by the
238
    predicate _Pred. */
239
#define __glibcxx_check_sorted_pred(_First,_Last,_Pred)			\
240
__glibcxx_check_valid_range(_First,_Last);				\
241
_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(			\
242
			__gnu_debug::__base(_First),			\
243
			__gnu_debug::__base(_Last), _Pred),		\
244
		      _M_message(__gnu_debug::__msg_unsorted_pred)      \
245
                      ._M_iterator(_First, #_First)			\
246
		      ._M_iterator(_Last, #_Last)			\
247
		      ._M_string(#_Pred))
248
 
249
// Special variant for std::merge, std::includes, std::set_*
250
#define __glibcxx_check_sorted_set(_First1,_Last1,_First2)		\
251
__glibcxx_check_valid_range(_First1,_Last1);				\
252
_GLIBCXX_DEBUG_VERIFY(                                                  \
253
  __gnu_debug::__check_sorted_set(__gnu_debug::__base(_First1),		\
254
				  __gnu_debug::__base(_Last1), _First2),\
255
  _M_message(__gnu_debug::__msg_unsorted)				\
256
  ._M_iterator(_First1, #_First1)					\
257
  ._M_iterator(_Last1, #_Last1))
258
 
259
// Likewise with a _Pred.
260
#define __glibcxx_check_sorted_set_pred(_First1,_Last1,_First2,_Pred)	\
261
__glibcxx_check_valid_range(_First1,_Last1);        			\
262
_GLIBCXX_DEBUG_VERIFY(							\
263
  __gnu_debug::__check_sorted_set(__gnu_debug::__base(_First1),		\
264
				  __gnu_debug::__base(_Last1),		\
265
				  _First2, _Pred),			\
266
  _M_message(__gnu_debug::__msg_unsorted_pred)				\
267
  ._M_iterator(_First1, #_First1)					\
268
  ._M_iterator(_Last1, #_Last1)						\
269
  ._M_string(#_Pred))
270
 
271
/** Verify that the iterator range [_First, _Last) is partitioned
272
    w.r.t. the value _Value. */
273
#define __glibcxx_check_partitioned_lower(_First,_Last,_Value)		\
274
__glibcxx_check_valid_range(_First,_Last);				\
275
_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_lower(		\
276
			__gnu_debug::__base(_First),			\
277
			__gnu_debug::__base(_Last), _Value),		\
278
		      _M_message(__gnu_debug::__msg_unpartitioned)      \
279
		      ._M_iterator(_First, #_First)			\
280
		      ._M_iterator(_Last, #_Last)			\
281
		      ._M_string(#_Value))
282
 
283
#define __glibcxx_check_partitioned_upper(_First,_Last,_Value)		\
284
__glibcxx_check_valid_range(_First,_Last);				\
285
_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper(		\
286
			__gnu_debug::__base(_First),			\
287
			__gnu_debug::__base(_Last), _Value),		\
288
		      _M_message(__gnu_debug::__msg_unpartitioned)      \
289
		      ._M_iterator(_First, #_First)			\
290
		      ._M_iterator(_Last, #_Last)			\
291
		      ._M_string(#_Value))
292
 
293
/** Verify that the iterator range [_First, _Last) is partitioned
294
    w.r.t. the value _Value and predicate _Pred. */
295
#define __glibcxx_check_partitioned_lower_pred(_First,_Last,_Value,_Pred) \
296
__glibcxx_check_valid_range(_First,_Last);				\
297
_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_lower(		\
298
			__gnu_debug::__base(_First),			\
299
			__gnu_debug::__base(_Last), _Value, _Pred),	\
300
		      _M_message(__gnu_debug::__msg_unpartitioned_pred) \
301
		      ._M_iterator(_First, #_First)			\
302
		      ._M_iterator(_Last, #_Last)			\
303
		      ._M_string(#_Pred)				\
304
                      ._M_string(#_Value))
305
 
306
/** Verify that the iterator range [_First, _Last) is partitioned
307
    w.r.t. the value _Value and predicate _Pred. */
308
#define __glibcxx_check_partitioned_upper_pred(_First,_Last,_Value,_Pred) \
309
__glibcxx_check_valid_range(_First,_Last);				\
310
_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper(		\
311
			__gnu_debug::__base(_First),			\
312
			__gnu_debug::__base(_Last), _Value, _Pred),	\
313
		      _M_message(__gnu_debug::__msg_unpartitioned_pred) \
314
		      ._M_iterator(_First, #_First)			\
315
		      ._M_iterator(_Last, #_Last)			\
316
		      ._M_string(#_Pred)				\
317
                      ._M_string(#_Value))
318
 
319
// Verify that the iterator range [_First, _Last) is a heap
320
#define __glibcxx_check_heap(_First,_Last)				\
321
  _GLIBCXX_DEBUG_VERIFY(std::__is_heap(__gnu_debug::__base(_First),	\
322
				       __gnu_debug::__base(_Last)),	\
323
		      _M_message(__gnu_debug::__msg_not_heap)	        \
324
		      ._M_iterator(_First, #_First)			\
325
		      ._M_iterator(_Last, #_Last))
326
 
327
/** Verify that the iterator range [_First, _Last) is a heap
328
    w.r.t. the predicate _Pred. */
329
#define __glibcxx_check_heap_pred(_First,_Last,_Pred)			\
330
  _GLIBCXX_DEBUG_VERIFY(std::__is_heap(__gnu_debug::__base(_First),	\
331
				       __gnu_debug::__base(_Last),	\
332
				       _Pred),				\
333
		      _M_message(__gnu_debug::__msg_not_heap_pred)      \
334
                      ._M_iterator(_First, #_First)			\
335
		      ._M_iterator(_Last, #_Last)			\
336
		      ._M_string(#_Pred))
337
 
338
// Verify that the container is not self move assigned
339
#define __glibcxx_check_self_move_assign(_Other)			\
340
_GLIBCXX_DEBUG_VERIFY(this != &_Other,					\
341
		      _M_message(__gnu_debug::__msg_self_move_assign)	\
342
                      ._M_sequence(*this, "this"))
343
 
344
// Verify that load factor is positive
345
#define __glibcxx_check_max_load_factor(_F)				\
346
_GLIBCXX_DEBUG_VERIFY(_F > 0.0f,					\
347
		      _M_message(__gnu_debug::__msg_valid_load_factor)	\
348
                      ._M_sequence(*this, "this"))
349
 
350
#define __glibcxx_check_equal_allocs(_This, _Other)			\
351
_GLIBCXX_DEBUG_VERIFY(_This.get_allocator() == _Other.get_allocator(),	\
352
		      _M_message(__gnu_debug::__msg_equal_allocs)	\
353
		      ._M_sequence(_This, "this"))
354
 
355
#ifdef _GLIBCXX_DEBUG_PEDANTIC
356
#  define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0)
357
#  define __glibcxx_check_string_len(_String,_Len) \
358
       _GLIBCXX_DEBUG_ASSERT(_String != 0 || _Len == 0)
359
#else
360
#  define __glibcxx_check_string(_String)
361
#  define __glibcxx_check_string_len(_String,_Len)
362
#endif
363
 
364
#endif