No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

471 líneas
15KB

  1. // Debugging support 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/functions.h
  21. * This file is a GNU debug extension to the Standard C++ Library.
  22. */
  23. #ifndef _GLIBCXX_DEBUG_FUNCTIONS_H
  24. #define _GLIBCXX_DEBUG_FUNCTIONS_H 1
  25. #include <bits/stl_function.h> // for less
  26. #if __cplusplus >= 201103L
  27. # include <bits/stl_iterator.h> // for __miter_base
  28. # include <type_traits> // for is_lvalue_reference and conditional.
  29. #endif
  30. #include <debug/helper_functions.h>
  31. #include <debug/formatter.h>
  32. namespace __gnu_debug
  33. {
  34. template<typename _Sequence>
  35. struct _Insert_range_from_self_is_safe
  36. { enum { __value = 0 }; };
  37. template<typename _Sequence>
  38. struct _Is_contiguous_sequence : std::__false_type { };
  39. /* Checks that [first, last) is a valid range, and then returns
  40. * __first. This routine is useful when we can't use a separate
  41. * assertion statement because, e.g., we are in a constructor.
  42. */
  43. template<typename _InputIterator>
  44. inline _InputIterator
  45. __check_valid_range(const _InputIterator& __first,
  46. const _InputIterator& __last,
  47. const char* __file,
  48. unsigned int __line,
  49. const char* __function)
  50. {
  51. __glibcxx_check_valid_range_at(__first, __last,
  52. __file, __line, __function);
  53. return __first;
  54. }
  55. /* Handle the case where __other is a pointer to _Sequence::value_type. */
  56. template<typename _Iterator, typename _Sequence, typename _Category>
  57. inline bool
  58. __foreign_iterator_aux4(
  59. const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
  60. const typename _Sequence::value_type* __other)
  61. {
  62. typedef const typename _Sequence::value_type* _PointerType;
  63. typedef std::less<_PointerType> _Less;
  64. #if __cplusplus >= 201103L
  65. constexpr _Less __l{};
  66. #else
  67. const _Less __l = _Less();
  68. #endif
  69. const _Sequence* __seq = __it._M_get_sequence();
  70. const _PointerType __begin = std::__addressof(*__seq->_M_base().begin());
  71. const _PointerType __end = std::__addressof(*(__seq->_M_base().end()-1));
  72. // Check whether __other points within the contiguous storage.
  73. return __l(__other, __begin) || __l(__end, __other);
  74. }
  75. /* Fallback overload for when we can't tell, assume it is valid. */
  76. template<typename _Iterator, typename _Sequence, typename _Category>
  77. inline bool
  78. __foreign_iterator_aux4(
  79. const _Safe_iterator<_Iterator, _Sequence, _Category>&, ...)
  80. { return true; }
  81. /* Handle sequences with contiguous storage */
  82. template<typename _Iterator, typename _Sequence, typename _Category,
  83. typename _InputIterator>
  84. inline bool
  85. __foreign_iterator_aux3(
  86. const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
  87. const _InputIterator& __other, const _InputIterator& __other_end,
  88. std::__true_type)
  89. {
  90. if (__other == __other_end)
  91. return true; // inserting nothing is safe even if not foreign iters
  92. if (__it._M_get_sequence()->empty())
  93. return true; // can't be self-inserting if self is empty
  94. return __foreign_iterator_aux4(__it, std::__addressof(*__other));
  95. }
  96. /* Handle non-contiguous containers, assume it is valid. */
  97. template<typename _Iterator, typename _Sequence, typename _Category,
  98. typename _InputIterator>
  99. inline bool
  100. __foreign_iterator_aux3(
  101. const _Safe_iterator<_Iterator, _Sequence, _Category>&,
  102. const _InputIterator&, const _InputIterator&,
  103. std::__false_type)
  104. { return true; }
  105. /** Handle debug iterators from the same type of container. */
  106. template<typename _Iterator, typename _Sequence, typename _Category,
  107. typename _OtherIterator>
  108. inline bool
  109. __foreign_iterator_aux2(
  110. const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
  111. const _Safe_iterator<_OtherIterator, _Sequence, _Category>& __other,
  112. const _Safe_iterator<_OtherIterator, _Sequence, _Category>&)
  113. { return __it._M_get_sequence() != __other._M_get_sequence(); }
  114. /** Handle debug iterators from different types of container. */
  115. template<typename _Iterator, typename _Sequence, typename _Category,
  116. typename _OtherIterator, typename _OtherSequence,
  117. typename _OtherCategory>
  118. inline bool
  119. __foreign_iterator_aux2(
  120. const _Safe_iterator<_Iterator, _Sequence, _Category>&,
  121. const _Safe_iterator<_OtherIterator, _OtherSequence,
  122. _OtherCategory>&,
  123. const _Safe_iterator<_OtherIterator, _OtherSequence,
  124. _OtherCategory>&)
  125. { return true; }
  126. /* Handle non-debug iterators. */
  127. template<typename _Iterator, typename _Sequence, typename _Category,
  128. typename _InputIterator>
  129. inline bool
  130. __foreign_iterator_aux2(
  131. const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
  132. const _InputIterator& __other,
  133. const _InputIterator& __other_end)
  134. {
  135. #if __cplusplus < 201103L
  136. typedef _Is_contiguous_sequence<_Sequence> __tag;
  137. #else
  138. using __lvalref = std::is_lvalue_reference<
  139. typename std::iterator_traits<_InputIterator>::reference>;
  140. using __contiguous = _Is_contiguous_sequence<_Sequence>;
  141. using __tag = typename std::conditional<__lvalref::value, __contiguous,
  142. std::__false_type>::type;
  143. #endif
  144. return __foreign_iterator_aux3(__it, __other, __other_end, __tag());
  145. }
  146. /* Handle the case where we aren't really inserting a range after all */
  147. template<typename _Iterator, typename _Sequence, typename _Category,
  148. typename _Integral>
  149. inline bool
  150. __foreign_iterator_aux(
  151. const _Safe_iterator<_Iterator, _Sequence, _Category>&,
  152. _Integral, _Integral, std::__true_type)
  153. { return true; }
  154. /* Handle all iterators. */
  155. template<typename _Iterator, typename _Sequence, typename _Category,
  156. typename _InputIterator>
  157. inline bool
  158. __foreign_iterator_aux(
  159. const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
  160. _InputIterator __other, _InputIterator __other_end,
  161. std::__false_type)
  162. {
  163. return _Insert_range_from_self_is_safe<_Sequence>::__value
  164. || __foreign_iterator_aux2(__it, std::__miter_base(__other),
  165. std::__miter_base(__other_end));
  166. }
  167. template<typename _Iterator, typename _Sequence, typename _Category,
  168. typename _InputIterator>
  169. inline bool
  170. __foreign_iterator(
  171. const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
  172. _InputIterator __other, _InputIterator __other_end)
  173. {
  174. typedef typename std::__is_integer<_InputIterator>::__type _Integral;
  175. return __foreign_iterator_aux(__it, __other, __other_end, _Integral());
  176. }
  177. // Can't check if an input iterator sequence is sorted, because we
  178. // can't step through the sequence.
  179. template<typename _InputIterator>
  180. _GLIBCXX20_CONSTEXPR
  181. inline bool
  182. __check_sorted_aux(const _InputIterator&, const _InputIterator&,
  183. std::input_iterator_tag)
  184. { return true; }
  185. // Can verify if a forward iterator sequence is in fact sorted using
  186. // std::__is_sorted
  187. template<typename _ForwardIterator>
  188. _GLIBCXX20_CONSTEXPR
  189. inline bool
  190. __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
  191. std::forward_iterator_tag)
  192. {
  193. if (__first == __last)
  194. return true;
  195. _ForwardIterator __next = __first;
  196. for (++__next; __next != __last; __first = __next, (void)++__next)
  197. if (*__next < *__first)
  198. return false;
  199. return true;
  200. }
  201. // Can't check if an input iterator sequence is sorted, because we can't step
  202. // through the sequence.
  203. template<typename _InputIterator, typename _Predicate>
  204. _GLIBCXX20_CONSTEXPR
  205. inline bool
  206. __check_sorted_aux(const _InputIterator&, const _InputIterator&,
  207. _Predicate, std::input_iterator_tag)
  208. { return true; }
  209. // Can verify if a forward iterator sequence is in fact sorted using
  210. // std::__is_sorted
  211. template<typename _ForwardIterator, typename _Predicate>
  212. _GLIBCXX20_CONSTEXPR
  213. inline bool
  214. __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
  215. _Predicate __pred, std::forward_iterator_tag)
  216. {
  217. if (__first == __last)
  218. return true;
  219. _ForwardIterator __next = __first;
  220. for (++__next; __next != __last; __first = __next, (void)++__next)
  221. if (__pred(*__next, *__first))
  222. return false;
  223. return true;
  224. }
  225. // Determine if a sequence is sorted.
  226. template<typename _InputIterator>
  227. _GLIBCXX20_CONSTEXPR
  228. inline bool
  229. __check_sorted(const _InputIterator& __first, const _InputIterator& __last)
  230. {
  231. return __check_sorted_aux(__first, __last,
  232. std::__iterator_category(__first));
  233. }
  234. template<typename _InputIterator, typename _Predicate>
  235. _GLIBCXX20_CONSTEXPR
  236. inline bool
  237. __check_sorted(const _InputIterator& __first, const _InputIterator& __last,
  238. _Predicate __pred)
  239. {
  240. return __check_sorted_aux(__first, __last, __pred,
  241. std::__iterator_category(__first));
  242. }
  243. template<typename _InputIterator>
  244. _GLIBCXX20_CONSTEXPR
  245. inline bool
  246. __check_sorted_set_aux(const _InputIterator& __first,
  247. const _InputIterator& __last,
  248. std::__true_type)
  249. { return __check_sorted(__first, __last); }
  250. template<typename _InputIterator>
  251. _GLIBCXX20_CONSTEXPR
  252. inline bool
  253. __check_sorted_set_aux(const _InputIterator&,
  254. const _InputIterator&,
  255. std::__false_type)
  256. { return true; }
  257. template<typename _InputIterator, typename _Predicate>
  258. _GLIBCXX20_CONSTEXPR
  259. inline bool
  260. __check_sorted_set_aux(const _InputIterator& __first,
  261. const _InputIterator& __last,
  262. _Predicate __pred, std::__true_type)
  263. { return __check_sorted(__first, __last, __pred); }
  264. template<typename _InputIterator, typename _Predicate>
  265. _GLIBCXX20_CONSTEXPR
  266. inline bool
  267. __check_sorted_set_aux(const _InputIterator&,
  268. const _InputIterator&, _Predicate,
  269. std::__false_type)
  270. { return true; }
  271. // ... special variant used in std::merge, std::includes, std::set_*.
  272. template<typename _InputIterator1, typename _InputIterator2>
  273. _GLIBCXX20_CONSTEXPR
  274. inline bool
  275. __check_sorted_set(const _InputIterator1& __first,
  276. const _InputIterator1& __last,
  277. const _InputIterator2&)
  278. {
  279. typedef typename std::iterator_traits<_InputIterator1>::value_type
  280. _ValueType1;
  281. typedef typename std::iterator_traits<_InputIterator2>::value_type
  282. _ValueType2;
  283. typedef typename std::__are_same<_ValueType1, _ValueType2>::__type
  284. _SameType;
  285. return __check_sorted_set_aux(__first, __last, _SameType());
  286. }
  287. template<typename _InputIterator1, typename _InputIterator2,
  288. typename _Predicate>
  289. _GLIBCXX20_CONSTEXPR
  290. inline bool
  291. __check_sorted_set(const _InputIterator1& __first,
  292. const _InputIterator1& __last,
  293. const _InputIterator2&, _Predicate __pred)
  294. {
  295. typedef typename std::iterator_traits<_InputIterator1>::value_type
  296. _ValueType1;
  297. typedef typename std::iterator_traits<_InputIterator2>::value_type
  298. _ValueType2;
  299. typedef typename std::__are_same<_ValueType1, _ValueType2>::__type
  300. _SameType;
  301. return __check_sorted_set_aux(__first, __last, __pred, _SameType());
  302. }
  303. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  304. // 270. Binary search requirements overly strict
  305. // Determine if a sequence is partitioned w.r.t. this element.
  306. template<typename _ForwardIterator, typename _Tp>
  307. _GLIBCXX20_CONSTEXPR
  308. inline bool
  309. __check_partitioned_lower(_ForwardIterator __first,
  310. _ForwardIterator __last, const _Tp& __value)
  311. {
  312. while (__first != __last && *__first < __value)
  313. ++__first;
  314. if (__first != __last)
  315. {
  316. ++__first;
  317. while (__first != __last && !(*__first < __value))
  318. ++__first;
  319. }
  320. return __first == __last;
  321. }
  322. template<typename _ForwardIterator, typename _Tp>
  323. _GLIBCXX20_CONSTEXPR
  324. inline bool
  325. __check_partitioned_upper(_ForwardIterator __first,
  326. _ForwardIterator __last, const _Tp& __value)
  327. {
  328. while (__first != __last && !(__value < *__first))
  329. ++__first;
  330. if (__first != __last)
  331. {
  332. ++__first;
  333. while (__first != __last && __value < *__first)
  334. ++__first;
  335. }
  336. return __first == __last;
  337. }
  338. // Determine if a sequence is partitioned w.r.t. this element.
  339. template<typename _ForwardIterator, typename _Tp, typename _Pred>
  340. _GLIBCXX20_CONSTEXPR
  341. inline bool
  342. __check_partitioned_lower(_ForwardIterator __first,
  343. _ForwardIterator __last, const _Tp& __value,
  344. _Pred __pred)
  345. {
  346. while (__first != __last && bool(__pred(*__first, __value)))
  347. ++__first;
  348. if (__first != __last)
  349. {
  350. ++__first;
  351. while (__first != __last && !bool(__pred(*__first, __value)))
  352. ++__first;
  353. }
  354. return __first == __last;
  355. }
  356. template<typename _ForwardIterator, typename _Tp, typename _Pred>
  357. _GLIBCXX20_CONSTEXPR
  358. inline bool
  359. __check_partitioned_upper(_ForwardIterator __first,
  360. _ForwardIterator __last, const _Tp& __value,
  361. _Pred __pred)
  362. {
  363. while (__first != __last && !bool(__pred(__value, *__first)))
  364. ++__first;
  365. if (__first != __last)
  366. {
  367. ++__first;
  368. while (__first != __last && bool(__pred(__value, *__first)))
  369. ++__first;
  370. }
  371. return __first == __last;
  372. }
  373. #if __cplusplus >= 201103L
  374. struct _Irreflexive_checker
  375. {
  376. template<typename _It>
  377. static typename std::iterator_traits<_It>::reference
  378. __deref();
  379. template<typename _It,
  380. typename = decltype(__deref<_It>() < __deref<_It>())>
  381. _GLIBCXX20_CONSTEXPR
  382. static bool
  383. _S_is_valid(_It __it)
  384. { return !(*__it < *__it); }
  385. // Fallback method if operator doesn't exist.
  386. template<typename... _Args>
  387. _GLIBCXX20_CONSTEXPR
  388. static bool
  389. _S_is_valid(_Args...)
  390. { return true; }
  391. template<typename _It, typename _Pred, typename
  392. = decltype(std::declval<_Pred>()(__deref<_It>(), __deref<_It>()))>
  393. _GLIBCXX20_CONSTEXPR
  394. static bool
  395. _S_is_valid_pred(_It __it, _Pred __pred)
  396. { return !__pred(*__it, *__it); }
  397. // Fallback method if predicate can't be invoked.
  398. template<typename... _Args>
  399. _GLIBCXX20_CONSTEXPR
  400. static bool
  401. _S_is_valid_pred(_Args...)
  402. { return true; }
  403. };
  404. template<typename _Iterator>
  405. _GLIBCXX20_CONSTEXPR
  406. inline bool
  407. __is_irreflexive(_Iterator __it)
  408. { return _Irreflexive_checker::_S_is_valid(__it); }
  409. template<typename _Iterator, typename _Pred>
  410. _GLIBCXX20_CONSTEXPR
  411. inline bool
  412. __is_irreflexive_pred(_Iterator __it, _Pred __pred)
  413. { return _Irreflexive_checker::_S_is_valid_pred(__it, __pred); }
  414. #endif
  415. } // namespace __gnu_debug
  416. #endif