Re-enabled intrusive_ptr

This commit is contained in:
Twan van Laarhoven
2020-05-07 22:25:02 +02:00
parent 360f8d71ad
commit 8b25815f72
7 changed files with 99 additions and 49 deletions
+1 -1
View File
@@ -183,7 +183,7 @@ class Package : public IntrusivePtrVirtualBase {
protected:
// TODO: I dislike putting this here very much. There ought to be a better way.
virtual VCSP getVCS() { return make_shared<VCS>(); }
virtual VCSP getVCS() { return make_intrusive<VCS>(); }
/// true if this is a zip file, false if a directory
bool isZipfile() const { return !wxDirExists(filename); }
+86 -25
View File
@@ -8,7 +8,7 @@
/** @file util/smart_ptr.hpp
*
* @brief Utilities related to boost smart pointers
* @brief Smart pointers and related utility functions
*/
// ----------------------------------------------------------------------------- : Includes
@@ -22,21 +22,96 @@ using std::dynamic_pointer_cast;
using std::make_shared;
using std::make_unique;
#ifndef USE_INTRUSIVE_PTR
#define USE_INTRUSIVE_PTR 1
#endif
// ----------------------------------------------------------------------------- : Intrusive pointers
#if USE_INTRUSIVE_PTR
#include <atomic>
#include <boost/smart_ptr/intrusive_ptr.hpp>
using boost::intrusive_ptr;
/// Base class for types that can be pointed to
template <typename T> class IntrusivePtrBase {
public:
IntrusivePtrBase() {}
// don't copy or assign ref count
IntrusivePtrBase(IntrusivePtrBase const&) {}
void operator = (IntrusivePtrBase const&) {}
protected:
inline void destroy() const {
delete static_cast<const T*>(this);
}
private:
mutable std::atomic<unsigned int> ref_count = 0;
template <typename T> friend void intrusive_ptr_add_ref(const IntrusivePtrBase<T>* ptr);
template <typename T> friend void intrusive_ptr_release(const IntrusivePtrBase<T>* ptr);
};
template <typename T> void intrusive_ptr_add_ref(const IntrusivePtrBase<T>* ptr) {
++(ptr->ref_count);
}
template <typename T> void intrusive_ptr_release(const IntrusivePtrBase<T>* ptr) {
if (--(ptr->ref_count) == 0) {
static_cast<const T*>(ptr)->destroy();
}
}
template <typename T>
class IntrusiveFromThis {
public:
inline intrusive_ptr<T> intrusive_from_this() noexcept {
return intrusive_ptr<T>(static_cast<T*>(this));
}
};
/// Allocate an object of type T and store it in a new intrusive_ptr, similar to std::make_shared
template <typename T, class... Args>
inline intrusive_ptr<T> make_intrusive(Args&&... args) {
return intrusive_ptr<T>(new T(std::forward<Args>(args)...));
}
// ----------------------------------------------------------------------------- : Shared pointers
#else
template <typename T> using intrusive_ptr = shared_ptr<T>;
/// Base class for types that can be pointed to
template <typename T> class IntrusivePtrBase {};
template <typename T>
class IntrusiveFromThis : public std::enable_shared_from_this<T> {
public:
inline intrusive_ptr<T> intrusive_from_this() {
return shared_from_this();
}
};
/// Allocate an object of type T and store it in a new intrusive_ptr, similar to std::make_shared
template <typename T, class... Args>
inline intrusive_ptr<T> make_intrusive(Args&&... args) {
return std::make_shared<T>(std::forward<Args>(args)...);
}
#endif
// ----------------------------------------------------------------------------- : Declaring
/// Declares the type TypeP as a intrusive_ptr<Type>
#define DECLARE_POINTER_TYPE(Type) \
class Type; \
typedef intrusive_ptr<Type> Type##P;
/// Declares the type TypeP as a shared_ptr<Type>
#define DECLARE_SHARED_POINTER_TYPE(Type) \
class Type; \
typedef shared_ptr<Type> Type##P;
// ----------------------------------------------------------------------------- : Shared pointers
#define DECLARE_POINTER_TYPE DECLARE_SHARED_POINTER_TYPE
template <typename T> using intrusive_ptr = shared_ptr<T>;
/// Base class for types that can be pointed to
template <typename T> class IntrusivePtrBase {};
// ----------------------------------------------------------------------------- : Utility
/// IntrusivePtrBase with a virtual destructor
class IntrusivePtrVirtualBase : public IntrusivePtrBase<IntrusivePtrVirtualBase> {
@@ -49,27 +124,13 @@ public:
virtual ~IntrusivePtrBaseWithDelete() {}
protected:
/// Delete this object
virtual void destroy() {
virtual void destroy() const {
delete this;
}
template <typename T> friend void intrusive_ptr_release(const IntrusivePtrBase<T>* ptr);
};
template <typename T>
class IntrusiveFromThis : public std::enable_shared_from_this<T> {
protected:
inline intrusive_ptr<T> intrusive_from_this() {
return shared_from_this();
}
};
/// Allocate an object of type T and store it in a new intrusive_ptr, similar to std::make_shared
template <typename T, class... Args>
inline intrusive_ptr<T> make_intrusive(Args&&... args) {
return std::make_shared<T>(std::forward<Args>(args)...);
}
/// Pointer to 'anything'
typedef intrusive_ptr<IntrusivePtrVirtualBase> VoidP;
// ----------------------------------------------------------------------------- : Intrusive pointers