Blame src/memory/SharedPtr.hpp

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