Skip to content

Commit

Permalink
Enable boolean testing of scoped_refptr<T>.
Browse files Browse the repository at this point in the history
BUG=110610

Review URL: https://codereview.chromium.org/758803002

Cr-Commit-Position: refs/heads/master@{#305763}
  • Loading branch information
zetafunction authored and Commit bot committed Nov 26, 2014
1 parent 58d7a81 commit 5ab2ac7
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
13 changes: 13 additions & 0 deletions base/memory/ref_counted.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,19 @@ class scoped_refptr {
swap(&r.ptr_);
}

private:
// Allow scoped_refptr<T> to be used in boolean expressions, but not
// implicitly convertible to a real bool (which is dangerous).
//
// Note that this trick is only safe when the == and != operators
// are declared explicitly, as otherwise "refptr1 == refptr2"
// will compile but do the wrong thing (i.e., convert to Testable
// and then do the comparison).
typedef T* scoped_refptr::*Testable;

public:
operator Testable() const { return ptr_ ? &scoped_refptr::ptr_ : nullptr; }

template <typename U>
bool operator==(const scoped_refptr<U>& rhs) const {
return ptr_ == rhs.get();
Expand Down
43 changes: 42 additions & 1 deletion base/memory/ref_counted_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,19 @@
namespace {

class SelfAssign : public base::RefCounted<SelfAssign> {
protected:
virtual ~SelfAssign() {}

private:
friend class base::RefCounted<SelfAssign>;
};

class Derived : public SelfAssign {
protected:
~Derived() override {}

~SelfAssign() {}
private:
friend class base::RefCounted<Derived>;
};

class CheckDerivedMemberAccess : public scoped_refptr<SelfAssign> {
Expand Down Expand Up @@ -72,3 +82,34 @@ TEST(RefCountedUnitTest, ScopedRefPtrToOpaque) {
base::TestOpaqueRefCounted(p);
base::TestOpaqueRefCounted(q);
}

TEST(RefCountedUnitTest, BooleanTesting) {
scoped_refptr<SelfAssign> p;
EXPECT_FALSE(p);
p = new SelfAssign;
EXPECT_TRUE(p);
}

TEST(RefCountedUnitTest, Equality) {
scoped_refptr<SelfAssign> p1(new SelfAssign);
scoped_refptr<SelfAssign> p2(new SelfAssign);

EXPECT_EQ(p1, p1);
EXPECT_EQ(p2, p2);

EXPECT_NE(p1, p2);
EXPECT_NE(p2, p1);
}

TEST(RefCountedUnitTest, ConvertibleEquality) {
scoped_refptr<Derived> p1(new Derived);
scoped_refptr<SelfAssign> p2;

EXPECT_NE(p1, p2);
EXPECT_NE(p2, p1);

p2 = p1;

EXPECT_EQ(p1, p2);
EXPECT_EQ(p2, p1);
}

0 comments on commit 5ab2ac7

Please sign in to comment.