wrap_iter.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. // -*- C++ -*-
  2. //===----------------------------------------------------------------------===//
  3. //
  4. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5. // See https://llvm.org/LICENSE.txt for license information.
  6. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef _LIBCPP___ITERATOR_WRAP_ITER_H
  10. #define _LIBCPP___ITERATOR_WRAP_ITER_H
  11. #include <__config>
  12. #include <__debug>
  13. #include <__iterator/iterator_traits.h>
  14. #include <__memory/addressof.h>
  15. #include <__memory/pointer_traits.h>
  16. #include <type_traits>
  17. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  18. #pragma GCC system_header
  19. #endif
  20. _LIBCPP_BEGIN_NAMESPACE_STD
  21. template <class _Iter>
  22. class __wrap_iter
  23. {
  24. public:
  25. typedef _Iter iterator_type;
  26. typedef typename iterator_traits<iterator_type>::value_type value_type;
  27. typedef typename iterator_traits<iterator_type>::difference_type difference_type;
  28. typedef typename iterator_traits<iterator_type>::pointer pointer;
  29. typedef typename iterator_traits<iterator_type>::reference reference;
  30. typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;
  31. #if _LIBCPP_STD_VER > 17
  32. typedef contiguous_iterator_tag iterator_concept;
  33. #endif
  34. private:
  35. iterator_type __i;
  36. public:
  37. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter() _NOEXCEPT
  38. #if _LIBCPP_STD_VER > 11
  39. : __i{}
  40. #endif
  41. {
  42. #if _LIBCPP_DEBUG_LEVEL == 2
  43. __get_db()->__insert_i(this);
  44. #endif
  45. }
  46. template <class _Up> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
  47. __wrap_iter(const __wrap_iter<_Up>& __u,
  48. typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = nullptr) _NOEXCEPT
  49. : __i(__u.base())
  50. {
  51. #if _LIBCPP_DEBUG_LEVEL == 2
  52. __get_db()->__iterator_copy(this, _VSTD::addressof(__u));
  53. #endif
  54. }
  55. #if _LIBCPP_DEBUG_LEVEL == 2
  56. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
  57. __wrap_iter(const __wrap_iter& __x)
  58. : __i(__x.base())
  59. {
  60. __get_db()->__iterator_copy(this, _VSTD::addressof(__x));
  61. }
  62. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
  63. __wrap_iter& operator=(const __wrap_iter& __x)
  64. {
  65. if (this != _VSTD::addressof(__x))
  66. {
  67. __get_db()->__iterator_copy(this, _VSTD::addressof(__x));
  68. __i = __x.__i;
  69. }
  70. return *this;
  71. }
  72. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
  73. ~__wrap_iter()
  74. {
  75. __get_db()->__erase_i(this);
  76. }
  77. #endif
  78. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator*() const _NOEXCEPT
  79. {
  80. #if _LIBCPP_DEBUG_LEVEL == 2
  81. _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
  82. "Attempted to dereference a non-dereferenceable iterator");
  83. #endif
  84. return *__i;
  85. }
  86. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG pointer operator->() const _NOEXCEPT
  87. {
  88. #if _LIBCPP_DEBUG_LEVEL == 2
  89. _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
  90. "Attempted to dereference a non-dereferenceable iterator");
  91. #endif
  92. return _VSTD::__to_address(__i);
  93. }
  94. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator++() _NOEXCEPT
  95. {
  96. #if _LIBCPP_DEBUG_LEVEL == 2
  97. _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
  98. "Attempted to increment a non-incrementable iterator");
  99. #endif
  100. ++__i;
  101. return *this;
  102. }
  103. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator++(int) _NOEXCEPT
  104. {__wrap_iter __tmp(*this); ++(*this); return __tmp;}
  105. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator--() _NOEXCEPT
  106. {
  107. #if _LIBCPP_DEBUG_LEVEL == 2
  108. _LIBCPP_ASSERT(__get_const_db()->__decrementable(this),
  109. "Attempted to decrement a non-decrementable iterator");
  110. #endif
  111. --__i;
  112. return *this;
  113. }
  114. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator--(int) _NOEXCEPT
  115. {__wrap_iter __tmp(*this); --(*this); return __tmp;}
  116. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator+ (difference_type __n) const _NOEXCEPT
  117. {__wrap_iter __w(*this); __w += __n; return __w;}
  118. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator+=(difference_type __n) _NOEXCEPT
  119. {
  120. #if _LIBCPP_DEBUG_LEVEL == 2
  121. _LIBCPP_ASSERT(__get_const_db()->__addable(this, __n),
  122. "Attempted to add/subtract an iterator outside its valid range");
  123. #endif
  124. __i += __n;
  125. return *this;
  126. }
  127. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator- (difference_type __n) const _NOEXCEPT
  128. {return *this + (-__n);}
  129. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator-=(difference_type __n) _NOEXCEPT
  130. {*this += -__n; return *this;}
  131. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator[](difference_type __n) const _NOEXCEPT
  132. {
  133. #if _LIBCPP_DEBUG_LEVEL == 2
  134. _LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n),
  135. "Attempted to subscript an iterator outside its valid range");
  136. #endif
  137. return __i[__n];
  138. }
  139. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG iterator_type base() const _NOEXCEPT {return __i;}
  140. private:
  141. #if _LIBCPP_DEBUG_LEVEL == 2
  142. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(const void* __p, iterator_type __x) : __i(__x)
  143. {
  144. __get_db()->__insert_ic(this, __p);
  145. }
  146. #else
  147. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {}
  148. #endif
  149. template <class _Up> friend class __wrap_iter;
  150. template <class _CharT, class _Traits, class _Alloc> friend class basic_string;
  151. template <class _Tp, class _Alloc> friend class _LIBCPP_TEMPLATE_VIS vector;
  152. template <class _Tp, size_t> friend class _LIBCPP_TEMPLATE_VIS span;
  153. };
  154. template <class _Iter1>
  155. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
  156. bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
  157. {
  158. return __x.base() == __y.base();
  159. }
  160. template <class _Iter1, class _Iter2>
  161. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
  162. bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
  163. {
  164. return __x.base() == __y.base();
  165. }
  166. template <class _Iter1>
  167. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
  168. bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
  169. {
  170. #if _LIBCPP_DEBUG_LEVEL == 2
  171. _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)),
  172. "Attempted to compare incomparable iterators");
  173. #endif
  174. return __x.base() < __y.base();
  175. }
  176. template <class _Iter1, class _Iter2>
  177. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
  178. bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
  179. {
  180. #if _LIBCPP_DEBUG_LEVEL == 2
  181. _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
  182. "Attempted to compare incomparable iterators");
  183. #endif
  184. return __x.base() < __y.base();
  185. }
  186. template <class _Iter1>
  187. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
  188. bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
  189. {
  190. return !(__x == __y);
  191. }
  192. template <class _Iter1, class _Iter2>
  193. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
  194. bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
  195. {
  196. return !(__x == __y);
  197. }
  198. template <class _Iter1>
  199. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
  200. bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
  201. {
  202. return __y < __x;
  203. }
  204. template <class _Iter1, class _Iter2>
  205. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
  206. bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
  207. {
  208. return __y < __x;
  209. }
  210. template <class _Iter1>
  211. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
  212. bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
  213. {
  214. return !(__x < __y);
  215. }
  216. template <class _Iter1, class _Iter2>
  217. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
  218. bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
  219. {
  220. return !(__x < __y);
  221. }
  222. template <class _Iter1>
  223. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
  224. bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
  225. {
  226. return !(__y < __x);
  227. }
  228. template <class _Iter1, class _Iter2>
  229. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
  230. bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
  231. {
  232. return !(__y < __x);
  233. }
  234. template <class _Iter1, class _Iter2>
  235. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
  236. #ifndef _LIBCPP_CXX03_LANG
  237. auto operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
  238. -> decltype(__x.base() - __y.base())
  239. #else
  240. typename __wrap_iter<_Iter1>::difference_type
  241. operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
  242. #endif // C++03
  243. {
  244. #if _LIBCPP_DEBUG_LEVEL == 2
  245. _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)),
  246. "Attempted to subtract incompatible iterators");
  247. #endif
  248. return __x.base() - __y.base();
  249. }
  250. template <class _Iter1>
  251. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
  252. __wrap_iter<_Iter1> operator+(typename __wrap_iter<_Iter1>::difference_type __n, __wrap_iter<_Iter1> __x) _NOEXCEPT
  253. {
  254. __x += __n;
  255. return __x;
  256. }
  257. #if _LIBCPP_STD_VER <= 17
  258. template <class _It>
  259. struct __is_cpp17_contiguous_iterator<__wrap_iter<_It> > : true_type {};
  260. #endif
  261. template <class _It>
  262. struct _LIBCPP_TEMPLATE_VIS pointer_traits<__wrap_iter<_It> >
  263. {
  264. typedef __wrap_iter<_It> pointer;
  265. typedef typename pointer_traits<_It>::element_type element_type;
  266. typedef typename pointer_traits<_It>::difference_type difference_type;
  267. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
  268. static element_type *to_address(pointer __w) _NOEXCEPT {
  269. return _VSTD::__to_address(__w.base());
  270. }
  271. };
  272. _LIBCPP_END_NAMESPACE_STD
  273. #endif // _LIBCPP___ITERATOR_WRAP_ITER_H