Frobby 0.9.5
NameFactory.h
Go to the documentation of this file.
1/* Frobby: Software for monomial ideal computations.
2 Copyright (C) 2007 Bjarke Hammersholt Roune (www.broune.com)
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see http://www.gnu.org/licenses/.
16*/
17#ifndef NAME_FACTORY_GUARD
18#define NAME_FACTORY_GUARD
19
20#include "error.h"
21#include <vector>
22#include <string>
23#include <algorithm>
24
32template<class AbstractProduct>
34 public:
37 NameFactory(const char* abstractName): _abstractName(abstractName) {}
38
39 typedef auto_ptr<AbstractProduct> (*FactoryFunction)();
40 void registerProduct(const string& name, FactoryFunction function);
41
45 auto_ptr<AbstractProduct> createNoThrow(const string& name) const;
46
49 auto_ptr<AbstractProduct> create(const string& name) const;
50
53 void getNamesWithPrefix(const string& prefix, vector<string>& names) const;
54
56 bool empty() const;
57
58 string getAbstractProductName() const;
59
60 private:
61 typedef pair<string, FactoryFunction> Pair;
62 typedef typename vector<Pair>::const_iterator const_iterator;
63 vector<Pair> _pairs;
64 const string _abstractName;
65};
66
69template<class ConcreteProduct, class AbstractProduct>
71
75template<class AbstractProduct>
76auto_ptr<AbstractProduct> createWithPrefix
77(const NameFactory<AbstractProduct>& factory, const string& prefix);
78
88template<class AbstractProduct>
90(const NameFactory<AbstractProduct>& factory, const string& prefix);
91
92
93// **************************************************************
94// These are implementations that have to be included here due
95// to being templates.
96
97template<class AbstractProduct>
98auto_ptr<AbstractProduct> NameFactory<AbstractProduct>::
99createNoThrow(const string& name) const {
100 for (const_iterator it = _pairs.begin(); it != _pairs.end(); ++it)
101 if (it->first == name)
102 return it->second();
103 return auto_ptr<AbstractProduct>();
104}
105
106template<class AbstractProduct>
107auto_ptr<AbstractProduct> NameFactory<AbstractProduct>::
108create(const string& name) const {
109 auto_ptr<AbstractProduct> product = createNoThrow(name);
110 if (product.get() == 0)
112 "Unknown " + getAbstractProductName() + " \"" + name + "\".");
113 return product;
114}
115
116template<class AbstractProduct>
118registerProduct(const string& name, FactoryFunction function) {
119 _pairs.push_back(Pair(name, function));
120}
121
122template<class AbstractProduct>
124getNamesWithPrefix(const string& prefix, vector<string>& names) const {
125 for (const_iterator it = _pairs.begin(); it != _pairs.end(); ++it)
126 if (it->first.compare(0, prefix.size(), prefix) == 0)
127 names.push_back(it->first);
128 sort(names.begin(), names.end());
129}
130
131template<class AbstractProduct>
133 return _pairs.empty();
134}
135
136template<class AbstractProduct>
138 return _abstractName;
139}
140
141template<class ConcreteProduct, class AbstractProduct>
143 struct HoldsFunction {
144 static auto_ptr<AbstractProduct> createConcreteProduct() {
145 return auto_ptr<AbstractProduct>(new ConcreteProduct());
146 }
147 };
148 factory.registerProduct(ConcreteProduct::staticGetName(),
149 HoldsFunction::createConcreteProduct);
150}
151
152template<class AbstractProduct>
153auto_ptr<AbstractProduct> createWithPrefix
154(const NameFactory<AbstractProduct>& factory, const string& prefix) {
155 return factory.createNoThrow(getUniqueNameWithPrefix(factory, prefix));
156}
157
158template<class AbstractProduct>
160(const NameFactory<AbstractProduct>& factory, const string& prefix) {
161 vector<string> names;
162 factory.getNamesWithPrefix(prefix, names);
163
164 if (find(names.begin(), names.end(), prefix) != names.end()) {
165 names.clear();
166 names.push_back(prefix);
167 }
168
169 if (names.empty()) {
171 ("No " + factory.getAbstractProductName() +
172 " has the prefix \"" + prefix + "\".");
173 }
174
175 if (names.size() >= 2) {
176 string errorMsg = "More than one " + factory.getAbstractProductName() +
177 " has prefix \"" + prefix + "\":\n ";
178 for (size_t name = 0; name < names.size(); ++name)
179 errorMsg += ' ' + names[name];
181 }
182
183 ASSERT(names.size() == 1);
184 return names.back();
185}
186
187#endif
void product(Matrix &prod, const Matrix &a, const Matrix &b)
Sets prod to a * b.
Definition Matrix.cpp:116
auto_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 ...
void nameFactoryRegister(NameFactory< AbstractProduct > &factory)
Registers the string returned by ConcreteProduct::getStaticName() to a function that default-construc...
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...
A NameFactory takes a name and then creates an instance of a class that has been previously registere...
Definition NameFactory.h:33
NameFactory(const char *abstractName)
Definition NameFactory.h:37
string getAbstractProductName() const
auto_ptr< AbstractProduct > createNoThrow(const string &name) const
Calls the function registered to the parameter name and returns the result.
Definition NameFactory.h:99
const string _abstractName
Definition NameFactory.h:64
vector< Pair > _pairs
Definition NameFactory.h:63
vector< Pair >::const_iterator const_iterator
Definition NameFactory.h:62
bool empty() const
Returns true if no names have been registered.
void getNamesWithPrefix(const string &prefix, vector< string > &names) const
Inserts into names all registered names that have the indicated prefix in lexicographic increasing or...
pair< string, FactoryFunction > Pair
Definition NameFactory.h:61
auto_ptr< AbstractProduct >(*) FactoryFunction()
Definition NameFactory.h:39
void registerProduct(const string &name, FactoryFunction function)
auto_ptr< AbstractProduct > create(const string &name) const
Calls the function registered to the parameter name and returns the result.
void throwError(const string &errorMsg)
Definition error.h:58
#define ASSERT(X)
Definition stdinc.h:86