|
Packit Service |
7770af |
#ifndef SASS_MEMORY_SHARED_PTR_H
|
|
Packit Service |
7770af |
#define SASS_MEMORY_SHARED_PTR_H
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#include "sass/base.h"
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#include <vector>
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
namespace Sass {
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
class SharedPtr;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Use macros for the allocation task, since overloading operator `new`
|
|
Packit Service |
7770af |
// has been proven to be flaky under certain compilers (see comment below).
|
|
Packit Service |
7770af |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#ifdef DEBUG_SHARED_PTR
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#define SASS_MEMORY_NEW(Class, ...) \
|
|
Packit Service |
7770af |
((Class*)(new Class(__VA_ARGS__))->trace(__FILE__, __LINE__)) \
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#define SASS_MEMORY_COPY(obj) \
|
|
Packit Service |
7770af |
((obj)->copy(__FILE__, __LINE__)) \
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#define SASS_MEMORY_CLONE(obj) \
|
|
Packit Service |
7770af |
((obj)->clone(__FILE__, __LINE__)) \
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#else
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#define SASS_MEMORY_NEW(Class, ...) \
|
|
Packit Service |
7770af |
new Class(__VA_ARGS__) \
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#define SASS_MEMORY_COPY(obj) \
|
|
Packit Service |
7770af |
((obj)->copy()) \
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#define SASS_MEMORY_CLONE(obj) \
|
|
Packit Service |
7770af |
((obj)->clone()) \
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#endif
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
class SharedObj {
|
|
Packit Service |
7770af |
protected:
|
|
Packit Service |
7770af |
friend class SharedPtr;
|
|
Packit Service |
7770af |
friend class Memory_Manager;
|
|
Packit Service |
7770af |
#ifdef DEBUG_SHARED_PTR
|
|
Packit Service |
7770af |
static std::vector<SharedObj*> all;
|
|
Packit Service |
7770af |
std::string file;
|
|
Packit Service |
7770af |
size_t line;
|
|
Packit Service |
7770af |
#endif
|
|
Packit Service |
7770af |
static bool taint;
|
|
Packit Service |
7770af |
long refcounter;
|
|
Packit Service |
7770af |
// long refcount;
|
|
Packit Service |
7770af |
bool detached;
|
|
Packit Service |
7770af |
#ifdef DEBUG_SHARED_PTR
|
|
Packit Service |
7770af |
bool dbg;
|
|
Packit Service |
7770af |
#endif
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
#ifdef DEBUG_SHARED_PTR
|
|
Packit Service |
7770af |
static void dumpMemLeaks();
|
|
Packit Service |
7770af |
SharedObj* trace(std::string file, size_t line) {
|
|
Packit Service |
7770af |
this->file = file;
|
|
Packit Service |
7770af |
this->line = line;
|
|
Packit Service |
7770af |
return this;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
#endif
|
|
Packit Service |
7770af |
SharedObj();
|
|
Packit Service |
7770af |
#ifdef DEBUG_SHARED_PTR
|
|
Packit Service |
7770af |
std::string getDbgFile() {
|
|
Packit Service |
7770af |
return file;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
size_t getDbgLine() {
|
|
Packit Service |
7770af |
return line;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
void setDbg(bool dbg) {
|
|
Packit Service |
7770af |
this->dbg = dbg;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
#endif
|
|
Packit Service |
7770af |
static void setTaint(bool val) {
|
|
Packit Service |
7770af |
taint = val;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual ~SharedObj();
|
|
Packit Service |
7770af |
long getRefCount() {
|
|
Packit Service |
7770af |
return refcounter;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
class SharedPtr {
|
|
Packit Service |
7770af |
protected:
|
|
Packit Service |
7770af |
SharedObj* node;
|
|
Packit Service |
7770af |
protected:
|
|
Packit Service |
7770af |
void decRefCount();
|
|
Packit Service |
7770af |
void incRefCount();
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
// the empty constructor
|
|
Packit Service |
7770af |
SharedPtr()
|
|
Packit Service |
7770af |
: node(NULL) {};
|
|
Packit Service |
7770af |
// the create constructor
|
|
Packit Service |
7770af |
SharedPtr(SharedObj* ptr);
|
|
Packit Service |
7770af |
// the copy constructor
|
|
Packit Service |
7770af |
SharedPtr(const SharedPtr& obj);
|
|
Packit Service |
7770af |
// the move constructor
|
|
Packit Service |
7770af |
SharedPtr(SharedPtr&& obj);
|
|
Packit Service |
7770af |
// copy assignment operator
|
|
Packit Service |
7770af |
SharedPtr& operator=(const SharedPtr& obj);
|
|
Packit Service |
7770af |
// move assignment operator
|
|
Packit Service |
7770af |
SharedPtr& operator=(SharedPtr&& obj);
|
|
Packit Service |
7770af |
// pure virtual destructor
|
|
Packit Service |
7770af |
virtual ~SharedPtr() = 0;
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
SharedObj* obj () const {
|
|
Packit Service |
7770af |
return node;
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
SharedObj* operator-> () const {
|
|
Packit Service |
7770af |
return node;
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
bool isNull () {
|
|
Packit Service |
7770af |
return node == NULL;
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
bool isNull () const {
|
|
Packit Service |
7770af |
return node == NULL;
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
SharedObj* detach() const {
|
|
Packit Service |
7770af |
if (node) {
|
|
Packit Service |
7770af |
node->detached = true;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return node;
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
operator bool() const {
|
|
Packit Service |
7770af |
return node != NULL;
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
template < class T >
|
|
Packit Service |
7770af |
class SharedImpl : private SharedPtr {
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
SharedImpl()
|
|
Packit Service |
7770af |
: SharedPtr(NULL) {};
|
|
Packit Service |
7770af |
SharedImpl(T* node)
|
|
Packit Service |
7770af |
: SharedPtr(node) {};
|
|
Packit Service |
7770af |
template < class U >
|
|
Packit Service |
7770af |
SharedImpl(SharedImpl<U> obj)
|
|
Packit Service |
7770af |
: SharedPtr(static_cast<T*>(obj.ptr())) {}
|
|
Packit Service |
7770af |
SharedImpl(T&& node)
|
|
Packit Service |
7770af |
: SharedPtr(node) {};
|
|
Packit Service |
7770af |
SharedImpl(const T& node)
|
|
Packit Service |
7770af |
: SharedPtr(node) {};
|
|
Packit Service |
7770af |
// the copy constructor
|
|
Packit Service |
7770af |
SharedImpl(const SharedImpl<T>& impl)
|
|
Packit Service |
7770af |
: SharedPtr(impl.node) {};
|
|
Packit Service |
7770af |
// the move constructor
|
|
Packit Service |
7770af |
SharedImpl(SharedImpl<T>&& impl)
|
|
Packit Service |
7770af |
: SharedPtr(impl.node) {};
|
|
Packit Service |
7770af |
// copy assignment operator
|
|
Packit Service |
7770af |
SharedImpl<T>& operator=(const SharedImpl<T>& rhs) {
|
|
Packit Service |
7770af |
if (node) decRefCount();
|
|
Packit Service |
7770af |
node = rhs.node;
|
|
Packit Service |
7770af |
incRefCount();
|
|
Packit Service |
7770af |
return *this;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
// move assignment operator
|
|
Packit Service |
7770af |
SharedImpl<T>& operator=(SharedImpl<T>&& rhs) {
|
|
Packit Service |
7770af |
// don't move our self
|
|
Packit Service |
7770af |
if (this != &rhs) {
|
|
Packit Service |
7770af |
if (node) decRefCount();
|
|
Packit Service |
7770af |
node = std::move(rhs.node);
|
|
Packit Service |
7770af |
rhs.node = NULL;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return *this;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
~SharedImpl() {};
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
operator T*() const {
|
|
Packit Service |
7770af |
return static_cast<T*>(this->obj());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
operator T&() const {
|
|
Packit Service |
7770af |
return *static_cast<T*>(this->obj());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
T& operator* () const {
|
|
Packit Service |
7770af |
return *static_cast<T*>(this->obj());
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
T* operator-> () const {
|
|
Packit Service |
7770af |
return static_cast<T*>(this->obj());
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
T* ptr () const {
|
|
Packit Service |
7770af |
return static_cast<T*>(this->obj());
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
T* detach() const {
|
|
Packit Service |
7770af |
if (this->obj() == NULL) return NULL;
|
|
Packit Service |
7770af |
return static_cast<T*>(SharedPtr::detach());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
bool isNull() const {
|
|
Packit Service |
7770af |
return this->obj() == NULL;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
bool operator<(const T& rhs) const {
|
|
Packit Service |
7770af |
return *this->ptr() < rhs;
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
operator bool() const {
|
|
Packit Service |
7770af |
return this->obj() != NULL;
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#endif
|