Skip to content

Commit 87f3ff3

Browse files
committed
[libc++][ranges] Implement the changes to container adaptors from P1206 (ranges::to):
- add the `from_range_t` constructors and the related deduction guides; - add the `push_range` member function. (Note: this patch is split from https://reviews.llvm.org/D142335) Reviewed By: #libc, ldionne Differential Revision: https://reviews.llvm.org/D149829
1 parent ab8d4f5 commit 87f3ff3

File tree

21 files changed

+1162
-54
lines changed

21 files changed

+1162
-54
lines changed

libcxx/include/queue

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public:
4343
explicit queue(container_type&& c)
4444
template<class InputIterator>
4545
queue(InputIterator first, InputIterator last); // since C++23
46+
template<container-compatible-range<T> R> queue(from_range_t, R&& rg); // since C++23
4647
template <class Alloc>
4748
explicit queue(const Alloc& a);
4849
template <class Alloc>
@@ -55,6 +56,8 @@ public:
5556
queue(queue&& q, const Alloc& a);
5657
template <class InputIterator, class Alloc>
5758
queue(InputIterator first, InputIterator last, const Alloc&); // since C++23
59+
template<container-compatible-range<T> R, class Alloc>
60+
queue(from_range_t, R&& rg, const Alloc&); // since C++23
5861
5962
bool empty() const;
6063
size_type size() const;
@@ -66,6 +69,8 @@ public:
6669
6770
void push(const value_type& v);
6871
void push(value_type&& v);
72+
template<container-compatible-range<T> R>
73+
void push_range(R&& rg); // C++23
6974
template <class... Args> reference emplace(Args&&... args); // reference in C++17
7075
void pop();
7176
@@ -78,6 +83,9 @@ template<class Container>
7883
template<class InputIterator>
7984
queue(InputIterator, InputIterator) -> queue<iter-value-type<InputIterator>>; // since C++23
8085
86+
template<ranges::input_range R>
87+
queue(from_range_t, R&&) -> queue<ranges::range_value_t<R>>; // since C++23
88+
8189
template<class Container, class Allocator>
8290
queue(Container, Allocator) -> queue<typename Container::value_type, Container>; // C++17
8391
@@ -86,6 +94,10 @@ template<class InputIterator, class Allocator>
8694
-> queue<iter-value-type<InputIterator>,
8795
deque<iter-value-type<InputIterator>, Allocator>>; // since C++23
8896
97+
template<ranges::input_range R, class Allocator>
98+
queue(from_range_t, R&&, Allocator)
99+
-> queue<ranges::range_value_t<R>, deque<ranges::range_value_t<R>, Allocator>>; // since C++23
100+
89101
template <class T, class Container>
90102
bool operator==(const queue<T, Container>& x,const queue<T, Container>& y);
91103
@@ -138,6 +150,8 @@ public:
138150
template <class InputIterator>
139151
priority_queue(InputIterator first, InputIterator last,
140152
const Compare& comp, Container&& c);
153+
template <container-compatible-range<T> R>
154+
priority_queue(from_range_t, R&& rg, const Compare& x = Compare()); // since C++23
141155
template <class Alloc>
142156
explicit priority_queue(const Alloc& a);
143157
template <class Alloc>
@@ -160,6 +174,10 @@ public:
160174
template <class InputIterator>
161175
priority_queue(InputIterator first, InputIterator last,
162176
const Compare& comp, Container&& c, const Alloc& a);
177+
template <container-compatible-range<T> R, class Alloc>
178+
priority_queue(from_range_t, R&& rg, const Compare&, const Alloc&); // since C++23
179+
template <container-compatible-range<T> R, class Alloc>
180+
priority_queue(from_range_t, R&& rg, const Alloc&); // since C++23
163181
template <class Alloc>
164182
priority_queue(const priority_queue& q, const Alloc& a);
165183
template <class Alloc>
@@ -171,6 +189,8 @@ public:
171189
172190
void push(const value_type& v);
173191
void push(value_type&& v);
192+
template<container-compatible-range<T> R>
193+
void push_range(R&& rg); // C++23
174194
template <class... Args> void emplace(Args&&... args);
175195
void pop();
176196
@@ -189,6 +209,10 @@ template<class InputIterator,
189209
priority_queue(InputIterator, InputIterator, Compare = Compare(), Container = Container())
190210
-> priority_queue<iter-value-type<InputIterator>, Container, Compare>; // C++17
191211
212+
template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>>
213+
priority_queue(from_range_t, R&&, Compare = Compare())
214+
-> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>>, Compare>; // C++23
215+
192216
template<class Compare, class Container, class Allocator>
193217
priority_queue(Compare, Container, Allocator)
194218
-> priority_queue<typename Container::value_type, Container, Compare>; // C++17
@@ -208,6 +232,15 @@ template<class InputIterator, class Compare, class Container, class Allocator>
208232
priority_queue(InputIterator, InputIterator, Compare, Container, Allocator)
209233
-> priority_queue<typename Container::value_type, Container, Compare>; // C++17
210234
235+
template<ranges::input_range R, class Compare, class Allocator>
236+
priority_queue(from_range_t, R&&, Compare, Allocator)
237+
-> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>, Allocator>,
238+
Compare>; // C++23
239+
240+
template<ranges::input_range R, class Allocator>
241+
priority_queue(from_range_t, R&&, Allocator)
242+
-> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>, Allocator>>; // C++23
243+
211244
template <class T, class Container, class Compare>
212245
void swap(priority_queue<T, Container, Compare>& x,
213246
priority_queue<T, Container, Compare>& y)
@@ -220,11 +253,17 @@ template <class T, class Container, class Compare>
220253
#include <__algorithm/make_heap.h>
221254
#include <__algorithm/pop_heap.h>
222255
#include <__algorithm/push_heap.h>
256+
#include <__algorithm/ranges_copy.h>
223257
#include <__assert> // all public C++ headers provide the assertion handler
224258
#include <__config>
225259
#include <__functional/operations.h>
260+
#include <__iterator/back_insert_iterator.h>
226261
#include <__iterator/iterator_traits.h>
227262
#include <__memory/uses_allocator.h>
263+
#include <__ranges/access.h>
264+
#include <__ranges/concepts.h>
265+
#include <__ranges/container_compatible_range.h>
266+
#include <__ranges/from_range.h>
228267
#include <__utility/forward.h>
229268
#include <deque>
230269
#include <vector>
@@ -283,12 +322,24 @@ public:
283322
_LIBCPP_HIDE_FROM_ABI
284323
queue(_InputIterator __first, _InputIterator __last) : c(__first, __last) {}
285324

325+
template <_ContainerCompatibleRange<_Tp> _Range>
326+
_LIBCPP_HIDE_FROM_ABI
327+
queue(from_range_t, _Range&& __range) : c(from_range, std::forward<_Range>(__range)) {}
328+
286329
template <class _InputIterator,
287330
class _Alloc,
288331
class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
289332
class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>>
290333
_LIBCPP_HIDE_FROM_ABI
291334
queue(_InputIterator __first, _InputIterator __second, const _Alloc& __alloc) : c(__first, __second, __alloc) {}
335+
336+
template <_ContainerCompatibleRange<_Tp> _Range,
337+
class _Alloc,
338+
class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>>
339+
_LIBCPP_HIDE_FROM_ABI
340+
queue(from_range_t, _Range&& __range, const _Alloc& __alloc)
341+
: c(from_range, std::forward<_Range>(__range), __alloc) {}
342+
292343
#endif
293344

294345
_LIBCPP_INLINE_VISIBILITY
@@ -360,6 +411,21 @@ public:
360411
#ifndef _LIBCPP_CXX03_LANG
361412
_LIBCPP_INLINE_VISIBILITY
362413
void push(value_type&& __v) {c.push_back(_VSTD::move(__v));}
414+
415+
#if _LIBCPP_STD_VER >= 23
416+
template <_ContainerCompatibleRange<_Tp> _Range>
417+
_LIBCPP_HIDE_FROM_ABI
418+
void push_range(_Range&& __range) {
419+
if constexpr (requires (container_type& __c) {
420+
__c.append_range(std::forward<_Range>(__range));
421+
}) {
422+
c.append_range(std::forward<_Range>(__range));
423+
} else {
424+
ranges::copy(std::forward<_Range>(__range), std::back_inserter(c));
425+
}
426+
}
427+
#endif
428+
363429
template <class... _Args>
364430
_LIBCPP_INLINE_VISIBILITY
365431
#if _LIBCPP_STD_VER >= 17
@@ -418,12 +484,22 @@ template <class _InputIterator,
418484
queue(_InputIterator, _InputIterator)
419485
-> queue<__iter_value_type<_InputIterator>>;
420486

487+
template <ranges::input_range _Range>
488+
queue(from_range_t, _Range&&)
489+
-> queue<ranges::range_value_t<_Range>>;
490+
421491
template <class _InputIterator,
422492
class _Alloc,
423493
class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
424494
class = __enable_if_t<__is_allocator<_Alloc>::value>>
425495
queue(_InputIterator, _InputIterator, _Alloc)
426496
-> queue<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>;
497+
498+
template <ranges::input_range _Range,
499+
class _Alloc,
500+
class = __enable_if_t<__is_allocator<_Alloc>::value>>
501+
queue(from_range_t, _Range&&, _Alloc)
502+
-> queue<ranges::range_value_t<_Range>, deque<ranges::range_value_t<_Range>, _Alloc>>;
427503
#endif
428504

429505
template <class _Tp, class _Container>
@@ -557,6 +633,17 @@ public:
557633
priority_queue(_InputIter __f, _InputIter __l,
558634
const value_compare& __comp, container_type&& __c);
559635
#endif // _LIBCPP_CXX03_LANG
636+
637+
#if _LIBCPP_STD_VER >= 23
638+
template <_ContainerCompatibleRange<_Tp> _Range>
639+
_LIBCPP_HIDE_FROM_ABI
640+
priority_queue(from_range_t, _Range&& __range, const value_compare& __comp = value_compare())
641+
: c(from_range, std::forward<_Range>(__range)),
642+
comp(__comp) {
643+
std::make_heap(c.begin(), c.end(), comp);
644+
}
645+
#endif
646+
560647
template <class _Alloc>
561648
_LIBCPP_INLINE_VISIBILITY
562649
explicit priority_queue(const _Alloc& __a,
@@ -611,6 +698,30 @@ public:
611698
__enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
612699
#endif // _LIBCPP_CXX03_LANG
613700

701+
#if _LIBCPP_STD_VER >= 23
702+
703+
template <_ContainerCompatibleRange<_Tp> _Range,
704+
class _Alloc,
705+
class = enable_if_t<uses_allocator<_Container, _Alloc>::value>>
706+
_LIBCPP_HIDE_FROM_ABI
707+
priority_queue(from_range_t, _Range&& __range, const value_compare& __comp, const _Alloc& __a)
708+
: c(from_range, std::forward<_Range>(__range), __a),
709+
comp(__comp) {
710+
std::make_heap(c.begin(), c.end(), comp);
711+
}
712+
713+
template <_ContainerCompatibleRange<_Tp> _Range,
714+
class _Alloc,
715+
class = enable_if_t<uses_allocator<_Container, _Alloc>::value>>
716+
_LIBCPP_HIDE_FROM_ABI
717+
priority_queue(from_range_t, _Range&& __range, const _Alloc& __a)
718+
: c(from_range, std::forward<_Range>(__range), __a),
719+
comp() {
720+
std::make_heap(c.begin(), c.end(), comp);
721+
}
722+
723+
#endif
724+
614725
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
615726
bool empty() const {return c.empty();}
616727
_LIBCPP_INLINE_VISIBILITY
@@ -623,6 +734,23 @@ public:
623734
#ifndef _LIBCPP_CXX03_LANG
624735
_LIBCPP_INLINE_VISIBILITY
625736
void push(value_type&& __v);
737+
738+
#if _LIBCPP_STD_VER >= 23
739+
template <_ContainerCompatibleRange<_Tp> _Range>
740+
_LIBCPP_HIDE_FROM_ABI
741+
void push_range(_Range&& __range) {
742+
if constexpr (requires (container_type& __c) {
743+
__c.append_range(std::forward<_Range>(__range));
744+
}) {
745+
c.append_range(std::forward<_Range>(__range));
746+
} else {
747+
ranges::copy(std::forward<_Range>(__range), std::back_inserter(c));
748+
}
749+
750+
std::make_heap(c.begin(), c.end(), comp);
751+
}
752+
#endif
753+
626754
template <class... _Args>
627755
_LIBCPP_INLINE_VISIBILITY
628756
void emplace(_Args&&... __args);
@@ -695,6 +823,31 @@ priority_queue(_InputIterator, _InputIterator, _Compare, _Container, _Alloc)
695823
-> priority_queue<typename _Container::value_type, _Container, _Compare>;
696824
#endif
697825

826+
#if _LIBCPP_STD_VER >= 23
827+
828+
template <ranges::input_range _Range,
829+
class _Compare = less<ranges::range_value_t<_Range>>,
830+
class = enable_if_t<!__is_allocator<_Compare>::value>>
831+
priority_queue(from_range_t, _Range&&, _Compare = _Compare())
832+
-> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>>, _Compare>;
833+
834+
template <ranges::input_range _Range,
835+
class _Compare,
836+
class _Alloc,
837+
class = enable_if_t<!__is_allocator<_Compare>::value>,
838+
class = enable_if_t<__is_allocator<_Alloc>::value>>
839+
priority_queue(from_range_t, _Range&&, _Compare, _Alloc)
840+
-> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>, _Alloc>,
841+
_Compare>;
842+
843+
template <ranges::input_range _Range,
844+
class _Alloc,
845+
class = enable_if_t<__is_allocator<_Alloc>::value>>
846+
priority_queue(from_range_t, _Range&&, _Alloc)
847+
-> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>, _Alloc>>;
848+
849+
#endif
850+
698851
template <class _Tp, class _Container, class _Compare>
699852
inline
700853
priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Compare& __comp,

0 commit comments

Comments
 (0)