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