1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // <queue>
10 // UNSUPPORTED: c++03, c++11, c++14
11 
12 // template<class Compare, class Container>
13 // priority_queue(Compare, Container)
14 //     -> priority_queue<typename Container::value_type, Container, Compare>;
15 //
16 // template<class InputIterator,
17 //          class Compare = less<typename iterator_traits<InputIterator>::value_type>,
18 //          class Container = vector<typename iterator_traits<InputIterator>::value_type>>
19 // priority_queue(InputIterator, InputIterator, Compare = Compare(), Container = Container())
20 //     -> priority_queue<typename iterator_traits<InputIterator>::value_type, Container, Compare>;
21 //
22 // template<class Compare, class Container, class Allocator>
23 // priority_queue(Compare, Container, Allocator)
24 //     -> priority_queue<typename Container::value_type, Container, Compare>;
25 
26 
27 #include <queue>
28 #include <vector>
29 #include <iterator>
30 #include <cassert>
31 #include <cstddef>
32 #include <climits> // INT_MAX
33 
34 #include "test_macros.h"
35 #include "test_iterators.h"
36 #include "test_allocator.h"
37 
38 struct A {};
39 
40 int main(int, char**)
41 {
42 
43 //  Test the explicit deduction guides
44     {
45     std::vector<int> v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
46     std::priority_queue pri(std::greater<int>(), v); // priority_queue(Compare, Container)
47 
48     static_assert(std::is_same_v<decltype(pri), std::priority_queue<int, std::vector<int>, std::greater<int>>>, "");
49     assert(pri.size() == v.size());
50     assert(pri.top() == 0);
51     }
52 
53     {
54     std::vector<long, test_allocator<long>> v{10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };
55     std::priority_queue pri(std::greater<long>(), v, test_allocator<long>(2)); // priority_queue(Compare, Container, Allocator)
56 
57     static_assert(std::is_same_v<decltype(pri),
58                                  std::priority_queue<long, std::vector<long, test_allocator<long>>, std::greater<long>>>, "");
59     assert(pri.size() == v.size());
60     assert(pri.top() == 10);
61     }
62 
63     {
64     std::vector<short> v{10, 11, 12, 13, 14, 15, 28, 17, 18, 19 };
65     std::priority_queue pri(v.begin(), v.end()); // priority_queue(Iter, Iter)
66 
67     static_assert(std::is_same_v<decltype(pri), std::priority_queue<short>>, "");
68     assert(pri.size() == v.size());
69     assert(pri.top() == 28);
70     }
71 
72     {
73     std::vector<double> v{10, 11, 12, 13, 6, 15, 28, 17, 18, 19 };
74     std::priority_queue pri(v.begin(), v.end(), std::greater<double>()); // priority_queue(Iter, Iter, Comp)
75 
76     static_assert(std::is_same_v<decltype(pri), std::priority_queue<double, std::vector<double>, std::greater<double>>>, "");
77     assert(pri.size() == v.size());
78     assert(pri.top() == 6);
79     }
80 
81     {
82     std::vector<double> v{10, 6, 15, 28, 4, 18, 19 };
83     std::deque<double> deq;
84     std::priority_queue pri(v.begin(), v.end(), std::greater<double>(), deq); // priority_queue(Iter, Iter, Comp, Container)
85 
86     static_assert(std::is_same_v<decltype(pri), std::priority_queue<double, std::deque<double>, std::greater<double>>>, "");
87     assert(pri.size() == v.size());
88     assert(pri.top() == 4);
89     }
90 
91 //  Test the implicit deduction guides
92     {
93 //  We don't expect this one to work - no way to implicitly get value_type
94 //  std::priority_queue pri(std::allocator<int>()); // queue (allocator &)
95     }
96 
97     {
98     std::priority_queue<float> source;
99     std::priority_queue pri(source); // priority_queue(priority_queue &)
100     static_assert(std::is_same_v<decltype(pri)::value_type, float>, "");
101     static_assert(std::is_same_v<decltype(pri)::container_type, std::vector<float>>, "");
102     assert(pri.size() == 0);
103     }
104 
105     {
106         typedef short T;
107         typedef std::greater<T> Comp;
108         typedef test_allocator<T> Alloc;
109         typedef std::deque<T, Alloc> Cont;
110         typedef test_allocator<int> ConvertibleToAlloc;
111         static_assert(std::uses_allocator_v<Cont, ConvertibleToAlloc> &&
112                       !std::is_same_v<typename Cont::allocator_type, ConvertibleToAlloc>);
113 
114         {
115         Comp comp;
116         Cont cont;
117         std::priority_queue pri(comp, cont, Alloc(2));
118         static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
119         }
120 
121         {
122         Comp comp;
123         Cont cont;
124         std::priority_queue pri(comp, cont, ConvertibleToAlloc(2));
125         static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
126         }
127 
128         {
129         Comp comp;
130         Cont cont;
131         std::priority_queue pri(comp, std::move(cont), Alloc(2));
132         static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
133         }
134 
135         {
136         Comp comp;
137         Cont cont;
138         std::priority_queue pri(comp, std::move(cont), ConvertibleToAlloc(2));
139         static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
140         }
141     }
142 
143     {
144         typedef short T;
145         typedef signed char ConvertibleToT;
146         typedef std::greater<T> Comp;
147         typedef test_allocator<T> Alloc;
148         typedef std::deque<T, Alloc> Cont;
149         typedef test_allocator<int> ConvertibleToAlloc;
150         static_assert(std::uses_allocator_v<Cont, ConvertibleToAlloc> &&
151                       !std::is_same_v<typename Cont::allocator_type, ConvertibleToAlloc>);
152 
153         {
154         std::priority_queue<T, Cont, Comp> source;
155         std::priority_queue pri(source, Alloc(2));
156         static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
157         }
158 
159         {
160         std::priority_queue<T, Cont, Comp> source;
161         std::priority_queue pri(source, ConvertibleToAlloc(2));
162         static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
163         }
164 
165         {
166         std::priority_queue<T, Cont, Comp> source;
167         std::priority_queue pri(std::move(source), Alloc(2));
168         static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
169         }
170 
171         {
172         std::priority_queue<T, Cont, Comp> source;
173         std::priority_queue pri(std::move(source), ConvertibleToAlloc(2));
174         static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
175         }
176 
177         {
178         Cont cont;
179         std::priority_queue pri(Comp(), cont, Alloc(2));
180         static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
181         }
182 
183         {
184         Cont cont;
185         std::priority_queue pri(Comp(), cont, ConvertibleToAlloc(2));
186         static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
187         }
188 
189         {
190         Cont cont;
191         std::priority_queue pri(Comp(), std::move(cont), Alloc(2));
192         static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
193         }
194 
195         {
196         Cont cont;
197         std::priority_queue pri(Comp(), std::move(cont), ConvertibleToAlloc(2));
198         static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
199         }
200 
201         {
202         T a[2] = {};
203         std::priority_queue pri(a, a+2, Alloc(2));
204         static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, std::vector<T, Alloc>>>);
205         }
206 
207         {
208         T a[2] = {};
209         std::priority_queue pri(a, a+2, Comp(), Alloc(2));
210         static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, std::vector<T, Alloc>, Comp>>);
211         }
212 
213         {
214         Cont cont;
215         ConvertibleToT a[2] = {};
216         std::priority_queue pri(a, a+2, Comp(), cont, Alloc(2));
217         static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
218         }
219 
220         {
221         Cont cont;
222         ConvertibleToT a[2] = {};
223         std::priority_queue pri(a, a+2, Comp(), cont, ConvertibleToAlloc(2));
224         static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
225         }
226 
227         {
228         Cont cont;
229         ConvertibleToT a[2] = {};
230         std::priority_queue pri(a, a+2, Comp(), std::move(cont), Alloc(2));
231         static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
232         }
233 
234         {
235         Cont cont;
236         ConvertibleToT a[2] = {};
237         std::priority_queue pri(a, a+2, Comp(), std::move(cont), ConvertibleToAlloc(2));
238         static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
239         }
240     }
241 
242     return 0;
243 }
244