#include "../sass.hpp"
#include <iostream>
#include <typeinfo>
#include "SharedPtr.hpp"
#include "../ast_fwd_decl.hpp"
#ifdef DEBUG_SHARED_PTR
#include "../debugger.hpp"
#endif
namespace Sass {
#ifdef DEBUG_SHARED_PTR
void SharedObj::dumpMemLeaks() {
if (!all.empty()) {
std::cerr << "###################################\n";
std::cerr << "# REPORTING MISSING DEALLOCATIONS #\n";
std::cerr << "###################################\n";
for (SharedObj* var : all) {
if (AST_Node_Ptr ast = dynamic_cast<AST_Node*>(var)) {
debug_ast(ast);
} else {
std::cerr << "LEAKED " << var << "\n";
}
}
}
}
std::vector<SharedObj*> SharedObj::all;
#endif
bool SharedObj::taint = false;
SharedObj::SharedObj()
: detached(false)
#ifdef DEBUG_SHARED_PTR
, dbg(false)
#endif
{
refcounter = 0;
#ifdef DEBUG_SHARED_PTR
if (taint) all.push_back(this);
#endif
};
SharedObj::~SharedObj() {
#ifdef DEBUG_SHARED_PTR
if (dbg) std::cerr << "Destruct " << this << "\n";
if(!all.empty()) { // check needed for MSVC (no clue why?)
all.erase(std::remove(all.begin(), all.end(), this), all.end());
}
#endif
};
void SharedPtr::decRefCount() {
if (node) {
-- node->refcounter;
#ifdef DEBUG_SHARED_PTR
if (node->dbg) std::cerr << "- " << node << " X " << node->refcounter << " (" << this << ") " << "\n";
#endif
if (node->refcounter == 0) {
#ifdef DEBUG_SHARED_PTR
// AST_Node_Ptr ast = dynamic_cast<AST_Node*>(node);
if (node->dbg) std::cerr << "DELETE NODE " << node << "\n";
#endif
if (!node->detached) {
delete(node);
}
}
}
}
void SharedPtr::incRefCount() {
if (node) {
++ node->refcounter;
node->detached = false;
#ifdef DEBUG_SHARED_PTR
if (node->dbg) {
std::cerr << "+ " << node << " X " << node->refcounter << " (" << this << ") " << "\n";
}
#endif
}
}
SharedPtr::~SharedPtr() {
decRefCount();
}
// the create constructor
SharedPtr::SharedPtr(SharedObj* ptr)
: node(ptr) {
incRefCount();
}
// copy assignment operator
SharedPtr& SharedPtr::operator=(const SharedPtr& rhs) {
void* cur_ptr = (void*) node;
void* rhs_ptr = (void*) rhs.node;
if (cur_ptr == rhs_ptr) {
return *this;
}
decRefCount();
node = rhs.node;
incRefCount();
return *this;
}
// the copy constructor
SharedPtr::SharedPtr(const SharedPtr& obj)
: node(obj.node) {
incRefCount();
}
}