Skip to content

Commit f2b6928

Browse files
committed
iterator
1 parent 090d009 commit f2b6928

File tree

4 files changed

+182
-25
lines changed

4 files changed

+182
-25
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ set(files
370370
__flat_map/sorted_unique.h
371371
__flat_map/utils.h
372372
__flat_set/flat_set.h
373+
__flat_set/ra_iterator.h
373374
__format/buffer.h
374375
__format/concepts.h
375376
__format/container_adaptor.h

libcxx/include/__flat_set/flat_set.h

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <__cstddef/byte.h>
2929
#include <__cstddef/ptrdiff_t.h>
3030
#include <__flat_map/sorted_unique.h>
31+
#include <__flat_set/ra_iterator.h>
3132
#include <__functional/invoke.h>
3233
#include <__functional/is_transparent.h>
3334
#include <__functional/operations.h>
@@ -55,6 +56,8 @@
5556
#include <__type_traits/is_allocator.h>
5657
#include <__type_traits/is_nothrow_constructible.h>
5758
#include <__type_traits/is_same.h>
59+
#include "__type_traits/remove_reference.h"
60+
#include <__utility/as_const.h>
5861
#include <__utility/exception_guard.h>
5962
#include <__utility/move.h>
6063
#include <__utility/pair.h>
@@ -81,6 +84,8 @@ class flat_set {
8184
static_assert(is_same_v<_Key, typename _KeyContainer::value_type>);
8285
static_assert(!is_same_v<_KeyContainer, std::vector<bool>>, "vector<bool> is not a sequence container");
8386

87+
using __key_iterator _LIBCPP_NODEBUG = typename _KeyContainer::const_iterator;
88+
8489
public:
8590
// types
8691
using key_type = _Key;
@@ -91,7 +96,7 @@ class flat_set {
9196
using const_reference = const value_type&;
9297
using size_type = typename _KeyContainer::size_type;
9398
using difference_type = typename _KeyContainer::difference_type;
94-
using iterator = typename _KeyContainer::const_iterator;
99+
using iterator = __ra_iterator<flat_set, typename _KeyContainer::const_iterator>;
95100
using const_iterator = iterator;
96101
using reverse_iterator = std::reverse_iterator<iterator>;
97102
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
@@ -328,10 +333,10 @@ class flat_set {
328333
}
329334

330335
// iterators
331-
_LIBCPP_HIDE_FROM_ABI iterator begin() noexcept { return __keys_.begin(); }
332-
_LIBCPP_HIDE_FROM_ABI const_iterator begin() const noexcept { return __keys_.begin(); }
333-
_LIBCPP_HIDE_FROM_ABI iterator end() noexcept { return __keys_.end(); }
334-
_LIBCPP_HIDE_FROM_ABI const_iterator end() const noexcept { return __keys_.end(); }
336+
_LIBCPP_HIDE_FROM_ABI iterator begin() noexcept { return iterator(std::as_const(__keys_).begin()); }
337+
_LIBCPP_HIDE_FROM_ABI const_iterator begin() const noexcept { return const_iterator(__keys_.begin()); }
338+
_LIBCPP_HIDE_FROM_ABI iterator end() noexcept { return iterator(std::as_const(__keys_).end()); }
339+
_LIBCPP_HIDE_FROM_ABI const_iterator end() const noexcept { return const_iterator(__keys_.end()); }
335340

336341
_LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
337342
_LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
@@ -442,9 +447,9 @@ class flat_set {
442447

443448
_LIBCPP_HIDE_FROM_ABI iterator erase(iterator __position) {
444449
auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
445-
auto __key_iter = __keys_.erase(__position);
450+
auto __key_iter = __keys_.erase(__position.__base());
446451
__on_failure.__complete();
447-
return __key_iter;
452+
return iterator(__key_iter);
448453
}
449454

450455
// The following overload is the same as the iterator overload
@@ -471,9 +476,9 @@ class flat_set {
471476

472477
_LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last) {
473478
auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
474-
auto __key_it = __keys_.erase(__first, __last);
479+
auto __key_it = __keys_.erase(__first.__base(), __last.__base());
475480
__on_failure.__complete();
476-
return __key_it;
481+
return iterator(std::move(__key_it));
477482
}
478483

479484
_LIBCPP_HIDE_FROM_ABI void swap(flat_set& __y) noexcept {
@@ -525,43 +530,43 @@ class flat_set {
525530
}
526531

527532
_LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __x) {
528-
return ranges::lower_bound(__keys_, __x, __compare_);
533+
return iterator(ranges::lower_bound(std::as_const(__keys_), __x, __compare_));
529534
}
530535

531536
_LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __x) const {
532-
return ranges::lower_bound(__keys_, __x, __compare_);
537+
return const_iterator(ranges::lower_bound(__keys_, __x, __compare_));
533538
}
534539

535540
template <class _Kp>
536541
requires __is_transparent_v<_Compare>
537542
_LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _Kp& __x) {
538-
return ranges::lower_bound(__keys_, __x, __compare_);
543+
return iterator(ranges::lower_bound(std::as_const(__keys_), __x, __compare_));
539544
}
540545

541546
template <class _Kp>
542547
requires __is_transparent_v<_Compare>
543548
_LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _Kp& __x) const {
544-
return ranges::lower_bound(__keys_, __x, __compare_);
549+
return const_iterator(ranges::lower_bound(__keys_, __x, __compare_));
545550
}
546551

547552
_LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __x) {
548-
return ranges::upper_bound(__keys_, __x, __compare_);
553+
return iterator(ranges::upper_bound(std::as_const(__keys_), __x, __compare_));
549554
}
550555

