Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

3 роки тому
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. // Debug-mode error formatting implementation -*- C++ -*-
  2. // Copyright (C) 2003-2020 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file debug/formatter.h
  21. * This file is a GNU debug extension to the Standard C++ Library.
  22. */
  23. #ifndef _GLIBCXX_DEBUG_FORMATTER_H
  24. #define _GLIBCXX_DEBUG_FORMATTER_H 1
  25. #include <bits/c++config.h>
  26. #if __cpp_rtti
  27. # include <typeinfo>
  28. # define _GLIBCXX_TYPEID(_Type) &typeid(_Type)
  29. #else
  30. namespace std
  31. {
  32. class type_info;
  33. }
  34. # define _GLIBCXX_TYPEID(_Type) 0
  35. #endif
  36. #if __cplusplus >= 201103L
  37. namespace __gnu_cxx
  38. {
  39. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  40. template<typename _Iterator, typename _Container>
  41. class __normal_iterator;
  42. _GLIBCXX_END_NAMESPACE_VERSION
  43. }
  44. namespace std
  45. {
  46. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  47. template<typename _Iterator>
  48. class reverse_iterator;
  49. template<typename _Iterator>
  50. class move_iterator;
  51. _GLIBCXX_END_NAMESPACE_VERSION
  52. }
  53. #endif
  54. namespace __gnu_debug
  55. {
  56. using std::type_info;
  57. template<typename _Iterator>
  58. bool __check_singular(const _Iterator&);
  59. class _Safe_sequence_base;
  60. template<typename _Iterator, typename _Sequence, typename _Category>
  61. class _Safe_iterator;
  62. template<typename _Iterator, typename _Sequence>
  63. class _Safe_local_iterator;
  64. template<typename _Sequence>
  65. class _Safe_sequence;
  66. enum _Debug_msg_id
  67. {
  68. // General checks
  69. __msg_valid_range,
  70. __msg_insert_singular,
  71. __msg_insert_different,
  72. __msg_erase_bad,
  73. __msg_erase_different,
  74. __msg_subscript_oob,
  75. __msg_empty,
  76. __msg_unpartitioned,
  77. __msg_unpartitioned_pred,
  78. __msg_unsorted,
  79. __msg_unsorted_pred,
  80. __msg_not_heap,
  81. __msg_not_heap_pred,
  82. // std::bitset checks
  83. __msg_bad_bitset_write,
  84. __msg_bad_bitset_read,
  85. __msg_bad_bitset_flip,
  86. // std::list checks
  87. __msg_self_splice,
  88. __msg_splice_alloc,
  89. __msg_splice_bad,
  90. __msg_splice_other,
  91. __msg_splice_overlap,
  92. // iterator checks
  93. __msg_init_singular,
  94. __msg_init_copy_singular,
  95. __msg_init_const_singular,
  96. __msg_copy_singular,
  97. __msg_bad_deref,
  98. __msg_bad_inc,
  99. __msg_bad_dec,
  100. __msg_iter_subscript_oob,
  101. __msg_advance_oob,
  102. __msg_retreat_oob,
  103. __msg_iter_compare_bad,
  104. __msg_compare_different,
  105. __msg_iter_order_bad,
  106. __msg_order_different,
  107. __msg_distance_bad,
  108. __msg_distance_different,
  109. // istream_iterator
  110. __msg_deref_istream,
  111. __msg_inc_istream,
  112. // ostream_iterator
  113. __msg_output_ostream,
  114. // istreambuf_iterator
  115. __msg_deref_istreambuf,
  116. __msg_inc_istreambuf,
  117. // forward_list
  118. __msg_insert_after_end,
  119. __msg_erase_after_bad,
  120. __msg_valid_range2,
  121. // unordered container local iterators
  122. __msg_local_iter_compare_bad,
  123. __msg_non_empty_range,
  124. // self move assign
  125. __msg_self_move_assign,
  126. // unordered container buckets
  127. __msg_bucket_index_oob,
  128. __msg_valid_load_factor,
  129. // others
  130. __msg_equal_allocs,
  131. __msg_insert_range_from_self,
  132. __msg_irreflexive_ordering
  133. };
  134. class _Error_formatter
  135. {
  136. // Tags denoting the type of parameter for construction
  137. struct _Is_iterator { };
  138. struct _Is_iterator_value_type { };
  139. struct _Is_sequence { };
  140. struct _Is_instance { };
  141. public:
  142. /// Whether an iterator is constant, mutable, or unknown
  143. enum _Constness
  144. {
  145. __unknown_constness,
  146. __const_iterator,
  147. __mutable_iterator,
  148. __last_constness
  149. };
  150. // The state of the iterator (fine-grained), if we know it.
  151. enum _Iterator_state
  152. {
  153. __unknown_state,
  154. __singular, // singular, may still be attached to a sequence
  155. __begin, // dereferenceable, and at the beginning
  156. __middle, // dereferenceable, not at the beginning
  157. __end, // past-the-end, may be at beginning if sequence empty
  158. __before_begin, // before begin
  159. __rbegin, // dereferenceable, and at the reverse-beginning
  160. __rmiddle, // reverse-dereferenceable, not at the reverse-beginning
  161. __rend, // reverse-past-the-end
  162. __last_state
  163. };
  164. // A parameter that may be referenced by an error message
  165. struct _Parameter
  166. {
  167. enum
  168. {
  169. __unused_param,
  170. __iterator,
  171. __sequence,
  172. __integer,
  173. __string,
  174. __instance,
  175. __iterator_value_type
  176. } _M_kind;
  177. struct _Type
  178. {
  179. const char* _M_name;
  180. const type_info* _M_type;
  181. };
  182. struct _Instance : _Type
  183. {
  184. const void* _M_address;
  185. };
  186. union
  187. {
  188. // When _M_kind == __iterator
  189. struct : _Instance
  190. {
  191. _Constness _M_constness;
  192. _Iterator_state _M_state;
  193. const void* _M_sequence;
  194. const type_info* _M_seq_type;
  195. } _M_iterator;
  196. // When _M_kind == __sequence
  197. _Instance _M_sequence;
  198. // When _M_kind == __integer
  199. struct
  200. {
  201. const char* _M_name;
  202. long _M_value;
  203. } _M_integer;
  204. // When _M_kind == __string
  205. struct
  206. {
  207. const char* _M_name;
  208. const char* _M_value;
  209. } _M_string;
  210. // When _M_kind == __instance
  211. _Instance _M_instance;
  212. // When _M_kind == __iterator_value_type
  213. _Type _M_iterator_value_type;
  214. } _M_variant;
  215. _Parameter() : _M_kind(__unused_param), _M_variant() { }
  216. _Parameter(long __value, const char* __name)
  217. : _M_kind(__integer), _M_variant()
  218. {
  219. _M_variant._M_integer._M_name = __name;
  220. _M_variant._M_integer._M_value = __value;
  221. }
  222. _Parameter(const char* __value, const char* __name)
  223. : _M_kind(__string), _M_variant()
  224. {
  225. _M_variant._M_string._M_name = __name;
  226. _M_variant._M_string._M_value = __value;
  227. }
  228. template<typename _Iterator, typename _Sequence, typename _Category>
  229. _Parameter(_Safe_iterator<_Iterator, _Sequence, _Category> const& __it,
  230. const char* __name, _Is_iterator)
  231. : _M_kind(__iterator), _M_variant()
  232. {
  233. _M_variant._M_iterator._M_name = __name;
  234. _M_variant._M_iterator._M_address = std::__addressof(__it);
  235. _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(_Iterator);
  236. _M_variant._M_iterator._M_constness =
  237. __it._S_constant() ? __const_iterator : __mutable_iterator;
  238. _M_variant._M_iterator._M_sequence = __it._M_get_sequence();
  239. _M_variant._M_iterator._M_seq_type = _GLIBCXX_TYPEID(_Sequence);
  240. if (__it._M_singular())
  241. _M_variant._M_iterator._M_state = __singular;
  242. else
  243. {
  244. if (__it._M_is_before_begin())
  245. _M_variant._M_iterator._M_state = __before_begin;
  246. else if (__it._M_is_end())
  247. _M_variant._M_iterator._M_state = __end;
  248. else if (__it._M_is_begin())
  249. _M_variant._M_iterator._M_state = __begin;
  250. else
  251. _M_variant._M_iterator._M_state = __middle;
  252. }
  253. }
  254. template<typename _Iterator, typename _Sequence>
  255. _Parameter(_Safe_local_iterator<_Iterator, _Sequence> const& __it,
  256. const char* __name, _Is_iterator)
  257. : _M_kind(__iterator), _M_variant()
  258. {
  259. _M_variant._M_iterator._M_name = __name;
  260. _M_variant._M_iterator._M_address = std::__addressof(__it);
  261. _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(_Iterator);
  262. _M_variant._M_iterator._M_constness =
  263. __it._S_constant() ? __const_iterator : __mutable_iterator;
  264. _M_variant._M_iterator._M_sequence = __it._M_get_sequence();
  265. _M_variant._M_iterator._M_seq_type = _GLIBCXX_TYPEID(_Sequence);
  266. if (__it._M_singular())
  267. _M_variant._M_iterator._M_state = __singular;
  268. else
  269. {
  270. if (__it._M_is_end())
  271. _M_variant._M_iterator._M_state = __end;
  272. else if (__it._M_is_begin())
  273. _M_variant._M_iterator._M_state = __begin;
  274. else
  275. _M_variant._M_iterator._M_state = __middle;
  276. }
  277. }
  278. template<typename _Type>
  279. _Parameter(const _Type* const& __it, const char* __name, _Is_iterator)
  280. : _M_kind(__iterator), _M_variant()
  281. {
  282. _M_variant._M_iterator._M_name = __name;
  283. _M_variant._M_iterator._M_address = std::__addressof(__it);
  284. _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it);
  285. _M_variant._M_iterator._M_constness = __const_iterator;
  286. _M_variant._M_iterator._M_state = __it ? __unknown_state : __singular;
  287. _M_variant._M_iterator._M_sequence = 0;
  288. _M_variant._M_iterator._M_seq_type = 0;
  289. }
  290. template<typename _Type>
  291. _Parameter(_Type* const& __it, const char* __name, _Is_iterator)
  292. : _M_kind(__iterator), _M_variant()
  293. {
  294. _M_variant._M_iterator._M_name = __name;
  295. _M_variant._M_iterator._M_address = std::__addressof(__it);
  296. _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it);
  297. _M_variant._M_iterator._M_constness = __mutable_iterator;
  298. _M_variant._M_iterator._M_state = __it ? __unknown_state : __singular;
  299. _M_variant._M_iterator._M_sequence = 0;
  300. _M_variant._M_iterator._M_seq_type = 0;
  301. }
  302. template<typename _Iterator>
  303. _Parameter(_Iterator const& __it, const char* __name, _Is_iterator)
  304. : _M_kind(__iterator), _M_variant()
  305. {
  306. _M_variant._M_iterator._M_name = __name;
  307. _M_variant._M_iterator._M_address = std::__addressof(__it);
  308. _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it);
  309. _M_variant._M_iterator._M_constness = __unknown_constness;
  310. _M_variant._M_iterator._M_state =
  311. __gnu_debug::__check_singular(__it) ? __singular : __unknown_state;
  312. _M_variant._M_iterator._M_sequence = 0;
  313. _M_variant._M_iterator._M_seq_type = 0;
  314. }
  315. #if __cplusplus >= 201103L
  316. // The following constructors are only defined in C++11 to take
  317. // advantage of the constructor delegation feature.
  318. template<typename _Iterator, typename _Container>
  319. _Parameter(
  320. __gnu_cxx::__normal_iterator<_Iterator, _Container> const& __it,
  321. const char* __name, _Is_iterator)
  322. : _Parameter(__it.base(), __name, _Is_iterator{})
  323. { _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it); }
  324. template<typename _Iterator>
  325. _Parameter(std::reverse_iterator<_Iterator> const& __it,
  326. const char* __name, _Is_iterator)
  327. : _Parameter(__it.base(), __name, _Is_iterator{})
  328. {
  329. _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it);
  330. _M_variant._M_iterator._M_state
  331. = _S_reverse_state(_M_variant._M_iterator._M_state);
  332. }
  333. template<typename _Iterator, typename _Sequence, typename _Category>
  334. _Parameter(std::reverse_iterator<_Safe_iterator<_Iterator, _Sequence,
  335. _Category>> const& __it,
  336. const char* __name, _Is_iterator)
  337. : _Parameter(__it.base(), __name, _Is_iterator{})
  338. {
  339. _M_variant._M_iterator._M_type
  340. = _GLIBCXX_TYPEID(std::reverse_iterator<_Iterator>);
  341. _M_variant._M_iterator._M_state
  342. = _S_reverse_state(_M_variant._M_iterator._M_state);
  343. }
  344. template<typename _Iterator>
  345. _Parameter(std::move_iterator<_Iterator> const& __it,
  346. const char* __name, _Is_iterator)
  347. : _Parameter(__it.base(), __name, _Is_iterator{})
  348. { _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it); }
  349. template<typename _Iterator, typename _Sequence, typename _Category>
  350. _Parameter(std::move_iterator<_Safe_iterator<_Iterator, _Sequence,
  351. _Category>> const& __it,
  352. const char* __name, _Is_iterator)
  353. : _Parameter(__it.base(), __name, _Is_iterator{})
  354. {
  355. _M_variant._M_iterator._M_type
  356. = _GLIBCXX_TYPEID(std::move_iterator<_Iterator>);
  357. }
  358. private:
  359. _Iterator_state
  360. _S_reverse_state(_Iterator_state __state)
  361. {
  362. switch (__state)
  363. {
  364. case __begin:
  365. return __rend;
  366. case __middle:
  367. return __rmiddle;
  368. case __end:
  369. return __rbegin;
  370. default:
  371. return __state;
  372. }
  373. }
  374. public:
  375. #endif
  376. template<typename _Sequence>
  377. _Parameter(const _Safe_sequence<_Sequence>& __seq,
  378. const char* __name, _Is_sequence)
  379. : _M_kind(__sequence), _M_variant()
  380. {
  381. _M_variant._M_sequence._M_name = __name;
  382. _M_variant._M_sequence._M_address =
  383. static_cast<const _Sequence*>(std::__addressof(__seq));
  384. _M_variant._M_sequence._M_type = _GLIBCXX_TYPEID(_Sequence);
  385. }
  386. template<typename _Sequence>
  387. _Parameter(const _Sequence& __seq, const char* __name, _Is_sequence)
  388. : _M_kind(__sequence), _M_variant()
  389. {
  390. _M_variant._M_sequence._M_name = __name;
  391. _M_variant._M_sequence._M_address = std::__addressof(__seq);
  392. _M_variant._M_sequence._M_type = _GLIBCXX_TYPEID(_Sequence);
  393. }
  394. template<typename _Iterator>
  395. _Parameter(const _Iterator& __it, const char* __name,
  396. _Is_iterator_value_type)
  397. : _M_kind(__iterator_value_type), _M_variant()
  398. {
  399. _M_variant._M_iterator_value_type._M_name = __name;
  400. _M_variant._M_iterator_value_type._M_type =
  401. _GLIBCXX_TYPEID(typename std::iterator_traits<_Iterator>::value_type);
  402. }
  403. template<typename _Type>
  404. _Parameter(const _Type& __inst, const char* __name, _Is_instance)
  405. : _M_kind(__instance), _M_variant()
  406. {
  407. _M_variant._M_instance._M_name = __name;
  408. _M_variant._M_instance._M_address = &__inst;
  409. _M_variant._M_instance._M_type = _GLIBCXX_TYPEID(_Type);
  410. }
  411. #if !_GLIBCXX_INLINE_VERSION
  412. void
  413. _M_print_field(const _Error_formatter* __formatter,
  414. const char* __name) const _GLIBCXX_DEPRECATED;
  415. void
  416. _M_print_description(const _Error_formatter* __formatter)
  417. const _GLIBCXX_DEPRECATED;
  418. #endif
  419. };
  420. template<typename _Iterator>
  421. _Error_formatter&
  422. _M_iterator(const _Iterator& __it, const char* __name = 0)
  423. {
  424. if (_M_num_parameters < std::size_t(__max_parameters))
  425. _M_parameters[_M_num_parameters++] = _Parameter(__it, __name,
  426. _Is_iterator());
  427. return *this;
  428. }
  429. template<typename _Iterator>
  430. _Error_formatter&
  431. _M_iterator_value_type(const _Iterator& __it,
  432. const char* __name = 0)
  433. {
  434. if (_M_num_parameters < __max_parameters)
  435. _M_parameters[_M_num_parameters++] =
  436. _Parameter(__it, __name, _Is_iterator_value_type());
  437. return *this;
  438. }
  439. _Error_formatter&
  440. _M_integer(long __value, const char* __name = 0)
  441. {
  442. if (_M_num_parameters < __max_parameters)
  443. _M_parameters[_M_num_parameters++] = _Parameter(__value, __name);
  444. return *this;
  445. }
  446. _Error_formatter&
  447. _M_string(const char* __value, const char* __name = 0)
  448. {
  449. if (_M_num_parameters < __max_parameters)
  450. _M_parameters[_M_num_parameters++] = _Parameter(__value, __name);
  451. return *this;
  452. }
  453. template<typename _Sequence>
  454. _Error_formatter&
  455. _M_sequence(const _Sequence& __seq, const char* __name = 0)
  456. {
  457. if (_M_num_parameters < __max_parameters)
  458. _M_parameters[_M_num_parameters++] = _Parameter(__seq, __name,
  459. _Is_sequence());
  460. return *this;
  461. }
  462. template<typename _Type>
  463. _Error_formatter&
  464. _M_instance(const _Type& __inst, const char* __name = 0)
  465. {
  466. if (_M_num_parameters < __max_parameters)
  467. _M_parameters[_M_num_parameters++] = _Parameter(__inst, __name,
  468. _Is_instance());
  469. return *this;
  470. }
  471. _Error_formatter&
  472. _M_message(const char* __text)
  473. { _M_text = __text; return *this; }
  474. // Kept const qualifier for backward compatibility, to keep the same
  475. // exported symbol.
  476. _Error_formatter&
  477. _M_message(_Debug_msg_id __id) const throw ();
  478. _GLIBCXX_NORETURN void
  479. _M_error() const;
  480. #if !_GLIBCXX_INLINE_VERSION
  481. template<typename _Tp>
  482. void
  483. _M_format_word(char*, int, const char*, _Tp)
  484. const throw () _GLIBCXX_DEPRECATED;
  485. void
  486. _M_print_word(const char* __word) const _GLIBCXX_DEPRECATED;
  487. void
  488. _M_print_string(const char* __string) const _GLIBCXX_DEPRECATED;
  489. #endif
  490. private:
  491. _Error_formatter(const char* __file, unsigned int __line,
  492. const char* __function)
  493. : _M_file(__file), _M_line(__line), _M_num_parameters(0), _M_text(0)
  494. , _M_function(__function)
  495. { }
  496. #if !_GLIBCXX_INLINE_VERSION
  497. void
  498. _M_get_max_length() const throw () _GLIBCXX_DEPRECATED;
  499. #endif
  500. enum { __max_parameters = 9 };
  501. const char* _M_file;
  502. unsigned int _M_line;
  503. _Parameter _M_parameters[__max_parameters];
  504. unsigned int _M_num_parameters;
  505. const char* _M_text;
  506. const char* _M_function;
  507. public:
  508. static _Error_formatter&
  509. _S_at(const char* __file, unsigned int __line, const char* __function)
  510. {
  511. static _Error_formatter __formatter(__file, __line, __function);
  512. return __formatter;
  513. }
  514. };
  515. } // namespace __gnu_debug
  516. #undef _GLIBCXX_TYPEID
  517. #endif