Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: compiled/intrusive_ptr.h

Issue 29333474: Issue 4125 - [emscripten] Convert filter classes to C++ (Closed)
Patch Set: Got rid of extra output in bindings.js file Created June 9, 2016, 1:35 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: compiled/intrusive_ptr.h
===================================================================
new file mode 100644
--- /dev/null
+++ b/compiled/intrusive_ptr.h
@@ -0,0 +1,197 @@
+// Parts of this code have been copied from boost/smart_ptr/intrusive_ptr.hpp.
+//
+// Copyright (c) 2001, 2002 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#pragma once
+
+#include <algorithm>
+#include <type_traits>
+
+class ref_counted
+{
+public:
+ void AddRef()
+ {
+ mRefCount++;
+ }
+
+ void ReleaseRef()
+ {
sergei 2016/06/16 21:17:29 It would be good to have assert that mRefCount is
Wladimir Palant 2016/12/06 10:48:29 Done.
+ if (--mRefCount == 0)
+ delete this;
+ }
+
+protected:
+ ref_counted()
+ : mRefCount(0)
sergei 2016/06/16 21:17:24 To tell the truth I'm not sure that the initial va
Wladimir Palant 2016/12/06 10:48:24 Yes, I changed that already along with the general
+ {
+ }
+
+ // We need this virtual destructor, otherwise pointers to ref_counted and
sergei 2016/06/16 21:17:18 This comment is incorrect, pointers are equal, so
Wladimir Palant 2016/12/06 10:48:28 Pointers are equal if you compare them in C++. How
sergei 2017/01/10 15:57:22 Pointers in c++ are already numeric values and are
Wladimir Palant 2017/03/13 17:41:46 Ok, I removed the comment here and instead added o
Wladimir Palant 2017/03/14 10:23:12 Actually, it is better to remove the footgun inste
+ // pointers to derived classes won't have the same value (e.g. converting from
+ // Filter* to ref_counted* decreases pointer value by 4).
+ virtual ~ref_counted()
+ {
sergei 2016/06/16 21:17:20 it would be good to have assert that mRefCount is
Wladimir Palant 2016/12/06 10:48:22 Done.
+ }
+
+private:
+ int mRefCount;
+};
+
+template<typename T,
+ class = typename std::enable_if<std::is_base_of<ref_counted,T>::value>::type>
+class intrusive_ptr
+{
+public:
+ intrusive_ptr()
+ : mPointer(nullptr)
+ {
+ }
+
+ intrusive_ptr(T* pointer)
+ : mPointer(pointer)
+ {
+ if (mPointer)
+ mPointer->AddRef();
+ }
+
+ intrusive_ptr(const intrusive_ptr& other)
+ : mPointer(other.mPointer)
+ {
+ if (mPointer)
+ mPointer->AddRef();
+ }
+
+ intrusive_ptr(intrusive_ptr&& other)
+ : mPointer(other.mPointer)
+ {
+ other.mPointer = nullptr;
+ }
+
+ ~intrusive_ptr()
+ {
+ if (mPointer)
+ mPointer->ReleaseRef();
+ }
+
+ intrusive_ptr& operator=(intrusive_ptr& other)
+ {
+ intrusive_ptr(other).swap(*this);
+ return *this;
+ }
+
+ intrusive_ptr& operator=(intrusive_ptr&& other)
+ {
+ intrusive_ptr(std::move(other)).swap(*this);
+ return *this;
+ }
+
+ intrusive_ptr& operator=(T* other)
+ {
+ intrusive_ptr(other).swap(*this);
+ return *this;
+ }
+
+ void reset()
+ {
+ intrusive_ptr().swap(*this);
+ }
+
+ void reset(T* other)
+ {
+ intrusive_ptr(other).swap(*this);
+ }
+
+ const T* get() const
+ {
+ return mPointer;
+ }
+
+ T* get()
+ {
+ return mPointer;
+ }
+
+ const T& operator*() const
+ {
+ return *mPointer;
+ }
+
+ T& operator*()
+ {
+ return *mPointer;
+ }
+
+ const T* operator->() const
+ {
+ return mPointer;
+ }
+
+ T* operator->()
+ {
+ return mPointer;
+ }
+
+ operator bool() const
sergei 2016/06/16 21:17:27 It would be also better to make it explicit operat
Wladimir Palant 2016/12/06 10:48:26 Done.
+ {
+ return mPointer != nullptr;
+ }
+
+ operator T*() const
sergei 2016/06/16 21:17:22 I personally don't like this operator because of i
Wladimir Palant 2016/12/06 10:48:16 Done.
+ {
+ return mPointer;
+ }
+
+ bool operator!() const
+ {
+ return mPointer == nullptr;
+ }
+
+ void swap(intrusive_ptr& other)
+ {
+ std::swap(mPointer, other.mPointer);
+ }
+
+private:
+ T* mPointer;
+};
+
+template<typename T, typename U>
+inline bool operator==(const intrusive_ptr<T>& a, const intrusive_ptr<U>& b)
sergei 2016/06/16 21:17:21 JIC, these operators don't always work, e.g. with
Wladimir Palant 2016/12/06 10:48:21 Won't C++ cast these pointers automatically in ord
sergei 2017/01/10 15:57:20 No.
+{
+ return a.get() == b.get();
+}
+
+template<typename T, typename U>
+inline bool operator!=(const intrusive_ptr<T>& a, const intrusive_ptr<U>& b)
+{
+ return a.get() != b.get();
+}
+
+template<typename T, typename U>
+inline bool operator==(const intrusive_ptr<T>& a, const U* b)
+{
+ return a.get() == b;
+}
+
+template<typename T, typename U>
+inline bool operator!=(const intrusive_ptr<T>& a, const U* b)
+{
+ return a.get() != b;
+}
+
+template<typename T, typename U>
+inline bool operator==(const T* a, const intrusive_ptr<U>& b)
+{
+ return a == b.get();
+}
+
+template<typename T, typename U>
+inline bool operator!=(const T* a, intrusive_ptr<U> const& b)
+{
+ return a != b.get();
+}

Powered by Google App Engine
This is Rietveld