/*
* dictstack.cc
*
* This file is part of NEST.
*
* Copyright (C) 2004 The NEST Initiative
*
* NEST is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* NEST is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NEST. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "dictstack.h"
DictionaryStack::DictionaryStack(const Token &t )
: VoidToken(t)
{
}
DictionaryStack::DictionaryStack(const DictionaryStack &ds )
: VoidToken(ds.VoidToken), d(ds.d)
{
}
DictionaryStack::~DictionaryStack()
{
// We have to clear the dictionary before we delete it, otherwise the
// dictionary references will prevent proper deletion.
for(std::list<DictionaryDatum>::iterator i=d.begin(); i != d.end(); ++i)
(*i)->clear();
}
void DictionaryStack::undef(const Name &n)
{
size_t num_erased = 0;
for (std::list<DictionaryDatum>::iterator it = d.begin();
it != d.end();
it++)
num_erased += (*it)->erase(n);
if (num_erased == 0)
throw UndefinedName(n.toString());
#ifdef DICTSTACK_CACHE
clear_token_from_cache(n);
clear_token_from_basecache(n);
#endif
}
void DictionaryStack::basedef(const Name &n, const Token &t)
{
//
// insert (n,t) in bottom level dictionary
// dictionary stack must contain at least one dictionary
// VoidToken is an illegal value for t.
#ifdef DICTSTACK_CACHE
clear_token_from_cache(n);
basecache_token(n,&(base_->insert(n,t)));
#endif
#ifndef DICTSTACK_CACHE
(*base_)[n]=t;
#endif
}
void DictionaryStack::basedef_move(const Name &n, Token &t)
{
#ifdef DICTSTACK_CACHE
clear_token_from_cache(n);
basecache_token(n,&(base_->insert_move(n,t)));
#endif
#ifndef DICTSTACK_CACHE
base_->insert_move(n, t);
#endif
}
void DictionaryStack::pop(void)
{
//
// remove top dictionary from stack
// dictionary stack must contain at least one dictionary
//
#ifdef DICTSTACK_CACHE
clear_dict_from_cache(*(d.begin()));
(*(d.begin()))->remove_dictstack_reference();
#endif
d.pop_front();
}
void DictionaryStack::clear(void)
{
d.erase(d.begin(),d.end());
#ifdef DICTSTACK_CACHE
clear_cache();
#endif
}
void DictionaryStack::top(Token &t) const
{
//
// create a copy of the top level dictionary
// and move it into Token t.
// new should throw an exception if it fails
//
DictionaryDatum *dd= new DictionaryDatum(*(d.begin()));
Token dt( dd);
t.move(dt);
}
void DictionaryStack::toArray(TokenArray &ta) const
{
//
// create a copy of the top level dictionary
// and move it into Token t.
// new should throw an exception if it fails
//
ta.erase();
std::list<DictionaryDatum>::const_reverse_iterator i(d.rbegin());
while (i!=d.rend())
{
ta.push_back((*i));
++i;
}
}
void DictionaryStack::push(Token& d)
{
DictionaryDatum *dd=dynamic_cast<DictionaryDatum *>(d.datum());
assert(dd !=NULL);
push(*dd);
}
void DictionaryStack::push(const DictionaryDatum& pd)
{
//
// extract Dictionary from Token envelope
// and push it on top of the stack.
// a non dictionary datum at this point is a program bug.
//
#ifdef DICTSTACK_CACHE
pd->add_dictstack_reference();
// This call will remove all names in the dict from the name cache.
clear_dict_from_cache(pd);
#endif
d.push_front(pd);
}
void DictionaryStack::set_basedict()
{
base_= *(--d.end()); // Cache base dictionary
}
size_t DictionaryStack::size(void) const
{
//
// return number of dictionaries on stack
//
return d.size();
}
void DictionaryStack::info(std::ostream& o) const
{
// for_each(d.rbegin(), d.rend(), bind_2nd(mem_fun(&Dictionary::info),o));
std::list<DictionaryDatum>::const_reverse_iterator i(d.rbegin());
o << "DictionaryStack::info" << std::endl;
o << "Size = " << d.size() << std::endl;
while (i!=d.rend())
{
(*i)->info(o);
++i;
}
}
void DictionaryStack::top_info(std::ostream& o) const
{
(*d.begin())->info(o);
}
const DictionaryStack& DictionaryStack::operator=(const DictionaryStack& ds)
{
if(&ds != this)
{
d=ds.d;
#ifdef DICTSTACK_CACHE
cache_=ds.cache_;
#endif
}
return *this;
}