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 
32 template<class AbstractProduct>
33 class NameFactory {
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 
69 template<class ConcreteProduct, class AbstractProduct>
71 
75 template<class AbstractProduct>
76 auto_ptr<AbstractProduct> createWithPrefix
77 (const NameFactory<AbstractProduct>& factory, const string& prefix);
78 
88 template<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 
97 template<class AbstractProduct>
98 auto_ptr<AbstractProduct> NameFactory<AbstractProduct>::
99 createNoThrow(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 
106 template<class AbstractProduct>
107 auto_ptr<AbstractProduct> NameFactory<AbstractProduct>::
108 create(const string& name) const {
109  auto_ptr<AbstractProduct> product = createNoThrow(name);
110  if (product.get() == 0)
111  throwError<UnknownNameException>(
112  "Unknown " + getAbstractProductName() + " \"" + name + "\".");
113  return product;
114 }
115 
116 template<class AbstractProduct>
118 registerProduct(const string& name, FactoryFunction function) {
119  _pairs.push_back(Pair(name, function));
120 }
121 
122 template<class AbstractProduct>
124 getNamesWithPrefix(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 
131 template<class AbstractProduct>
133  return _pairs.empty();
134 }
135 
136 template<class AbstractProduct>
138  return _abstractName;
139 }
140 
141 template<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 
152 template<class AbstractProduct>
153 auto_ptr<AbstractProduct> createWithPrefix
154 (const NameFactory<AbstractProduct>& factory, const string& prefix) {
155  return factory.createNoThrow(getUniqueNameWithPrefix(factory, prefix));
156 }
157 
158 template<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()) {
170  throwError<UnknownNameException>
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];
180  throwError<AmbiguousNameException>(errorMsg);
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 ...
Definition: NameFactory.h:154
void nameFactoryRegister(NameFactory< AbstractProduct > &factory)
Registers the string returned by ConcreteProduct::getStaticName() to a function that default-construc...
Definition: NameFactory.h:142
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
A NameFactory takes a name and then creates an instance of a class that has been previously registere...
Definition: NameFactory.h:33
pair< string, FactoryFunction > Pair
Definition: NameFactory.h:61
auto_ptr< AbstractProduct >(* FactoryFunction)()
Definition: NameFactory.h:39
NameFactory(const char *abstractName)
Definition: NameFactory.h:37
vector< Pair >::const_iterator const_iterator
Definition: NameFactory.h:62
string getAbstractProductName() const
Definition: NameFactory.h:137
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
bool empty() const
Returns true if no names have been registered.
Definition: NameFactory.h:132
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
void registerProduct(const string &name, FactoryFunction function)
Definition: NameFactory.h:118
auto_ptr< AbstractProduct > create(const string &name) const
Calls the function registered to the parameter name and returns the result.
Definition: NameFactory.h:108
#define ASSERT(X)
Definition: stdinc.h:86