StlAllocator.h + MakeUnique.h -> Memory.h
[folly.git] / folly / test / ArenaSmartPtrTest.cpp
1 /*
2  * Copyright 2013 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /*
18  * @author: Marcelo Juchem <marcelo@fb.com>
19  */
20
21 #include "folly/Memory.h"
22 #include "folly/Arena.h"
23
24 #include <gtest/gtest.h>
25
26 using namespace folly;
27
28 struct global_counter {
29   global_counter(): count_(0) {}
30
31   void increase() { ++count_; }
32   void decrease() {
33     EXPECT_GT(count_, 0);
34     --count_;
35   }
36
37   unsigned count() const { return count_; }
38
39 private:
40   unsigned count_;
41 };
42
43 struct Foo {
44   explicit Foo(global_counter& counter):
45     counter_(counter)
46   {
47     counter_.increase();
48   }
49
50   ~Foo() {
51     counter_.decrease();
52   }
53
54 private:
55   global_counter& counter_;
56 };
57
58 template <typename Allocator>
59 void unique_ptr_test(Allocator& allocator) {
60   typedef typename AllocatorUniquePtr<Foo, Allocator>::type ptr_type;
61
62   global_counter counter;
63   EXPECT_EQ(counter.count(), 0);
64
65   Foo* foo = nullptr;
66
67   {
68     auto p = folly::allocate_unique<Foo>(allocator, counter);
69     EXPECT_EQ(counter.count(), 1);
70
71     p.reset();
72     EXPECT_EQ(counter.count(), 0);
73
74     p = folly::allocate_unique<Foo>(allocator, counter);
75     EXPECT_EQ(counter.count(), 1);
76
77     foo = p.release();
78     EXPECT_EQ(counter.count(), 1);
79   }
80   EXPECT_EQ(counter.count(), 1);
81
82   {
83     auto p = folly::allocate_unique<Foo>(allocator, counter);
84     EXPECT_EQ(counter.count(), 2);
85
86     [&](ptr_type g) {
87       EXPECT_EQ(counter.count(), 2);
88       g.reset();
89       EXPECT_EQ(counter.count(), 1);
90     }(std::move(p));
91   }
92   EXPECT_EQ(counter.count(), 1);
93
94   StlAllocator<Allocator, Foo>().destroy(foo);
95   EXPECT_EQ(counter.count(), 0);
96 }
97
98 TEST(ArenaSmartPtr, unique_ptr_SysArena) {
99   SysArena arena;
100   unique_ptr_test(arena);
101 }
102
103 TEST(ArenaSmartPtr, unique_ptr_StlAlloc_SysArena) {
104   SysArena arena;
105   StlAllocator<SysArena, Foo> alloc(&arena);
106   unique_ptr_test(alloc);
107 }
108
109 template <typename Allocator>
110 void shared_ptr_test(Allocator& allocator) {
111   typedef std::shared_ptr<Foo> ptr_type;
112
113   global_counter counter;
114   EXPECT_EQ(counter.count(), 0);
115
116   ptr_type foo;
117   EXPECT_EQ(counter.count(), 0);
118   EXPECT_EQ(foo.use_count(), 0);
119
120   {
121     auto p = folly::allocate_shared<Foo>(allocator, counter);
122     EXPECT_EQ(counter.count(), 1);
123     EXPECT_EQ(p.use_count(), 1);
124
125     p.reset();
126     EXPECT_EQ(counter.count(), 0);
127     EXPECT_EQ(p.use_count(), 0);
128
129     p = folly::allocate_shared<Foo>(allocator, counter);
130     EXPECT_EQ(counter.count(), 1);
131     EXPECT_EQ(p.use_count(), 1);
132
133     foo = p;
134     EXPECT_EQ(p.use_count(), 2);
135   }
136   EXPECT_EQ(counter.count(), 1);
137   EXPECT_EQ(foo.use_count(), 1);
138
139   {
140     auto p = foo;
141     EXPECT_EQ(counter.count(), 1);
142     EXPECT_EQ(p.use_count(), 2);
143
144     [&](ptr_type g) {
145       EXPECT_EQ(counter.count(), 1);
146       EXPECT_EQ(p.use_count(), 3);
147       EXPECT_EQ(g.use_count(), 3);
148       g.reset();
149       EXPECT_EQ(counter.count(), 1);
150       EXPECT_EQ(p.use_count(), 2);
151       EXPECT_EQ(g.use_count(), 0);
152     }(p);
153     EXPECT_EQ(counter.count(), 1);
154     EXPECT_EQ(p.use_count(), 2);
155   }
156   EXPECT_EQ(counter.count(), 1);
157   EXPECT_EQ(foo.use_count(), 1);
158
159   foo.reset();
160   EXPECT_EQ(counter.count(), 0);
161   EXPECT_EQ(foo.use_count(), 0);
162 }
163
164 TEST(ArenaSmartPtr, shared_ptr_SysArena) {
165   SysArena arena;
166   shared_ptr_test(arena);
167 }
168
169 TEST(ArenaSmartPtr, shared_ptr_StlAlloc_SysArena) {
170   SysArena arena;
171   StlAllocator<SysArena, Foo> alloc(&arena);
172   shared_ptr_test(alloc);
173 }
174
175 int main(int argc, char *argv[]) {
176   testing::InitGoogleTest(&argc, argv);
177   return RUN_ALL_TESTS();
178 }