1// Copyright (c) 2012 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/memory/ref_counted.h"
6#include "testing/gtest/include/gtest/gtest.h"
7
8namespace {
9
10class SelfAssign : public base::RefCounted<SelfAssign> {
11  friend class base::RefCounted<SelfAssign>;
12
13  ~SelfAssign() {}
14};
15
16class CheckDerivedMemberAccess : public scoped_refptr<SelfAssign> {
17 public:
18  CheckDerivedMemberAccess() {
19    // This shouldn't compile if we don't have access to the member variable.
20    SelfAssign** pptr = &ptr_;
21    EXPECT_EQ(*pptr, ptr_);
22  }
23};
24
25class ScopedRefPtrToSelf : public base::RefCounted<ScopedRefPtrToSelf> {
26 public:
27  ScopedRefPtrToSelf() : self_ptr_(this) {}
28
29  static bool was_destroyed() { return was_destroyed_; }
30
31  void SelfDestruct() { self_ptr_ = NULL; }
32
33 private:
34  friend class base::RefCounted<ScopedRefPtrToSelf>;
35  ~ScopedRefPtrToSelf() { was_destroyed_ = true; }
36
37  static bool was_destroyed_;
38
39  scoped_refptr<ScopedRefPtrToSelf> self_ptr_;
40};
41
42bool ScopedRefPtrToSelf::was_destroyed_ = false;
43
44}  // end namespace
45
46TEST(RefCountedUnitTest, TestSelfAssignment) {
47  SelfAssign* p = new SelfAssign;
48  scoped_refptr<SelfAssign> var(p);
49  var = var;
50  EXPECT_EQ(var.get(), p);
51}
52
53TEST(RefCountedUnitTest, ScopedRefPtrMemberAccess) {
54  CheckDerivedMemberAccess check;
55}
56
57TEST(RefCountedUnitTest, ScopedRefPtrToSelf) {
58  ScopedRefPtrToSelf* check = new ScopedRefPtrToSelf();
59  EXPECT_FALSE(ScopedRefPtrToSelf::was_destroyed());
60  check->SelfDestruct();
61  EXPECT_TRUE(ScopedRefPtrToSelf::was_destroyed());
62}
63