]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp
Vendor import of libc++ trunk r290819:
[FreeBSD/FreeBSD.git] / test / std / utilities / memory / specialized.algorithms / uninitialized.move / uninitialized_move_n.pass.cpp
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 // UNSUPPORTED: c++98, c++03, c++11, c++14
11
12 // <memory>
13
14 // template <class InputIt, class Size, class ForwardIt>
15 // pair<InputIt, ForwardIt> uninitialized_move_n(InputIt, Size, ForwardIt);
16
17 #include <memory>
18 #include <cstdlib>
19 #include <cassert>
20
21 #include "test_macros.h"
22 #include "test_iterators.h"
23
24 struct Counted {
25   static int count;
26   static int constructed;
27   static void reset() { count = constructed =  0; }
28   explicit Counted(int&& x) : value(x) { x = 0; ++count; ++constructed; }
29   Counted(Counted const&) { assert(false); }
30   ~Counted() { assert(count > 0); --count; }
31   friend void operator&(Counted) = delete;
32   int value;
33 };
34 int Counted::count = 0;
35 int Counted::constructed = 0;
36
37 struct ThrowsCounted {
38   static int count;
39   static int constructed;
40   static int throw_after;
41   static void reset() { throw_after = count = constructed =  0; }
42   explicit ThrowsCounted(int&& x) {
43       ++constructed;
44       if (throw_after > 0 && --throw_after == 0) {
45         TEST_THROW(1);
46       }
47       ++count;
48       x = 0;
49   }
50   ThrowsCounted(ThrowsCounted const&) { assert(false); }
51   ~ThrowsCounted() { assert(count > 0); --count; }
52   friend void operator&(ThrowsCounted) = delete;
53 };
54 int ThrowsCounted::count = 0;
55 int ThrowsCounted::constructed = 0;
56 int ThrowsCounted::throw_after = 0;
57
58 void test_ctor_throws()
59 {
60 #ifndef TEST_HAS_NO_EXCEPTIONS
61     using It = forward_iterator<ThrowsCounted*>;
62     const int N = 5;
63     int values[N] = {1, 2, 3, 4, 5};
64     alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {};
65     ThrowsCounted* p = (ThrowsCounted*)pool;
66     try {
67         ThrowsCounted::throw_after = 4;
68         std::uninitialized_move_n(values, N, It(p));
69         assert(false);
70     } catch (...) {}
71     assert(ThrowsCounted::count == 0);
72     assert(ThrowsCounted::constructed == 4); // forth construction throws
73     assert(values[0] == 0);
74     assert(values[1] == 0);
75     assert(values[2] == 0);
76     assert(values[3] == 4);
77     assert(values[4] == 5);
78 #endif
79 }
80
81 void test_counted()
82 {
83     using It = input_iterator<int*>;
84     using FIt = forward_iterator<Counted*>;
85     const int N = 5;
86     int values[N] = {1, 2, 3, 4, 5};
87     alignas(Counted) char pool[sizeof(Counted)*N] = {};
88     Counted* p = (Counted*)pool;
89     auto ret = std::uninitialized_move_n(It(values), 1, FIt(p));
90     assert(ret.first == It(values +1));
91     assert(ret.second == FIt(p +1));
92     assert(Counted::constructed = 1);
93     assert(Counted::count == 1);
94     assert(p[0].value == 1);
95     assert(values[0] == 0);
96     ret = std::uninitialized_move_n(It(values+1), N-1, FIt(p+1));
97     assert(ret.first == It(values+N));
98     assert(ret.second == FIt(p + N));
99     assert(Counted::count == 5);
100     assert(Counted::constructed == 5);
101     assert(p[1].value == 2);
102     assert(p[2].value == 3);
103     assert(p[3].value == 4);
104     assert(p[4].value == 5);
105     assert(values[1] == 0);
106     assert(values[2] == 0);
107     assert(values[3] == 0);
108     assert(values[4] == 0);
109     std::destroy(p, p+N);
110     assert(Counted::count == 0);
111 }
112
113 int main()
114 {
115     test_counted();
116     test_ctor_throws();
117 }