551556
_LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __x) const {
552-
return ranges::upper_bound(__keys_, __x, __compare_);
557+
return const_iterator(ranges::upper_bound(__keys_, __x, __compare_));
553558
}
554559

555560
template <class _Kp>
556561
requires __is_transparent_v<_Compare>
557562
_LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _Kp& __x) {
558-
return ranges::upper_bound(__keys_, __x, __compare_);
563+
return iterator(ranges::upper_bound(std::as_const(__keys_), __x, __compare_));
559564
}
560565

561566
template <class _Kp>
562567
requires __is_transparent_v<_Compare>
563568
_LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _Kp& __x) const {
564-
return ranges::upper_bound(__keys_, __x, __compare_);
569+
return const_iterator(ranges::upper_bound(__keys_, __x, __compare_));
565570
}
566571

567572
_LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __x) {
@@ -661,12 +666,13 @@ class flat_set {
661666

662667
template <class _Self, class _Kp>
663668
_LIBCPP_HIDE_FROM_ABI static auto __equal_range_impl(_Self&& __self, const _Kp& __key) {
664-
auto __it = ranges::lower_bound(__self.__keys_, __key, __self.__compare_);
665-
auto __last = __self.__keys_.end();
669+
using __iter = _If<__is_const(__libcpp_remove_reference_t<_Self>), const_iterator, iterator>;
670+
auto __it = ranges::lower_bound(__self.__keys_, __key, __self.__compare_);
671+
auto __last = __self.__keys_.end();
666672
if (__it == __last || __self.__compare_(__key, *__it)) {
667-
return std::make_pair(__it, __it);
673+
return std::make_pair(__iter(__it), __iter(__it));
668674
}
669-
return std::make_pair(__it, std::next(__it));
675+
return std::make_pair(__iter(__it), __iter(std::next(__it)));
670676
}
671677

672678
template <class _KeyArg>
@@ -676,18 +682,18 @@ class flat_set {
676682
clear() /* noexcept */;
677683
}
678684
});
679-
auto __key_it = __keys_.emplace(__it, std::forward<_KeyArg>(__key));
685+
auto __key_it = __keys_.emplace(__it.__base(), std::forward<_KeyArg>(__key));
680686
__on_failure.__complete();
681-
return __key_it;
687+
return iterator(std::move(__key_it));
682688
}
683689

