functions.h 16 KB

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