File generic_factory.hxx#

Defines

__BOUT_GENERIC_FACTORY_H__#

Base type for factories.

template<class BaseType, class DerivedFactory, class ...BaseArgs>
class Factory#
#include <generic_factory.hxx>

Generic Factory, adapted from Modern C++ Design/Loki by A. Alexandrescu

Use with RegisterInFactory to provide a generic way of creating new derived types at runtime. By default assumes the type can be created with an Options*

Uses static polymorphism (via CRTP) to overload static data. This is done by inheriting from this class and templating on the inherited class, and then providing four public data members:

Example:

class Base {
public:
  Base(Options*) {}
};
class Derived : public Base {
public:
  Derived(Options*) : Base({}) {}
};

class MyFactory : public Factory<Base, MyFactory> {
 public:
  static constexpr auto type_name = "Base";
  static constexpr auto section_name = "base";
  static constexpr auto option_name = "type";
  static constexpr auto default_type = "derived_type";
};

RegisterInFactory<Base, Derived, MyFactory, Options*> register("derived_type");
auto foo = MyFactory::getInstance().create("derived_type");

In a .cxx file the static members should be declared:

constexpr decltype(MyFactory::type_name) MyFactory::type_name; constexpr decltype(MyFactory::section_name) MyFactory::section_name; constexpr decltype(MyFactory::option_name) MyFactory::option_name; constexpr decltype(MyFactory::default_type) MyFactory::default_type;

MIT Licence

Template Parameters:
  • BaseType – The base class that this factory creates

  • DerivedFactory – The derived factory inheriting from this class

  • TypeCreator – The function signature for creating a new BaseType

Public Functions

virtual ~Factory() = default#
inline virtual bool add(const std::string &name, TypeCreator creator)#

Add a new type name to the factory

Parameters:
  • name[in] An identifier for this type

  • creator[in] A function for creating this type

Returns:

true if the type was successfully added

inline bool addUnavailable(const std::string &name, const std::string &reason)#

Add a new “unavailable” type name to the factory. This type cannot be created, but will be shown as a valid type, in conjunction with the reason it cannot be created

Parameters:
  • name[in] An identifier for this type

  • reason[in] The reason this type is unavailable

Returns:

true if the type was successfully added

inline virtual bool remove(const std::string &name)#

Remove a type name from the factory

Parameters:

name[in] The identifier for the type to be removed

Returns:

true if the type was successfully removed

inline bool removeUnavailable(const std::string &name)#

Remove a unavailable type name from the factory

Parameters:

name[in] The identifier for the type to be removed

Returns:

true if the type was successfully removed

inline std::string getType(Options *options = nullptr) const#

Get the name of the type to create

Looks in options first, then the root Options

Parameters:

options[in] Options section to look for type name

Returns:

the name of the type to create

inline ReturnType create(Options *options = nullptr) const#

Create a new object using the type set in options.

inline ReturnType create(const std::string &name) const#

Create a new object of type name using the root Options.

template<typename ...Args>
inline ReturnType create(const std::string &name, Args&&... args) const#

Create a new object of type name

Parameters:

name[in] The identifier for the type to be created

Returns:

the new object

template<typename ...Args>
inline ReturnType create(Options *options, Args&&... args) const#

Create a new object of the type given in options[“type”]

Parameters:

options[in] The Options object to get the type to be created from

Returns:

the new object

inline std::vector<std::string> listAvailable() const#

List available types that can be created

Returns:

a vector of std::string

inline std::vector<std::string> listUnavailableReasons() const#

Public Static Functions

static inline DerivedFactory &getInstance()#

Get the singleton instance.

static inline constexpr auto getDefaultType()#

Return the name of the default type to create.

static inline constexpr auto getSectionName()#

Return the name of the section to get from the root Options.

static inline constexpr auto getOptionName()#

Return the name of the Option value that sets the type.

Protected Types

using ReturnType = typename TypeCreator::result_type#

Protected Functions

Factory() = default#
inline Options *optionsOrDefaultSection(Options *options) const#

Return either options or the section from root.

Protected Static Functions

static inline void ensureRegistered()#

Disgusting hack to defeat linker throwing out the registration symbols. If necessary, override this and put the (empty) implementation in the same TU as the registration symbols

Private Types

using TypeCreator = std::function<std::unique_ptr<BaseType>(BaseArgs...)>#

Private Members

std::map<std::string, TypeCreator> type_map#

Storage of the creation functions.

std::map<std::string, std::string> unavailable_options#

Known implementations that are unavailable, along with the reason.

template<class DerivedType>
struct RegisterInFactory#
#include <generic_factory.hxx>

Helper class for adding new types to Factory

See Factory for example

Adapted from http://www.drdobbs.com/conversations-abstract-factory-template/184403786

Template Parameters:
  • BaseType – Which factory to add DerivedType to

  • DerivedType – The new type to add to Factory<BaseType>

Public Functions

inline RegisterInFactory(const std::string &name)#
class RegisterUnavailableInFactory#
#include <generic_factory.hxx>

Helper class for adding new (unavailable) types to Factory

See Factory for example

Adapted from http://www.drdobbs.com/conversations-abstract-factory-template/184403786

Template Parameters:

BaseType – Which factory to add DerivedType to

Public Functions

inline RegisterUnavailableInFactory(const std::string &name, const std::string &reason)#