]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/debug/formatter.h
configure.ac: Add --enable-build-poststage1-with-cxx.
[thirdparty/gcc.git] / libstdc++-v3 / include / debug / formatter.h
CommitLineData
285b36d6
BK
1// Debug-mode error formatting implementation -*- C++ -*-
2
d652f226 3// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
0f136367 4// Free Software Foundation, Inc.
285b36d6
BK
5//
6// This file is part of the GNU ISO C++ Library. This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
748086b7 9// Free Software Foundation; either version 3, or (at your option)
285b36d6
BK
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16
748086b7
JJ
17// Under Section 7 of GPL version 3, you are granted additional
18// permissions described in the GCC Runtime Library Exception, version
19// 3.1, as published by the Free Software Foundation.
285b36d6 20
748086b7
JJ
21// You should have received a copy of the GNU General Public License and
22// a copy of the GCC Runtime Library Exception along with this program;
23// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24// <http://www.gnu.org/licenses/>.
285b36d6 25
78a53887
BK
26/** @file debug/formatter.h
27 * This file is a GNU debug extension to the Standard C++ Library.
28 */
29
285b36d6
BK
30#ifndef _GLIBCXX_DEBUG_FORMATTER_H
31#define _GLIBCXX_DEBUG_FORMATTER_H 1
32
b8add594 33#include <bits/c++config.h>
67c495be 34#include <bits/cpp_type_traits.h>
285b36d6 35#include <typeinfo>
285b36d6
BK
36
37namespace __gnu_debug
38{
45f388bb
BK
39 using std::type_info;
40
1f5ca1a1
PC
41 template<typename _Iterator>
42 bool __check_singular(_Iterator&);
43
285b36d6
BK
44 class _Safe_sequence_base;
45
526da49c 46 template<typename _Iterator, typename _Sequence>
285b36d6
BK
47 class _Safe_iterator;
48
526da49c 49 template<typename _Sequence>
285b36d6
BK
50 class _Safe_sequence;
51
52 enum _Debug_msg_id
53 {
54 // General checks
55 __msg_valid_range,
56 __msg_insert_singular,
57 __msg_insert_different,
58 __msg_erase_bad,
59 __msg_erase_different,
60 __msg_subscript_oob,
61 __msg_empty,
62 __msg_unpartitioned,
63 __msg_unpartitioned_pred,
64 __msg_unsorted,
65 __msg_unsorted_pred,
66 __msg_not_heap,
67 __msg_not_heap_pred,
68 // std::bitset checks
69 __msg_bad_bitset_write,
70 __msg_bad_bitset_read,
71 __msg_bad_bitset_flip,
72 // std::list checks
73 __msg_self_splice,
74 __msg_splice_alloc,
75 __msg_splice_bad,
76 __msg_splice_other,
77 __msg_splice_overlap,
78 // iterator checks
79 __msg_init_singular,
80 __msg_init_copy_singular,
81 __msg_init_const_singular,
82 __msg_copy_singular,
83 __msg_bad_deref,
84 __msg_bad_inc,
85 __msg_bad_dec,
86 __msg_iter_subscript_oob,
87 __msg_advance_oob,
88 __msg_retreat_oob,
89 __msg_iter_compare_bad,
90 __msg_compare_different,
91 __msg_iter_order_bad,
92 __msg_order_different,
93 __msg_distance_bad,
94 __msg_distance_different,
95 // istream_iterator
96 __msg_deref_istream,
97 __msg_inc_istream,
98 // ostream_iterator
99 __msg_output_ostream,
100 // istreambuf_iterator
101 __msg_deref_istreambuf,
b8b4301e
PC
102 __msg_inc_istreambuf,
103 // forward_list
104 __msg_insert_after_end,
105 __msg_erase_after_bad,
106 __msg_valid_range2
285b36d6
BK
107 };
108
109 class _Error_formatter
110 {
111 /// Whether an iterator is constant, mutable, or unknown
112 enum _Constness
113 {
114 __unknown_constness,
115 __const_iterator,
116 __mutable_iterator,
117 __last_constness
526da49c 118 };
285b36d6
BK
119
120 // The state of the iterator (fine-grained), if we know it.
121 enum _Iterator_state
122 {
123 __unknown_state,
124 __singular, // singular, may still be attached to a sequence
125 __begin, // dereferenceable, and at the beginning
126 __middle, // dereferenceable, not at the beginning
127 __end, // past-the-end, may be at beginning if sequence empty
b8b4301e 128 __before_begin, // before begin
285b36d6
BK
129 __last_state
130 };
131
132 // Tags denoting the type of parameter for construction
133 struct _Is_iterator { };
134 struct _Is_sequence { };
135
136 // A parameter that may be referenced by an error message
137 struct _Parameter
138 {
526da49c
BI
139 enum
140 {
141 __unused_param,
142 __iterator,
143 __sequence,
285b36d6
BK
144 __integer,
145 __string
146 } _M_kind;
526da49c 147
285b36d6
BK
148 union
149 {
150 // When _M_kind == __iterator
526da49c 151 struct
285b36d6 152 {
526da49c
BI
153 const char* _M_name;
154 const void* _M_address;
155 const type_info* _M_type;
285b36d6
BK
156 _Constness _M_constness;
157 _Iterator_state _M_state;
526da49c 158 const void* _M_sequence;
285b36d6
BK
159 const type_info* _M_seq_type;
160 } _M_iterator;
526da49c 161
285b36d6
BK
162 // When _M_kind == __sequence
163 struct
164 {
165 const char* _M_name;
166 const void* _M_address;
167 const type_info* _M_type;
168 } _M_sequence;
169
170 // When _M_kind == __integer
171 struct
172 {
173 const char* _M_name;
174 long _M_value;
175 } _M_integer;
176
177 // When _M_kind == __string
178 struct
179 {
180 const char* _M_name;
181 const char* _M_value;
182 } _M_string;
183 } _M_variant;
184
26c691a8 185 _Parameter() : _M_kind(__unused_param), _M_variant() { }
526da49c 186
26c691a8
BK
187 _Parameter(long __value, const char* __name)
188 : _M_kind(__integer), _M_variant()
526da49c 189 {
285b36d6 190 _M_variant._M_integer._M_name = __name;
526da49c 191 _M_variant._M_integer._M_value = __value;
285b36d6
BK
192 }
193
26c691a8
BK
194 _Parameter(const char* __value, const char* __name)
195 : _M_kind(__string), _M_variant()
285b36d6
BK
196 {
197 _M_variant._M_string._M_name = __name;
526da49c 198 _M_variant._M_string._M_value = __value;
285b36d6
BK
199 }
200
201 template<typename _Iterator, typename _Sequence>
202 _Parameter(const _Safe_iterator<_Iterator, _Sequence>& __it,
203 const char* __name, _Is_iterator)
26c691a8 204 : _M_kind(__iterator), _M_variant()
285b36d6
BK
205 {
206 _M_variant._M_iterator._M_name = __name;
207 _M_variant._M_iterator._M_address = &__it;
0f136367 208#ifdef __GXX_RTTI
285b36d6 209 _M_variant._M_iterator._M_type = &typeid(__it);
0f136367
PC
210#else
211 _M_variant._M_iterator._M_type = 0;
212#endif
526da49c 213 _M_variant._M_iterator._M_constness =
67c495be
PC
214 std::__are_same<_Safe_iterator<_Iterator, _Sequence>,
215 typename _Sequence::iterator>::
216 __value ? __mutable_iterator : __const_iterator;
285b36d6 217 _M_variant._M_iterator._M_sequence = __it._M_get_sequence();
0f136367 218#ifdef __GXX_RTTI
285b36d6 219 _M_variant._M_iterator._M_seq_type = &typeid(_Sequence);
0f136367
PC
220#else
221 _M_variant._M_iterator._M_seq_type = 0;
222#endif
285b36d6
BK
223
224 if (__it._M_singular())
225 _M_variant._M_iterator._M_state = __singular;
226 else
227 {
b8b4301e
PC
228 if (__it._M_is_before_begin())
229 _M_variant._M_iterator._M_state = __before_begin;
230 else if (__it._M_is_end())
285b36d6 231 _M_variant._M_iterator._M_state = __end;
b8b4301e 232 else if (__it._M_is_begin())
285b36d6
BK
233 _M_variant._M_iterator._M_state = __begin;
234 else
235 _M_variant._M_iterator._M_state = __middle;
236 }
237 }
238
239 template<typename _Type>
240 _Parameter(const _Type*& __it, const char* __name, _Is_iterator)
26c691a8 241 : _M_kind(__iterator), _M_variant()
285b36d6
BK
242 {
243 _M_variant._M_iterator._M_name = __name;
244 _M_variant._M_iterator._M_address = &__it;
0f136367 245#ifdef __GXX_RTTI
285b36d6 246 _M_variant._M_iterator._M_type = &typeid(__it);
0f136367
PC
247#else
248 _M_variant._M_iterator._M_type = 0;
249#endif
285b36d6
BK
250 _M_variant._M_iterator._M_constness = __mutable_iterator;
251 _M_variant._M_iterator._M_state = __it? __unknown_state : __singular;
252 _M_variant._M_iterator._M_sequence = 0;
253 _M_variant._M_iterator._M_seq_type = 0;
254 }
255
256 template<typename _Type>
257 _Parameter(_Type*& __it, const char* __name, _Is_iterator)
26c691a8 258 : _M_kind(__iterator), _M_variant()
285b36d6
BK
259 {
260 _M_variant._M_iterator._M_name = __name;
261 _M_variant._M_iterator._M_address = &__it;
0f136367 262#ifdef __GXX_RTTI
285b36d6 263 _M_variant._M_iterator._M_type = &typeid(__it);
0f136367
PC
264#else
265 _M_variant._M_iterator._M_type = 0;
266#endif
285b36d6
BK
267 _M_variant._M_iterator._M_constness = __const_iterator;
268 _M_variant._M_iterator._M_state = __it? __unknown_state : __singular;
269 _M_variant._M_iterator._M_sequence = 0;
270 _M_variant._M_iterator._M_seq_type = 0;
271 }
526da49c 272
285b36d6
BK
273 template<typename _Iterator>
274 _Parameter(const _Iterator& __it, const char* __name, _Is_iterator)
26c691a8 275 : _M_kind(__iterator), _M_variant()
285b36d6
BK
276 {
277 _M_variant._M_iterator._M_name = __name;
278 _M_variant._M_iterator._M_address = &__it;
0f136367 279#ifdef __GXX_RTTI
285b36d6 280 _M_variant._M_iterator._M_type = &typeid(__it);
0f136367
PC
281#else
282 _M_variant._M_iterator._M_type = 0;
283#endif
285b36d6 284 _M_variant._M_iterator._M_constness = __unknown_constness;
526da49c 285 _M_variant._M_iterator._M_state =
285b36d6
BK
286 __gnu_debug::__check_singular(__it)? __singular : __unknown_state;
287 _M_variant._M_iterator._M_sequence = 0;
288 _M_variant._M_iterator._M_seq_type = 0;
289 }
290
291 template<typename _Sequence>
526da49c 292 _Parameter(const _Safe_sequence<_Sequence>& __seq,
285b36d6 293 const char* __name, _Is_sequence)
26c691a8 294 : _M_kind(__sequence), _M_variant()
285b36d6
BK
295 {
296 _M_variant._M_sequence._M_name = __name;
526da49c 297 _M_variant._M_sequence._M_address =
285b36d6 298 static_cast<const _Sequence*>(&__seq);
0f136367 299#ifdef __GXX_RTTI
285b36d6 300 _M_variant._M_sequence._M_type = &typeid(_Sequence);
0f136367
PC
301#else
302 _M_variant._M_sequence._M_type = 0;
303#endif
285b36d6
BK
304 }
305
306 template<typename _Sequence>
307 _Parameter(const _Sequence& __seq, const char* __name, _Is_sequence)
26c691a8 308 : _M_kind(__sequence), _M_variant()
285b36d6
BK
309 {
310 _M_variant._M_sequence._M_name = __name;
311 _M_variant._M_sequence._M_address = &__seq;
0f136367 312#ifdef __GXX_RTTI
285b36d6 313 _M_variant._M_sequence._M_type = &typeid(_Sequence);
0f136367
PC
314#else
315 _M_variant._M_sequence._M_type = 0;
316#endif
285b36d6 317 }
526da49c 318
285b36d6 319 void
526da49c 320 _M_print_field(const _Error_formatter* __formatter,
285b36d6 321 const char* __name) const;
526da49c 322
285b36d6
BK
323 void
324 _M_print_description(const _Error_formatter* __formatter) const;
325 };
326
327 friend struct _Parameter;
328
526da49c 329 public:
285b36d6
BK
330 template<typename _Iterator>
331 const _Error_formatter&
332 _M_iterator(const _Iterator& __it, const char* __name = 0) const
333 {
8fc81078 334 if (_M_num_parameters < std::size_t(__max_parameters))
285b36d6
BK
335 _M_parameters[_M_num_parameters++] = _Parameter(__it, __name,
336 _Is_iterator());
337 return *this;
338 }
339
340 const _Error_formatter&
341 _M_integer(long __value, const char* __name = 0) const
342 {
8fc81078 343 if (_M_num_parameters < std::size_t(__max_parameters))
285b36d6
BK
344 _M_parameters[_M_num_parameters++] = _Parameter(__value, __name);
345 return *this;
346 }
347
348 const _Error_formatter&
349 _M_string(const char* __value, const char* __name = 0) const
350 {
8fc81078 351 if (_M_num_parameters < std::size_t(__max_parameters))
285b36d6
BK
352 _M_parameters[_M_num_parameters++] = _Parameter(__value, __name);
353 return *this;
354 }
355
356 template<typename _Sequence>
357 const _Error_formatter&
358 _M_sequence(const _Sequence& __seq, const char* __name = 0) const
359 {
8fc81078 360 if (_M_num_parameters < std::size_t(__max_parameters))
526da49c 361 _M_parameters[_M_num_parameters++] = _Parameter(__seq, __name,
285b36d6
BK
362 _Is_sequence());
363 return *this;
364 }
365
366 const _Error_formatter&
367 _M_message(const char* __text) const
368 { _M_text = __text; return *this; }
369
370 const _Error_formatter&
5d51b87a 371 _M_message(_Debug_msg_id __id) const throw ();
285b36d6 372
b8add594 373 _GLIBCXX_NORETURN void
285b36d6
BK
374 _M_error() const;
375
376 private:
8fc81078 377 _Error_formatter(const char* __file, std::size_t __line)
285b36d6
BK
378 : _M_file(__file), _M_line(__line), _M_num_parameters(0), _M_text(0),
379 _M_max_length(78), _M_column(1), _M_first_line(true), _M_wordwrap(false)
5dddb7e5 380 { _M_get_max_length(); }
285b36d6 381
9dc420e6 382 template<typename _Tp>
4be58168 383 void
5d51b87a 384 _M_format_word(char*, int, const char*, _Tp) const throw ();
4be58168 385
526da49c 386 void
285b36d6
BK
387 _M_print_word(const char* __word) const;
388
526da49c 389 void
285b36d6
BK
390 _M_print_string(const char* __string) const;
391
5dddb7e5 392 void
5d51b87a 393 _M_get_max_length() const throw ();
5dddb7e5 394
285b36d6
BK
395 enum { __max_parameters = 9 };
396
397 const char* _M_file;
8fc81078 398 std::size_t _M_line;
285b36d6 399 mutable _Parameter _M_parameters[__max_parameters];
8fc81078 400 mutable std::size_t _M_num_parameters;
285b36d6 401 mutable const char* _M_text;
8fc81078 402 mutable std::size_t _M_max_length;
285b36d6 403 enum { _M_indent = 4 } ;
8fc81078 404 mutable std::size_t _M_column;
285b36d6
BK
405 mutable bool _M_first_line;
406 mutable bool _M_wordwrap;
407
408 public:
409 static _Error_formatter
8fc81078 410 _M_at(const char* __file, std::size_t __line)
285b36d6
BK
411 { return _Error_formatter(__file, __line); }
412 };
413} // namespace __gnu_debug
414
526da49c 415#endif