1 // Debug-mode error formatting implementation -*- C++ -*-
3 // Copyright (C) 2003-2020 Free Software Foundation, Inc.
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)
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.
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.
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 // <http://www.gnu.org/licenses/>.
25 /** @file debug/formatter.h
26 * This file is a GNU debug extension to the Standard C++ Library.
29 #ifndef _GLIBCXX_DEBUG_FORMATTER_H
30 #define _GLIBCXX_DEBUG_FORMATTER_H 1
32 #include <bits/c++config.h>
36 # define _GLIBCXX_TYPEID(_Type) &typeid(_Type)
42 # define _GLIBCXX_TYPEID(_Type) 0
45 #if __cplusplus >= 201103L
48 _GLIBCXX_BEGIN_NAMESPACE_VERSION
50 template<typename _Iterator
, typename _Container
>
51 class __normal_iterator
;
53 _GLIBCXX_END_NAMESPACE_VERSION
58 _GLIBCXX_BEGIN_NAMESPACE_VERSION
60 template<typename _Iterator
>
61 class reverse_iterator
;
63 template<typename _Iterator
>
66 _GLIBCXX_END_NAMESPACE_VERSION
74 template<typename _Iterator
>
75 bool __check_singular(const _Iterator
&);
77 class _Safe_sequence_base
;
79 template<typename _Iterator
, typename _Sequence
, typename _Category
>
82 template<typename _Iterator
, typename _Sequence
>
83 class _Safe_local_iterator
;
85 template<typename _Sequence
>
92 __msg_insert_singular
,
93 __msg_insert_different
,
95 __msg_erase_different
,
99 __msg_unpartitioned_pred
,
104 // std::bitset checks
105 __msg_bad_bitset_write
,
106 __msg_bad_bitset_read
,
107 __msg_bad_bitset_flip
,
113 __msg_splice_overlap
,
116 __msg_init_copy_singular
,
117 __msg_init_const_singular
,
122 __msg_iter_subscript_oob
,
125 __msg_iter_compare_bad
,
126 __msg_compare_different
,
127 __msg_iter_order_bad
,
128 __msg_order_different
,
130 __msg_distance_different
,
135 __msg_output_ostream
,
136 // istreambuf_iterator
137 __msg_deref_istreambuf
,
138 __msg_inc_istreambuf
,
140 __msg_insert_after_end
,
141 __msg_erase_after_bad
,
143 // unordered container local iterators
144 __msg_local_iter_compare_bad
,
145 __msg_non_empty_range
,
146 // self move assign (no longer used)
147 __msg_self_move_assign
,
148 // unordered container buckets
149 __msg_bucket_index_oob
,
150 __msg_valid_load_factor
,
153 __msg_insert_range_from_self
,
154 __msg_irreflexive_ordering
157 class _Error_formatter
159 // Tags denoting the type of parameter for construction
160 struct _Is_iterator
{ };
161 struct _Is_iterator_value_type
{ };
162 struct _Is_sequence
{ };
163 struct _Is_instance
{ };
166 /// Whether an iterator is constant, mutable, or unknown
175 // The state of the iterator (fine-grained), if we know it.
179 __singular
, // singular, may still be attached to a sequence
180 __begin
, // dereferenceable, and at the beginning
181 __middle
, // dereferenceable, not at the beginning
182 __end
, // past-the-end, may be at beginning if sequence empty
183 __before_begin
, // before begin
184 __rbegin
, // dereferenceable, and at the reverse-beginning
185 __rmiddle
, // reverse-dereferenceable, not at the reverse-beginning
186 __rend
, // reverse-past-the-end
190 // A parameter that may be referenced by an error message
201 __iterator_value_type
207 const type_info
* _M_type
;
210 struct _Instance
: _Type
212 const void* _M_address
;
217 // When _M_kind == __iterator
220 _Constness _M_constness
;
221 _Iterator_state _M_state
;
222 const void* _M_sequence
;
223 const type_info
* _M_seq_type
;
226 // When _M_kind == __sequence
227 _Instance _M_sequence
;
229 // When _M_kind == __integer
236 // When _M_kind == __string
240 const char* _M_value
;
243 // When _M_kind == __instance
244 _Instance _M_instance
;
246 // When _M_kind == __iterator_value_type
247 _Type _M_iterator_value_type
;
250 _Parameter() : _M_kind(__unused_param
), _M_variant() { }
252 _Parameter(long __value
, const char* __name
)
253 : _M_kind(__integer
), _M_variant()
255 _M_variant
._M_integer
._M_name
= __name
;
256 _M_variant
._M_integer
._M_value
= __value
;
259 _Parameter(const char* __value
, const char* __name
)
260 : _M_kind(__string
), _M_variant()
262 _M_variant
._M_string
._M_name
= __name
;
263 _M_variant
._M_string
._M_value
= __value
;
266 template<typename _Iterator
, typename _Sequence
, typename _Category
>
267 _Parameter(_Safe_iterator
<_Iterator
, _Sequence
, _Category
> const& __it
,
268 const char* __name
, _Is_iterator
)
269 : _M_kind(__iterator
), _M_variant()
271 _M_variant
._M_iterator
._M_name
= __name
;
272 _M_variant
._M_iterator
._M_address
= std::__addressof(__it
);
273 _M_variant
._M_iterator
._M_type
= _GLIBCXX_TYPEID(_Iterator
);
274 _M_variant
._M_iterator
._M_constness
=
275 __it
._S_constant() ? __const_iterator
: __mutable_iterator
;
276 _M_variant
._M_iterator
._M_sequence
= __it
._M_get_sequence();
277 _M_variant
._M_iterator
._M_seq_type
= _GLIBCXX_TYPEID(_Sequence
);
279 if (__it
._M_singular())
280 _M_variant
._M_iterator
._M_state
= __singular
;
283 if (__it
._M_is_before_begin())
284 _M_variant
._M_iterator
._M_state
= __before_begin
;
285 else if (__it
._M_is_end())
286 _M_variant
._M_iterator
._M_state
= __end
;
287 else if (__it
._M_is_begin())
288 _M_variant
._M_iterator
._M_state
= __begin
;
290 _M_variant
._M_iterator
._M_state
= __middle
;
294 template<typename _Iterator
, typename _Sequence
>
295 _Parameter(_Safe_local_iterator
<_Iterator
, _Sequence
> const& __it
,
296 const char* __name
, _Is_iterator
)
297 : _M_kind(__iterator
), _M_variant()
299 _M_variant
._M_iterator
._M_name
= __name
;
300 _M_variant
._M_iterator
._M_address
= std::__addressof(__it
);
301 _M_variant
._M_iterator
._M_type
= _GLIBCXX_TYPEID(_Iterator
);
302 _M_variant
._M_iterator
._M_constness
=
303 __it
._S_constant() ? __const_iterator
: __mutable_iterator
;
304 _M_variant
._M_iterator
._M_sequence
= __it
._M_get_sequence();
305 _M_variant
._M_iterator
._M_seq_type
= _GLIBCXX_TYPEID(_Sequence
);
307 if (__it
._M_singular())
308 _M_variant
._M_iterator
._M_state
= __singular
;
311 if (__it
._M_is_end())
312 _M_variant
._M_iterator
._M_state
= __end
;
313 else if (__it
._M_is_begin())
314 _M_variant
._M_iterator
._M_state
= __begin
;
316 _M_variant
._M_iterator
._M_state
= __middle
;
320 template<typename _Type
>
321 _Parameter(const _Type
* const& __it
, const char* __name
, _Is_iterator
)
322 : _M_kind(__iterator
), _M_variant()
324 _M_variant
._M_iterator
._M_name
= __name
;
325 _M_variant
._M_iterator
._M_address
= std::__addressof(__it
);
326 _M_variant
._M_iterator
._M_type
= _GLIBCXX_TYPEID(__it
);
327 _M_variant
._M_iterator
._M_constness
= __const_iterator
;
328 _M_variant
._M_iterator
._M_state
= __it
? __unknown_state
: __singular
;
329 _M_variant
._M_iterator
._M_sequence
= 0;
330 _M_variant
._M_iterator
._M_seq_type
= 0;
333 template<typename _Type
>
334 _Parameter(_Type
* const& __it
, const char* __name
, _Is_iterator
)
335 : _M_kind(__iterator
), _M_variant()
337 _M_variant
._M_iterator
._M_name
= __name
;
338 _M_variant
._M_iterator
._M_address
= std::__addressof(__it
);
339 _M_variant
._M_iterator
._M_type
= _GLIBCXX_TYPEID(__it
);
340 _M_variant
._M_iterator
._M_constness
= __mutable_iterator
;
341 _M_variant
._M_iterator
._M_state
= __it
? __unknown_state
: __singular
;
342 _M_variant
._M_iterator
._M_sequence
= 0;
343 _M_variant
._M_iterator
._M_seq_type
= 0;
346 template<typename _Iterator
>
347 _Parameter(_Iterator
const& __it
, const char* __name
, _Is_iterator
)
348 : _M_kind(__iterator
), _M_variant()
350 _M_variant
._M_iterator
._M_name
= __name
;
351 _M_variant
._M_iterator
._M_address
= std::__addressof(__it
);
352 _M_variant
._M_iterator
._M_type
= _GLIBCXX_TYPEID(__it
);
353 _M_variant
._M_iterator
._M_constness
= __unknown_constness
;
354 _M_variant
._M_iterator
._M_state
=
355 __gnu_debug::__check_singular(__it
) ? __singular
: __unknown_state
;
356 _M_variant
._M_iterator
._M_sequence
= 0;
357 _M_variant
._M_iterator
._M_seq_type
= 0;
360 #if __cplusplus >= 201103L
361 // The following constructors are only defined in C++11 to take
362 // advantage of the constructor delegation feature.
363 template<typename _Iterator
, typename _Container
>
365 __gnu_cxx::__normal_iterator
<_Iterator
, _Container
> const& __it
,
366 const char* __name
, _Is_iterator
)
367 : _Parameter(__it
.base(), __name
, _Is_iterator
{})
368 { _M_variant
._M_iterator
._M_type
= _GLIBCXX_TYPEID(__it
); }
370 template<typename _Iterator
>
371 _Parameter(std::reverse_iterator
<_Iterator
> const& __it
,
372 const char* __name
, _Is_iterator
)
373 : _Parameter(__it
.base(), __name
, _Is_iterator
{})
375 _M_variant
._M_iterator
._M_type
= _GLIBCXX_TYPEID(__it
);
376 _M_variant
._M_iterator
._M_state
377 = _S_reverse_state(_M_variant
._M_iterator
._M_state
);
380 template<typename _Iterator
, typename _Sequence
, typename _Category
>
381 _Parameter(std::reverse_iterator
<_Safe_iterator
<_Iterator
, _Sequence
,
382 _Category
>> const& __it
,
383 const char* __name
, _Is_iterator
)
384 : _Parameter(__it
.base(), __name
, _Is_iterator
{})
386 _M_variant
._M_iterator
._M_type
387 = _GLIBCXX_TYPEID(std::reverse_iterator
<_Iterator
>);
388 _M_variant
._M_iterator
._M_state
389 = _S_reverse_state(_M_variant
._M_iterator
._M_state
);
392 template<typename _Iterator
>
393 _Parameter(std::move_iterator
<_Iterator
> const& __it
,
394 const char* __name
, _Is_iterator
)
395 : _Parameter(__it
.base(), __name
, _Is_iterator
{})
396 { _M_variant
._M_iterator
._M_type
= _GLIBCXX_TYPEID(__it
); }
398 template<typename _Iterator
, typename _Sequence
, typename _Category
>
399 _Parameter(std::move_iterator
<_Safe_iterator
<_Iterator
, _Sequence
,
400 _Category
>> const& __it
,
401 const char* __name
, _Is_iterator
)
402 : _Parameter(__it
.base(), __name
, _Is_iterator
{})
404 _M_variant
._M_iterator
._M_type
405 = _GLIBCXX_TYPEID(std::move_iterator
<_Iterator
>);
410 _S_reverse_state(_Iterator_state __state
)
428 template<typename _Sequence
>
429 _Parameter(const _Safe_sequence
<_Sequence
>& __seq
,
430 const char* __name
, _Is_sequence
)
431 : _M_kind(__sequence
), _M_variant()
433 _M_variant
._M_sequence
._M_name
= __name
;
434 _M_variant
._M_sequence
._M_address
=
435 static_cast<const _Sequence
*>(std::__addressof(__seq
));
436 _M_variant
._M_sequence
._M_type
= _GLIBCXX_TYPEID(_Sequence
);
439 template<typename _Sequence
>
440 _Parameter(const _Sequence
& __seq
, const char* __name
, _Is_sequence
)
441 : _M_kind(__sequence
), _M_variant()
443 _M_variant
._M_sequence
._M_name
= __name
;
444 _M_variant
._M_sequence
._M_address
= std::__addressof(__seq
);
445 _M_variant
._M_sequence
._M_type
= _GLIBCXX_TYPEID(_Sequence
);
448 template<typename _Iterator
>
449 _Parameter(const _Iterator
& __it
, const char* __name
,
450 _Is_iterator_value_type
)
451 : _M_kind(__iterator_value_type
), _M_variant()
453 _M_variant
._M_iterator_value_type
._M_name
= __name
;
454 _M_variant
._M_iterator_value_type
._M_type
=
455 _GLIBCXX_TYPEID(typename
std::iterator_traits
<_Iterator
>::value_type
);
458 template<typename _Type
>
459 _Parameter(const _Type
& __inst
, const char* __name
, _Is_instance
)
460 : _M_kind(__instance
), _M_variant()
462 _M_variant
._M_instance
._M_name
= __name
;
463 _M_variant
._M_instance
._M_address
= &__inst
;
464 _M_variant
._M_instance
._M_type
= _GLIBCXX_TYPEID(_Type
);
467 #if !_GLIBCXX_INLINE_VERSION
469 _M_print_field(const _Error_formatter
* __formatter
,
470 const char* __name
) const _GLIBCXX_DEPRECATED
;
473 _M_print_description(const _Error_formatter
* __formatter
)
474 const _GLIBCXX_DEPRECATED
;
478 template<typename _Iterator
>
480 _M_iterator(const _Iterator
& __it
, const char* __name
= 0)
482 if (_M_num_parameters
< std::size_t(__max_parameters
))
483 _M_parameters
[_M_num_parameters
++] = _Parameter(__it
, __name
,
488 template<typename _Iterator
>
490 _M_iterator_value_type(const _Iterator
& __it
,
491 const char* __name
= 0)
493 if (_M_num_parameters
< __max_parameters
)
494 _M_parameters
[_M_num_parameters
++] =
495 _Parameter(__it
, __name
, _Is_iterator_value_type());
500 _M_integer(long __value
, const char* __name
= 0)
502 if (_M_num_parameters
< __max_parameters
)
503 _M_parameters
[_M_num_parameters
++] = _Parameter(__value
, __name
);
508 _M_string(const char* __value
, const char* __name
= 0)
510 if (_M_num_parameters
< __max_parameters
)
511 _M_parameters
[_M_num_parameters
++] = _Parameter(__value
, __name
);
515 template<typename _Sequence
>
517 _M_sequence(const _Sequence
& __seq
, const char* __name
= 0)
519 if (_M_num_parameters
< __max_parameters
)
520 _M_parameters
[_M_num_parameters
++] = _Parameter(__seq
, __name
,
525 template<typename _Type
>
527 _M_instance(const _Type
& __inst
, const char* __name
= 0)
529 if (_M_num_parameters
< __max_parameters
)
530 _M_parameters
[_M_num_parameters
++] = _Parameter(__inst
, __name
,
536 _M_message(const char* __text
)
537 { _M_text
= __text
; return *this; }
539 // Kept const qualifier for backward compatibility, to keep the same
542 _M_message(_Debug_msg_id __id
) const throw ();
544 _GLIBCXX_NORETURN
void
547 #if !_GLIBCXX_INLINE_VERSION
548 template<typename _Tp
>
550 _M_format_word(char*, int, const char*, _Tp
)
551 const throw () _GLIBCXX_DEPRECATED
;
554 _M_print_word(const char* __word
) const _GLIBCXX_DEPRECATED
;
557 _M_print_string(const char* __string
) const _GLIBCXX_DEPRECATED
;
561 _Error_formatter(const char* __file
, unsigned int __line
,
562 const char* __function
)
563 : _M_file(__file
), _M_line(__line
), _M_num_parameters(0), _M_text(0)
564 , _M_function(__function
)
567 #if !_GLIBCXX_INLINE_VERSION
569 _M_get_max_length() const throw () _GLIBCXX_DEPRECATED
;
572 enum { __max_parameters
= 9 };
575 unsigned int _M_line
;
576 _Parameter _M_parameters
[__max_parameters
];
577 unsigned int _M_num_parameters
;
579 const char* _M_function
;
582 static _Error_formatter
&
583 _S_at(const char* __file
, unsigned int __line
, const char* __function
)
585 static _Error_formatter
__formatter(__file
, __line
, __function
);
589 } // namespace __gnu_debug
591 #undef _GLIBCXX_TYPEID