17
17
#include < __ranges/all.h>
18
18
#include < __ranges/concepts.h>
19
19
#include < __ranges/enable_borrowed_range.h>
20
+ #include < __ranges/non_propagating_cache.h>
20
21
#include < __ranges/size.h>
21
22
#include < __ranges/view_interface.h>
22
- #include < optional>
23
+ #include < __utility/move.h>
24
+ #include < concepts>
23
25
#include < type_traits>
24
26
25
27
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -36,21 +38,16 @@ _LIBCPP_BEGIN_NAMESPACE_STD
36
38
namespace ranges {
37
39
template <view _View>
38
40
class drop_view
39
- : public view_interface<drop_view<_View>> {
40
-
41
+ : public view_interface<drop_view<_View>>
42
+ {
41
43
// We cache begin() whenever ranges::next is not guaranteed O(1) to provide an
42
44
// amortized O(1) begin() method. If this is an input_range, then we cannot cache
43
45
// begin because begin is not equality preserving.
44
46
// Note: drop_view<input-range>::begin() is still trivially amortized O(1) because
45
47
// one can't call begin() on it more than once.
46
48
static constexpr bool _UseCache = forward_range<_View> && !(random_access_range<_View> && sized_range<_View>);
47
- using _Cache = optional<iterator_t <_View>>;
48
- struct _Empty { };
49
-
50
- // For forward ranges use std::optional to cache the begin iterator.
51
- // No unique address + _Empty means we don't use any extra space when this
52
- // is not a forward iterator.
53
- [[no_unique_address]] conditional_t <_UseCache, _Cache, _Empty> __cached_begin_;
49
+ using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t <_View>>, __empty_cache>;
50
+ [[no_unique_address]] _Cache __cached_begin_ = _Cache();
54
51
range_difference_t <_View> __count_ = 0 ;
55
52
_View __base_ = _View();
56
53
@@ -59,48 +56,12 @@ namespace ranges {
59
56
60
57
_LIBCPP_HIDE_FROM_ABI
61
58
constexpr drop_view (_View __base, range_difference_t <_View> __count)
62
- : __cached_begin_()
63
- , __count_(__count)
59
+ : __count_(__count)
64
60
, __base_(_VSTD::move(__base))
65
61
{
66
62
_LIBCPP_ASSERT (__count_ >= 0 , " count must be greater than or equal to zero." );
67
63
}
68
64
69
- _LIBCPP_HIDE_FROM_ABI
70
- constexpr drop_view (drop_view const & __other)
71
- : __cached_begin_() // Intentionally not propagating the cached begin iterator.
72
- , __count_(__other.__count_)
73
- , __base_(__other.__base_)
74
- { }
75
-
76
- _LIBCPP_HIDE_FROM_ABI
77
- constexpr drop_view (drop_view&& __other)
78
- : __cached_begin_() // Intentionally not propagating the cached begin iterator.
79
- , __count_(_VSTD::move(__other.__count_))
80
- , __base_(_VSTD::move(__other.__base_))
81
- { }
82
-
83
- _LIBCPP_HIDE_FROM_ABI
84
- constexpr drop_view& operator =(drop_view const & __other) {
85
- if constexpr (_UseCache) {
86
- __cached_begin_.reset ();
87
- }
88
- __base_ = __other.__base_ ;
89
- __count_ = __other.__count_ ;
90
- return *this ;
91
- }
92
-
93
- _LIBCPP_HIDE_FROM_ABI
94
- constexpr drop_view& operator =(drop_view&& __other) {
95
- if constexpr (_UseCache) {
96
- __cached_begin_.reset ();
97
- __other.__cached_begin_ .reset ();
98
- }
99
- __base_ = _VSTD::move (__other.__base_ );
100
- __count_ = _VSTD::move (__other.__count_ );
101
- return *this ;
102
- }
103
-
104
65
_LIBCPP_HIDE_FROM_ABI constexpr _View base () const & requires copy_constructible<_View> { return __base_; }
105
66
_LIBCPP_HIDE_FROM_ABI constexpr _View base () && { return _VSTD::move (__base_); }
106
67
@@ -110,12 +71,12 @@ namespace ranges {
110
71
random_access_range<const _View> && sized_range<const _View>))
111
72
{
112
73
if constexpr (_UseCache)
113
- if (__cached_begin_)
74
+ if (__cached_begin_. __has_value () )
114
75
return *__cached_begin_;
115
76
116
77
auto __tmp = ranges::next (ranges::begin (__base_), __count_, ranges::end (__base_));
117
78
if constexpr (_UseCache)
118
- __cached_begin_ = __tmp;
79
+ __cached_begin_. __set ( __tmp) ;
119
80
return __tmp;
120
81
}
121
82
0 commit comments