2 #ifndef WIRECELL_NAMEDFACTORY_H 3 #define WIRECELL_NAMEDFACTORY_H 12 #include <unordered_map> 39 auto it = m_objects.find(name);
40 if (it == m_objects.end()) {
49 auto it = m_objects.find(name);
50 if (it == m_objects.end()) {
51 pointer_type
p(
new Type);
62 std::unordered_map<std::string, pointer_type>
m_objects;
70 template <
class IType>
82 m_known_types.insert(classname);
83 return m_known_types.size();
89 m_lookup[classname] = factory;
96 if (classname ==
"") {
97 l->error(
"no class name given for type \"{}\"",
102 auto it = m_lookup.
find(classname);
103 if (it != m_lookup.end()) {
111 std::string factory_maker =
"make_" + classname +
"_factory";
112 auto plugin = pm.
find(factory_maker.c_str());
114 l->error(
"no plugin for \"{}\"", classname);
118 typedef void* (*maker_function)();
120 if (!plugin->symbol(factory_maker.c_str(), mf)) {
121 l->error(
"no factory maker symbol for \"{}\"", classname);
125 void* fac_void_ptr = mf();
128 l->error(
"no factory for \"{}\"", classname);
132 factory_ptr fptr =
reinterpret_cast<factory_ptr
>(fac_void_ptr);
133 m_lookup[classname] = fptr;
142 bool create=
true,
bool nullok =
false) {
148 l->error(
"no factory for class \"{}\" (instance \"{}\")", classname, instname);
149 std::cerr <<
"WireCell::NamedFactory: no factory for class \"" 150 << classname <<
"\", (instance \"" << instname <<
"\"\n";
157 iptr = fac->
create(instname);
161 iptr = fac->
find(instname);
168 std::string msg =
"NamedFactory: Failed to "+action+
" instance \"" + instname;
169 msg +=
"\" of class \"" + classname +
"\"";
173 interface_ptr uptype = std::dynamic_pointer_cast<interface_type>(iptr);
178 std::string msg =
"NamedFactory: Failed to cast instance: " + instname;
179 msg +=
" of class " + classname;
180 msg +=
" c++ type: " +
type(iptr);
181 msg +=
" to " +
type(uptype);
192 std::vector<std::string> ret;
193 for (
auto it : m_lookup) {
194 ret.push_back(it.first);
209 template<
class IType>
213 bool ok = nfr.
associate(classname, factory);
214 if (ok) {
return ok; }
219 template<
class IType>
224 if (ret) {
return ret; }
232 template<
class IType>
235 bool create=
true,
bool nullok=
false) {
238 std::shared_ptr<IType> ret = nfr.
instance(classname, instname,
create, nullok);
239 if (ret) {
return ret; }
240 if (nullok) {
return nullptr; }
246 template<
class IType>
248 std::shared_ptr<IType> ret = lookup<IType>(classname, instname,
false,
false);
252 template<
class IType>
254 std::shared_ptr<IType> ret = lookup<IType>(classname, instname,
false,
true);
259 template<
class IType>
270 return lookup<IType>(
t,
n,
create, nullok);
274 template<
class IType>
276 std::shared_ptr<IType> ret = lookup_tn<IType>(tn,
false,
false);
280 template<
class IType>
282 std::shared_ptr<IType> ret = lookup_tn<IType>(tn,
false,
true);
287 template<
class IType>
293 template<
class IType>
298 std::vector<std::string> ret(ktset.begin(), ktset.end());
310 template<
class Concrete,
class...
Interface>
312 static void* void_factory =
nullptr;
313 if (! void_factory) {
317 std::vector<bool> ret{WireCell::Factory::associate<Interface>(
name, factory)...};
323 template<
class Concrete,
class... Interface>
332 #define WIRECELL_FACTORY(NAME, CONCRETE,...) \ 333 static size_t hello_##NAME##_me = namedfactory_hello< CONCRETE , __VA_ARGS__ >(#NAME); \ 334 extern "C" { void* make_##NAME##_factory() { \ 335 return make_named_factory_factory< CONCRETE , __VA_ARGS__ >(#NAME); \ virtual const std::string & classname()
Access name of class this factory can make.
std::shared_ptr< IType > find_maybe_tn(const std::string &tn)
Like find_tn but with nullok true.
bool associate(const std::string &classname, factory_ptr factory)
Register an existing factory by the "class" name of the instance it can create.
std::shared_ptr< Type > pointer_type
The exposed pointer type.
void * make_named_factory_factory(std::string name)
void msg(const char *fmt,...)
WireCell::INamedFactory * lookup_factory(const std::string &classname)
Lookup up a factory for the given type.
Interface::pointer create(const std::string &name)
Create an instance by name.
boost::error_info< struct tag_errmsg, std::string > errmsg
Type type
Remember the underlying type.
factory_ptr lookup_factory(const std::string &classname)
Look up an existing factory by the name of the "class" it can create.
std::shared_ptr< IType > find_maybe(const std::string &classname, const std::string &instname="")
As above but quietly returns nullptr on failure.
virtual void set_classname(const std::string &name)
Set name of class this factory can make.
WireCell::INamedFactory * factory_ptr
std::shared_ptr< IType > lookup(const std::string &classname, const std::string &instname="", bool create=true, bool nullok=false)
std::pair< std::string, std::string > parse_pair(const std::string &in, const std::string &delim=":")
interface_ptr instance(const std::string &classname, const std::string &instname="", bool create=true, bool nullok=false)
virtual Interface::pointer create(const std::string &name)=0
Create an instance by name.
static PluginManager & instance()
std::vector< std::string > known_classes()
std::unordered_map< std::string, pointer_type > m_objects
Configuration find(Configuration &lst, const std::string &dotpath, const T &val)
Return dictionary in given list if it value at dotpath matches.
Plugin * find(const std::string &symbol_name)
std::vector< std::string > known_types()
std::shared_ptr< IType > lookup_tn(const std::string &tn, bool create=true, bool nullok=false)
Lookup an interface by a type:name pair.
size_t namedfactory_hello(std::string name)
std::string demangle(const std::string &name)
std::shared_ptr< Interface > pointer
std::shared_ptr< IType > find_tn(const std::string &tn)
Like lookup_tn but with create false.
logptr_t logger(std::string name)
std::shared_ptr< spdlog::logger > logptr_t
std::vector< std::string > known_classes()
Return a vector of all known classes of given interface.
Interface::pointer find(const std::string &name)
Return existing instance of given name or nullptr if not found.
Interface::pointer create()
Return an instance associated with the given name.
std::string type(const T &t)
size_t hello(const std::string &classname)
known_type_set m_known_types
The base wire cell exception.
std::shared_ptr< spdlog::logger > create(std::string logger_name, SinkArgs &&...sink_args)
bool associate(const std::string &classname, WireCell::INamedFactory *factory)
Associate a factory with the type it makes.
std::unordered_map< std::string, factory_ptr > factory_lookup
std::shared_ptr< IType > interface_ptr
virtual Interface::pointer find(const std::string &name)=0
Return existing instance or nullptr if not found.
std::set< std::string > known_type_set
known_type_set known_types() const