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