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