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