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() { assert(count > 0); --count; }
30 friend void operator&(Counted) = delete;
31};
32int Counted::count = 0;
33int Counted::constructed = 0;
34
35
36struct 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() { assert(count > 0); --count; }
50 friend void operator&(ThrowsCounted) = delete;
51};
52int ThrowsCounted::count = 0;
53int ThrowsCounted::constructed = 0;
54int ThrowsCounted::throw_after = 0;
55
56void 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(It(p), It(p+N));
66 assert(false);
67 } catch (...) {}
68 assert(ThrowsCounted::count == 0);
69 assert(ThrowsCounted::constructed == 4); // forth construction throws
70#endif
71}
72
73void test_counted()
74{
75 using It = forward_iterator<Counted*>;
76 const int N = 5;
77 alignas(Counted) char pool[sizeof(Counted)*N] = {};
78 Counted* p = (Counted*)pool;
79 std::uninitialized_value_construct(It(p), It(p+1));
80 assert(Counted::count == 1);
81 assert(Counted::constructed == 1);
82 std::uninitialized_value_construct(It(p+1), It(p+N));
83 assert(Counted::count == 5);
84 assert(Counted::constructed == 5);
85 std::destroy(first: p, last: p+N);
86 assert(Counted::count == 0);
87}
88
89void test_value_initialized()
90{
91 using It = forward_iterator<int*>;
92 const int N = 5;
93 int pool[N] = {-1, -1, -1, -1, -1};
94 int* p = pool;
95 std::uninitialized_value_construct(It(p), It(p+1));
96 assert(pool[0] == 0);
97 assert(pool[1] == -1);
98 std::uninitialized_value_construct(It(p+1), It(p+N));
99 assert(pool[1] == 0);
100 assert(pool[2] == 0);
101 assert(pool[3] == 0);
102 assert(pool[4] == 0);
103}
104
105int main(int, char**)
106{
107 test_counted();
108 test_value_initialized();
109 test_ctor_throws();
110
111 return 0;
112}
113

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