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 // <stack>
10 // UNSUPPORTED: c++03, c++11, c++14
11 // UNSUPPORTED: clang-5, apple-clang-9
12 // Clang 5 will generate bad implicit deduction guides
13 //	Specifically, for the copy constructor.
14 
15 // template<class Container>
16 //   stack(Container) -> stack<typename Container::value_type, Container>;
17 //
18 // template<class Container, class Allocator>
19 //   stack(Container, Allocator) -> stack<typename Container::value_type, Container>;
20 
21 
22 #include <stack>
23 #include <deque>
24 #include <vector>
25 #include <list>
26 #include <iterator>
27 #include <cassert>
28 #include <cstddef>
29 #include <climits> // INT_MAX
30 
31 #include "test_macros.h"
32 #include "test_iterators.h"
33 #include "test_allocator.h"
34 
35 struct A {};
36 
37 int main(int, char**)
38 {
39 
40 //  Test the explicit deduction guides
41     {
42     std::vector<int> v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
43     std::stack stk(v);
44 
45     static_assert(std::is_same_v<decltype(stk), std::stack<int, std::vector<int>>>, "");
46     assert(stk.size() == v.size());
47     assert(stk.top() == v.back());
48     }
49 
50     {
51     std::list<long, test_allocator<long>> l{10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };
52     std::stack stk(l, test_allocator<long>(0,2)); // different allocator
53     static_assert(std::is_same_v<decltype(stk)::container_type, std::list<long, test_allocator<long>>>, "");
54     static_assert(std::is_same_v<decltype(stk)::value_type, long>, "");
55     assert(stk.size() == 10);
56     assert(stk.top() == 19);
57 //  I'd like to assert that we've gotten the right allocator in the stack, but
58 //  I don't know how to get at the underlying container.
59     }
60 
61 //  Test the implicit deduction guides
62 
63     {
64 //  We don't expect this one to work - no way to implicitly get value_type
65 //  std::stack stk(std::allocator<int>()); // stack (allocator &)
66     }
67 
68     {
69     std::stack<A> source;
70     std::stack stk(source); // stack(stack &)
71     static_assert(std::is_same_v<decltype(stk)::value_type, A>, "");
72     static_assert(std::is_same_v<decltype(stk)::container_type, std::deque<A>>, "");
73     assert(stk.size() == 0);
74     }
75 
76     {
77         typedef short T;
78         typedef test_allocator<T> Alloc;
79         typedef std::list<T, Alloc> Cont;
80         typedef test_allocator<int> ConvertibleToAlloc;
81         static_assert(std::uses_allocator_v<Cont, ConvertibleToAlloc> &&
82                       !std::is_same_v<typename Cont::allocator_type, ConvertibleToAlloc>);
83 
84         {
85         Cont cont;
86         std::stack stk(cont, Alloc(2));
87         static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>);
88         }
89 
90         {
91         Cont cont;
92         std::stack stk(cont, ConvertibleToAlloc(2));
93         static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>);
94         }
95 
96         {
97         Cont cont;
98         std::stack stk(std::move(cont), Alloc(2));
99         static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>);
100         }
101 
102         {
103         Cont cont;
104         std::stack stk(std::move(cont), ConvertibleToAlloc(2));
105         static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>);
106         }
107     }
108 
109     {
110         typedef short T;
111         typedef test_allocator<T> Alloc;
112         typedef std::list<T, Alloc> Cont;
113         typedef test_allocator<int> ConvertibleToAlloc;
114         static_assert(std::uses_allocator_v<Cont, ConvertibleToAlloc> &&
115                       !std::is_same_v<typename Cont::allocator_type, ConvertibleToAlloc>);
116 
117         {
118         std::stack<T, Cont> source;
119         std::stack stk(source, Alloc(2));
120         static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>);
121         }
122 
123         {
124         std::stack<T, Cont> source;
125         std::stack stk(source, ConvertibleToAlloc(2));
126         static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>);
127         }
128 
129         {
130         std::stack<T, Cont> source;
131         std::stack stk(std::move(source), Alloc(2));
132         static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>);
133         }
134 
135         {
136         std::stack<T, Cont> source;
137         std::stack stk(std::move(source), ConvertibleToAlloc(2));
138         static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>);
139         }
140     }
141 
142     return 0;
143 }
144