00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
#ifndef _GLIBCXX_DEBUG_FORMATTER_H
00032
#define _GLIBCXX_DEBUG_FORMATTER_H 1
00033
00034
#include <typeinfo>
00035
#include <debug/debug.h>
00036
00037
namespace __gnu_debug
00038 {
00039
using std::type_info;
00040
00041
00042
template<
typename _Type1,
typename _Type2>
00043 struct __is_same
00044 {
00045
static const bool value =
false;
00046 };
00047
00048
template<
typename _Type>
00049
struct __is_same<_Type, _Type>
00050 {
00051
static const bool value =
true;
00052 };
00053
00054
template<
bool>
struct __truth { };
00055
00056
class _Safe_sequence_base;
00057
00058
template<
typename _Iterator,
typename _Sequence>
00059
class _Safe_iterator;
00060
00061
template<
typename _Sequence>
00062
class _Safe_sequence;
00063
00064
enum _Debug_msg_id
00065 {
00066
00067 __msg_valid_range,
00068 __msg_insert_singular,
00069 __msg_insert_different,
00070 __msg_erase_bad,
00071 __msg_erase_different,
00072 __msg_subscript_oob,
00073 __msg_empty,
00074 __msg_unpartitioned,
00075 __msg_unpartitioned_pred,
00076 __msg_unsorted,
00077 __msg_unsorted_pred,
00078 __msg_not_heap,
00079 __msg_not_heap_pred,
00080
00081 __msg_bad_bitset_write,
00082 __msg_bad_bitset_read,
00083 __msg_bad_bitset_flip,
00084
00085 __msg_self_splice,
00086 __msg_splice_alloc,
00087 __msg_splice_bad,
00088 __msg_splice_other,
00089 __msg_splice_overlap,
00090
00091 __msg_init_singular,
00092 __msg_init_copy_singular,
00093 __msg_init_const_singular,
00094 __msg_copy_singular,
00095 __msg_bad_deref,
00096 __msg_bad_inc,
00097 __msg_bad_dec,
00098 __msg_iter_subscript_oob,
00099 __msg_advance_oob,
00100 __msg_retreat_oob,
00101 __msg_iter_compare_bad,
00102 __msg_compare_different,
00103 __msg_iter_order_bad,
00104 __msg_order_different,
00105 __msg_distance_bad,
00106 __msg_distance_different,
00107
00108 __msg_deref_istream,
00109 __msg_inc_istream,
00110
00111 __msg_output_ostream,
00112
00113 __msg_deref_istreambuf,
00114 __msg_inc_istreambuf
00115 };
00116
00117
class _Error_formatter
00118 {
00119
00120
enum _Constness
00121 {
00122 __unknown_constness,
00123 __const_iterator,
00124 __mutable_iterator,
00125 __last_constness
00126 };
00127
00128
00129
enum _Iterator_state
00130 {
00131 __unknown_state,
00132 __singular,
00133 __begin,
00134 __middle,
00135 __end,
00136 __last_state
00137 };
00138
00139
00140
struct _Is_iterator { };
00141
struct _Is_sequence { };
00142
00143
00144
struct _Parameter
00145 {
00146
enum
00147 {
00148 __unused_param,
00149 __iterator,
00150 __sequence,
00151 __integer,
00152 __string
00153 } _M_kind;
00154
00155
union
00156
{
00157
00158
struct
00159
{
00160
const char* _M_name;
00161
const void* _M_address;
00162
const type_info* _M_type;
00163 _Constness _M_constness;
00164 _Iterator_state _M_state;
00165
const void* _M_sequence;
00166
const type_info* _M_seq_type;
00167 } _M_iterator;
00168
00169
00170
struct
00171
{
00172
const char* _M_name;
00173
const void* _M_address;
00174
const type_info* _M_type;
00175 } _M_sequence;
00176
00177
00178
struct
00179
{
00180
const char* _M_name;
00181
long _M_value;
00182 } _M_integer;
00183
00184
00185
struct
00186
{
00187
const char* _M_name;
00188
const char* _M_value;
00189 } _M_string;
00190 } _M_variant;
00191
00192 _Parameter() : _M_kind(__unused_param), _M_variant() { }
00193
00194 _Parameter(
long __value,
const char* __name)
00195 : _M_kind(__integer), _M_variant()
00196 {
00197 _M_variant._M_integer._M_name = __name;
00198 _M_variant._M_integer._M_value = __value;
00199 }
00200
00201 _Parameter(
const char* __value,
const char* __name)
00202 : _M_kind(__string), _M_variant()
00203 {
00204 _M_variant._M_string._M_name = __name;
00205 _M_variant._M_string._M_value = __value;
00206 }
00207
00208
template<
typename _Iterator,
typename _Sequence>
00209 _Parameter(
const _Safe_iterator<_Iterator, _Sequence>& __it,
00210
const char* __name, _Is_iterator)
00211 : _M_kind(__iterator), _M_variant()
00212 {
00213 _M_variant._M_iterator._M_name = __name;
00214 _M_variant._M_iterator._M_address = &__it;
00215 _M_variant._M_iterator._M_type = &
typeid(__it);
00216 _M_variant._M_iterator._M_constness =
00217 __is_same<_Safe_iterator<_Iterator, _Sequence>,
00218
typename _Sequence::iterator>::
00219 value? __mutable_iterator : __const_iterator;
00220 _M_variant._M_iterator._M_sequence = __it._M_get_sequence();
00221 _M_variant._M_iterator._M_seq_type = &
typeid(_Sequence);
00222
00223
if (__it._M_singular())
00224 _M_variant._M_iterator._M_state = __singular;
00225
else
00226 {
00227
bool __is_begin = __it._M_is_begin();
00228
bool __is_end = __it._M_is_end();
00229
if (__is_end)
00230 _M_variant._M_iterator._M_state = __end;
00231
else if (__is_begin)
00232 _M_variant._M_iterator._M_state = __begin;
00233
else
00234 _M_variant._M_iterator._M_state = __middle;
00235 }
00236 }
00237
00238
template<
typename _Type>
00239 _Parameter(
const _Type*& __it,
const char* __name, _Is_iterator)
00240 : _M_kind(__iterator), _M_variant()
00241 {
00242 _M_variant._M_iterator._M_name = __name;
00243 _M_variant._M_iterator._M_address = &__it;
00244 _M_variant._M_iterator._M_type = &
typeid(__it);
00245 _M_variant._M_iterator._M_constness = __mutable_iterator;
00246 _M_variant._M_iterator._M_state = __it? __unknown_state : __singular;
00247 _M_variant._M_iterator._M_sequence = 0;
00248 _M_variant._M_iterator._M_seq_type = 0;
00249 }
00250
00251
template<
typename _Type>
00252 _Parameter(_Type*& __it,
const char* __name, _Is_iterator)
00253 : _M_kind(__iterator), _M_variant()
00254 {
00255 _M_variant._M_iterator._M_name = __name;
00256 _M_variant._M_iterator._M_address = &__it;
00257 _M_variant._M_iterator._M_type = &
typeid(__it);
00258 _M_variant._M_iterator._M_constness = __const_iterator;
00259 _M_variant._M_iterator._M_state = __it? __unknown_state : __singular;
00260 _M_variant._M_iterator._M_sequence = 0;
00261 _M_variant._M_iterator._M_seq_type = 0;
00262 }
00263
00264
template<
typename _Iterator>
00265 _Parameter(
const _Iterator& __it,
const char* __name, _Is_iterator)
00266 : _M_kind(__iterator), _M_variant()
00267 {
00268 _M_variant._M_iterator._M_name = __name;
00269 _M_variant._M_iterator._M_address = &__it;
00270 _M_variant._M_iterator._M_type = &
typeid(__it);
00271 _M_variant._M_iterator._M_constness = __unknown_constness;
00272 _M_variant._M_iterator._M_state =
00273 __gnu_debug::__check_singular(__it)? __singular : __unknown_state;
00274 _M_variant._M_iterator._M_sequence = 0;
00275 _M_variant._M_iterator._M_seq_type = 0;
00276 }
00277
00278
template<
typename _Sequence>
00279 _Parameter(
const _Safe_sequence<_Sequence>& __seq,
00280
const char* __name, _Is_sequence)
00281 : _M_kind(__sequence), _M_variant()
00282 {
00283 _M_variant._M_sequence._M_name = __name;
00284 _M_variant._M_sequence._M_address =
00285 static_cast<const _Sequence*>(&__seq);
00286 _M_variant._M_sequence._M_type = &
typeid(_Sequence);
00287 }
00288
00289
template<
typename _Sequence>
00290 _Parameter(
const _Sequence& __seq,
const char* __name, _Is_sequence)
00291 : _M_kind(__sequence), _M_variant()
00292 {
00293 _M_variant._M_sequence._M_name = __name;
00294 _M_variant._M_sequence._M_address = &__seq;
00295 _M_variant._M_sequence._M_type = &
typeid(_Sequence);
00296 }
00297
00298
void
00299 _M_print_field(
const _Error_formatter* __formatter,
00300
const char* __name)
const;
00301
00302
void
00303 _M_print_description(
const _Error_formatter* __formatter)
const;
00304 };
00305
00306
friend struct _Parameter;
00307
00308
public:
00309
template<
typename _Iterator>
00310
const _Error_formatter&
00311 _M_iterator(
const _Iterator& __it,
const char* __name = 0)
const
00312 {
00313
if (_M_num_parameters < __max_parameters)
00314 _M_parameters[_M_num_parameters++] = _Parameter(__it, __name,
00315 _Is_iterator());
00316
return *
this;
00317 }
00318
00319
const _Error_formatter&
00320 _M_integer(
long __value,
const char* __name = 0)
const
00321
{
00322
if (_M_num_parameters < __max_parameters)
00323 _M_parameters[_M_num_parameters++] = _Parameter(__value, __name);
00324
return *
this;
00325 }
00326
00327
const _Error_formatter&
00328 _M_string(
const char* __value,
const char* __name = 0)
const
00329
{
00330
if (_M_num_parameters < __max_parameters)
00331 _M_parameters[_M_num_parameters++] = _Parameter(__value, __name);
00332
return *
this;
00333 }
00334
00335
template<
typename _Sequence>
00336
const _Error_formatter&
00337 _M_sequence(
const _Sequence& __seq,
const char* __name = 0)
const
00338
{
00339
if (_M_num_parameters < __max_parameters)
00340 _M_parameters[_M_num_parameters++] = _Parameter(__seq, __name,
00341 _Is_sequence());
00342
return *
this;
00343 }
00344
00345
const _Error_formatter&
00346 _M_message(
const char* __text)
const
00347
{ _M_text = __text;
return *
this; }
00348
00349
const _Error_formatter&
00350 _M_message(_Debug_msg_id __id)
const;
00351
00352
void
00353 _M_error() const;
00354
00355 private:
00356 _Error_formatter(const
char* __file, size_t __line)
00357 : _M_file(__file), _M_line(__line), _M_num_parameters(0), _M_text(0),
00358 _M_max_length(78), _M_column(1), _M_first_line(true), _M_wordwrap(false)
00359 { }
00360
00361
template<
typename _Tp>
00362
void
00363 _M_format_word(
char*,
int,
const char*, _Tp) const;
00364
00365
void
00366 _M_print_word(const
char* __word) const;
00367
00368
void
00369 _M_print_string(const
char* __string) const;
00370
00371 enum { __max_parameters = 9 };
00372
00373
const char* _M_file;
00374 size_t _M_line;
00375
mutable _Parameter _M_parameters[__max_parameters];
00376
mutable size_t _M_num_parameters;
00377
mutable const char* _M_text;
00378
mutable size_t _M_max_length;
00379
enum { _M_indent = 4 } ;
00380
mutable size_t _M_column;
00381
mutable bool _M_first_line;
00382
mutable bool _M_wordwrap;
00383
00384
public:
00385
static _Error_formatter
00386 _M_at(
const char* __file, size_t __line)
00387 {
return _Error_formatter(__file, __line); }
00388 };
00389 }
00390
00391
#endif