SelectiveFactory
A monostate meta-factory which forwards the input to a matching Base factory, based on the given Criterion. A SelectiveFactory can generically instantiate whatever derived class can be constructed that fits Criterion.
A SelectiveFactory is templated as follows, the key functions are listed:
template <
typename Base, // the base class for instantiations
typename Criterion, // selection criterion for factories
typename... Input // input to base class factories
>
class SelectiveFactory{
public:
// Predicate function pointers
typedef bool(*Predicate)(Criterion);
// Factory function pointers
typedef std::unique_ptr<Base>(*Factory)(Input...);
/**
* Registers a new factory with given selection predicate.
*/
static void registerPtr(Predicate predicate, Factory factory);
/**
* Constructs Base objects using all registered Factories for which
* predicate(criterion) holds.
*/
static std::vector<std::unique_ptr<Base>> Produce(Criterion criterion, Input... value);
};
The key advantage to this factory is that candidate constructors can be registered from anywhere, for example using a global prior to main(). This works because the factory is a monostate, which allows registration to occur in library code if desired. In EnsembleSVM we opted to perform explicit registration in includes/Registration.hpp
to make the code's structure clearer.
Since Predicates are user-defined, several derived classes may fit a given Criterion. Therefore a SelectiveFactory can, in principle, return a collection of constructed Base objects.
Note that this implementation is not thread safe, but it's easy to fix that by adding a mutex to container().