Factory< Base, Args > Struct Template Reference

SPADES API: spades::Factory< Base, Args > Struct Template Reference
SPADES API

#include <Factory.H>

Classes

struct  Register
 Class to handle registration of subclass for runtime selection. More...
 

Public Member Functions

virtual ~Factory ()=default
 

Static Public Member Functions

static std::unique_ptr< Basecreate (const std::string &key, Args... args)
 
static void print (std::ostream &os)
 

Public Attributes

friend Base
 

Private Types

using CreatorFunc = std::unique_ptr<Base> (*)(Args...)
 
using LookupTable = std::unordered_map<std::string, CreatorFunc>
 

Private Member Functions

 Factory ()=default
 

Static Private Member Functions

static void key_exists_or_error (const std::string &key)
 
static LookupTabletable ()
 Lookup table containing all registered instances.
 

Detailed Description

template<class Base, class... Args>
struct spades::Factory< Base, Args >

Runtime selection of options based on string keyword lookup

This is lifted straight from AMR-wind, https://github.com/Exawind/amr-wind

Factory provides an automated way to register subclasses that can be instantiated during runtime using string based lookups. The facility mimics the runTimeSelectionTable in OpenFOAM and the current structure is adapted from http://www.nirfriedman.com/2018/04/29/unforgettable-factory/

The usage is described using the following example from code. We would like to support creation of a turbulence model based on user inputs that are read from a file. We will create a base class TurbulenceModel that defines the API for the turbulence model and how it interacts with the rest of the code. Then new models, e.g., Smagorinsky, k-Omega SST/SAS, etc., are added as subclasses to this instance.

// Create a base class that can be used to register and create instances
//
// The template arguments are the classname for CRTP and types of additional
// arguments to be passed to the constructor of the object
class TurbulenceModel : public Factory<TurbulenceModel, const CFDSim&>
{
// Define a base identifier string for debugging purposes
static const std::string base_identifier() { return "TurbulenceModel";
}
// Define API as appropriate here
};
// Define a subclass
// Instead of using the base class we use Base::Register to allow
registration class Smagorinsky : public
TurbulenceModel::Register<Smagorinsky>
{
// This is the keyword that is used to lookup and create this instance
static const std::string identifier() { return "Smagorinsky"; }
// Model implementation here
};
// To create a turbulence model instance
auto sim = CFDSim(mesh);
// tmodel is a std::unique_ptr<TurbulenceModel> instance
auto tmodel = TurbulenceModel::create("Smagorinsky", sim);
Definition Factory.H:66
Template Parameters
Basebase class (e.g., Physics)
ArgsArguments types to be passed to the constructor during instantiation

Member Typedef Documentation

◆ CreatorFunc

template<class Base , class... Args>
using spades::Factory< Base, Args >::CreatorFunc = std::unique_ptr<Base> (*)(Args...)
private

◆ LookupTable

template<class Base , class... Args>
using spades::Factory< Base, Args >::LookupTable = std::unordered_map<std::string, CreatorFunc>
private

Constructor & Destructor Documentation

◆ ~Factory()

template<class Base , class... Args>
virtual spades::Factory< Base, Args >::~Factory ( )
virtualdefault

◆ Factory()

template<class Base , class... Args>
spades::Factory< Base, Args >::Factory ( )
privatedefault

Member Function Documentation

◆ create()

template<class Base , class... Args>
static std::unique_ptr< Base > spades::Factory< Base, Args >::create ( const std::string & key,
Args... args )
inlinestatic

Create an instance of the concrete subclass based on the runtime keyword

Parameters
keyUnique identifier used to lookup subclass instance
argsArguments to the constructor of the subclass
73 {
75 auto ptr = table().at(key)(std::forward<Args>(args)...);
76 amrex::Print() << "Creating " << Base::base_identifier()
77 << " instance: " << key << std::endl;
78 return ptr;
79 }
static void key_exists_or_error(const std::string &key)
Definition Factory.H:134
static LookupTable & table()
Lookup table containing all registered instances.
Definition Factory.H:150
Here is the call graph for this function:

◆ key_exists_or_error()

template<class Base , class... Args>
static void spades::Factory< Base, Args >::key_exists_or_error ( const std::string & key)
inlinestaticprivate

Check if the keyword exists in table or print diagnostic message and abort

135 {
136 const auto& tbl = table();
137 if (tbl.find(key) == tbl.end()) {
138 // Print valid options
139 if (amrex::ParallelDescriptor::IOProcessor()) {
140 print(std::cout);
141 }
142 // Quit with error
143 amrex::Abort(
144 "In " + Base::base_identifier() +
145 " cannot find instance: " + key);
146 }
147 }
static void print(std::ostream &os)
Definition Factory.H:85
Here is the call graph for this function:
Here is the caller graph for this function:

◆ print()

template<class Base , class... Args>
static void spades::Factory< Base, Args >::print ( std::ostream & os)
inlinestatic

Print a list of the valid subclasses registered to this base instance

Parameters
osValid output stream
86 {
87 const auto& tbl = table();
88 os << Base::base_identifier() << " " << tbl.size() << std::endl;
89 for (const auto& it : tbl) {
90 os << " - " << it.first << std::endl;
91 }
92 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ table()

template<class Base , class... Args>
static LookupTable & spades::Factory< Base, Args >::table ( )
inlinestaticprivate

Lookup table containing all registered instances.

151 {
152 static LookupTable tbl;
153 return tbl;
154 }
std::unordered_map< std::string, CreatorFunc > LookupTable
Definition Factory.H:130
Here is the caller graph for this function:

Member Data Documentation

◆ Base

template<class Base , class... Args>
friend spades::Factory< Base, Args >::Base

The documentation for this struct was generated from the following file:
  • /home/runner/work/spades/spades/Source/Factory.H