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