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// shared_ptr
12
13// template<class T, class A, class... Args>
14// shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not an array
15
16#include <memory>
17#include <new>
18#include <cstdlib>
19#include <cassert>
20
21#include "min_allocator.h"
22#include "operator_hijacker.h"
23#include "test_allocator.h"
24#include "test_macros.h"
25
26int new_count = 0;
27
28struct A
29{
30 static int count;
31
32 A(int i, char c) : int_(i), char_(c) {++count;}
33 A(const A& a)
34 : int_(a.int_), char_(a.char_)
35 {++count;}
36 ~A() {--count;}
37
38 int get_int() const {return int_;}
39 char get_char() const {return char_;}
40
41 A* operator& () = delete;
42private:
43 int int_;
44 char char_;
45};
46
47int A::count = 0;
48
49struct Zero
50{
51 static int count;
52 Zero() {++count;}
53 Zero(Zero const &) {++count;}
54 ~Zero() {--count;}
55};
56
57int Zero::count = 0;
58
59struct One
60{
61 static int count;
62 int value;
63 explicit One(int v) : value(v) {++count;}
64 One(One const & o) : value(o.value) {++count;}
65 ~One() {--count;}
66};
67
68int One::count = 0;
69
70
71struct Two
72{
73 static int count;
74 int value;
75 Two(int v, int) : value(v) {++count;}
76 Two(Two const & o) : value(o.value) {++count;}
77 ~Two() {--count;}
78};
79
80int Two::count = 0;
81
82struct Three
83{
84 static int count;
85 int value;
86 Three(int v, int, int) : value(v) {++count;}
87 Three(Three const & o) : value(o.value) {++count;}
88 ~Three() {--count;}
89};
90
91int Three::count = 0;
92
93template <class Alloc>
94void test()
95{
96 int const bad = -1;
97 {
98 std::shared_ptr<Zero> p = std::allocate_shared<Zero>(Alloc());
99 assert(Zero::count == 1);
100 }
101 assert(Zero::count == 0);
102 {
103 int const i = 42;
104 std::shared_ptr<One> p = std::allocate_shared<One>(Alloc(), i);
105 assert(One::count == 1);
106 assert(p->value == i);
107 }
108 assert(One::count == 0);
109 {
110 int const i = 42;
111 std::shared_ptr<Two> p = std::allocate_shared<Two>(Alloc(), i, bad);
112 assert(Two::count == 1);
113 assert(p->value == i);
114 }
115 assert(Two::count == 0);
116 {
117 int const i = 42;
118 std::shared_ptr<Three> p = std::allocate_shared<Three>(Alloc(), i, bad, bad);
119 assert(Three::count == 1);
120 assert(p->value == i);
121 }
122 assert(Three::count == 0);
123}
124
125int main(int, char**)
126{
127 test<bare_allocator<void> >();
128 test<test_allocator<void> >();
129
130 test_allocator_statistics alloc_stats;
131 {
132 int i = 67;
133 char c = 'e';
134 std::shared_ptr<A> p = std::allocate_shared<A>(test_allocator<A>(54, &alloc_stats), i, c);
135 assert(alloc_stats.alloc_count == 1);
136 assert(A::count == 1);
137 assert(p->get_int() == 67);
138 assert(p->get_char() == 'e');
139 }
140 assert(A::count == 0);
141 assert(alloc_stats.alloc_count == 0);
142 {
143 int i = 67;
144 char c = 'e';
145 std::shared_ptr<A> p = std::allocate_shared<A>(min_allocator<void>(), i, c);
146 assert(A::count == 1);
147 assert(p->get_int() == 67);
148 assert(p->get_char() == 'e');
149 }
150 assert(A::count == 0);
151 {
152 int i = 68;
153 char c = 'f';
154 std::shared_ptr<A> p = std::allocate_shared<A>(bare_allocator<void>(), i, c);
155 assert(A::count == 1);
156 assert(p->get_int() == 68);
157 assert(p->get_char() == 'f');
158 }
159 assert(A::count == 0);
160
161 // Make sure std::allocate_shared handles badly-behaved types properly
162 {
163 std::shared_ptr<operator_hijacker> p1 = std::allocate_shared<operator_hijacker>(min_allocator<operator_hijacker>());
164 std::shared_ptr<operator_hijacker> p2 = std::allocate_shared<operator_hijacker>(min_allocator<operator_hijacker>(), operator_hijacker());
165 assert(p1 != nullptr);
166 assert(p2 != nullptr);
167 }
168
169 return 0;
170}
171

source code of libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp