NameFactory.h
Go to the documentation of this file.
/* Frobby: Software for monomial ideal computations.
Copyright (C) 2007 Bjarke Hammersholt Roune (www.broune.com)
This program 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.
This program 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 this program. If not, see http://www.gnu.org/licenses/.
*/
#ifndef NAME_FACTORY_GUARD
#define NAME_FACTORY_GUARD
#include "error.h"
#include <vector>
#include <string>
#include <algorithm>
template<class AbstractProduct>
class NameFactory {
public:
NameFactory(const char* abstractName): _abstractName(abstractName) {}
typedef unique_ptr<AbstractProduct> (*FactoryFunction)();
void registerProduct(const string& name, FactoryFunction function);
unique_ptr<AbstractProduct> createNoThrow(const string& name) const;
unique_ptr<AbstractProduct> create(const string& name) const;
void getNamesWithPrefix(const string& prefix, vector<string>& names) const;
bool empty() const;
string getAbstractProductName() const;
private:
typedef pair<string, FactoryFunction> Pair;
typedef typename vector<Pair>::const_iterator const_iterator;
vector<Pair> _pairs;
const string _abstractName;
};
template<class ConcreteProduct, class AbstractProduct>
void nameFactoryRegister(NameFactory<AbstractProduct>& factory);
template<class AbstractProduct>
unique_ptr<AbstractProduct> createWithPrefix
(const NameFactory<AbstractProduct>& factory, const string& prefix);
template<class AbstractProduct>
string getUniqueNameWithPrefix
(const NameFactory<AbstractProduct>& factory, const string& prefix);
// **************************************************************
// These are implementations that have to be included here due
// to being templates.
template<class AbstractProduct>
unique_ptr<AbstractProduct> NameFactory<AbstractProduct>::
createNoThrow(const string& name) const {
for (const_iterator it = _pairs.begin(); it != _pairs.end(); ++it)
if (it->first == name)
return it->second();
return unique_ptr<AbstractProduct>();
}
template<class AbstractProduct>
unique_ptr<AbstractProduct> NameFactory<AbstractProduct>::
create(const string& name) const {
unique_ptr<AbstractProduct> product = createNoThrow(name);
if (product.get() == 0)
throwError<UnknownNameException>(
"Unknown " + getAbstractProductName() + " \"" + name + "\".");
return product;
}
template<class AbstractProduct>
void NameFactory<AbstractProduct>::
registerProduct(const string& name, FactoryFunction function) {
_pairs.push_back(Pair(name, function));
}
template<class AbstractProduct>
void NameFactory<AbstractProduct>::
getNamesWithPrefix(const string& prefix, vector<string>& names) const {
for (const_iterator it = _pairs.begin(); it != _pairs.end(); ++it)
if (it->first.compare(0, prefix.size(), prefix) == 0)
names.push_back(it->first);
sort(names.begin(), names.end());
}
template<class AbstractProduct>
bool NameFactory<AbstractProduct>::empty() const {
return _pairs.empty();
}
template<class AbstractProduct>
string NameFactory<AbstractProduct>::getAbstractProductName() const {
return _abstractName;
}
template<class ConcreteProduct, class AbstractProduct>
void nameFactoryRegister(NameFactory<AbstractProduct>& factory) {
struct HoldsFunction {
static unique_ptr<AbstractProduct> createConcreteProduct() {
return unique_ptr<AbstractProduct>(new ConcreteProduct());
}
};
factory.registerProduct(ConcreteProduct::staticGetName(),
HoldsFunction::createConcreteProduct);
}
template<class AbstractProduct>
unique_ptr<AbstractProduct> createWithPrefix
(const NameFactory<AbstractProduct>& factory, const string& prefix) {
return factory.createNoThrow(getUniqueNameWithPrefix(factory, prefix));
}
template<class AbstractProduct>
string getUniqueNameWithPrefix
(const NameFactory<AbstractProduct>& factory, const string& prefix) {
vector<string> names;
factory.getNamesWithPrefix(prefix, names);
if (find(names.begin(), names.end(), prefix) != names.end()) {
names.clear();
names.push_back(prefix);
}
if (names.empty()) {
throwError<UnknownNameException>
("No " + factory.getAbstractProductName() +
" has the prefix \"" + prefix + "\".");
}
if (names.size() >= 2) {
string errorMsg = "More than one " + factory.getAbstractProductName() +
" has prefix \"" + prefix + "\":\n ";
for (size_t name = 0; name < names.size(); ++name)
errorMsg += ' ' + names[name];
throwError<AmbiguousNameException>(errorMsg);
}
ASSERT(names.size() == 1);
return names.back();
}
#endif
product
void product(Matrix &prod, const Matrix &a, const Matrix &b)
Sets prod to a * b.
Definition Matrix.cpp:116
nameFactoryRegister
void nameFactoryRegister(NameFactory< AbstractProduct > &factory)
Registers the string returned by ConcreteProduct::getStaticName() to a function that default-construc...
Definition NameFactory.h:142
getUniqueNameWithPrefix
string getUniqueNameWithPrefix(const NameFactory< AbstractProduct > &factory, const string &prefix)
Returns the unique product name that has the indicated prefix, or return prefix itself if it is the a...
Definition NameFactory.h:160
createWithPrefix
unique_ptr< AbstractProduct > createWithPrefix(const NameFactory< AbstractProduct > &factory, const string &prefix)
Creates the unique product that has the indicated prefix, or create the actual product that has name ...
Definition NameFactory.h:154
NameFactory
A NameFactory takes a name and then creates an instance of a class that has been previously registere...
Definition NameFactory.h:33
NameFactory::Pair
pair< string, FactoryFunction > Pair
Definition NameFactory.h:61
NameFactory::NameFactory
NameFactory(const char *abstractName)
Definition NameFactory.h:37
NameFactory::const_iterator
vector< Pair >::const_iterator const_iterator
Definition NameFactory.h:62
NameFactory::getAbstractProductName
string getAbstractProductName() const
Definition NameFactory.h:137
NameFactory::_abstractName
const string _abstractName
Definition NameFactory.h:64
NameFactory::_pairs
vector< Pair > _pairs
Definition NameFactory.h:63
NameFactory::empty
bool empty() const
Returns true if no names have been registered.
Definition NameFactory.h:132
NameFactory::createNoThrow
unique_ptr< AbstractProduct > createNoThrow(const string &name) const
Calls the function registered to the parameter name and returns the result.
Definition NameFactory.h:99
NameFactory::FactoryFunction
unique_ptr< AbstractProduct >(* FactoryFunction)()
Definition NameFactory.h:39
NameFactory::create
unique_ptr< AbstractProduct > create(const string &name) const
Calls the function registered to the parameter name and returns the result.
Definition NameFactory.h:108
NameFactory::getNamesWithPrefix
void getNamesWithPrefix(const string &prefix, vector< string > &names) const
Inserts into names all registered names that have the indicated prefix in lexicographic increasing or...
Definition NameFactory.h:124
NameFactory::registerProduct
void registerProduct(const string &name, FactoryFunction function)
Definition NameFactory.h:118
error.h
throwError
void throwError(const string &errorMsg)
Definition error.h:58
ASSERT
#define ASSERT(X)
Definition stdinc.h:86