/*
* instance.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 INSTANCE_H
#define INSTANCE_H
#include "nest.h"
#include "allocator.h"
namespace nest
{
/**
* @addtogroup MemoryManagement Memory management
* Classes which are involved in Memory management.
*/
/**
* @defgroup InstanceTemplate Instance template
* The Instance template is used to extend normal classes with a pool based
* memory management. It provides a framework of functions which allow the kernel
* to efficiently create or delete nodes. Also functions for getting information
* about the allocated/used memory are included. For example the function allocate
* in an arbitrary template class can be written as
* @code
* template<typename ElementT>
* inline Node* GenericModel<ElementT>::allocate(void)
* {
* Node *n=new Instance<ElementT>;
* assert(n !=NULL);
* return n;
* }
* @endcode
* to take advantage of the pool based allocator. Likewise the function reserve()
* looks like
* @code
* template< typename ElementT>
* inline void GenericModel<ElementT>::reserve(size_t s)
* {
* Instance<ElementT>::reserve(s);
* }
* @endcode
* @note
* Probably the best way to see how Instance is used is to look into the code where
* it is used. One Place for this is GenericModel-Template
* @note
* J. M. Eppler, 2003-11-12, 02:49
* @ingroup MemoryManagement
*/
/**
* Instance is a template is used to provide a pool-based management for arbitrary
* classes.
* @ingroup MemoryManagement
* @ingroup InstanceTemplate
*/
template<typename ClassT>
class Instance: public ClassT
{
public:
Instance()
:ClassT(){}
Instance(const Instance<ClassT>&c)
:ClassT(c){}
Instance(const ClassT &c)
:ClassT(c){}
ClassT *clone() const;
static void reserve(size_t);
static void * operator new(size_t size);
static void operator delete(void *p, size_t size);
static size_t memory_used();
static size_t memory_capacity();
static size_t instantiations();
private:
static sli::pool memory_;
};
template<typename ClassT>
inline
ClassT * Instance<ClassT>::clone() const
{
return new Instance<ClassT>(*this);
}
template<typename ClassT>
inline
void * Instance<ClassT>::operator new(size_t size)
{
if(size != sizeof(Instance<ClassT>))
{
/**
* If a derived class does not possess its own
* new/delete operators, they will end up here.
* Thus, we forward their request to the standard
* new/delete operators.
*/
return ::operator new(size);
}
return memory_.alloc();
}
template< typename ClassT>
inline
void Instance<ClassT>::operator delete(void *p, size_t size)
{
if(p == NULL)
return;
if(size != sizeof(Instance<ClassT>))
{
/*
* If a derived class does not possess its own
* new/delete operators, they will end up here.
* Thus, we forward their request to the standard
* new/delete operators.
*/
::operator delete(p);
return;
}
memory_.free(p);
}
template <typename ClassT>
inline
void Instance<ClassT>::reserve(size_t s)
{
memory_.reserve(s);
}
template <typename ClassT>
inline
size_t Instance<ClassT>::memory_used()
{
return memory_.get_instantiations() * memory_.get_el_size();
}
template <typename ClassT>
inline
size_t Instance<ClassT>::memory_capacity()
{
return memory_.get_total() * memory_.get_el_size();
}
template <typename ClassT>
inline
size_t Instance<ClassT>::instantiations()
{
return memory_.get_instantiations();
}
/** Declaration of static memory object */
template <typename ClassT>
sli::pool Instance<ClassT>::memory_(sizeof(Instance<ClassT>), 1024, 1);
} // namespace nest
#endif