Skip to content

Commit

Permalink
[libc++][ranges] Implement the changes to container adaptors from P12…
Browse files Browse the repository at this point in the history
…06 (`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
  • Loading branch information
var-const committed Jun 6, 2023
1 parent ab8d4f5 commit 87f3ff3
Show file tree
Hide file tree
Showing 21 changed files with 1,162 additions and 54 deletions.
153 changes: 153 additions & 0 deletions libcxx/include/queue
Expand Up @@ -43,6 +43,7 @@ public:
explicit queue(container_type&& c)
template<class InputIterator>
queue(InputIterator first, InputIterator last); // since C++23
template<container-compatible-range<T> R> queue(from_range_t, R&& rg); // since C++23
template <class Alloc>
explicit queue(const Alloc& a);
template <class Alloc>
Expand All @@ -55,6 +56,8 @@ public:
queue(queue&& q, const Alloc& a);
template <class InputIterator, class Alloc>
queue(InputIterator first, InputIterator last, const Alloc&); // since C++23
template<container-compatible-range<T> R, class Alloc>
queue(from_range_t, R&& rg, const Alloc&); // since C++23
bool empty() const;
size_type size() const;
Expand All @@ -66,6 +69,8 @@ public:
void push(const value_type& v);
void push(value_type&& v);
template<container-compatible-range<T> R>
void push_range(R&& rg); // C++23
template <class... Args> reference emplace(Args&&... args); // reference in C++17
void pop();
Expand All @@ -78,6 +83,9 @@ template<class Container>
template<class InputIterator>
queue(InputIterator, InputIterator) -> queue<iter-value-type<InputIterator>>; // since C++23
template<ranges::input_range R>
queue(from_range_t, R&&) -> queue<ranges::range_value_t<R>>; // since C++23
template<class Container, class Allocator>
queue(Container, Allocator) -> queue<typename Container::value_type, Container>; // C++17
Expand All @@ -86,6 +94,10 @@ template<class InputIterator, class Allocator>
-> queue<iter-value-type<InputIterator>,
deque<iter-value-type<InputIterator>, Allocator>>; // since C++23
template<ranges::input_range R, class Allocator>
queue(from_range_t, R&&, Allocator)
-> queue<ranges::range_value_t<R>, deque<ranges::range_value_t<R>, Allocator>>; // since C++23
template <class T, class Container>
bool operator==(const queue<T, Container>& x,const queue<T, Container>& y);
Expand Down Expand Up @@ -138,6 +150,8 @@ public:
template <class InputIterator>
priority_queue(InputIterator first, InputIterator last,
const Compare& comp, Container&& c);
template <container-compatible-range<T> R>
priority_queue(from_range_t, R&& rg, const Compare& x = Compare()); // since C++23
template <class Alloc>
explicit priority_queue(const Alloc& a);
template <class Alloc>
Expand All @@ -160,6 +174,10 @@ public:
template <class InputIterator>
priority_queue(InputIterator first, InputIterator last,
const Compare& comp, Container&& c, const Alloc& a);
template <container-compatible-range<T> R, class Alloc>
priority_queue(from_range_t, R&& rg, const Compare&, const Alloc&); // since C++23
template <container-compatible-range<T> R, class Alloc>
priority_queue(from_range_t, R&& rg, const Alloc&); // since C++23
template <class Alloc>
priority_queue(const priority_queue& q, const Alloc& a);
template <class Alloc>
Expand All @@ -171,6 +189,8 @@ public:
void push(const value_type& v);
void push(value_type&& v);
template<container-compatible-range<T> R>
void push_range(R&& rg); // C++23
template <class... Args> void emplace(Args&&... args);
void pop();
Expand All @@ -189,6 +209,10 @@ template<class InputIterator,
priority_queue(InputIterator, InputIterator, Compare = Compare(), Container = Container())
-> priority_queue<iter-value-type<InputIterator>, Container, Compare>; // C++17
template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>>
priority_queue(from_range_t, R&&, Compare = Compare())
-> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>>, Compare>; // C++23
template<class Compare, class Container, class Allocator>
priority_queue(Compare, Container, Allocator)
-> priority_queue<typename Container::value_type, Container, Compare>; // C++17
Expand All @@ -208,6 +232,15 @@ template<class InputIterator, class Compare, class Container, class Allocator>
priority_queue(InputIterator, InputIterator, Compare, Container, Allocator)
-> priority_queue<typename Container::value_type, Container, Compare>; // C++17
template<ranges::input_range R, class Compare, class Allocator>
priority_queue(from_range_t, R&&, Compare, Allocator)
-> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>, Allocator>,
Compare>; // C++23
template<ranges::input_range R, class Allocator>
priority_queue(from_range_t, R&&, Allocator)
-> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>, Allocator>>; // C++23
template <class T, class Container, class Compare>
void swap(priority_queue<T, Container, Compare>& x,
priority_queue<T, Container, Compare>& y)
Expand All @@ -220,11 +253,17 @@ template <class T, class Container, class Compare>
#include <__algorithm/make_heap.h>
#include <__algorithm/pop_heap.h>
#include <__algorithm/push_heap.h>
#include <__algorithm/ranges_copy.h>
#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__functional/operations.h>
#include <__iterator/back_insert_iterator.h>
#include <__iterator/iterator_traits.h>
#include <__memory/uses_allocator.h>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/container_compatible_range.h>
#include <__ranges/from_range.h>
#include <__utility/forward.h>
#include <deque>
#include <vector>
Expand Down Expand Up @@ -283,12 +322,24 @@ public:
_LIBCPP_HIDE_FROM_ABI
queue(_InputIterator __first, _InputIterator __last) : c(__first, __last) {}

template <_ContainerCompatibleRange<_Tp> _Range>
_LIBCPP_HIDE_FROM_ABI
queue(from_range_t, _Range&& __range) : c(from_range, std::forward<_Range>(__range)) {}

template <class _InputIterator,
class _Alloc,
class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>>
_LIBCPP_HIDE_FROM_ABI
queue(_InputIterator __first, _InputIterator __second, const _Alloc& __alloc) : c(__first, __second, __alloc) {}

template <_ContainerCompatibleRange<_Tp> _Range,
class _Alloc,
class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>>
_LIBCPP_HIDE_FROM_ABI
queue(from_range_t, _Range&& __range, const _Alloc& __alloc)
: c(from_range, std::forward<_Range>(__range), __alloc) {}

#endif

_LIBCPP_INLINE_VISIBILITY
Expand Down Expand Up @@ -360,6 +411,21 @@ public:
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
void push(value_type&& __v) {c.push_back(_VSTD::move(__v));}

#if _LIBCPP_STD_VER >= 23
template <_ContainerCompatibleRange<_Tp> _Range>
_LIBCPP_HIDE_FROM_ABI
void push_range(_Range&& __range) {
if constexpr (requires (container_type& __c) {
__c.append_range(std::forward<_Range>(__range));
}) {
c.append_range(std::forward<_Range>(__range));
} else {
ranges::copy(std::forward<_Range>(__range), std::back_inserter(c));
}
}
#endif

template <class... _Args>
_LIBCPP_INLINE_VISIBILITY
#if _LIBCPP_STD_VER >= 17
Expand Down Expand Up @@ -418,12 +484,22 @@ template <class _InputIterator,
queue(_InputIterator, _InputIterator)
-> queue<__iter_value_type<_InputIterator>>;

template <ranges::input_range _Range>
queue(from_range_t, _Range&&)
-> queue<ranges::range_value_t<_Range>>;

template <class _InputIterator,
class _Alloc,
class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
class = __enable_if_t<__is_allocator<_Alloc>::value>>
queue(_InputIterator, _InputIterator, _Alloc)
-> queue<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>;

template <ranges::input_range _Range,
class _Alloc,
class = __enable_if_t<__is_allocator<_Alloc>::value>>
queue(from_range_t, _Range&&, _Alloc)
-> queue<ranges::range_value_t<_Range>, deque<ranges::range_value_t<_Range>, _Alloc>>;
#endif

template <class _Tp, class _Container>
Expand Down Expand Up @@ -557,6 +633,17 @@ public:
priority_queue(_InputIter __f, _InputIter __l,
const value_compare& __comp, container_type&& __c);
#endif // _LIBCPP_CXX03_LANG

#if _LIBCPP_STD_VER >= 23
template <_ContainerCompatibleRange<_Tp> _Range>
_LIBCPP_HIDE_FROM_ABI
priority_queue(from_range_t, _Range&& __range, const value_compare& __comp = value_compare())
: c(from_range, std::forward<_Range>(__range)),
comp(__comp) {
std::make_heap(c.begin(), c.end(), comp);
}
#endif

template <class _Alloc>
_LIBCPP_INLINE_VISIBILITY
explicit priority_queue(const _Alloc& __a,
Expand Down Expand Up @@ -611,6 +698,30 @@ public:
__enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
#endif // _LIBCPP_CXX03_LANG

#if _LIBCPP_STD_VER >= 23

template <_ContainerCompatibleRange<_Tp> _Range,
class _Alloc,
class = enable_if_t<uses_allocator<_Container, _Alloc>::value>>
_LIBCPP_HIDE_FROM_ABI
priority_queue(from_range_t, _Range&& __range, const value_compare& __comp, const _Alloc& __a)
: c(from_range, std::forward<_Range>(__range), __a),
comp(__comp) {
std::make_heap(c.begin(), c.end(), comp);
}

template <_ContainerCompatibleRange<_Tp> _Range,
class _Alloc,
class = enable_if_t<uses_allocator<_Container, _Alloc>::value>>
_LIBCPP_HIDE_FROM_ABI
priority_queue(from_range_t, _Range&& __range, const _Alloc& __a)
: c(from_range, std::forward<_Range>(__range), __a),
comp() {
std::make_heap(c.begin(), c.end(), comp);
}

#endif

_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
bool empty() const {return c.empty();}
_LIBCPP_INLINE_VISIBILITY
Expand All @@ -623,6 +734,23 @@ public:
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
void push(value_type&& __v);

#if _LIBCPP_STD_VER >= 23
template <_ContainerCompatibleRange<_Tp> _Range>
_LIBCPP_HIDE_FROM_ABI
void push_range(_Range&& __range) {
if constexpr (requires (container_type& __c) {
__c.append_range(std::forward<_Range>(__range));
}) {
c.append_range(std::forward<_Range>(__range));
} else {
ranges::copy(std::forward<_Range>(__range), std::back_inserter(c));
}

std::make_heap(c.begin(), c.end(), comp);
}
#endif

template <class... _Args>
_LIBCPP_INLINE_VISIBILITY
void emplace(_Args&&... __args);
Expand Down Expand Up @@ -695,6 +823,31 @@ priority_queue(_InputIterator, _InputIterator, _Compare, _Container, _Alloc)
-> priority_queue<typename _Container::value_type, _Container, _Compare>;
#endif

#if _LIBCPP_STD_VER >= 23

template <ranges::input_range _Range,
class _Compare = less<ranges::range_value_t<_Range>>,
class = enable_if_t<!__is_allocator<_Compare>::value>>
priority_queue(from_range_t, _Range&&, _Compare = _Compare())
-> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>>, _Compare>;

template <ranges::input_range _Range,
class _Compare,
class _Alloc,
class = enable_if_t<!__is_allocator<_Compare>::value>,
class = enable_if_t<__is_allocator<_Alloc>::value>>
priority_queue(from_range_t, _Range&&, _Compare, _Alloc)
-> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>, _Alloc>,
_Compare>;

template <ranges::input_range _Range,
class _Alloc,
class = enable_if_t<__is_allocator<_Alloc>::value>>
priority_queue(from_range_t, _Range&&, _Alloc)
-> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>, _Alloc>>;

#endif

template <class _Tp, class _Container, class _Compare>
inline
priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Compare& __comp,
Expand Down

0 comments on commit 87f3ff3

Please sign in to comment.