]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp
Vendor import of libc++ trunk r290819:
[FreeBSD/FreeBSD.git] / test / std / utilities / memory / specialized.algorithms / uninitialized.construct.value / uninitialized_value_construct_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 ForwardIt>
15 // void uninitialized_value_construct(ForwardIt, 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() { ++count; ++constructed; }
29   Counted(Counted const&) { assert(false); }
30   ~Counted() { --count; }
31   friend void operator&(Counted) = delete;
32 };
33 int Counted::count = 0;
34 int Counted::constructed = 0;
35
36 struct ThrowsCounted {
37   static int count;
38   static int constructed;
39   static int throw_after;
40   static void reset() { throw_after = count = constructed =  0; }
41   explicit ThrowsCounted() {
42       ++constructed;
43       if (throw_after > 0 && --throw_after == 0) {
44           TEST_THROW(1);
45       }
46       ++count;
47   }
48   ThrowsCounted(ThrowsCounted const&) { assert(false); }
49   ~ThrowsCounted() { --count; }
50   friend void operator&(ThrowsCounted) = delete;
51 };
52 int ThrowsCounted::count = 0;
53 int ThrowsCounted::constructed = 0;
54 int ThrowsCounted::throw_after = 0;
55
56 void test_ctor_throws()
57 {
58 #ifndef TEST_HAS_NO_EXCEPTIONS
59     using It = forward_iterator<ThrowsCounted*>;
60     const int N = 5;
61     alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {};
62     ThrowsCounted* p = (ThrowsCounted*)pool;
63     try {
64         ThrowsCounted::throw_after = 4;
65         std::uninitialized_value_construct_n(It(p), N);
66         assert(false);
67     } catch (...) {}
68     assert(ThrowsCounted::count == 3);
69     assert(ThrowsCounted::constructed == 4); // forth construction throws
70     std::destroy(p, p+3);
71     assert(ThrowsCounted::count == 0);
72 #endif
73 }
74
75 void test_counted()
76 {
77     using It = forward_iterator<Counted*>;
78     const int N = 5;
79     alignas(Counted) char pool[sizeof(Counted)*N] = {};
80     Counted* p = (Counted*)pool;
81     It e = std::uninitialized_value_construct_n(It(p), 1);
82     assert(e == It(p+1));
83     assert(Counted::count == 1);
84     assert(Counted::constructed = 1);
85     e = std::uninitialized_value_construct_n(It(p+1), 4);
86     assert(e == It(p+N));
87     assert(Counted::count == 5);
88     assert(Counted::constructed == 5);
89     std::destroy(p, p+N);
90     assert(Counted::count == 0);
91 }
92
93 void test_value_initialized()
94 {
95     using It = forward_iterator<int*>;
96     const int N = 5;
97     int pool[N] = {-1, -1, -1, -1, -1};
98     int* p = pool;
99     It e = std::uninitialized_value_construct_n(It(p), 1);
100     assert(e == It(p+1));
101     assert(pool[0] == 0);
102     assert(pool[1] == -1);
103     e = std::uninitialized_value_construct_n(It(p+1), 4);
104     assert(e == It(p+N));
105     assert(pool[1] == 0);
106     assert(pool[2] == 0);
107     assert(pool[3] == 0);
108     assert(pool[4] == 0);
109 }
110
111 int main()
112 {
113     test_counted();
114     test_value_initialized();
115 }