/* * 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; }