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 #ifndef _GLIBCXX_DEBUG_FORMATTER_H
00031 #define _GLIBCXX_DEBUG_FORMATTER_H 1
00032
00033 #include <bits/c++config.h>
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 #ifdef __GXX_RTTI
00216 _M_variant._M_iterator._M_type = &typeid(__it);
00217 #else
00218 _M_variant._M_iterator._M_type = 0;
00219 #endif
00220 _M_variant._M_iterator._M_constness =
00221 __is_same<_Safe_iterator<_Iterator, _Sequence>,
00222 typename _Sequence::iterator>::
00223 value? __mutable_iterator : __const_iterator;
00224 _M_variant._M_iterator._M_sequence = __it._M_get_sequence();
00225 #ifdef __GXX_RTTI
00226 _M_variant._M_iterator._M_seq_type = &typeid(_Sequence);
00227 #else
00228 _M_variant._M_iterator._M_seq_type = 0;
00229 #endif
00230
00231 if (__it._M_singular())
00232 _M_variant._M_iterator._M_state = __singular;
00233 else
00234 {
00235 bool __is_begin = __it._M_is_begin();
00236 bool __is_end = __it._M_is_end();
00237 if (__is_end)
00238 _M_variant._M_iterator._M_state = __end;
00239 else if (__is_begin)
00240 _M_variant._M_iterator._M_state = __begin;
00241 else
00242 _M_variant._M_iterator._M_state = __middle;
00243 }
00244 }
00245
00246 template<typename _Type>
00247 _Parameter(const _Type*& __it, const char* __name, _Is_iterator)
00248 : _M_kind(__iterator), _M_variant()
00249 {
00250 _M_variant._M_iterator._M_name = __name;
00251 _M_variant._M_iterator._M_address = &__it;
00252 #ifdef __GXX_RTTI
00253 _M_variant._M_iterator._M_type = &typeid(__it);
00254 #else
00255 _M_variant._M_iterator._M_type = 0;
00256 #endif
00257 _M_variant._M_iterator._M_constness = __mutable_iterator;
00258 _M_variant._M_iterator._M_state = __it? __unknown_state : __singular;
00259 _M_variant._M_iterator._M_sequence = 0;
00260 _M_variant._M_iterator._M_seq_type = 0;
00261 }
00262
00263 template<typename _Type>
00264 _Parameter(_Type*& __it, const char* __name, _Is_iterator)
00265 : _M_kind(__iterator), _M_variant()
00266 {
00267 _M_variant._M_iterator._M_name = __name;
00268 _M_variant._M_iterator._M_address = &__it;
00269 #ifdef __GXX_RTTI
00270 _M_variant._M_iterator._M_type = &typeid(__it);
00271 #else
00272 _M_variant._M_iterator._M_type = 0;
00273 #endif
00274 _M_variant._M_iterator._M_constness = __const_iterator;
00275 _M_variant._M_iterator._M_state = __it? __unknown_state : __singular;
00276 _M_variant._M_iterator._M_sequence = 0;
00277 _M_variant._M_iterator._M_seq_type = 0;
00278 }
00279
00280 template<typename _Iterator>
00281 _Parameter(const _Iterator& __it, const char* __name, _Is_iterator)
00282 : _M_kind(__iterator), _M_variant()
00283 {
00284 _M_variant._M_iterator._M_name = __name;
00285 _M_variant._M_iterator._M_address = &__it;
00286 #ifdef __GXX_RTTI
00287 _M_variant._M_iterator._M_type = &typeid(__it);
00288 #else
00289 _M_variant._M_iterator._M_type = 0;
00290 #endif
00291 _M_variant._M_iterator._M_constness = __unknown_constness;
00292 _M_variant._M_iterator._M_state =
00293 __gnu_debug::__check_singular(__it)? __singular : __unknown_state;
00294 _M_variant._M_iterator._M_sequence = 0;
00295 _M_variant._M_iterator._M_seq_type = 0;
00296 }
00297
00298 template<typename _Sequence>
00299 _Parameter(const _Safe_sequence<_Sequence>& __seq,
00300 const char* __name, _Is_sequence)
00301 : _M_kind(__sequence), _M_variant()
00302 {
00303 _M_variant._M_sequence._M_name = __name;
00304 _M_variant._M_sequence._M_address =
00305 static_cast<const _Sequence*>(&__seq);
00306 #ifdef __GXX_RTTI
00307 _M_variant._M_sequence._M_type = &typeid(_Sequence);
00308 #else
00309 _M_variant._M_sequence._M_type = 0;
00310 #endif
00311 }
00312
00313 template<typename _Sequence>
00314 _Parameter(const _Sequence& __seq, const char* __name, _Is_sequence)
00315 : _M_kind(__sequence), _M_variant()
00316 {
00317 _M_variant._M_sequence._M_name = __name;
00318 _M_variant._M_sequence._M_address = &__seq;
00319 #ifdef __GXX_RTTI
00320 _M_variant._M_sequence._M_type = &typeid(_Sequence);
00321 #else
00322 _M_variant._M_sequence._M_type = 0;
00323 #endif
00324 }
00325
00326 void
00327 _M_print_field(const _Error_formatter* __formatter,
00328 const char* __name) const;
00329
00330 void
00331 _M_print_description(const _Error_formatter* __formatter) const;
00332 };
00333
00334 friend struct _Parameter;
00335
00336 public:
00337 template<typename _Iterator>
00338 const _Error_formatter&
00339 _M_iterator(const _Iterator& __it, const char* __name = 0) const
00340 {
00341 if (_M_num_parameters < size_t(__max_parameters))
00342 _M_parameters[_M_num_parameters++] = _Parameter(__it, __name,
00343 _Is_iterator());
00344 return *this;
00345 }
00346
00347 const _Error_formatter&
00348 _M_integer(long __value, const char* __name = 0) const
00349 {
00350 if (_M_num_parameters < size_t(__max_parameters))
00351 _M_parameters[_M_num_parameters++] = _Parameter(__value, __name);
00352 return *this;
00353 }
00354
00355 const _Error_formatter&
00356 _M_string(const char* __value, const char* __name = 0) const
00357 {
00358 if (_M_num_parameters < size_t(__max_parameters))
00359 _M_parameters[_M_num_parameters++] = _Parameter(__value, __name);
00360 return *this;
00361 }
00362
00363 template<typename _Sequence>
00364 const _Error_formatter&
00365 _M_sequence(const _Sequence& __seq, const char* __name = 0) const
00366 {
00367 if (_M_num_parameters < size_t(__max_parameters))
00368 _M_parameters[_M_num_parameters++] = _Parameter(__seq, __name,
00369 _Is_sequence());
00370 return *this;
00371 }
00372
00373 const _Error_formatter&
00374 _M_message(const char* __text) const
00375 { _M_text = __text; return *this; }
00376
00377 const _Error_formatter&
00378 _M_message(_Debug_msg_id __id) const throw ();
00379
00380 _GLIBCXX_NORETURN void
00381 _M_error() const;
00382
00383 private:
00384 _Error_formatter(const char* __file, size_t __line)
00385 : _M_file(__file), _M_line(__line), _M_num_parameters(0), _M_text(0),
00386 _M_max_length(78), _M_column(1), _M_first_line(true), _M_wordwrap(false)
00387 { _M_get_max_length(); }
00388
00389 template<typename _Tp>
00390 void
00391 _M_format_word(char*, int, const char*, _Tp) const throw ();
00392
00393 void
00394 _M_print_word(const char* __word) const;
00395
00396 void
00397 _M_print_string(const char* __string) const;
00398
00399 void
00400 _M_get_max_length() const throw ();
00401
00402 enum { __max_parameters = 9 };
00403
00404 const char* _M_file;
00405 size_t _M_line;
00406 mutable _Parameter _M_parameters[__max_parameters];
00407 mutable size_t _M_num_parameters;
00408 mutable const char* _M_text;
00409 mutable size_t _M_max_length;
00410 enum { _M_indent = 4 } ;
00411 mutable size_t _M_column;
00412 mutable bool _M_first_line;
00413 mutable bool _M_wordwrap;
00414
00415 public:
00416 static _Error_formatter
00417 _M_at(const char* __file, size_t __line)
00418 { return _Error_formatter(__file, __line); }
00419 };
00420 }
00421
00422 #endif