safe_iterator.h 31 KB

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