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