aboutsummaryrefslogblamecommitdiffstats
path: root/meowpp/oo/Properties.hpp
blob: 90d98058779310e0b68e80b7839dad506e69dea2 (plain) (tree)












































































































































































                                                                               
#include "Properties.h"

#include <map>
#include <queue>


namespace meow{
  inline Properties::Property::Property(ObjBase* __pointer, bool __autoRemove):
  _pointer(__pointer),
  _counter(__autoRemove ? -1 : 1){
  }
  inline Properties::Property::Property(Property const& __property):
  _pointer(__property._pointer),
  _counter(__property._counter){
  }
  inline Properties::Property::~Property(){
  }
  inline bool Properties::Property::attach(){
    if(_pointer == NULL || _counter <= 0) return false;
    _counter++;
    return true;
  }
  inline bool Properties::Property::detach(){
    if(_pointer == NULL || _counter <= 0) return false;
    _counter--;
    if(_counter <= 0){
      delete _pointer;
      _pointer = NULL;
    }
    return true;
  }
  ////////////////////////////////////////////////////////////////////
  inline size_t Properties::newIndex(std::string const& __name){
    size_t i;
    if(_freeIndex.size() > 0){
      i = _freeIndex.front();
      _freeIndex.pop();
    }else{
      i = size();
    }
    _index[__name] = i;
    return i;
  }
  inline void Properties::delIndex(size_t __index){
    _properties.erase(__index);
    for(std::map<std::string, size_t>::iterator it = _index.begin();
        it != _index.end();
        it++){
      if(it->second == __index){
        _index.erase(it);
        break;
      }
    }
    _freeIndex.push(__index);
  }
  inline void Properties::detach(size_t __index){
    _properties[__index]->detach();
    if(_properties[__index]->_counter == 0){
      delete _properties[__index];
    }
    _properties[__index] = NULL;
  }
  inline Properties::Properties(){
  }
  inline Properties::Properties(Properties const& __p){
    copy(__p);
  }
  inline Properties::~Properties(){
    clear();
  }
  inline void Properties::clear(){
    for(std::map<size_t, Property*>::iterator it = _properties.begin();
        it != _properties.end();
        it++){
      it->second->detach();
    }
    _properties.clear();
    _index     .clear();
    while(!_freeIndex.empty())
      _freeIndex.pop();
  }
  inline Properties& Properties::copy(Properties const& __p){
    clear();
    _properties = ((Properties&)__p)._properties;
    _index      = ((Properties&)__p)._index;
    _freeIndex  = ((Properties&)__p)._freeIndex;
    for(std::map<size_t, Property*>::iterator it = _properties.begin();
        it != _properties.end();
        it++){
      it->second->attach();
    }
    return *this;
  }
  inline size_t Properties::size() const{
    return (_properties.size());
  }
  inline bool Properties::empty() const{
    return (size() == 0u);
  }
  inline bool Properties::chg(size_t   __index,
                              ObjBase* __pointer,
                              bool     __autoRemove){
    if(get(__index) == NULL)
      return false;
    detach(__index);
    _properties[__index] = new Property(__pointer, __autoRemove);
    return true;
  }
  inline bool Properties::add(std::string __name ,
                              ObjBase*    __pointer,
                              bool        __autoRemove){
    if(get(__name) != NULL)
      del(__name);
    _properties[newIndex(__name)] = new Property(__pointer, __autoRemove);
    return true;
  }
  inline bool Properties::del(size_t __index){
    if(get(__index) == NULL){
      return false;
    }
    detach(__index);
    delIndex(__index);
    return true;
  }
  inline bool Properties::del(std::string __name){
    if(get(__name) == NULL){
      return false;
    }
    return del(_index[__name]);
  }
  inline ObjBase* Properties::get(size_t __index) const{
    std::map<size_t, Property*>::const_iterator i = _properties.find(__index);
    if(i == _properties.end()) return NULL;
    return (ObjBase*)(i->second->_pointer);
  }
  inline ObjBase* Properties::get(std::string __name) const{
    std::map<std::string, size_t>::const_iterator i = _index.find(__name);
    if(i == _index.end()) return NULL;
    return get(i->second);
  }
  inline ssize_t Properties::getIndex(ObjBase* __pointer) const{
    for(std::map<size_t, Property*>::const_iterator it = _properties.begin();
        it != _properties.end();
        it++){
      if(it->second->_pointer == __pointer){
        return it->first;
      }
    }
    return -1;
  }
  inline std::string Properties::getName(ObjBase* __pointer) const{
    ssize_t t = getIndex(__pointer);
    if(t < 0) return std::string();
    for(std::map<std::string, size_t>::const_iterator it = _index.begin();
        it != _index.end();
        it++){
      if(it->second == (size_t)t){
        if(it == _index.end()) return std::string();
        return it->first;
      }
    }
    return std::string();
  }
  inline Properties& Properties::operator=(Properties const& __p){
    return copy(__p);
  }
  inline ObjBase* Properties::operator()(size_t __index) const{
    return get(__index);
  }
  inline ObjBase* Properties::operator()(std::string __name) const{
    return get(__name);
  }
};