safe_iterator.h 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001
  1. // Safe iterator implementation -*- C++ -*-
  2. // Copyright (C) 2003-2021 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/safe_iterator.h
  21. * This file is a GNU debug extension to the Standard C++ Library.
  22. */
  23. #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H
  24. #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1
  25. #include <debug/assertions.h>
  26. #include <debug/macros.h>
  27. #include <debug/functions.h>
  28. #include <debug/safe_base.h>
  29. #include <bits/stl_pair.h>
  30. #include <ext/type_traits.h>
  31. #if __cplusplus > 201703L
  32. # include <compare>
  33. #endif
  34. #define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, _BadMsgId, _DiffMsgId) \
  35. _GLIBCXX_DEBUG_VERIFY(!_Lhs._M_singular() && !_Rhs._M_singular() \
  36. || (_Lhs.base() == _Iterator() \
  37. && _Rhs.base() == _Iterator()), \
  38. _M_message(_BadMsgId) \
  39. ._M_iterator(_Lhs, #_Lhs) \
  40. ._M_iterator(_Rhs, #_Rhs)); \
  41. _GLIBCXX_DEBUG_VERIFY(_Lhs._M_can_compare(_Rhs), \
  42. _M_message(_DiffMsgId) \
  43. ._M_iterator(_Lhs, #_Lhs) \
  44. ._M_iterator(_Rhs, #_Rhs))
  45. #define _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(_Lhs, _Rhs) \
  46. _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_iter_compare_bad, \
  47. __msg_compare_different)
  48. #define _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(_Lhs, _Rhs) \
  49. _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_iter_order_bad, \
  50. __msg_order_different)
  51. #define _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(_Lhs, _Rhs) \
  52. _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_distance_bad, \
  53. __msg_distance_different)
  54. namespace __gnu_debug
  55. {
  56. /** Helper struct to deal with sequence offering a before_begin
  57. * iterator.
  58. **/
  59. template<typename _Sequence>
  60. struct _BeforeBeginHelper
  61. {
  62. template<typename _Iterator, typename _Category>
  63. static bool
  64. _S_Is(const _Safe_iterator<_Iterator, _Sequence, _Category>&)
  65. { return false; }
  66. template<typename _Iterator, typename _Category>
  67. static bool
  68. _S_Is_Beginnest(const _Safe_iterator<_Iterator, _Sequence, _Category>& __it)
  69. { return __it.base() == __it._M_get_sequence()->_M_base().begin(); }
  70. };
  71. /** Sequence traits giving the size of a container if possible. */
  72. template<typename _Sequence>
  73. struct _Sequence_traits
  74. {
  75. typedef _Distance_traits<typename _Sequence::iterator> _DistTraits;
  76. static typename _DistTraits::__type
  77. _S_size(const _Sequence& __seq)
  78. { return std::make_pair(__seq.size(), __dp_exact); }
  79. };
  80. /** \brief Safe iterator wrapper.
  81. *
  82. * The class template %_Safe_iterator is a wrapper around an
  83. * iterator that tracks the iterator's movement among sequences and
  84. * checks that operations performed on the "safe" iterator are
  85. * legal. In additional to the basic iterator operations (which are
  86. * validated, and then passed to the underlying iterator),
  87. * %_Safe_iterator has member functions for iterator invalidation,
  88. * attaching/detaching the iterator from sequences, and querying
  89. * the iterator's state.
  90. *
  91. * Note that _Iterator must be the first base class so that it gets
  92. * initialized before the iterator is being attached to the container's list
  93. * of iterators and it is being detached before _Iterator get
  94. * destroyed. Otherwise it would result in a data race.
  95. */
  96. template<typename _Iterator, typename _Sequence, typename _Category
  97. = typename std::iterator_traits<_Iterator>::iterator_category>
  98. class _Safe_iterator
  99. : private _Iterator,
  100. public _Safe_iterator_base
  101. {
  102. typedef _Iterator _Iter_base;
  103. typedef _Safe_iterator_base _Safe_base;
  104. typedef std::iterator_traits<_Iterator> _Traits;
  105. protected:
  106. typedef std::__are_same<typename _Sequence::_Base::const_iterator,
  107. _Iterator> _IsConstant;
  108. typedef typename __gnu_cxx::__conditional_type<
  109. _IsConstant::__value,
  110. typename _Sequence::_Base::iterator,
  111. typename _Sequence::_Base::const_iterator>::__type _OtherIterator;
  112. struct _Attach_single
  113. { };
  114. _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
  115. _GLIBCXX_NOEXCEPT
  116. : _Iter_base(__i)
  117. { _M_attach_single(__seq); }
  118. public:
  119. typedef _Iterator iterator_type;
  120. typedef typename _Traits::iterator_category iterator_category;
  121. typedef typename _Traits::value_type value_type;
  122. typedef typename _Traits::difference_type difference_type;
  123. typedef typename _Traits::reference reference;
  124. typedef typename _Traits::pointer pointer;
  125. #if __cplusplus > 201703L && __cpp_lib_concepts
  126. using iterator_concept = std::__detail::__iter_concept<_Iterator>;
  127. #endif
  128. /// @post the iterator is singular and unattached
  129. _Safe_iterator() _GLIBCXX_NOEXCEPT : _Iter_base() { }
  130. /**
  131. * @brief Safe iterator construction from an unsafe iterator and
  132. * its sequence.
  133. *
  134. * @pre @p seq is not NULL
  135. * @post this is not singular
  136. */
  137. _Safe_iterator(_Iterator __i, const _Safe_sequence_base* __seq)
  138. _GLIBCXX_NOEXCEPT
  139. : _Iter_base(__i), _Safe_base(__seq, _S_constant())
  140. {
  141. _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
  142. _M_message(__msg_init_singular)
  143. ._M_iterator(*this, "this"));
  144. }
  145. /**
  146. * @brief Copy construction.
  147. */
  148. _Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
  149. : _Iter_base(__x.base()), _Safe_base()
  150. {
  151. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  152. // DR 408. Is vector<reverse_iterator<char*> > forbidden?
  153. _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
  154. || __x.base() == _Iterator(),
  155. _M_message(__msg_init_copy_singular)
  156. ._M_iterator(*this, "this")
  157. ._M_iterator(__x, "other"));
  158. _M_attach(__x._M_sequence);
  159. }
  160. #if __cplusplus >= 201103L
  161. /**
  162. * @brief Move construction.
  163. * @post __x is singular and unattached
  164. */
  165. _Safe_iterator(_Safe_iterator&& __x) noexcept
  166. : _Iter_base()
  167. {
  168. _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
  169. || __x.base() == _Iterator(),
  170. _M_message(__msg_init_copy_singular)
  171. ._M_iterator(*this, "this")
  172. ._M_iterator(__x, "other"));
  173. _Safe_sequence_base* __seq = __x._M_sequence;
  174. __x._M_detach();
  175. std::swap(base(), __x.base());
  176. _M_attach(__seq);
  177. }
  178. #endif
  179. /**
  180. * @brief Converting constructor from a mutable iterator to a
  181. * constant iterator.
  182. */
  183. template<typename _MutableIterator>
  184. _Safe_iterator(
  185. const _Safe_iterator<_MutableIterator, _Sequence,
  186. typename __gnu_cxx::__enable_if<_IsConstant::__value &&
  187. std::__are_same<_MutableIterator, _OtherIterator>::__value,
  188. _Category>::__type>& __x)
  189. _GLIBCXX_NOEXCEPT
  190. : _Iter_base(__x.base())
  191. {
  192. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  193. // DR 408. Is vector<reverse_iterator<char*> > forbidden?
  194. _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
  195. || __x.base() == _MutableIterator(),
  196. _M_message(__msg_init_const_singular)
  197. ._M_iterator(*this, "this")
  198. ._M_iterator(__x, "other"));
  199. _M_attach(__x._M_sequence);
  200. }
  201. /**
  202. * @brief Copy assignment.
  203. */
  204. _Safe_iterator&
  205. operator=(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
  206. {
  207. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  208. // DR 408. Is vector<reverse_iterator<char*> > forbidden?
  209. _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
  210. || __x.base() == _Iterator(),
  211. _M_message(__msg_copy_singular)
  212. ._M_iterator(*this, "this")
  213. ._M_iterator(__x, "other"));
  214. if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
  215. {
  216. __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
  217. base() = __x.base();
  218. _M_version = __x._M_sequence->_M_version;
  219. }
  220. else
  221. {
  222. _M_detach();
  223. base() = __x.base();
  224. _M_attach(__x._M_sequence);
  225. }
  226. return *this;
  227. }
  228. #if __cplusplus >= 201103L
  229. /**
  230. * @brief Move assignment.
  231. * @post __x is singular and unattached
  232. */
  233. _Safe_iterator&
  234. operator=(_Safe_iterator&& __x) noexcept
  235. {
  236. _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
  237. || __x.base() == _Iterator(),
  238. _M_message(__msg_copy_singular)
  239. ._M_iterator(*this, "this")
  240. ._M_iterator(__x, "other"));
  241. if (std::__addressof(__x) == this)
  242. return *this;
  243. if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
  244. {
  245. __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
  246. base() = __x.base();
  247. _M_version = __x._M_sequence->_M_version;
  248. }
  249. else
  250. {
  251. _M_detach();
  252. base() = __x.base();
  253. _M_attach(__x._M_sequence);
  254. }
  255. __x._M_detach();
  256. __x.base() = _Iterator();
  257. return *this;
  258. }
  259. #endif
  260. /**
  261. * @brief Iterator dereference.
  262. * @pre iterator is dereferenceable
  263. */
  264. reference
  265. operator*() const _GLIBCXX_NOEXCEPT
  266. {
  267. _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
  268. _M_message(__msg_bad_deref)
  269. ._M_iterator(*this, "this"));
  270. return *base();
  271. }
  272. /**
  273. * @brief Iterator dereference.
  274. * @pre iterator is dereferenceable
  275. */
  276. pointer
  277. operator->() const _GLIBCXX_NOEXCEPT
  278. {
  279. _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
  280. _M_message(__msg_bad_deref)
  281. ._M_iterator(*this, "this"));
  282. return base().operator->();
  283. }
  284. // ------ Input iterator requirements ------
  285. /**
  286. * @brief Iterator preincrement
  287. * @pre iterator is incrementable
  288. */
  289. _Safe_iterator&
  290. operator++() _GLIBCXX_NOEXCEPT
  291. {
  292. _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
  293. _M_message(__msg_bad_inc)
  294. ._M_iterator(*this, "this"));
  295. __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
  296. ++base();
  297. return *this;
  298. }
  299. /**
  300. * @brief Iterator postincrement
  301. * @pre iterator is incrementable
  302. */
  303. _Safe_iterator
  304. operator++(int) _GLIBCXX_NOEXCEPT
  305. {
  306. _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
  307. _M_message(__msg_bad_inc)
  308. ._M_iterator(*this, "this"));
  309. __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
  310. return _Safe_iterator(base()++, this->_M_sequence, _Attach_single());
  311. }
  312. // ------ Utilities ------
  313. /// Determine if this is a constant iterator.
  314. static _GLIBCXX_CONSTEXPR bool
  315. _S_constant()
  316. { return _IsConstant::__value; }
  317. /**
  318. * @brief Return the underlying iterator
  319. */
  320. _Iterator&
  321. base() _GLIBCXX_NOEXCEPT { return *this; }
  322. const _Iterator&
  323. base() const _GLIBCXX_NOEXCEPT { return *this; }
  324. /**
  325. * @brief Conversion to underlying non-debug iterator to allow
  326. * better interaction with non-debug containers.
  327. */
  328. operator _Iterator() const _GLIBCXX_NOEXCEPT { return *this; }
  329. /** Attach iterator to the given sequence. */
  330. void
  331. _M_attach(_Safe_sequence_base* __seq)
  332. { _Safe_base::_M_attach(__seq, _S_constant()); }
  333. /** Likewise, but not thread-safe. */
  334. void
  335. _M_attach_single(_Safe_sequence_base* __seq)
  336. { _Safe_base::_M_attach_single(__seq, _S_constant()); }
  337. /// Is the iterator dereferenceable?
  338. bool
  339. _M_dereferenceable() const
  340. { return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
  341. /// Is the iterator before a dereferenceable one?
  342. bool
  343. _M_before_dereferenceable() const
  344. {
  345. if (this->_M_incrementable())
  346. {
  347. _Iterator __base = base();
  348. return ++__base != _M_get_sequence()->_M_base().end();
  349. }
  350. return false;
  351. }
  352. /// Is the iterator incrementable?
  353. bool
  354. _M_incrementable() const
  355. { return !this->_M_singular() && !_M_is_end(); }
  356. // Can we advance the iterator @p __n steps (@p __n may be negative)
  357. bool
  358. _M_can_advance(difference_type __n, bool __strict = false) const;
  359. // Can we advance the iterator using @p __dist in @p __way direction.
  360. template<typename _Diff>
  361. bool
  362. _M_can_advance(const std::pair<_Diff, _Distance_precision>& __dist,
  363. int __way) const;
  364. // Is the iterator range [*this, __rhs) valid?
  365. bool
  366. _M_valid_range(const _Safe_iterator& __rhs,
  367. std::pair<difference_type, _Distance_precision>& __dist,
  368. bool __check_dereferenceable = true) const;
  369. // The sequence this iterator references.
  370. typename __gnu_cxx::__conditional_type<
  371. _IsConstant::__value, const _Sequence*, _Sequence*>::__type
  372. _M_get_sequence() const
  373. { return static_cast<_Sequence*>(_M_sequence); }
  374. // Get distance to __rhs.
  375. typename _Distance_traits<_Iterator>::__type
  376. _M_get_distance_to(const _Safe_iterator& __rhs) const;
  377. // Get distance from sequence begin up to *this.
  378. typename _Distance_traits<_Iterator>::__type
  379. _M_get_distance_from_begin() const;
  380. // Get distance from *this to sequence end.
  381. typename _Distance_traits<_Iterator>::__type
  382. _M_get_distance_to_end() const;
  383. /// Is this iterator equal to the sequence's begin() iterator?
  384. bool
  385. _M_is_begin() const
  386. { return base() == _M_get_sequence()->_M_base().begin(); }
  387. /// Is this iterator equal to the sequence's end() iterator?
  388. bool
  389. _M_is_end() const
  390. { return base() == _M_get_sequence()->_M_base().end(); }
  391. /// Is this iterator equal to the sequence's before_begin() iterator if
  392. /// any?
  393. bool
  394. _M_is_before_begin() const
  395. { return _BeforeBeginHelper<_Sequence>::_S_Is(*this); }
  396. /// Is this iterator equal to the sequence's before_begin() iterator if
  397. /// any or begin() otherwise?
  398. bool
  399. _M_is_beginnest() const
  400. { return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(*this); }
  401. // ------ Operators ------
  402. typedef _Safe_iterator<_Iterator, _Sequence, iterator_category> _Self;
  403. friend bool
  404. operator==(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
  405. {
  406. _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
  407. return __lhs.base() == __rhs.base();
  408. }
  409. template<typename _IteR>
  410. friend bool
  411. operator==(const _Self& __lhs,
  412. const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
  413. _GLIBCXX_NOEXCEPT
  414. {
  415. _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
  416. return __lhs.base() == __rhs.base();
  417. }
  418. #if ! __cpp_lib_three_way_comparison
  419. friend bool
  420. operator!=(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
  421. {
  422. _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
  423. return __lhs.base() != __rhs.base();
  424. }
  425. template<typename _IteR>
  426. friend bool
  427. operator!=(const _Self& __lhs,
  428. const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
  429. _GLIBCXX_NOEXCEPT
  430. {
  431. _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
  432. return __lhs.base() != __rhs.base();
  433. }
  434. #endif // three-way comparison
  435. };
  436. template<typename _Iterator, typename _Sequence>
  437. class _Safe_iterator<_Iterator, _Sequence, std::bidirectional_iterator_tag>
  438. : public _Safe_iterator<_Iterator, _Sequence, std::forward_iterator_tag>
  439. {
  440. typedef _Safe_iterator<_Iterator, _Sequence,
  441. std::forward_iterator_tag> _Safe_base;
  442. protected:
  443. typedef typename _Safe_base::_OtherIterator _OtherIterator;
  444. typedef typename _Safe_base::_Attach_single _Attach_single;
  445. _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
  446. _GLIBCXX_NOEXCEPT
  447. : _Safe_base(__i, __seq, _Attach_single())
  448. { }
  449. public:
  450. /// @post the iterator is singular and unattached
  451. _Safe_iterator() _GLIBCXX_NOEXCEPT { }
  452. /**
  453. * @brief Safe iterator construction from an unsafe iterator and
  454. * its sequence.
  455. *
  456. * @pre @p seq is not NULL
  457. * @post this is not singular
  458. */
  459. _Safe_iterator(_Iterator __i, const _Safe_sequence_base* __seq)
  460. _GLIBCXX_NOEXCEPT
  461. : _Safe_base(__i, __seq)
  462. { }
  463. /**
  464. * @brief Copy construction.
  465. */
  466. _Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
  467. : _Safe_base(__x)
  468. { }
  469. #if __cplusplus >= 201103L
  470. /** @brief Move construction. */
  471. _Safe_iterator(_Safe_iterator&&) = default;
  472. #endif
  473. /**
  474. * @brief Converting constructor from a mutable iterator to a
  475. * constant iterator.
  476. */
  477. template<typename _MutableIterator>
  478. _Safe_iterator(
  479. const _Safe_iterator<_MutableIterator, _Sequence,
  480. typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
  481. std::__are_same<_MutableIterator, _OtherIterator>::__value,
  482. std::bidirectional_iterator_tag>::__type>& __x)
  483. _GLIBCXX_NOEXCEPT
  484. : _Safe_base(__x)
  485. { }
  486. #if __cplusplus >= 201103L
  487. /** @brief Copy assignment. */
  488. _Safe_iterator&
  489. operator=(const _Safe_iterator&) = default;
  490. /** @brief Move assignment. */
  491. _Safe_iterator&
  492. operator=(_Safe_iterator&&) = default;
  493. #else
  494. /** @brief Copy assignment. */
  495. _Safe_iterator&
  496. operator=(const _Safe_iterator& __x)
  497. {
  498. _Safe_base::operator=(__x);
  499. return *this;
  500. }
  501. #endif
  502. // ------ Input iterator requirements ------
  503. /**
  504. * @brief Iterator preincrement
  505. * @pre iterator is incrementable
  506. */
  507. _Safe_iterator&
  508. operator++() _GLIBCXX_NOEXCEPT
  509. {
  510. _Safe_base::operator++();
  511. return *this;
  512. }
  513. /**
  514. * @brief Iterator postincrement
  515. * @pre iterator is incrementable
  516. */
  517. _Safe_iterator
  518. operator++(int) _GLIBCXX_NOEXCEPT
  519. {
  520. _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
  521. _M_message(__msg_bad_inc)
  522. ._M_iterator(*this, "this"));
  523. __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
  524. return _Safe_iterator(this->base()++, this->_M_sequence,
  525. _Attach_single());
  526. }
  527. // ------ Bidirectional iterator requirements ------
  528. /**
  529. * @brief Iterator predecrement
  530. * @pre iterator is decrementable
  531. */
  532. _Safe_iterator&
  533. operator--() _GLIBCXX_NOEXCEPT
  534. {
  535. _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
  536. _M_message(__msg_bad_dec)
  537. ._M_iterator(*this, "this"));
  538. __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
  539. --this->base();
  540. return *this;
  541. }
  542. /**
  543. * @brief Iterator postdecrement
  544. * @pre iterator is decrementable
  545. */
  546. _Safe_iterator
  547. operator--(int) _GLIBCXX_NOEXCEPT
  548. {
  549. _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
  550. _M_message(__msg_bad_dec)
  551. ._M_iterator(*this, "this"));
  552. __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
  553. return _Safe_iterator(this->base()--, this->_M_sequence,
  554. _Attach_single());
  555. }
  556. // ------ Utilities ------
  557. // Is the iterator decrementable?
  558. bool
  559. _M_decrementable() const
  560. { return !this->_M_singular() && !this->_M_is_begin(); }
  561. };
  562. template<typename _Iterator, typename _Sequence>
  563. class _Safe_iterator<_Iterator, _Sequence, std::random_access_iterator_tag>
  564. : public _Safe_iterator<_Iterator, _Sequence,
  565. std::bidirectional_iterator_tag>
  566. {
  567. typedef _Safe_iterator<_Iterator, _Sequence,
  568. std::bidirectional_iterator_tag> _Safe_base;
  569. typedef typename _Safe_base::_OtherIterator _OtherIterator;
  570. typedef typename _Safe_base::_Self _Self;
  571. typedef _Safe_iterator<_OtherIterator, _Sequence,
  572. std::random_access_iterator_tag> _OtherSelf;
  573. typedef typename _Safe_base::_Attach_single _Attach_single;
  574. _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
  575. _GLIBCXX_NOEXCEPT
  576. : _Safe_base(__i, __seq, _Attach_single())
  577. { }
  578. public:
  579. typedef typename _Safe_base::difference_type difference_type;
  580. typedef typename _Safe_base::reference reference;
  581. /// @post the iterator is singular and unattached
  582. _Safe_iterator() _GLIBCXX_NOEXCEPT { }
  583. /**
  584. * @brief Safe iterator construction from an unsafe iterator and
  585. * its sequence.
  586. *
  587. * @pre @p seq is not NULL
  588. * @post this is not singular
  589. */
  590. _Safe_iterator(_Iterator __i, const _Safe_sequence_base* __seq)
  591. _GLIBCXX_NOEXCEPT
  592. : _Safe_base(__i, __seq)
  593. { }
  594. /**
  595. * @brief Copy construction.
  596. */
  597. _Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
  598. : _Safe_base(__x)
  599. { }
  600. #if __cplusplus >= 201103L
  601. /** @brief Move construction. */
  602. _Safe_iterator(_Safe_iterator&&) = default;
  603. #endif
  604. /**
  605. * @brief Converting constructor from a mutable iterator to a
  606. * constant iterator.
  607. */
  608. template<typename _MutableIterator>
  609. _Safe_iterator(
  610. const _Safe_iterator<_MutableIterator, _Sequence,
  611. typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
  612. std::__are_same<_MutableIterator, _OtherIterator>::__value,
  613. std::random_access_iterator_tag>::__type>& __x)
  614. _GLIBCXX_NOEXCEPT
  615. : _Safe_base(__x)
  616. { }
  617. #if __cplusplus >= 201103L
  618. /** @brief Copy assignment. */
  619. _Safe_iterator&
  620. operator=(const _Safe_iterator&) = default;
  621. /** @brief Move assignment. */
  622. _Safe_iterator&
  623. operator=(_Safe_iterator&&) = default;
  624. #else
  625. /** @brief Copy assignment. */
  626. _Safe_iterator&
  627. operator=(const _Safe_iterator& __x)
  628. {
  629. _Safe_base::operator=(__x);
  630. return *this;
  631. }
  632. #endif
  633. // Is the iterator range [*this, __rhs) valid?
  634. bool
  635. _M_valid_range(const _Safe_iterator& __rhs,
  636. std::pair<difference_type,
  637. _Distance_precision>& __dist) const;
  638. // ------ Input iterator requirements ------
  639. /**
  640. * @brief Iterator preincrement
  641. * @pre iterator is incrementable
  642. */
  643. _Safe_iterator&
  644. operator++() _GLIBCXX_NOEXCEPT
  645. {
  646. _Safe_base::operator++();
  647. return *this;
  648. }
  649. /**
  650. * @brief Iterator postincrement
  651. * @pre iterator is incrementable
  652. */
  653. _Safe_iterator
  654. operator++(int) _GLIBCXX_NOEXCEPT
  655. {
  656. _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
  657. _M_message(__msg_bad_inc)
  658. ._M_iterator(*this, "this"));
  659. __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
  660. return _Safe_iterator(this->base()++, this->_M_sequence,
  661. _Attach_single());
  662. }
  663. // ------ Bidirectional iterator requirements ------
  664. /**
  665. * @brief Iterator predecrement
  666. * @pre iterator is decrementable
  667. */
  668. _Safe_iterator&
  669. operator--() _GLIBCXX_NOEXCEPT
  670. {
  671. _Safe_base::operator--();
  672. return *this;
  673. }
  674. /**
  675. * @brief Iterator postdecrement
  676. * @pre iterator is decrementable
  677. */
  678. _Safe_iterator
  679. operator--(int) _GLIBCXX_NOEXCEPT
  680. {
  681. _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
  682. _M_message(__msg_bad_dec)
  683. ._M_iterator(*this, "this"));
  684. __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
  685. return _Safe_iterator(this->base()--, this->_M_sequence,
  686. _Attach_single());
  687. }
  688. // ------ Random access iterator requirements ------
  689. reference
  690. operator[](difference_type __n) const _GLIBCXX_NOEXCEPT
  691. {
  692. _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
  693. && this->_M_can_advance(__n + 1),
  694. _M_message(__msg_iter_subscript_oob)
  695. ._M_iterator(*this)._M_integer(__n));
  696. return this->base()[__n];
  697. }
  698. _Safe_iterator&
  699. operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
  700. {
  701. _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
  702. _M_message(__msg_advance_oob)
  703. ._M_iterator(*this)._M_integer(__n));
  704. __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
  705. this->base() += __n;
  706. return *this;
  707. }
  708. _Safe_iterator&
  709. operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
  710. {
  711. _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
  712. _M_message(__msg_retreat_oob)
  713. ._M_iterator(*this)._M_integer(__n));
  714. __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
  715. this->base() -= __n;
  716. return *this;
  717. }
  718. #if __cpp_lib_three_way_comparison
  719. friend auto
  720. operator<=>(const _Self& __lhs, const _Self& __rhs) noexcept
  721. {
  722. _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
  723. return __lhs.base() <=> __rhs.base();
  724. }
  725. friend auto
  726. operator<=>(const _Self& __lhs, const _OtherSelf& __rhs) noexcept
  727. {
  728. _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
  729. return __lhs.base() <=> __rhs.base();
  730. }
  731. #else
  732. friend bool
  733. operator<(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
  734. {
  735. _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
  736. return __lhs.base() < __rhs.base();
  737. }
  738. friend bool
  739. operator<(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
  740. {
  741. _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
  742. return __lhs.base() < __rhs.base();
  743. }
  744. friend bool
  745. operator<=(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
  746. {
  747. _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
  748. return __lhs.base() <= __rhs.base();
  749. }
  750. friend bool
  751. operator<=(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
  752. {
  753. _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
  754. return __lhs.base() <= __rhs.base();
  755. }
  756. friend bool
  757. operator>(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
  758. {
  759. _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
  760. return __lhs.base() > __rhs.base();
  761. }
  762. friend bool
  763. operator>(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
  764. {
  765. _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
  766. return __lhs.base() > __rhs.base();
  767. }
  768. friend bool
  769. operator>=(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
  770. {
  771. _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
  772. return __lhs.base() >= __rhs.base();
  773. }
  774. friend bool
  775. operator>=(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
  776. {
  777. _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
  778. return __lhs.base() >= __rhs.base();
  779. }
  780. #endif // three-way comparison
  781. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  782. // According to the resolution of DR179 not only the various comparison
  783. // operators but also operator- must accept mixed iterator/const_iterator
  784. // parameters.
  785. friend difference_type
  786. operator-(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
  787. {
  788. _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
  789. return __lhs.base() - __rhs.base();
  790. }
  791. friend difference_type
  792. operator-(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
  793. {
  794. _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
  795. return __lhs.base() - __rhs.base();
  796. }
  797. friend _Self
  798. operator+(const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
  799. {
  800. _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
  801. _M_message(__msg_advance_oob)
  802. ._M_iterator(__x)._M_integer(__n));
  803. return _Safe_iterator(__x.base() + __n, __x._M_sequence);
  804. }
  805. friend _Self
  806. operator+(difference_type __n, const _Self& __x) _GLIBCXX_NOEXCEPT
  807. {
  808. _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
  809. _M_message(__msg_advance_oob)
  810. ._M_iterator(__x)._M_integer(__n));
  811. return _Safe_iterator(__n + __x.base(), __x._M_sequence);
  812. }
  813. friend _Self
  814. operator-(const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
  815. {
  816. _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(-__n),
  817. _M_message(__msg_retreat_oob)
  818. ._M_iterator(__x)._M_integer(__n));
  819. return _Safe_iterator(__x.base() - __n, __x._M_sequence);
  820. }
  821. };
  822. /** Safe iterators know how to check if they form a valid range. */
  823. template<typename _Iterator, typename _Sequence, typename _Category>
  824. inline bool
  825. __valid_range(const _Safe_iterator<_Iterator, _Sequence,
  826. _Category>& __first,
  827. const _Safe_iterator<_Iterator, _Sequence,
  828. _Category>& __last,
  829. typename _Distance_traits<_Iterator>::__type& __dist)
  830. { return __first._M_valid_range(__last, __dist); }
  831. template<typename _Iterator, typename _Sequence, typename _Category>
  832. inline bool
  833. __valid_range(const _Safe_iterator<_Iterator, _Sequence,
  834. _Category>& __first,
  835. const _Safe_iterator<_Iterator, _Sequence,
  836. _Category>& __last)
  837. {
  838. typename _Distance_traits<_Iterator>::__type __dist;
  839. return __first._M_valid_range(__last, __dist);
  840. }
  841. template<typename _Iterator, typename _Sequence, typename _Category,
  842. typename _Size>
  843. inline bool
  844. __can_advance(const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
  845. _Size __n)
  846. { return __it._M_can_advance(__n); }
  847. template<typename _Iterator, typename _Sequence, typename _Category,
  848. typename _Diff>
  849. inline bool
  850. __can_advance(const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
  851. const std::pair<_Diff, _Distance_precision>& __dist,
  852. int __way)
  853. { return __it._M_can_advance(__dist, __way); }
  854. template<typename _Iterator, typename _Sequence>
  855. _Iterator
  856. __base(const _Safe_iterator<_Iterator, _Sequence,
  857. std::random_access_iterator_tag>& __it)
  858. { return __it.base(); }
  859. #if __cplusplus < 201103L
  860. template<typename _Iterator, typename _Sequence>
  861. struct _Unsafe_type<_Safe_iterator<_Iterator, _Sequence> >
  862. { typedef _Iterator _Type; };
  863. #endif
  864. template<typename _Iterator, typename _Sequence>
  865. inline _Iterator
  866. __unsafe(const _Safe_iterator<_Iterator, _Sequence>& __it)
  867. { return __it.base(); }
  868. } // namespace __gnu_debug
  869. #undef _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS
  870. #undef _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS
  871. #undef _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS
  872. #undef _GLIBCXX_DEBUG_VERIFY_OPERANDS
  873. #include <debug/safe_iterator.tcc>
  874. #endif