summaryrefslogtreecommitdiff
path: root/src/base/refcnt.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/refcnt.hh')
-rw-r--r--src/base/refcnt.hh60
1 files changed, 58 insertions, 2 deletions
diff --git a/src/base/refcnt.hh b/src/base/refcnt.hh
index baf08c62e..f2821231d 100644
--- a/src/base/refcnt.hh
+++ b/src/base/refcnt.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2017 ARM Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
@@ -31,6 +43,8 @@
#ifndef __BASE_REFCNT_HH__
#define __BASE_REFCNT_HH__
+#include <type_traits>
+
/**
* @file base/refcnt.hh
*
@@ -80,11 +94,11 @@ class RefCounted
virtual ~RefCounted() {}
/// Increment the reference count
- void incref() { ++count; }
+ void incref() const { ++count; }
/// Decrement the reference count and destroy the object if all
/// references are gone.
- void decref() { if (--count <= 0) delete this; }
+ void decref() const { if (--count <= 0) delete this; }
};
/**
@@ -106,6 +120,18 @@ template <class T>
class RefCountingPtr
{
protected:
+ /** Convenience aliases for const/non-const versions of T w/ friendship. */
+ /** @{ */
+ static constexpr auto TisConst = std::is_const<T>::value;
+ using ConstT = typename std::conditional<TisConst,
+ RefCountingPtr<T>,
+ RefCountingPtr<typename std::add_const<T>::type>>::type;
+ friend ConstT;
+ using NonConstT = typename std::conditional<TisConst,
+ RefCountingPtr<typename std::remove_const<T>::type>,
+ RefCountingPtr<T>>::type;
+ friend NonConstT;
+ /** @} */
/// The stored pointer.
/// Arguably this should be private.
T *data;
@@ -163,6 +189,18 @@ class RefCountingPtr
/// one. Adds a reference.
RefCountingPtr(const RefCountingPtr &r) { copy(r.data); }
+ /** Move-constructor.
+ * Does not add a reference.
+ */
+ RefCountingPtr(RefCountingPtr&& r)
+ {
+ data = r.data;
+ r.data = nullptr;
+ }
+
+ template <bool B = TisConst>
+ RefCountingPtr(const NonConstT &r) { copy(r.data); }
+
/// Destroy the pointer and any reference it may hold.
~RefCountingPtr() { del(); }
@@ -179,6 +217,12 @@ class RefCountingPtr
/// Directly access the pointer itself without taking a reference.
T *get() const { return data; }
+ template <bool B = TisConst>
+ operator RefCountingPtr<typename std::enable_if<!B, ConstT>::type>()
+ {
+ return RefCountingPtr<const T>(*this);
+ }
+
/// Assign a new value to the pointer
const RefCountingPtr &operator=(T *p) { set(p); return *this; }
@@ -186,6 +230,18 @@ class RefCountingPtr
const RefCountingPtr &operator=(const RefCountingPtr &r)
{ return operator=(r.data); }
+ /// Move-assign the pointer from another RefCountingPtr
+ const RefCountingPtr &operator=(RefCountingPtr&& r)
+ {
+ /* This happens regardless of whether the pointer is the same or not,
+ * because of the move semantics, the rvalue needs to be 'destroyed'.
+ */
+ del();
+ data = r.data;
+ r.data = nullptr;
+ return *this;
+ }
+
/// Check if the pointer is empty
bool operator!() const { return data == 0; }