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 12 // template<class Container> 13 // stack(Container) -> stack<typename Container::value_type, Container>; 14 // 15 // template<class Container, class Allocator> 16 // stack(Container, Allocator) -> stack<typename Container::value_type, Container>; 17 18 19 #include <array> 20 #include <stack> 21 #include <deque> 22 #include <vector> 23 #include <list> 24 #include <iterator> 25 #include <cassert> 26 #include <cstddef> 27 #include <climits> // INT_MAX 28 29 #include "deduction_guides_sfinae_checks.h" 30 #include "test_macros.h" 31 #include "test_iterators.h" 32 #include "test_allocator.h" 33 34 struct A {}; 35 36 int main(int, char**) 37 { 38 39 // Test the explicit deduction guides 40 { 41 std::vector<int> v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 42 std::stack stk(v); 43 44 static_assert(std::is_same_v<decltype(stk), std::stack<int, std::vector<int>>>, ""); 45 assert(stk.size() == v.size()); 46 assert(stk.top() == v.back()); 47 } 48 49 { 50 std::list<long, test_allocator<long>> l{10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; 51 std::stack stk(l, test_allocator<long>(0,2)); // different allocator 52 static_assert(std::is_same_v<decltype(stk)::container_type, std::list<long, test_allocator<long>>>, ""); 53 static_assert(std::is_same_v<decltype(stk)::value_type, long>, ""); 54 assert(stk.size() == 10); 55 assert(stk.top() == 19); 56 // I'd like to assert that we've gotten the right allocator in the stack, but 57 // I don't know how to get at the underlying container. 58 } 59 60 // Test the implicit deduction guides 61 62 { 63 // We don't expect this one to work - no way to implicitly get value_type 64 // std::stack stk(std::allocator<int>()); // stack (allocator &) 65 } 66 67 { 68 std::stack<A> source; 69 std::stack stk(source); // stack(stack &) 70 static_assert(std::is_same_v<decltype(stk)::value_type, A>, ""); 71 static_assert(std::is_same_v<decltype(stk)::container_type, std::deque<A>>, ""); 72 assert(stk.size() == 0); 73 } 74 75 { 76 typedef short T; 77 typedef test_allocator<T> Alloc; 78 typedef std::list<T, Alloc> Cont; 79 typedef test_allocator<int> ConvertibleToAlloc; 80 static_assert(std::uses_allocator_v<Cont, ConvertibleToAlloc> && 81 !std::is_same_v<typename Cont::allocator_type, ConvertibleToAlloc>); 82 83 { 84 Cont cont; 85 std::stack stk(cont, Alloc(2)); 86 static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>); 87 } 88 89 { 90 Cont cont; 91 std::stack stk(cont, ConvertibleToAlloc(2)); 92 static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>); 93 } 94 95 { 96 Cont cont; 97 std::stack stk(std::move(cont), Alloc(2)); 98 static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>); 99 } 100 101 { 102 Cont cont; 103 std::stack stk(std::move(cont), ConvertibleToAlloc(2)); 104 static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>); 105 } 106 } 107 108 { 109 typedef short T; 110 typedef test_allocator<T> Alloc; 111 typedef std::list<T, Alloc> Cont; 112 typedef test_allocator<int> ConvertibleToAlloc; 113 static_assert(std::uses_allocator_v<Cont, ConvertibleToAlloc> && 114 !std::is_same_v<typename Cont::allocator_type, ConvertibleToAlloc>); 115 116 { 117 std::stack<T, Cont> source; 118 std::stack stk(source, Alloc(2)); 119 static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>); 120 } 121 122 { 123 std::stack<T, Cont> source; 124 std::stack stk(source, ConvertibleToAlloc(2)); 125 static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>); 126 } 127 128 { 129 std::stack<T, Cont> source; 130 std::stack stk(std::move(source), Alloc(2)); 131 static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>); 132 } 133 134 { 135 std::stack<T, Cont> source; 136 std::stack stk(std::move(source), ConvertibleToAlloc(2)); 137 static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>); 138 } 139 } 140 141 // Deduction guides should be SFINAE'd away when given: 142 // - a "bad" allocator (that is, a type not qualifying as an allocator); 143 // - an allocator instead of a container; 144 // - an allocator and a container that uses a different allocator. 145 { 146 using Cont = std::list<int>; 147 using Alloc = std::allocator<int>; 148 using DiffAlloc = test_allocator<int>; 149 using Iter = int; 150 151 struct NotIter {}; 152 struct NotAlloc {}; 153 154 static_assert(SFINAEs_away<std::stack, Alloc, Alloc>); 155 static_assert(SFINAEs_away<std::stack, Cont, NotAlloc>); 156 static_assert(SFINAEs_away<std::stack, Cont, DiffAlloc>); 157 static_assert(SFINAEs_away<std::stack, Iter, NotIter>); 158 #if TEST_STD_VER > 20 159 static_assert(SFINAEs_away<std::stack, Iter, NotIter, Alloc>); 160 static_assert(SFINAEs_away<std::stack, Iter, Iter, NotAlloc>); 161 #endif 162 } 163 164 #if TEST_STD_VER > 20 165 { 166 typedef short T; 167 typedef test_allocator<T> Alloc; 168 std::list<T> a; 169 { 170 std::stack s(a.begin(), a.end()); 171 static_assert(std::is_same_v<decltype(s), std::stack<T>>); 172 } 173 { 174 std::stack s(a.begin(), a.end(), Alloc()); 175 static_assert(std::is_same_v<decltype(s), std::stack<T, std::deque<T, Alloc>>>); 176 } 177 } 178 #endif 179 180 return 0; 181 } 182