//
// This file defines IntrusiveRefCntPtr, a template class that
// implements a "smart" pointer for objects that maintain their own
-// internal reference count, and RefCountedBase/RefCountedBaseVPTR, two
-// generic base classes for objects that wish to have their lifetimes
-// managed using reference counting.
+// internal reference count, and RefCountedBase, a generic base class
+// for objects that wish to have their lifetimes managed using reference
+// counting.
//
// IntrusiveRefCntPtr is similar to Boost's intrusive_ptr with added
// LLVM-style casting.
}
};
-//===----------------------------------------------------------------------===//
-/// RefCountedBaseVPTR - A class that has the same function as
-/// RefCountedBase, but with a virtual destructor. Should be used
-/// instead of RefCountedBase for classes that already have virtual
-/// methods to enforce dynamic allocation via 'new'. Classes that
-/// inherit from RefCountedBaseVPTR can't be allocated on stack -
-/// attempting to do this will produce a compile error.
-//===----------------------------------------------------------------------===//
- class RefCountedBaseVPTR {
- mutable unsigned ref_cnt = 0;
-
- virtual void anchor();
-
- protected:
- RefCountedBaseVPTR() = default;
- RefCountedBaseVPTR(const RefCountedBaseVPTR &) : ref_cnt(0) {}
-
- virtual ~RefCountedBaseVPTR() = default;
-
- void Retain() const { ++ref_cnt; }
- void Release() const {
- assert (ref_cnt > 0 && "Reference count is already zero.");
- if (--ref_cnt == 0) delete this;
- }
-
- template <typename T>
- friend struct IntrusiveRefCntPtrInfo;
- };
-
-
template <typename T> struct IntrusiveRefCntPtrInfo {
static void retain(T *obj) { obj->Retain(); }
static void release(T *obj) { obj->Release(); }
/// wrapping NULL pointers.
///
/// Reference counting is implemented via calls to
-/// Obj->Retain()/Obj->Release(). Release() is required to destroy
-/// the object when the reference count reaches zero. Inheriting from
-/// RefCountedBase/RefCountedBaseVPTR takes care of this
-/// automatically.
+/// Obj->Retain()/Obj->Release(). Release() is required to destroy the
+/// object when the reference count reaches zero. Inheriting from
+/// RefCountedBase takes care of this automatically.
//===----------------------------------------------------------------------===//
template <typename T>
class IntrusiveRefCntPtr {
+++ /dev/null
-//== IntrusiveRefCntPtr.cpp - Smart Refcounting Pointer ----------*- C++ -*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-
-using namespace llvm;
-
-void RefCountedBaseVPTR::anchor() { }
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "gtest/gtest.h"
-namespace {
-struct VirtualRefCounted : public llvm::RefCountedBaseVPTR {
- virtual void f() {}
-};
-}
-
namespace llvm {
-// Run this test with valgrind to detect memory leaks.
-TEST(IntrusiveRefCntPtr, RefCountedBaseVPTRCopyDoesNotLeak) {
- VirtualRefCounted *V1 = new VirtualRefCounted;
- IntrusiveRefCntPtr<VirtualRefCounted> R1 = V1;
- VirtualRefCounted *V2 = new VirtualRefCounted(*V1);
- IntrusiveRefCntPtr<VirtualRefCounted> R2 = V2;
-}
+namespace {
+struct SimpleRefCounted : public RefCountedBase<SimpleRefCounted> {
+ SimpleRefCounted() { ++NumInstances; }
+ SimpleRefCounted(const SimpleRefCounted &) { ++NumInstances; }
+ ~SimpleRefCounted() { --NumInstances; }
-struct SimpleRefCounted : public RefCountedBase<SimpleRefCounted> {};
+ static int NumInstances;
+};
+int SimpleRefCounted::NumInstances = 0;
+} // anonymous namespace
-// Run this test with valgrind to detect memory leaks.
TEST(IntrusiveRefCntPtr, RefCountedBaseCopyDoesNotLeak) {
- SimpleRefCounted *S1 = new SimpleRefCounted;
- IntrusiveRefCntPtr<SimpleRefCounted> R1 = S1;
- SimpleRefCounted *S2 = new SimpleRefCounted(*S1);
- IntrusiveRefCntPtr<SimpleRefCounted> R2 = S2;
+ EXPECT_EQ(0, SimpleRefCounted::NumInstances);
+ {
+ SimpleRefCounted *S1 = new SimpleRefCounted;
+ IntrusiveRefCntPtr<SimpleRefCounted> R1 = S1;
+ SimpleRefCounted *S2 = new SimpleRefCounted(*S1);
+ IntrusiveRefCntPtr<SimpleRefCounted> R2 = S2;
+ EXPECT_EQ(2, SimpleRefCounted::NumInstances);
+ }
+ EXPECT_EQ(0, SimpleRefCounted::NumInstances);
}
struct InterceptRefCounted : public RefCountedBase<InterceptRefCounted> {