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 | // <memory> |
10 | |
11 | // template <class InputIterator, class Size, class ForwardIterator> |
12 | // ForwardIterator |
13 | // uninitialized_copy_n(InputIterator first, Size n, |
14 | // ForwardIterator result); |
15 | |
16 | #include <memory> |
17 | #include <cassert> |
18 | |
19 | #include "test_macros.h" |
20 | #include "../overload_compare_iterator.h" |
21 | |
22 | struct B |
23 | { |
24 | static int count_; |
25 | static int population_; |
26 | int data_; |
27 | explicit B() : data_(1) { ++population_; } |
28 | B(const B &b) { |
29 | ++count_; |
30 | if (count_ == 3) |
31 | TEST_THROW(1); |
32 | data_ = b.data_; |
33 | ++population_; |
34 | } |
35 | ~B() {data_ = 0; --population_; } |
36 | }; |
37 | |
38 | int B::population_ = 0; |
39 | int B::count_ = 0; |
40 | |
41 | struct Nasty |
42 | { |
43 | Nasty() : i_ ( counter_++ ) {} |
44 | Nasty * operator &() const { return nullptr; } |
45 | int i_; |
46 | static int counter_; |
47 | }; |
48 | |
49 | int Nasty::counter_ = 0; |
50 | |
51 | int main(int, char**) |
52 | { |
53 | { |
54 | const int N = 5; |
55 | char pool[sizeof(B)*N] = {0}; |
56 | B* bp = (B*)pool; |
57 | B b[N]; |
58 | assert(B::population_ == N); |
59 | #ifndef TEST_HAS_NO_EXCEPTIONS |
60 | try |
61 | { |
62 | std::uninitialized_copy_n(first: b, n: 5, result: bp); |
63 | assert(false); |
64 | } |
65 | catch (...) |
66 | { |
67 | assert(B::population_ == N); |
68 | } |
69 | #endif |
70 | B::count_ = 0; |
71 | std::uninitialized_copy_n(first: b, n: 2, result: bp); |
72 | for (int i = 0; i < 2; ++i) |
73 | assert(bp[i].data_ == 1); |
74 | assert(B::population_ == N + 2); |
75 | } |
76 | |
77 | { |
78 | const int N = 5; |
79 | char pool[sizeof(Nasty)*N] = {0}; |
80 | Nasty * p = (Nasty *) pool; |
81 | Nasty arr[N]; |
82 | std::uninitialized_copy_n(first: arr, n: N, result: p); |
83 | for (int i = 0; i < N; ++i) { |
84 | assert(arr[i].i_ == i); |
85 | assert( p[i].i_ == i); |
86 | } |
87 | } |
88 | |
89 | // Test with an iterator that overloads operator== and operator!= as the input and output iterators |
90 | { |
91 | using T = int; |
92 | using Iterator = overload_compare_iterator<T*>; |
93 | const int N = 5; |
94 | |
95 | // input |
96 | { |
97 | char pool[sizeof(T) * N] = {0}; |
98 | T* p = reinterpret_cast<T*>(pool); |
99 | T array[N] = {1, 2, 3, 4, 5}; |
100 | std::uninitialized_copy_n(first: Iterator(array), n: N, result: p); |
101 | for (int i = 0; i != N; ++i) { |
102 | assert(array[i] == p[i]); |
103 | } |
104 | } |
105 | |
106 | // output |
107 | { |
108 | char pool[sizeof(T) * N] = {0}; |
109 | T* p = reinterpret_cast<T*>(pool); |
110 | T array[N] = {1, 2, 3, 4, 5}; |
111 | std::uninitialized_copy_n(first: array, n: N, result: Iterator(p)); |
112 | for (int i = 0; i != N; ++i) { |
113 | assert(array[i] == p[i]); |
114 | } |
115 | } |
116 | } |
117 | |
118 | return 0; |
119 | } |
120 | |