684690
template <class _Kp>
685691
_LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __try_emplace(_Kp&& __key) {
686692
auto __it = lower_bound(__key);
687693
if (__it == end() || __compare_(__key, *__it)) {
688-
return pair<iterator, bool>(__emplace_exact_pos(__it, std::forward<_Kp>(__key)), true);
694+
return pair<iterator, bool>(iterator(__emplace_exact_pos(__it, std::forward<_Kp>(__key))), true);
689695
} else {
690-
return pair<iterator, bool>(std::move(__it), false);
696+
return pair<iterator, bool>(iterator(std::move(__it)), false);
691697
}
692698
}
693699

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
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 <__compare/three_way_comparable.h>
14+
#include <__config>
15+
#include <__iterator/incrementable_traits.h>
16+
#include <__iterator/iterator_traits.h>
17+
#include <__type_traits/is_constructible.h>
18+
#include <__utility/move.h>
19+
20+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21+
# pragma GCC system_header
22+
#endif
23+
24+
_LIBCPP_PUSH_MACROS
25+
#include <__undef_macros>
26+
27+
#if _LIBCPP_STD_VER >= 23
28+
29+
_LIBCPP_BEGIN_NAMESPACE_STD
30+
31+
/**
32+
* __ra_iterator is a random access iterator that wraps an underlying iterator.
33+
* It also stores the underlying container type in its type so that algorithms
34+
* can optimize based on the underlying container type.
35+
*/
36+
template <class _Container, class _Iterator>
37+
struct __ra_iterator {
38+
private:
39+
_Iterator __iter_;
40+
41+
friend _Container;
42+
43+
public:
44+
using iterator_concept = random_access_iterator_tag; // deliberately lower contiguous_iterator
45+
using iterator_category = random_access_iterator_tag;
46+
using value_type = iter_value_t<_Iterator>;
47+
using difference_type = iter_difference_t<_Iterator>;
48+
49+
_LIBCPP_HIDE_FROM_ABI __ra_iterator()
50+
requires is_default_constructible_v<_Iterator>
51+
= default;
52+
53+
_LIBCPP_HIDE_FROM_ABI explicit __ra_iterator(_Iterator __iter) : __iter_(std::move(__iter)) {}
54+
55+
_Iterator __base() const noexcept(noexcept(_Iterator(__iter_))) { return __iter_; }
56+
57+
_LIBCPP_HIDE_FROM_ABI decltype(auto) operator*() const { return *__iter_; }
58+
_LIBCPP_HIDE_FROM_ABI decltype(auto) operator->() const
59+
requires requires { __iter_.operator->(); }
60+
{
61+
return __iter_.operator->();
62+
}
63+
64+
_LIBCPP_HIDE_FROM_ABI __ra_iterator& operator++() {
65+
++__iter_;
66+
return *this;
67+
}
68+
69+
_LIBCPP_HIDE_FROM_ABI __ra_iterator operator++(int) {
70+
__ra_iterator __tmp(*this);
71+
++*this;
72+
return __tmp;
73+
}
74+
75+
_LIBCPP_HIDE_FROM_ABI __ra_iterator& operator--() {
76+
--__iter_;
77+
return *this;
78+
}
79+
80+
_LIBCPP_HIDE_FROM_ABI __ra_iterator operator--(int) {
81+
__ra_iterator __tmp(*this);
82+
--*this;
83+
return __tmp;
84+
}
85+
86+
_LIBCPP_HIDE_FROM_ABI __ra_iterator& operator+=(difference_type __x) {
87+
__iter_ += __x;
88+
return *this;
89+
}
90+
91+
_LIBCPP_HIDE_FROM_ABI __ra_iterator& operator-=(difference_type __x) {
92+
__iter_ -= __x;
93+
return *this;
94+
}
95+
96+
_LIBCPP_HIDE_FROM_ABI decltype(auto) operator[](difference_type __n) const { return *(*this + __n); }
97+
98+
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __ra_iterator& __x, const __ra_iterator& __y) {
99+
return __x.__iter_ == __y.__iter_;
100+
}
101+
102+
_LIBCPP_HIDE_FROM_ABI friend bool operator<(const __ra_iterator& __x, const __ra_iterator& __y) {
103+
return __x.__iter_ < __y.__iter_;
104+
}
105+
106+
_LIBCPP_HIDE_FROM_ABI friend bool operator>(const __ra_iterator& __x, const __ra_iterator& __y) { return __y < __x; }
107+
108+
_LIBCPP_HIDE_FROM_ABI friend bool operator<=(const __ra_iterator& __x, const __ra_iterator& __y) {
109+
return !(__y < __x);
110+
}
111+
112+
_LIBCPP_HIDE_FROM_ABI friend bool operator>=(const __ra_iterator& __x, const __ra_iterator& __y) {
113+
return !(__x < __y);
114+
}
115+
116+
_LIBCPP_HIDE_FROM_ABI friend auto operator<=>(const __ra_iterator& __x, const __ra_iterator& __y)
117+
requires three_way_comparable<_Iterator>
118+
{
119+
return __x.__iter_ <=> __y.__iter_;
120+
}
121+
122+
_LIBCPP_HIDE_FROM_ABI friend __ra_iterator operator+(const __ra_iterator& __i, difference_type __n) {
123+
auto __tmp = __i;
124+
__tmp += __n;
125+
return __tmp;
126+
}
127+
128+
_LIBCPP_HIDE_FROM_ABI friend __ra_iterator operator+(difference_type __n, const __ra_iterator& __i) {
129+
return __i + __n;
130+
}
131+
132+
_LIBCPP_HIDE_FROM_ABI friend __ra_iterator operator-(const __ra_iterator& __i, difference_type __n) {
133+
auto __tmp = __i;
134+
__tmp -= __n;
135+
return __tmp;
136+
}
137+
138+
_LIBCPP_HIDE_FROM_ABI friend difference_type operator-(const __ra_iterator& __x, const __ra_iterator& __y) {
139+
return __x.__iter_ - __y.__iter_;
140+
}
141+
};
142+
143+
_LIBCPP_END_NAMESPACE_STD
144+
145+
#endif // _LIBCPP_STD_VER >= 23
146+
147+
_LIBCPP_POP_MACROS
148+
149+
#endif // _LIBCPP___FLAT_SET_RA_ITERATOR_H

libcxx/include/module.modulemap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,7 @@ module std [system] {
12921292
export std.vector.vector
12931293
export std.vector.fwd
12941294
}
1295+
module ra_iterator { header "__flat_set/ra_iterator.h" }
12951296

12961297
header "flat_set"
12971298
export std.flat_map.sorted_unique

0 commit comments

Comments
 (0)