21 #ifndef mia_core_factory_hh
22 #define mia_core_factory_hh
50 public TPlugin<typename P::plugin_data, typename P::plugin_type>
81 virtual Product *do_create() const __attribute__((warn_unused_result)) = 0 ;
121 ProductPtr produce(
const std::string& plugindescr)
const;
126 return produce(std::string(plugindescr));
136 UniqueProduct produce_unique(
const std::string& plugindescr)
const;
141 return produce_unique(std::string(plugindescr));
149 void set_caching(
bool enable)
const;
153 std::string get_handler_type_string_and_help(std::ostream& os)
const;
155 std::string do_get_handler_type_string()
const;
157 virtual bool do_validate_parameter_string(
const std::string& s)
const;
159 typename I::Product *produce_raw(
const std::string& plugindescr)
const;
163 template <
typename Handler,
typename Chained,
bool chainable>
172 template <
typename I>
174 TPlugin<typename I::plugin_data, typename I::plugin_type>(name)
178 template <
typename I>
184 this->set_parameters(options);
185 this->check_parameters();
186 auto product = this->do_create();
189 product->set_module(this->get_module());
190 product->set_init_string(params);
194 }
catch (std::length_error& x) {
195 std::stringstream msg;
196 msg <<
"CParamList::set: Some string was not created properly\n";
197 msg <<
" options were:\n";
199 for (
auto i = options.begin();
200 i != options.end(); ++i) {
201 msg <<
" " << i->first <<
"=" << i->second <<
"\n";
204 cverr() << msg.str();
205 throw std::logic_error(
"Probably a race condition");
209 template <
typename I>
211 m_cache(this->get_descriptor())
216 template <
typename I>
219 cvdebug() << this->get_descriptor() <<
":Set cache policy to " << enable <<
"\n";
220 m_cache.enable_write(enable);
223 template <
typename I>
227 auto result = m_cache.get(plugindescr);
230 result.reset(this->produce_raw(plugindescr));
231 m_cache.add(plugindescr, result);
233 cvdebug() <<
"Use cached '" << plugindescr <<
"'\n";
238 template <
typename I>
245 template <
typename I>
248 os <<
" The string value will be used to construct a plug-in.";
249 return do_get_handler_type_string();
252 template <
typename I>
258 template <
typename I>
261 cvdebug() <<
"Check whether factory '" << this->get_descriptor() <<
"' can understand '" << s <<
"'\n";
264 auto colon_pos = s.find(
':');
265 auto plugin_name = s.substr(0, colon_pos);
267 if (this->plugin(plugin_name.c_str()))
273 template <
typename Handler,
typename Chained,
bool chainable>
278 if (param_list.
size() > 1) {
279 throw create_exception<std::invalid_argument>(
"Factory ", h.get_descriptor(),
280 ": No chaining supported but ", param_list.
size(),
281 " plugin descriptors were given. "
282 "If the description contains a '+' sign as part "
283 "of a parameter you must protect it by enclosing the "
284 "value in square brackets like this: [1e+6]");
287 cvdebug() <<
"TFactoryPluginHandler<P>::produce use '" << param_list.
begin()->first <<
"'\n";
288 const std::string& factory_name = param_list.
begin()->first;
297 cvdebug() <<
"TFactoryPluginHandler<" << h.get_descriptor() <<
">::produce: "
298 "Create plugin from '" << factory_name <<
"'\n";
299 auto factory = h.plugin(factory_name.c_str());
302 throw create_exception<std::invalid_argument>(
"Factory ", h.get_descriptor(),
303 ":Unable to find plugin for '", factory_name,
"'");
305 return factory->create(param_list.
begin()->second, params.c_str());
309 template <
typename Handler,
typename ProductChained>
315 if (param_list.
size() == 1)
318 ProductChained *result =
new ProductChained();
321 for (
auto ipl = param_list.
begin(); ipl != param_list.
end(); ++ipl) {
322 const std::string& factory_name = ipl->first;
323 cvdebug() <<
"TFactoryPluginHandler<P>::produce use '" << factory_name <<
"\n";
333 auto factory = h.plugin(factory_name.c_str());
337 throw create_exception<std::invalid_argument>(
"Factory ", h.get_descriptor(),
338 "Unable to find plugin for '", factory_name,
"'");
341 auto r = factory->create(ipl->second, params.c_str());
342 result->push_back(
typename Product::Pointer(r));
345 result->set_init_string(params.c_str());
346 }
catch (std::exception& x) {
356 template <
typename I>
359 if (params.empty()) {
360 throw create_exception<std::invalid_argument>(
"Factory ", this->get_descriptor(),
": Empty description string given. "
361 "Supported plug-ins are '", this->get_plugin_names(),
"'. "
362 "Set description to 'help' for more information.");
367 if (param_list.size() < 1) {
368 throw create_exception<std::invalid_argument>(
"Factory ", this->get_descriptor(),
": Description string '"
369 , params,
"' can not be interpreted. "
370 "Supported plug-ins are '", this->get_plugin_names(),
"'. "
371 "Set description to 'help' for more information.");
383 #define EXPLICIT_INSTANCE_PLUGIN(T) \
384 template class TPlugin<T::plugin_data, T::plugin_type>; \
385 template class TFactory<T>;
391 #define EXPLICIT_INSTANCE_PLUGIN_HANDLER(P) \
392 template class TPluginHandler<P>; \
393 template class TFactoryPluginHandler<P>; \
394 template class THandlerSingleton<TFactoryPluginHandler<P> >;
401 #define EXPLICIT_INSTANCE_HANDLER(T) \
402 template class TPlugin<T::plugin_data, T::plugin_type>; \
403 template class TFactory<T>; \
404 template class TPluginHandler<TFactory<T> >; \
405 template class TFactoryPluginHandler<TFactory<T> >; \
406 template class THandlerSingleton<TFactoryPluginHandler<TFactory<T> > >;
414 #define EXPLICIT_INSTANCE_DERIVED_FACTORY_HANDLER(T, F) \
415 template class TPlugin<T::plugin_data, T::plugin_type>; \
416 template class TFactory<T>; \
417 template class TPluginHandler<F>; \
418 template class TFactoryPluginHandler<F>; \
419 template class THandlerSingleton<TFactoryPluginHandler<F> >;