1fe6060f1SDimitry Andric // -*- C++ -*- 2fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 3fe6060f1SDimitry Andric // 4fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7fe6060f1SDimitry Andric // 8fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 9fe6060f1SDimitry Andric 10fe6060f1SDimitry Andric #ifndef _LIBCPP___ITERATOR_COMMON_ITERATOR_H 11fe6060f1SDimitry Andric #define _LIBCPP___ITERATOR_COMMON_ITERATOR_H 12fe6060f1SDimitry Andric 1381ad6265SDimitry Andric #include <__assert> 14bdd1243dSDimitry Andric #include <__concepts/assignable.h> 15bdd1243dSDimitry Andric #include <__concepts/constructible.h> 16bdd1243dSDimitry Andric #include <__concepts/convertible_to.h> 17bdd1243dSDimitry Andric #include <__concepts/copyable.h> 18bdd1243dSDimitry Andric #include <__concepts/derived_from.h> 19bdd1243dSDimitry Andric #include <__concepts/equality_comparable.h> 20bdd1243dSDimitry Andric #include <__concepts/same_as.h> 21fe6060f1SDimitry Andric #include <__config> 22fe6060f1SDimitry Andric #include <__iterator/concepts.h> 23fe6060f1SDimitry Andric #include <__iterator/incrementable_traits.h> 24fe6060f1SDimitry Andric #include <__iterator/iter_move.h> 25fe6060f1SDimitry Andric #include <__iterator/iter_swap.h> 26fe6060f1SDimitry Andric #include <__iterator/iterator_traits.h> 27fe6060f1SDimitry Andric #include <__iterator/readable_traits.h> 2806c3fb27SDimitry Andric #include <__memory/addressof.h> 29bdd1243dSDimitry Andric #include <__type_traits/is_pointer.h> 30bdd1243dSDimitry Andric #include <__utility/declval.h> 31fe6060f1SDimitry Andric #include <variant> 32fe6060f1SDimitry Andric 33fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 34fe6060f1SDimitry Andric # pragma GCC system_header 35fe6060f1SDimitry Andric #endif 36fe6060f1SDimitry Andric 3706c3fb27SDimitry Andric _LIBCPP_PUSH_MACROS 3806c3fb27SDimitry Andric #include <__undef_macros> 3906c3fb27SDimitry Andric 40fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 41fe6060f1SDimitry Andric 4206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 43fe6060f1SDimitry Andric 4404eeddc0SDimitry Andric template <class _Iter> 4504eeddc0SDimitry Andric concept __can_use_postfix_proxy = 46cb14a3feSDimitry Andric constructible_from<iter_value_t<_Iter>, iter_reference_t<_Iter>> && move_constructible<iter_value_t<_Iter>>; 4704eeddc0SDimitry Andric 48fe6060f1SDimitry Andric template <input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent> 49fe6060f1SDimitry Andric requires(!same_as<_Iter, _Sent> && copyable<_Iter>) 50fe6060f1SDimitry Andric class common_iterator { 5181ad6265SDimitry Andric struct __proxy { 5206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const iter_value_t<_Iter>* operator->() const noexcept { 535f757f3fSDimitry Andric return std::addressof(__value_); 54fe6060f1SDimitry Andric } 5581ad6265SDimitry Andric iter_value_t<_Iter> __value_; 56fe6060f1SDimitry Andric }; 57fe6060f1SDimitry Andric 5881ad6265SDimitry Andric struct __postfix_proxy { 59cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const iter_value_t<_Iter>& operator*() const noexcept { return __value_; } 6081ad6265SDimitry Andric iter_value_t<_Iter> __value_; 61fe6060f1SDimitry Andric }; 62fe6060f1SDimitry Andric 63fe6060f1SDimitry Andric variant<_Iter, _Sent> __hold_; 645f757f3fSDimitry Andric template <input_or_output_iterator _OtherIter, sentinel_for<_OtherIter> _OtherSent> 655f757f3fSDimitry Andric requires(!same_as<_OtherIter, _OtherSent> && copyable<_OtherIter>) 665f757f3fSDimitry Andric friend class common_iterator; 67fe6060f1SDimitry Andric 685f757f3fSDimitry Andric public: 69cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI common_iterator() 70cb14a3feSDimitry Andric requires default_initializable<_Iter> 71cb14a3feSDimitry Andric = default; 72fe6060f1SDimitry Andric 735f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(_Iter __i) : __hold_(in_place_type<_Iter>, std::move(__i)) {} 745f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(_Sent __s) : __hold_(in_place_type<_Sent>, std::move(__s)) {} 75fe6060f1SDimitry Andric 76fe6060f1SDimitry Andric template <class _I2, class _S2> 77fe6060f1SDimitry Andric requires convertible_to<const _I2&, _Iter> && convertible_to<const _S2&, _Sent> 7806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(const common_iterator<_I2, _S2>& __other) 79fe6060f1SDimitry Andric : __hold_([&]() -> variant<_Iter, _Sent> { 80cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 81cb14a3feSDimitry Andric !__other.__hold_.valueless_by_exception(), "Attempted to construct from a valueless common_iterator"); 82fe6060f1SDimitry Andric if (__other.__hold_.index() == 0) 835f757f3fSDimitry Andric return variant<_Iter, _Sent>{in_place_index<0>, std::__unchecked_get<0>(__other.__hold_)}; 845f757f3fSDimitry Andric return variant<_Iter, _Sent>{in_place_index<1>, std::__unchecked_get<1>(__other.__hold_)}; 85fe6060f1SDimitry Andric }()) {} 86fe6060f1SDimitry Andric 87fe6060f1SDimitry Andric template <class _I2, class _S2> 88fe6060f1SDimitry Andric requires convertible_to<const _I2&, _Iter> && convertible_to<const _S2&, _Sent> && 89fe6060f1SDimitry Andric assignable_from<_Iter&, const _I2&> && assignable_from<_Sent&, const _S2&> 9006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI common_iterator& operator=(const common_iterator<_I2, _S2>& __other) { 91cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 92cb14a3feSDimitry Andric !__other.__hold_.valueless_by_exception(), "Attempted to assign from a valueless common_iterator"); 93fe6060f1SDimitry Andric 94fe6060f1SDimitry Andric auto __idx = __hold_.index(); 95fe6060f1SDimitry Andric auto __other_idx = __other.__hold_.index(); 96fe6060f1SDimitry Andric 97fe6060f1SDimitry Andric // If they're the same index, just assign. 98fe6060f1SDimitry Andric if (__idx == 0 && __other_idx == 0) 995f757f3fSDimitry Andric std::__unchecked_get<0>(__hold_) = std::__unchecked_get<0>(__other.__hold_); 100fe6060f1SDimitry Andric else if (__idx == 1 && __other_idx == 1) 1015f757f3fSDimitry Andric std::__unchecked_get<1>(__hold_) = std::__unchecked_get<1>(__other.__hold_); 102fe6060f1SDimitry Andric 103fe6060f1SDimitry Andric // Otherwise replace with the oposite element. 104fe6060f1SDimitry Andric else if (__other_idx == 1) 1055f757f3fSDimitry Andric __hold_.template emplace<1>(std::__unchecked_get<1>(__other.__hold_)); 106fe6060f1SDimitry Andric else if (__other_idx == 0) 1075f757f3fSDimitry Andric __hold_.template emplace<0>(std::__unchecked_get<0>(__other.__hold_)); 108fe6060f1SDimitry Andric 109fe6060f1SDimitry Andric return *this; 110fe6060f1SDimitry Andric } 111fe6060f1SDimitry Andric 112cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() { 113cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 114cb14a3feSDimitry Andric std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); 1155f757f3fSDimitry Andric return *std::__unchecked_get<_Iter>(__hold_); 116fe6060f1SDimitry Andric } 117fe6060f1SDimitry Andric 11806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const 119fe6060f1SDimitry Andric requires __dereferenceable<const _Iter> 120fe6060f1SDimitry Andric { 121cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 122cb14a3feSDimitry Andric std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); 1235f757f3fSDimitry Andric return *std::__unchecked_get<_Iter>(__hold_); 124fe6060f1SDimitry Andric } 125fe6060f1SDimitry Andric 126fe6060f1SDimitry Andric template <class _I2 = _Iter> 127*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI auto operator->() const 128cb14a3feSDimitry Andric requires indirectly_readable<const _I2> && (requires(const _I2& __i) { 129cb14a3feSDimitry Andric __i.operator->(); 130cb14a3feSDimitry Andric } || is_reference_v<iter_reference_t<_I2>> || constructible_from<iter_value_t<_I2>, iter_reference_t<_I2>>) 131fe6060f1SDimitry Andric { 132cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 133cb14a3feSDimitry Andric std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); 134fe6060f1SDimitry Andric if constexpr (is_pointer_v<_Iter> || requires(const _Iter& __i) { __i.operator->(); }) { 1355f757f3fSDimitry Andric return std::__unchecked_get<_Iter>(__hold_); 136fe6060f1SDimitry Andric } else if constexpr (is_reference_v<iter_reference_t<_Iter>>) { 1375f757f3fSDimitry Andric auto&& __tmp = *std::__unchecked_get<_Iter>(__hold_); 1385f757f3fSDimitry Andric return std::addressof(__tmp); 139fe6060f1SDimitry Andric } else { 1405f757f3fSDimitry Andric return __proxy{*std::__unchecked_get<_Iter>(__hold_)}; 141fe6060f1SDimitry Andric } 142fe6060f1SDimitry Andric } 143fe6060f1SDimitry Andric 14406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI common_iterator& operator++() { 145cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 146cb14a3feSDimitry Andric std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); 147cb14a3feSDimitry Andric ++std::__unchecked_get<_Iter>(__hold_); 148cb14a3feSDimitry Andric return *this; 149fe6060f1SDimitry Andric } 150fe6060f1SDimitry Andric 15106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI decltype(auto) operator++(int) { 152cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 153cb14a3feSDimitry Andric std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); 154fe6060f1SDimitry Andric if constexpr (forward_iterator<_Iter>) { 155fe6060f1SDimitry Andric auto __tmp = *this; 156fe6060f1SDimitry Andric ++*this; 157fe6060f1SDimitry Andric return __tmp; 158cb14a3feSDimitry Andric } else if constexpr (requires(_Iter& __i) { 159cb14a3feSDimitry Andric { *__i++ } -> __can_reference; 160cb14a3feSDimitry Andric } || !__can_use_postfix_proxy<_Iter>) { 1615f757f3fSDimitry Andric return std::__unchecked_get<_Iter>(__hold_)++; 162fe6060f1SDimitry Andric } else { 16381ad6265SDimitry Andric auto __p = __postfix_proxy{**this}; 164fe6060f1SDimitry Andric ++*this; 165fe6060f1SDimitry Andric return __p; 166fe6060f1SDimitry Andric } 167fe6060f1SDimitry Andric } 168fe6060f1SDimitry Andric 169fe6060f1SDimitry Andric template <class _I2, sentinel_for<_Iter> _S2> 170fe6060f1SDimitry Andric requires sentinel_for<_Sent, _I2> 171cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr bool 172cb14a3feSDimitry Andric operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { 173cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 174cb14a3feSDimitry Andric !__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); 175cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 176cb14a3feSDimitry Andric !__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); 177fe6060f1SDimitry Andric 178fe6060f1SDimitry Andric auto __x_index = __x.__hold_.index(); 179fe6060f1SDimitry Andric auto __y_index = __y.__hold_.index(); 180fe6060f1SDimitry Andric 181fe6060f1SDimitry Andric if (__x_index == __y_index) 182fe6060f1SDimitry Andric return true; 183fe6060f1SDimitry Andric 184fe6060f1SDimitry Andric if (__x_index == 0) 1855f757f3fSDimitry Andric return std::__unchecked_get<_Iter>(__x.__hold_) == std::__unchecked_get<_S2>(__y.__hold_); 186fe6060f1SDimitry Andric 1875f757f3fSDimitry Andric return std::__unchecked_get<_Sent>(__x.__hold_) == std::__unchecked_get<_I2>(__y.__hold_); 188fe6060f1SDimitry Andric } 189fe6060f1SDimitry Andric 190fe6060f1SDimitry Andric template <class _I2, sentinel_for<_Iter> _S2> 191fe6060f1SDimitry Andric requires sentinel_for<_Sent, _I2> && equality_comparable_with<_Iter, _I2> 192cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr bool 193cb14a3feSDimitry Andric operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { 194cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 195cb14a3feSDimitry Andric !__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); 196cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 197cb14a3feSDimitry Andric !__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); 198fe6060f1SDimitry Andric 199fe6060f1SDimitry Andric auto __x_index = __x.__hold_.index(); 200fe6060f1SDimitry Andric auto __y_index = __y.__hold_.index(); 201fe6060f1SDimitry Andric 202fe6060f1SDimitry Andric if (__x_index == 1 && __y_index == 1) 203fe6060f1SDimitry Andric return true; 204fe6060f1SDimitry Andric 205fe6060f1SDimitry Andric if (__x_index == 0 && __y_index == 0) 2065f757f3fSDimitry Andric return std::__unchecked_get<_Iter>(__x.__hold_) == std::__unchecked_get<_I2>(__y.__hold_); 207fe6060f1SDimitry Andric 208fe6060f1SDimitry Andric if (__x_index == 0) 2095f757f3fSDimitry Andric return std::__unchecked_get<_Iter>(__x.__hold_) == std::__unchecked_get<_S2>(__y.__hold_); 210fe6060f1SDimitry Andric 2115f757f3fSDimitry Andric return std::__unchecked_get<_Sent>(__x.__hold_) == std::__unchecked_get<_I2>(__y.__hold_); 212fe6060f1SDimitry Andric } 213fe6060f1SDimitry Andric 214fe6060f1SDimitry Andric template <sized_sentinel_for<_Iter> _I2, sized_sentinel_for<_Iter> _S2> 215fe6060f1SDimitry Andric requires sized_sentinel_for<_Sent, _I2> 216cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_I2> 217cb14a3feSDimitry Andric operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { 218cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 219cb14a3feSDimitry Andric !__x.__hold_.valueless_by_exception(), "Attempted to subtract from a valueless common_iterator"); 220cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 221cb14a3feSDimitry Andric !__y.__hold_.valueless_by_exception(), "Attempted to subtract a valueless common_iterator"); 222fe6060f1SDimitry Andric 223fe6060f1SDimitry Andric auto __x_index = __x.__hold_.index(); 224fe6060f1SDimitry Andric auto __y_index = __y.__hold_.index(); 225fe6060f1SDimitry Andric 226fe6060f1SDimitry Andric if (__x_index == 1 && __y_index == 1) 227fe6060f1SDimitry Andric return 0; 228fe6060f1SDimitry Andric 229fe6060f1SDimitry Andric if (__x_index == 0 && __y_index == 0) 2305f757f3fSDimitry Andric return std::__unchecked_get<_Iter>(__x.__hold_) - std::__unchecked_get<_I2>(__y.__hold_); 231fe6060f1SDimitry Andric 232fe6060f1SDimitry Andric if (__x_index == 0) 2335f757f3fSDimitry Andric return std::__unchecked_get<_Iter>(__x.__hold_) - std::__unchecked_get<_S2>(__y.__hold_); 234fe6060f1SDimitry Andric 2355f757f3fSDimitry Andric return std::__unchecked_get<_Sent>(__x.__hold_) - std::__unchecked_get<_I2>(__y.__hold_); 236fe6060f1SDimitry Andric } 237fe6060f1SDimitry Andric 238cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iter> 239cb14a3feSDimitry Andric iter_move(const common_iterator& __i) noexcept(noexcept(ranges::iter_move(std::declval<const _Iter&>()))) 240fe6060f1SDimitry Andric requires input_iterator<_Iter> 241fe6060f1SDimitry Andric { 242cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 243cb14a3feSDimitry Andric std::holds_alternative<_Iter>(__i.__hold_), "Attempted to iter_move a non-dereferenceable common_iterator"); 2445f757f3fSDimitry Andric return ranges::iter_move(std::__unchecked_get<_Iter>(__i.__hold_)); 245fe6060f1SDimitry Andric } 246fe6060f1SDimitry Andric 247fe6060f1SDimitry Andric template <indirectly_swappable<_Iter> _I2, class _S2> 248cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr void 249cb14a3feSDimitry Andric iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) noexcept( 250cb14a3feSDimitry Andric noexcept(ranges::iter_swap(std::declval<const _Iter&>(), std::declval<const _I2&>()))) { 251cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 252cb14a3feSDimitry Andric std::holds_alternative<_Iter>(__x.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); 253cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 254cb14a3feSDimitry Andric std::holds_alternative<_I2>(__y.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); 2555f757f3fSDimitry Andric return ranges::iter_swap(std::__unchecked_get<_Iter>(__x.__hold_), std::__unchecked_get<_I2>(__y.__hold_)); 256fe6060f1SDimitry Andric } 257fe6060f1SDimitry Andric }; 258fe6060f1SDimitry Andric 259fe6060f1SDimitry Andric template <class _Iter, class _Sent> 260fe6060f1SDimitry Andric struct incrementable_traits<common_iterator<_Iter, _Sent>> { 261fe6060f1SDimitry Andric using difference_type = iter_difference_t<_Iter>; 262fe6060f1SDimitry Andric }; 263fe6060f1SDimitry Andric 264fe6060f1SDimitry Andric template <class _Iter> 265cb14a3feSDimitry Andric concept __denotes_forward_iter = requires { 266cb14a3feSDimitry Andric typename iterator_traits<_Iter>::iterator_category; 267cb14a3feSDimitry Andric } && derived_from<typename iterator_traits<_Iter>::iterator_category, forward_iterator_tag>; 268fe6060f1SDimitry Andric 269fe6060f1SDimitry Andric template <class _Iter, class _Sent> 270cb14a3feSDimitry Andric concept __common_iter_has_ptr_op = requires(const common_iterator<_Iter, _Sent>& __a) { __a.operator->(); }; 271fe6060f1SDimitry Andric 272fe6060f1SDimitry Andric template <class, class> 273fe6060f1SDimitry Andric struct __arrow_type_or_void { 274fe6060f1SDimitry Andric using type = void; 275fe6060f1SDimitry Andric }; 276fe6060f1SDimitry Andric 277fe6060f1SDimitry Andric template <class _Iter, class _Sent> 278fe6060f1SDimitry Andric requires __common_iter_has_ptr_op<_Iter, _Sent> 279fe6060f1SDimitry Andric struct __arrow_type_or_void<_Iter, _Sent> { 280bdd1243dSDimitry Andric using type = decltype(std::declval<const common_iterator<_Iter, _Sent>&>().operator->()); 281fe6060f1SDimitry Andric }; 282fe6060f1SDimitry Andric 28304eeddc0SDimitry Andric template <input_iterator _Iter, class _Sent> 284fe6060f1SDimitry Andric struct iterator_traits<common_iterator<_Iter, _Sent>> { 285cb14a3feSDimitry Andric using iterator_concept = _If<forward_iterator<_Iter>, forward_iterator_tag, input_iterator_tag>; 286cb14a3feSDimitry Andric using iterator_category = _If<__denotes_forward_iter<_Iter>, forward_iterator_tag, input_iterator_tag>; 287fe6060f1SDimitry Andric using pointer = typename __arrow_type_or_void<_Iter, _Sent>::type; 288fe6060f1SDimitry Andric using value_type = iter_value_t<_Iter>; 289fe6060f1SDimitry Andric using difference_type = iter_difference_t<_Iter>; 290fe6060f1SDimitry Andric using reference = iter_reference_t<_Iter>; 291fe6060f1SDimitry Andric }; 292fe6060f1SDimitry Andric 29306c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 294fe6060f1SDimitry Andric 295fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 296fe6060f1SDimitry Andric 29706c3fb27SDimitry Andric _LIBCPP_POP_MACROS 29806c3fb27SDimitry Andric 299fe6060f1SDimitry Andric #endif // _LIBCPP___ITERATOR_COMMON_ITERATOR_H 300