1// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/basictypes.h"
6#include "base/scoped_ptr.h"
7#include "testing/gtest/include/gtest/gtest.h"
8
9namespace {
10
11class ConDecLogger {
12 public:
13  ConDecLogger() : ptr_(NULL) { }
14  explicit ConDecLogger(int* ptr) { set_ptr(ptr); }
15  ~ConDecLogger() { --*ptr_; }
16
17  void set_ptr(int* ptr) { ptr_ = ptr; ++*ptr_; }
18
19  int SomeMeth(int x) { return x; }
20
21 private:
22  int* ptr_;
23  DISALLOW_COPY_AND_ASSIGN(ConDecLogger);
24};
25
26}  // namespace
27
28TEST(ScopedPtrTest, ScopedPtr) {
29  int constructed = 0;
30
31  {
32    scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
33    EXPECT_EQ(1, constructed);
34    EXPECT_TRUE(scoper.get());
35
36    EXPECT_EQ(10, scoper->SomeMeth(10));
37    EXPECT_EQ(10, scoper.get()->SomeMeth(10));
38    EXPECT_EQ(10, (*scoper).SomeMeth(10));
39  }
40  EXPECT_EQ(0, constructed);
41
42  // Test reset() and release()
43  {
44    scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
45    EXPECT_EQ(1, constructed);
46    EXPECT_TRUE(scoper.get());
47
48    scoper.reset(new ConDecLogger(&constructed));
49    EXPECT_EQ(1, constructed);
50    EXPECT_TRUE(scoper.get());
51
52    scoper.reset();
53    EXPECT_EQ(0, constructed);
54    EXPECT_FALSE(scoper.get());
55
56    scoper.reset(new ConDecLogger(&constructed));
57    EXPECT_EQ(1, constructed);
58    EXPECT_TRUE(scoper.get());
59
60    ConDecLogger* take = scoper.release();
61    EXPECT_EQ(1, constructed);
62    EXPECT_FALSE(scoper.get());
63    delete take;
64    EXPECT_EQ(0, constructed);
65
66    scoper.reset(new ConDecLogger(&constructed));
67    EXPECT_EQ(1, constructed);
68    EXPECT_TRUE(scoper.get());
69  }
70  EXPECT_EQ(0, constructed);
71
72  // Test swap(), == and !=
73  {
74    scoped_ptr<ConDecLogger> scoper1;
75    scoped_ptr<ConDecLogger> scoper2;
76    EXPECT_TRUE(scoper1 == scoper2.get());
77    EXPECT_FALSE(scoper1 != scoper2.get());
78
79    ConDecLogger* logger = new ConDecLogger(&constructed);
80    scoper1.reset(logger);
81    EXPECT_EQ(logger, scoper1.get());
82    EXPECT_FALSE(scoper2.get());
83    EXPECT_FALSE(scoper1 == scoper2.get());
84    EXPECT_TRUE(scoper1 != scoper2.get());
85
86    scoper2.swap(scoper1);
87    EXPECT_EQ(logger, scoper2.get());
88    EXPECT_FALSE(scoper1.get());
89    EXPECT_FALSE(scoper1 == scoper2.get());
90    EXPECT_TRUE(scoper1 != scoper2.get());
91  }
92  EXPECT_EQ(0, constructed);
93}
94
95TEST(ScopedPtrTest, ScopedArray) {
96  static const int kNumLoggers = 12;
97
98  int constructed = 0;
99
100  {
101    scoped_array<ConDecLogger> scoper(new ConDecLogger[kNumLoggers]);
102    EXPECT_TRUE(scoper.get());
103    EXPECT_EQ(&scoper[0], scoper.get());
104    for (int i = 0; i < kNumLoggers; ++i) {
105      scoper[i].set_ptr(&constructed);
106    }
107    EXPECT_EQ(12, constructed);
108
109    EXPECT_EQ(10, scoper.get()->SomeMeth(10));
110    EXPECT_EQ(10, scoper[2].SomeMeth(10));
111  }
112  EXPECT_EQ(0, constructed);
113
114  // Test reset() and release()
115  {
116    scoped_array<ConDecLogger> scoper;
117    EXPECT_FALSE(scoper.get());
118    scoper.release();
119    EXPECT_FALSE(scoper.get());
120    scoper.reset();
121    EXPECT_FALSE(scoper.get());
122
123    scoper.reset(new ConDecLogger[kNumLoggers]);
124    for (int i = 0; i < kNumLoggers; ++i) {
125      scoper[i].set_ptr(&constructed);
126    }
127    EXPECT_EQ(12, constructed);
128    scoper.reset();
129    EXPECT_EQ(0, constructed);
130
131    scoper.reset(new ConDecLogger[kNumLoggers]);
132    for (int i = 0; i < kNumLoggers; ++i) {
133      scoper[i].set_ptr(&constructed);
134    }
135    EXPECT_EQ(12, constructed);
136    ConDecLogger* ptr = scoper.release();
137    EXPECT_EQ(12, constructed);
138    delete[] ptr;
139    EXPECT_EQ(0, constructed);
140  }
141  EXPECT_EQ(0, constructed);
142
143  // Test swap(), == and !=
144  {
145    scoped_array<ConDecLogger> scoper1;
146    scoped_array<ConDecLogger> scoper2;
147    EXPECT_TRUE(scoper1 == scoper2.get());
148    EXPECT_FALSE(scoper1 != scoper2.get());
149
150    ConDecLogger* loggers = new ConDecLogger[kNumLoggers];
151    for (int i = 0; i < kNumLoggers; ++i) {
152      loggers[i].set_ptr(&constructed);
153    }
154    scoper1.reset(loggers);
155    EXPECT_EQ(loggers, scoper1.get());
156    EXPECT_FALSE(scoper2.get());
157    EXPECT_FALSE(scoper1 == scoper2.get());
158    EXPECT_TRUE(scoper1 != scoper2.get());
159
160    scoper2.swap(scoper1);
161    EXPECT_EQ(loggers, scoper2.get());
162    EXPECT_FALSE(scoper1.get());
163    EXPECT_FALSE(scoper1 == scoper2.get());
164    EXPECT_TRUE(scoper1 != scoper2.get());
165  }
166  EXPECT_EQ(0, constructed);
167}
168
169// TODO scoped_ptr_malloc
170