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 merge(forward_list& x);
12
13#include <forward_list>
14#include <iterator>
15#include <vector>
16#include <cassert>
17
18#include "test_macros.h"
19#include "min_allocator.h"
20
21#if TEST_STD_VER >= 11
22# include <functional>
23#endif
24
25/// Helper struct to test a stable sort.
26///
27/// relation comparison uses a.
28/// equality comparison uses a and b.
29struct value {
30 int a;
31 int b;
32
33 friend bool operator<(const value& lhs, const value& rhs) { return lhs.a < rhs.a; }
34 friend bool operator==(const value& lhs, const value& rhs) { return lhs.a == rhs.a && lhs.b == rhs.b; }
35};
36
37int main(int, char**) {
38 { // Basic merge operation.
39 typedef int T;
40 typedef std::forward_list<T> C;
41 const T t1[] = {3, 5, 6, 7, 12, 13};
42 const T t2[] = {0, 1, 2, 4, 8, 9, 10, 11, 14, 15};
43 const T t3[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
44
45 C c1(std::begin(arr: t1), std::end(arr: t1));
46 C c2(std::begin(arr: t2), std::end(arr: t2));
47 c1.merge(list&: c2);
48 assert(c2.empty());
49
50 C c3(std::begin(arr: t3), std::end(arr: t3));
51 assert(c1 == c3);
52 }
53 { // Pointers, references, and iterators should remain valid after merging.
54 typedef int T;
55 typedef std::forward_list<T> C;
56 typedef T* P;
57 typedef typename C::iterator I;
58 const T to[3] = {0, 1, 2};
59
60 C c2(std::begin(arr: to), std::end(arr: to));
61 I io[3] = {c2.begin(), ++c2.begin(), ++ ++c2.begin()};
62#if TEST_STD_VER >= 11
63 std::reference_wrapper<T> ro[3] = {*io[0], *io[1], *io[2]};
64#endif
65 P po[3] = {&*io[0], &*io[1], &*io[2]};
66
67 C c1;
68 c1.merge(list&: c2);
69 assert(c2.empty());
70
71 for (std::size_t i = 0; i < 3; ++i) {
72 assert(to[i] == *io[i]);
73#if TEST_STD_VER >= 11
74 assert(to[i] == ro[i].get());
75#endif
76 assert(to[i] == *po[i]);
77 }
78 }
79 { // Sorting is stable.
80 typedef value T;
81 typedef std::forward_list<T> C;
82 const T t1[] = {{.a: 0, .b: 0}, {.a: 2, .b: 0}, {.a: 3, .b: 0}};
83 const T t2[] = {{.a: 0, .b: 1}, {.a: 1, .b: 1}, {.a: 2, .b: 1}, {.a: 4, .b: 1}};
84 const T t3[] = {{.a: 0, .b: 0}, {.a: 0, .b: 1}, {.a: 1, .b: 1}, {.a: 2, .b: 0}, {.a: 2, .b: 1}, {.a: 3, .b: 0}, {.a: 4, .b: 1}};
85
86 C c1(std::begin(arr: t1), std::end(arr: t1));
87 C c2(std::begin(arr: t2), std::end(arr: t2));
88 c1.merge(list&: c2);
89 assert(c2.empty());
90
91 C c3(std::begin(arr: t3), std::end(arr: t3));
92 assert(c1 == c3);
93 }
94#if TEST_STD_VER >= 11
95 { // Test with a different allocator.
96 typedef int T;
97 typedef std::forward_list<T, min_allocator<T>> C;
98 const T t1[] = {3, 5, 6, 7, 12, 13};
99 const T t2[] = {0, 1, 2, 4, 8, 9, 10, 11, 14, 15};
100 const T t3[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
101
102 C c1(std::begin(t1), std::end(t1));
103 C c2(std::begin(t2), std::end(t2));
104 c1.merge(c2);
105 assert(c2.empty());
106
107 C c3(std::begin(t3), std::end(t3));
108 assert(c1 == c3);
109 }
110#endif
111
112 return 0;
113}
114

source code of libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_lvalue.pass.cpp