diff options
author | Francisco Jerez <[email protected]> | 2014-02-18 13:20:07 +0100 |
---|---|---|
committer | Francisco Jerez <[email protected]> | 2014-02-21 12:51:22 +0100 |
commit | 1b9fb2fd9129f834f041efe7f96e83998477c78b (patch) | |
tree | fc37a2b898d913b94a5659d3262f776a9493bf51 /src/gallium/state_trackers | |
parent | 9ae0bd3829a34d4239521d9c7838089395c2336c (diff) |
clover: Define an intrusive smart reference class.
Tested-by: Tom Stellard <[email protected]>
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r-- | src/gallium/state_trackers/clover/util/pointer.hpp | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/gallium/state_trackers/clover/util/pointer.hpp b/src/gallium/state_trackers/clover/util/pointer.hpp index b7a633b523c..98823aa7860 100644 --- a/src/gallium/state_trackers/clover/util/pointer.hpp +++ b/src/gallium/state_trackers/clover/util/pointer.hpp @@ -134,6 +134,72 @@ namespace clover { } /// + /// Intrusive smart reference for objects that implement the + /// clover::ref_counter interface. + /// + template<typename T> + class intrusive_ref { + public: + intrusive_ref(T &o) : p(&o) { + p->retain(); + } + + intrusive_ref(const intrusive_ref &ref) : + intrusive_ref(*ref.p) { + } + + intrusive_ref(intrusive_ref &&ref) : + p(ref.p) { + ref.p = NULL; + } + + ~intrusive_ref() { + if (p && p->release()) + delete p; + } + + intrusive_ref & + operator=(intrusive_ref ref) { + std::swap(ref.p, p); + return *this; + } + + bool + operator==(const intrusive_ref &ref) const { + return p == ref.p; + } + + bool + operator!=(const intrusive_ref &ref) const { + return p != ref.p; + } + + T & + operator()() const { + return *p; + } + + operator T &() const { + return *p; + } + + private: + T *p; + }; + + /// + /// Transfer the caller's ownership of a reference-counted object + /// to a clover::intrusive_ref smart reference. + /// + template<typename T> + inline intrusive_ref<T> + transfer(T &o) { + intrusive_ref<T> ref { o }; + o.release(); + return ref; + } + + /// /// Class that implements the usual pointer interface but in fact /// contains the object it seems to be pointing to. /// |