17 #ifndef NAME_FACTORY_GUARD
18 #define NAME_FACTORY_GUARD
32 template<
class AbstractProduct>
45 auto_ptr<AbstractProduct>
createNoThrow(
const string& name)
const;
49 auto_ptr<AbstractProduct>
create(
const string& name)
const;
61 typedef pair<string, FactoryFunction>
Pair;
69 template<
class ConcreteProduct,
class AbstractProduct>
75 template<
class AbstractProduct>
88 template<
class AbstractProduct>
97 template<
class AbstractProduct>
100 for (
const_iterator it = _pairs.begin(); it != _pairs.end(); ++it)
101 if (it->first == name)
103 return auto_ptr<AbstractProduct>();
106 template<
class AbstractProduct>
109 auto_ptr<AbstractProduct>
product = createNoThrow(name);
111 throwError<UnknownNameException>(
112 "Unknown " + getAbstractProductName() +
" \"" + name +
"\".");
116 template<
class AbstractProduct>
119 _pairs.push_back(
Pair(name,
function));
122 template<
class AbstractProduct>
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());
131 template<
class AbstractProduct>
133 return _pairs.empty();
136 template<
class AbstractProduct>
138 return _abstractName;
141 template<
class ConcreteProduct,
class AbstractProduct>
143 struct HoldsFunction {
144 static auto_ptr<AbstractProduct> createConcreteProduct() {
145 return auto_ptr<AbstractProduct>(
new ConcreteProduct());
149 HoldsFunction::createConcreteProduct);
152 template<
class AbstractProduct>
158 template<
class AbstractProduct>
161 vector<string> names;
164 if (find(names.begin(), names.end(), prefix) != names.end()) {
166 names.push_back(prefix);
170 throwError<UnknownNameException>
172 " has the prefix \"" + prefix +
"\".");
175 if (names.size() >= 2) {
177 " has prefix \"" + prefix +
"\":\n ";
178 for (
size_t name = 0; name < names.size(); ++name)
179 errorMsg +=
' ' + names[name];
180 throwError<AmbiguousNameException>(errorMsg);
183 ASSERT(names.size() == 1);