
Hi, Caleb Epstein wrote:
There is a Factory implementation in the current review queue. The code is in the vault:
Thanks, I will have a look at it when I'm back home from work.
Look for factory3.zip. The implementation doesn't require inheritance from any particular base class.
The registrable/registry base classes are generic registries, as opposed to the more specific registry (that only takes creator object) the factory provides. I thought it might be a good idea to have that functionality split out into a separate class. The advantage of this approach is that there is a single entry point for any objects that need to be registered. If your program loads plug-in code from a DLL, and a plug-in provides a factory, creators for that factory can again be provided through the same entry point. By designing the plugin interface to contain a list of "registrable" objects that are passed to the (static) registry::register_object() function by the plugin loader, you can completely avoid any dependency of plugin code on dynamic symbols provided by the main program or other plugins, which makes programs more portable to platforms without a sane dynamic linker.
The factory objects are templated on an mpl::vector of types that they can create. The factory methods themselves are, I believe, pluggable at runtime.
Allowing multiple different objects to be created is a good thing. I will definitely enjoy reading that code. :-)
- template<typename obj, typename stream> class parser
The purpose of your parser/parseiterator stuff eludes me. What is it for? Is it akin to Spirit?
No, it is a wrapper around the actual parser that provides an input iterator interface (that can be constructed on the stack), but uses a factory to get the actual parser object (which is silently created on the heap). This makes sense if you have a (possibly abstract) base data type, several concrete data types and possibly multiple input formats. For example: class base { public: virtual int getData(void) = 0; }; class derived { public: virtual int getData(void); }; parseiterator<base> iter(std::cin, "derived-1"); parseiterator<base> end; This will get a "derived-1" parser from the parser factory (which is a global object), and have that object parse "derived" objects from stdin (how it does that is up to the virtual functions in the concrete parser class). When you dereference the iterator, you get a reference to a base object (as that is all that is known at compile time). New derived object types and parsers can then be added at runtime. Simon