 Issue 29333474:
  Issue 4125 - [emscripten] Convert filter classes to C++  (Closed)
    
  
    Issue 29333474:
  Issue 4125 - [emscripten] Convert filter classes to C++  (Closed) 
  | Index: compiled/intrusive_ptr.h | 
| =================================================================== | 
| new file mode 100644 | 
| --- /dev/null | 
| +++ b/compiled/intrusive_ptr.h | 
| @@ -0,0 +1,182 @@ | 
| +// 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 | 
| 
sergei
2016/02/17 12:55:05
Yahoo! Finally we start it! I am looking forward t
 | 
| + | 
| +#include <algorithm> | 
| +#include <type_traits> | 
| + | 
| +class ref_counted | 
| +{ | 
| +public: | 
| + void AddRef() | 
| + { | 
| + mRefCount++; | 
| + } | 
| + | 
| + void ReleaseRef() | 
| + { | 
| + if (--mRefCount == 0) | 
| + delete this; | 
| + } | 
| + | 
| +protected: | 
| + ref_counted() | 
| + : mRefCount(0) | 
| + { | 
| + } | 
| + | 
| + // We need this virtual destructor, otherwise pointers to ref_counted and | 
| + // 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() | 
| + { | 
| + } | 
| + | 
| +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(other).swap(*this); | 
| 
sergei
2016/02/17 12:55:07
JIC, `other` is just a reference here, I guess, to
 
Wladimir Palant
2016/02/18 16:07:14
I'll just trust you on this one, currently I have
 | 
| + 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); | 
| + } | 
| + | 
| + T* get() const | 
| 
sergei
2016/02/17 12:55:06
Although it's a common practice, I'm personally no
 
Wladimir Palant
2016/02/18 16:07:13
Done, here and for the methods below. None of this
 | 
| + { | 
| + return mPointer; | 
| + } | 
| + | 
| + T& operator*() const | 
| + { | 
| + return *mPointer; | 
| + } | 
| + | 
| + T* operator->() const | 
| + { | 
| + return mPointer; | 
| + } | 
| + | 
| + operator bool() const | 
| + { | 
| + return mPointer != nullptr; | 
| + } | 
| + | 
| + operator T*() const | 
| + { | 
| + 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) | 
| +{ | 
| + 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(); | 
| +} |