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 | // <forward_list> |
10 | // UNSUPPORTED: c++03, c++11, c++14 |
11 | |
12 | // template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> |
13 | // forward_list(InputIterator, InputIterator, Allocator = Allocator()) |
14 | // -> forward_list<typename iterator_traits<InputIterator>::value_type, Allocator>; |
15 | // |
16 | // template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>> |
17 | // forward_list(from_range_t, R&&, Allocator = Allocator()) |
18 | // -> forward_list<ranges::range_value_t<R>, Allocator>; // C++23 |
19 | |
20 | #include <algorithm> |
21 | #include <array> |
22 | #include <forward_list> |
23 | #include <iterator> |
24 | #include <cassert> |
25 | #include <cstddef> |
26 | #include <climits> // INT_MAX |
27 | |
28 | #include "deduction_guides_sfinae_checks.h" |
29 | #include "test_macros.h" |
30 | #include "test_iterators.h" |
31 | #include "test_allocator.h" |
32 | |
33 | struct A {}; |
34 | |
35 | int main(int, char**) |
36 | { |
37 | |
38 | // Test the explicit deduction guides |
39 | { |
40 | const int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; |
41 | std::forward_list fwl(std::begin(arr: arr), std::end(arr: arr)); |
42 | |
43 | static_assert(std::is_same_v<decltype(fwl), std::forward_list<int>>, "" ); |
44 | assert(std::equal(fwl.begin(), fwl.end(), std::begin(arr), std::end(arr))); |
45 | } |
46 | |
47 | { |
48 | const long arr[] = {INT_MAX, 1L, 2L, 3L }; |
49 | std::forward_list fwl(std::begin(arr: arr), std::end(arr: arr), std::allocator<long>()); |
50 | static_assert(std::is_same_v<decltype(fwl)::value_type, long>, "" ); |
51 | assert(std::distance(fwl.begin(), fwl.end()) == 4); // no size for forward_list |
52 | auto it = fwl.begin(); |
53 | assert(*it++ == INT_MAX); |
54 | assert(*it++ == 1L); |
55 | assert(*it++ == 2L); |
56 | } |
57 | |
58 | // Test the implicit deduction guides |
59 | |
60 | { |
61 | // We don't expect this one to work. |
62 | // std::forward_list fwl(std::allocator<int>()); // deque (allocator &) |
63 | } |
64 | |
65 | { |
66 | std::forward_list fwl(1, A{}); // deque (size_type, T) |
67 | static_assert(std::is_same_v<decltype(fwl)::value_type, A>, "" ); |
68 | static_assert(std::is_same_v<decltype(fwl)::allocator_type, std::allocator<A>>, "" ); |
69 | assert(std::distance(fwl.begin(), fwl.end()) == 1); // no size for forward_list |
70 | } |
71 | |
72 | { |
73 | std::forward_list fwl(1, A{}, test_allocator<A>()); // deque (size_type, T, allocator) |
74 | static_assert(std::is_same_v<decltype(fwl)::value_type, A>, "" ); |
75 | static_assert(std::is_same_v<decltype(fwl)::allocator_type, test_allocator<A>>, "" ); |
76 | assert(std::distance(fwl.begin(), fwl.end()) == 1); // no size for forward_list |
77 | } |
78 | |
79 | { |
80 | std::forward_list fwl{1U, 2U, 3U, 4U, 5U}; // deque(initializer-list) |
81 | static_assert(std::is_same_v<decltype(fwl)::value_type, unsigned>, "" ); |
82 | assert(std::distance(fwl.begin(), fwl.end()) == 5); // no size for forward_list |
83 | auto it = fwl.begin(); |
84 | std::advance(i&: it, n: 2); |
85 | assert(*it == 3U); |
86 | } |
87 | |
88 | { |
89 | std::forward_list fwl({1.0, 2.0, 3.0, 4.0}, test_allocator<double>()); // deque(initializer-list, allocator) |
90 | static_assert(std::is_same_v<decltype(fwl)::value_type, double>, "" ); |
91 | static_assert(std::is_same_v<decltype(fwl)::allocator_type, test_allocator<double>>, "" ); |
92 | assert(std::distance(fwl.begin(), fwl.end()) == 4); // no size for forward_list |
93 | auto it = fwl.begin(); |
94 | std::advance(it, 3); |
95 | assert(*it == 4.0); |
96 | } |
97 | |
98 | { |
99 | std::forward_list<long double> source; |
100 | std::forward_list fwl(source); // deque(deque &) |
101 | static_assert(std::is_same_v<decltype(fwl)::value_type, long double>, "" ); |
102 | static_assert(std::is_same_v<decltype(fwl)::allocator_type, std::allocator<long double>>, "" ); |
103 | assert(std::distance(fwl.begin(), fwl.end()) == 0); // no size for forward_list |
104 | } |
105 | |
106 | { |
107 | typedef test_allocator<short> Alloc; |
108 | typedef test_allocator<int> ConvertibleToAlloc; |
109 | |
110 | { |
111 | std::forward_list<short, Alloc> source; |
112 | std::forward_list fwl(source, Alloc(2)); |
113 | static_assert(std::is_same_v<decltype(fwl), decltype(source)>); |
114 | } |
115 | |
116 | { |
117 | std::forward_list<short, Alloc> source; |
118 | std::forward_list fwl(source, ConvertibleToAlloc(2)); |
119 | static_assert(std::is_same_v<decltype(fwl), decltype(source)>); |
120 | } |
121 | |
122 | { |
123 | std::forward_list<short, Alloc> source; |
124 | std::forward_list fwl(std::move(source), Alloc(2)); |
125 | static_assert(std::is_same_v<decltype(fwl), decltype(source)>); |
126 | } |
127 | |
128 | { |
129 | std::forward_list<short, Alloc> source; |
130 | std::forward_list fwl(std::move(source), ConvertibleToAlloc(2)); |
131 | static_assert(std::is_same_v<decltype(fwl), decltype(source)>); |
132 | } |
133 | } |
134 | |
135 | #if TEST_STD_VER >= 23 |
136 | { |
137 | { |
138 | std::forward_list c(std::from_range, std::array<int, 0>()); |
139 | static_assert(std::is_same_v<decltype(c), std::forward_list<int>>); |
140 | } |
141 | |
142 | { |
143 | using Alloc = test_allocator<int>; |
144 | std::forward_list c(std::from_range, std::array<int, 0>(), Alloc()); |
145 | static_assert(std::is_same_v<decltype(c), std::forward_list<int, Alloc>>); |
146 | } |
147 | } |
148 | #endif |
149 | |
150 | SequenceContainerDeductionGuidesSfinaeAway<std::forward_list, std::forward_list<int>>(); |
151 | |
152 | return 0; |
153 | } |
154 | |