/*
* sibling_container.h
*
* 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/>.
*
*/
#ifndef SIBLING_CONTAINER_H
#define SIBLING_CONTAINER_H
#include <vector>
#include <string>
#include "node.h"
#include "dictdatum.h"
namespace nest{
using std::vector;
class Node;
class Network;
class Scheduler;
/**
* SiblingContainer class.
* This class is used to group the replicas of nodes on different
* threads into one entity. It is derived from node in order to take
* advantage of the pool allocator, which has only very little
* overhead compared to a normal std::vector.
*/
class SiblingContainer: public Node
{
friend class Network;
friend class Scheduler;
friend class Subnet;
public:
SiblingContainer();
SiblingContainer(const SiblingContainer &);
virtual ~SiblingContainer(){}
void set_status(const DictionaryDatum&) { assert(false); }
void get_status(DictionaryDatum&) const { assert(false); }
bool has_proxies() const;
bool empty() const;
void reserve(size_t);
void push_back(Node*);
/**
* Return iterator to the first child node.
*/
vector<Node*>::iterator begin();
/**
* Return iterator to the end of the child-list.
*/
vector<Node*>::iterator end();
/**
* Return const iterator to the first child node.
*/
vector<Node*>::const_iterator begin() const;
/**
* Return const iterator to the end of the child-list.
*/
vector<Node*>::const_iterator end() const;
protected:
size_t num_thread_siblings_() const;
Node* get_thread_sibling_(index) const;
Node* get_thread_sibling_safe_(index) const;
void init_node_(const Node&) {}
void init_state_(const Node&) {}
void init_buffers_() {}
void calibrate() {}
void update(Time const &, const long_t, const long_t) {}
/**
* Pointer to child nodes.
* This vector contains the pointers to the child nodes.
* Since deletion of Nodes is possible, entries in this
* vector may be NULL. Note that all code must handle
* this case gracefully.
*/
vector<Node *> nodes_; //!< Pointer to child nodes.
};
inline
void SiblingContainer::push_back(Node *n)
{
nodes_.push_back(n);
}
inline
Node* SiblingContainer::get_thread_sibling_safe_(index i) const
{
return nodes_.at(i); //with range check
}
inline
Node* SiblingContainer::get_thread_sibling_(index i) const
{
return nodes_[i]; //without range check
}
inline
vector<Node*>::iterator SiblingContainer::begin()
{
return nodes_.begin();
}
inline
vector<Node*>::iterator SiblingContainer::end()
{
return nodes_.end();
}
inline
vector<Node*>::const_iterator SiblingContainer::begin() const
{
return nodes_.begin();
}
inline
vector<Node*>::const_iterator SiblingContainer::end() const
{
return nodes_.end();
}
inline
bool SiblingContainer::empty() const
{
return nodes_.empty();
}
inline
size_t SiblingContainer::num_thread_siblings_() const
{
return nodes_.size();
}
inline
void SiblingContainer::reserve(size_t n)
{
nodes_.reserve(n);
}
inline
bool SiblingContainer::has_proxies() const
{
return false;
}
} // namespace
#endif