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
11 // void splice_after(const_iterator p, forward_list&& x,
12 // const_iterator first, const_iterator last);
13
14 #include <stddef.h>
15 #include <forward_list>
16 #include <cassert>
17 #include <iterator>
18
19 #include "test_macros.h"
20 #include "min_allocator.h"
21
22 typedef ptrdiff_t T;
23 const T t1[] = {0, 1, 2, 3, 4, 5, 6, 7};
24 const T t2[] = {10, 11, 12, 13, 14, 15};
25 const ptrdiff_t size_t1 = std::end(t1) - std::begin(t1);
26 const ptrdiff_t size_t2 = std::end(t2) - std::begin(t2);
27
28 template <class C>
29 void
testd(const C & c,ptrdiff_t p,ptrdiff_t f,ptrdiff_t l)30 testd(const C& c, ptrdiff_t p, ptrdiff_t f, ptrdiff_t l)
31 {
32 typename C::const_iterator i = c.begin();
33 ptrdiff_t n1 = 0;
34 for (; n1 < p; ++n1, ++i)
35 assert(*i == t1[n1]);
36 for (ptrdiff_t n2 = f; n2 < l-1; ++n2, ++i)
37 assert(*i == t2[n2]);
38 for (; n1 < size_t1; ++n1, ++i)
39 assert(*i == t1[n1]);
40 assert(distance(c.begin(), c.end()) == size_t1 + (l > f+1 ? l-1-f : 0));
41 }
42
43 template <class C>
44 void
tests(const C & c,ptrdiff_t p,ptrdiff_t f,ptrdiff_t l)45 tests(const C& c, ptrdiff_t p, ptrdiff_t f, ptrdiff_t l)
46 {
47 typename C::const_iterator i = c.begin();
48 ptrdiff_t n = 0;
49 ptrdiff_t d = l > f+1 ? l-1-f : 0;
50 if (d == 0 || p == f)
51 {
52 for (n = 0; n < size_t1; ++n, ++i)
53 assert(*i == t1[n]);
54 }
55 else if (p < f)
56 {
57 for (n = 0; n < p; ++n, ++i)
58 assert(*i == t1[n]);
59 for (n = f; n < l-1; ++n, ++i)
60 assert(*i == t1[n]);
61 for (n = p; n < f; ++n, ++i)
62 assert(*i == t1[n]);
63 for (n = l-1; n < size_t1; ++n, ++i)
64 assert(*i == t1[n]);
65 }
66 else // p > f
67 {
68 for (n = 0; n < f; ++n, ++i)
69 assert(*i == t1[n]);
70 for (n = l-1; n < p; ++n, ++i)
71 assert(*i == t1[n]);
72 for (n = f; n < l-1; ++n, ++i)
73 assert(*i == t1[n]);
74 for (n = p; n < size_t1; ++n, ++i)
75 assert(*i == t1[n]);
76 }
77 assert(distance(c.begin(), c.end()) == size_t1);
78 }
79
main(int,char **)80 int main(int, char**)
81 {
82 {
83 // splicing different containers
84 typedef std::forward_list<T> C;
85 for (ptrdiff_t f = 0; f <= size_t2+1; ++f)
86 {
87 for (ptrdiff_t l = f; l <= size_t2+1; ++l)
88 {
89 for (ptrdiff_t p = 0; p <= size_t1; ++p)
90 {
91 C c1(std::begin(t1), std::end(t1));
92 C c2(std::begin(t2), std::end(t2));
93
94 c1.splice_after(next(c1.cbefore_begin(), p), std::move(c2),
95 next(c2.cbefore_begin(), f), next(c2.cbefore_begin(), l));
96 testd(c1, p, f, l);
97 }
98 }
99 }
100
101 // splicing within same container
102 for (ptrdiff_t f = 0; f <= size_t1+1; ++f)
103 {
104 for (ptrdiff_t l = f; l <= size_t1; ++l)
105 {
106 for (ptrdiff_t p = 0; p <= f; ++p)
107 {
108 C c1(std::begin(t1), std::end(t1));
109
110 c1.splice_after(next(c1.cbefore_begin(), p), std::move(c1),
111 next(c1.cbefore_begin(), f), next(c1.cbefore_begin(), l));
112 tests(c1, p, f, l);
113 }
114 for (ptrdiff_t p = l; p <= size_t1; ++p)
115 {
116 C c1(std::begin(t1), std::end(t1));
117
118 c1.splice_after(next(c1.cbefore_begin(), p), std::move(c1),
119 next(c1.cbefore_begin(), f), next(c1.cbefore_begin(), l));
120 tests(c1, p, f, l);
121 }
122 }
123 }
124 }
125 #if TEST_STD_VER >= 11
126 {
127 // splicing different containers
128 typedef std::forward_list<T, min_allocator<T>> C;
129 for (ptrdiff_t f = 0; f <= size_t2+1; ++f)
130 {
131 for (ptrdiff_t l = f; l <= size_t2+1; ++l)
132 {
133 for (ptrdiff_t p = 0; p <= size_t1; ++p)
134 {
135 C c1(std::begin(t1), std::end(t1));
136 C c2(std::begin(t2), std::end(t2));
137
138 c1.splice_after(next(c1.cbefore_begin(), p), std::move(c2),
139 next(c2.cbefore_begin(), f), next(c2.cbefore_begin(), l));
140 testd(c1, p, f, l);
141 }
142 }
143 }
144
145 // splicing within same container
146 for (ptrdiff_t f = 0; f <= size_t1+1; ++f)
147 {
148 for (ptrdiff_t l = f; l <= size_t1; ++l)
149 {
150 for (ptrdiff_t p = 0; p <= f; ++p)
151 {
152 C c1(std::begin(t1), std::end(t1));
153
154 c1.splice_after(next(c1.cbefore_begin(), p), std::move(c1),
155 next(c1.cbefore_begin(), f), next(c1.cbefore_begin(), l));
156 tests(c1, p, f, l);
157 }
158 for (ptrdiff_t p = l; p <= size_t1; ++p)
159 {
160 C c1(std::begin(t1), std::end(t1));
161
162 c1.splice_after(next(c1.cbefore_begin(), p), std::move(c1),
163 next(c1.cbefore_begin(), f), next(c1.cbefore_begin(), l));
164 tests(c1, p, f, l);
165 }
166 }
167 }
168 }
169 #endif
170
171 return 0;
172 }
173