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