#ifndef GENERIC_FACTORY_H
#define GENERIC_FACTORY_H
/*
* generic_factory.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/>.
*
*/
#include <map>
#include "nest.h"
#include "dictdatum.h"
namespace nest
{
class AbstractGeneric;
/**
* Generic Factory class for objects deriving from a base class
* BaseT. Keeps a register of subtypes which may be created
* dynamically. New subtypes may be added by registering either a class
* (which must have a constructor taking as a parameter a dictionary
* containing parameters for the mask) or a specialized factory function.
* @see Alexandrescu, A (2001). Modern C++ Design, Addison-Wesley, ch. 8.
*/
template<class BaseT>
class GenericFactory {
public:
typedef BaseT * (*CreatorFunction)(const DictionaryDatum &d);
typedef std::map<Name,CreatorFunction> AssocMap;
/**
* Factory function.
* @param name Subtype.
* @param d Dictionary containing parameters for this subtype.
* @returns dynamically allocated new object.
*/
BaseT *create(const Name& name, const DictionaryDatum &d) const;
/**
* Register a new subtype. The type name must not already exist. The
* class for the subtype is supplied via the template argument. This
* class should have a constructor taking a const DictionaryDatum& as
* parameter.
* @param name subtype name.
* @returns true if subtype was successfully registered.
*/
template<class T>
bool register_subtype(const Name & name);
/**
* Register a new subtype. The type name must not already exist.
* @param name Subtype name.
* @param creator A factory function creating objects of this subtype
* from a const DictionaryDatum& containing parameters
* @returns true if mask was successfully registered.
*/
bool register_subtype(const Name& name, CreatorFunction creator);
private:
template<class T>
static
BaseT * new_from_dict_(const DictionaryDatum &d);
AssocMap associations_;
};
template<class BaseT>
inline
BaseT * GenericFactory<BaseT>::create(const Name& name, const DictionaryDatum &d) const
{
typename AssocMap::const_iterator i = associations_.find(name);
if ( i != associations_.end() ) {
return (i->second)(d);
}
throw UndefinedName(name.toString());
}
template<class BaseT>
template<class T>
inline
bool GenericFactory<BaseT>::register_subtype(const Name & name)
{
return register_subtype(name,new_from_dict_<T>);
}
template<class BaseT>
inline
bool GenericFactory<BaseT>::register_subtype(const Name& name, CreatorFunction creator)
{
return associations_.insert(std::pair<Name,CreatorFunction>(name,creator)).second;
}
template<class BaseT>
template<class T>
BaseT * GenericFactory<BaseT>::new_from_dict_(const DictionaryDatum &d) {
return new T(d);
}
} // namespace nest
#endif