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