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

source code of libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp