xref: /freebsd/contrib/llvm-project/libcxx/include/__flat_set/ra_iterator.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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 
10 #ifndef _LIBCPP___FLAT_SET_RA_ITERATOR_H
11 #define _LIBCPP___FLAT_SET_RA_ITERATOR_H
12 
13 #include "__type_traits/is_same.h"
14 #include <__compare/three_way_comparable.h>
15 #include <__config>
16 #include <__iterator/incrementable_traits.h>
17 #include <__iterator/iterator_traits.h>
18 #include <__type_traits/is_constructible.h>
19 #include <__utility/move.h>
20 
21 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22 #  pragma GCC system_header
23 #endif
24 
25 _LIBCPP_PUSH_MACROS
26 #include <__undef_macros>
27 
28 #if _LIBCPP_STD_VER >= 23
29 
30 _LIBCPP_BEGIN_NAMESPACE_STD
31 
32 /**
33  * __ra_iterator is a random access iterator that wraps an underlying iterator.
34  * It also stores the underlying container type in its type so that algorithms
35  * can optimize based on the underlying container type, and to avoid inadvertently
36  * mixing iterators coming from different containers..
37  */
38 template <class _Container, class _Iterator>
39 struct __ra_iterator {
40 private:
41   _Iterator __iter_;
42 
43   friend _Container;
44 
45   // note: checking the concept random_access_iterator does not work for incomplete types
46   static_assert(_IsSame<typename iterator_traits<_Iterator>::iterator_category, random_access_iterator_tag>::value,
47                 "Underlying iterator must be a random access iterator");
48 
49 public:
50   using iterator_concept  = random_access_iterator_tag; // deliberately lower contiguous_iterator
51   using iterator_category = random_access_iterator_tag;
52   using value_type        = iter_value_t<_Iterator>;
53   using difference_type   = iter_difference_t<_Iterator>;
54 
55   _LIBCPP_HIDE_FROM_ABI __ra_iterator()
56     requires is_default_constructible_v<_Iterator>
57   = default;
58 
__ra_iterator__ra_iterator59   _LIBCPP_HIDE_FROM_ABI explicit constexpr __ra_iterator(_Iterator __iter) : __iter_(std::move(__iter)) {}
60 
__base__ra_iterator61   _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __base() const noexcept(noexcept(_Iterator(__iter_))) { return __iter_; }
62 
decltype__ra_iterator63   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { return *__iter_; }
64   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator->() const
65     requires requires { __iter_.operator->(); }
66   {
67     return __iter_.operator->();
68   }
69 
70   _LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator& operator++() {
71     ++__iter_;
72     return *this;
73   }
74 
75   _LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator operator++(int) {
76     __ra_iterator __tmp(*this);
77     ++*this;
78     return __tmp;
79   }
80 
81   _LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator& operator--() {
82     --__iter_;
83     return *this;
84   }
85 
86   _LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator operator--(int) {
87     __ra_iterator __tmp(*this);
88     --*this;
89     return __tmp;
90   }
91 
92   _LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator& operator+=(difference_type __x) {
93     __iter_ += __x;
94     return *this;
95   }
96 
97   _LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator& operator-=(difference_type __x) {
98     __iter_ -= __x;
99     return *this;
100   }
101 
decltype__ra_iterator102   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const { return *(*this + __n); }
103 
104   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __ra_iterator& __x, const __ra_iterator& __y) {
105     return __x.__iter_ == __y.__iter_;
106   }
107 
108   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __ra_iterator& __x, const __ra_iterator& __y) {
109     return __x.__iter_ < __y.__iter_;
110   }
111 
112   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __ra_iterator& __x, const __ra_iterator& __y) {
113     return __y < __x;
114   }
115 
116   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __ra_iterator& __x, const __ra_iterator& __y) {
117     return !(__y < __x);
118   }
119 
120   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __ra_iterator& __x, const __ra_iterator& __y) {
121     return !(__x < __y);
122   }
123 
124   _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __ra_iterator& __x, const __ra_iterator& __y)
125     requires three_way_comparable<_Iterator>
126   {
127     return __x.__iter_ <=> __y.__iter_;
128   }
129 
130   _LIBCPP_HIDE_FROM_ABI friend constexpr __ra_iterator operator+(const __ra_iterator& __i, difference_type __n) {
131     auto __tmp = __i;
132     __tmp += __n;
133     return __tmp;
134   }
135 
136   _LIBCPP_HIDE_FROM_ABI friend constexpr __ra_iterator operator+(difference_type __n, const __ra_iterator& __i) {
137     return __i + __n;
138   }
139 
140   _LIBCPP_HIDE_FROM_ABI friend constexpr __ra_iterator operator-(const __ra_iterator& __i, difference_type __n) {
141     auto __tmp = __i;
142     __tmp -= __n;
143     return __tmp;
144   }
145 
146   _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __ra_iterator& __x, const __ra_iterator& __y) {
147     return __x.__iter_ - __y.__iter_;
148   }
149 };
150 
151 _LIBCPP_END_NAMESPACE_STD
152 
153 #endif // _LIBCPP_STD_VER >= 23
154 
155 _LIBCPP_POP_MACROS
156 
157 #endif // _LIBCPP___FLAT_SET_RA_ITERATOR_H
158