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