InFact
Interpreter and factory for easily creating C++ objects at run-time
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Classes | Namespaces | Macros
factory.h File Reference

Provides a generic dynamic object factory. More...

#include <iostream>
#include <sstream>
#include <memory>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <stdexcept>
#include "environment.h"
#include "error.h"
#include "stream-tokenizer.h"

Go to the source code of this file.

Classes

class  infact::TypeName< T >
 We use the templated class TypeName to be able to take an actual C++ type and get the type name string used by the Interpreter and Environment classes. More...
 
class  infact::TypeName< bool >
 A specialization so that an object of type bool converts to "bool". More...
 
class  infact::TypeName< int >
 A specialization so that an object of type int converts to "int". More...
 
class  infact::TypeName< double >
 A specialization so that an object of type double converts to "double". More...
 
class  infact::TypeName< string >
 A specialization so that an object of type string converts to "string". More...
 
class  infact::TypeName< shared_ptr< T > >
 A partial specialization so that an object of type shared_ptr<T>, where T is some Factory-constructible type, converts to the string produced by TypeName<T>. More...
 
class  infact::TypeName< vector< T > >
 A partial specialization so that an object of type vector<T> gets converted to the type name of T followed by the string "[]", equivalent to the result of executing the following expression: More...
 
class  infact::MemberInitializer
 An interface for data member initializers of members of a Factory-constructible object. More...
 
class  infact::TypedMemberInitializer< T >
 A concrete, typed implementation of the MemberInitializer base class. More...
 
class  infact::Initializers
 A container for all the member initializers for a particular Factory-constructible instance. More...
 
class  infact::FactoryBase
 An interface for all Factory instances, specifying a few pure virtual methods. More...
 
class  infact::FactoryContainer
 A class to hold all Factory instances that have been created. More...
 
class  infact::Constructor< T >
 An interface with a single virtual method that constructs a concrete instance of the abstract type T. More...
 
class  infact::FactoryConstructible
 An interface simply to make it easier to implement Factory-constructible types by implementing both required methods to do nothing (use of this interface is completely optional; read more for more information). More...
 
class  infact::Factory< T >
 Factory for dynamically created instance of the specified type. More...
 

Namespaces

 infact
 The namespace for the entire InFact library.
 

Macros

#define INFACT_ADD_PARAM(param)   initializers.Add(#param, &_ ## param)
 A macro to make it easy to register a parameter for initialization inside a RegisterInitializers implementation, in a very readable way. More...
 
#define INFACT_ADD_PARAM_(param)   initializers.Add(#param, &param ## _)
 A macro to make it easy to register a parameter for initialization inside a RegisterInitializers implementation, in a very readable way. More...
 
#define INFACT_ADD_REQUIRED_PARAM(param)   initializers.Add(#param, &_ ## param, true)
 Identical to INFACT_ADD_PARAM but for a required parameter. More...
 
#define INFACT_ADD_REQUIRED_PARAM_(param)   initializers.Add(#param, &param ## _, true)
 Identical to INFACT_ADD_PARAM_ but for a required parameter. More...
 
#define INFACT_ADD_TEMPORARY(type, var)   initializers.Add(#var, static_cast<type *>(nullptr))
 A macro to make it easier to register a temporary variable inside a RegisterInitializers implementation, for extraction from the Environment inside a PostInit implementation. More...
 
#define INFACT_ADD_REQUIRED_TEMPORARY(type, var)   initializers.Add(#var, static_cast<type *>(nullptr), true)
 Identical to INFACT_ADD_TEMPORARY but for a required temporary. More...
 
#define DEFINE_CONS_CLASS(TYPE, NAME, BASE)
 A macro to define a subclass of Constructor whose NewInstance method constructs an instance of TYPE, a concrete subclass of BASE. More...
 
#define REGISTER_NAMED(TYPE, NAME, BASE)
 This macro registers the concrete subtype TYPE with the specified factory for instances of type BASE; the TYPE is associated with the specified NAME. More...
 
#define IMPLEMENT_FACTORY(BASE)
 Provides the necessary implementation for a factory for the specified BASE class type. More...
 

Detailed Description

Provides a generic dynamic object factory.

Author
dbike.nosp@m.l@go.nosp@m.ogle..nosp@m.com (Dan Bikel)

Definition in file factory.h.

Macro Definition Documentation

#define DEFINE_CONS_CLASS (   TYPE,
  NAME,
  BASE 
)
Value:
class NAME ## Constructor : public infact::Constructor<BASE> { \
public: virtual BASE *NewInstance() const { return new TYPE(); } };
An interface with a single virtual method that constructs a concrete instance of the abstract type T...
Definition: factory.h:531
virtual T * NewInstance() const =0

A macro to define a subclass of Constructor whose NewInstance method constructs an instance of TYPE, a concrete subclass of BASE.

The concrete subclass TYPE must have a no-argument constructor. This is a helper macro used only by the REGISTER macro.

Definition at line 1030 of file factory.h.

#define IMPLEMENT_FACTORY (   BASE)
Value:
template<> const char *infact::Factory<BASE>::base_name_ = #BASE;
Factory for dynamically created instance of the specified type.
Definition: factory.h:593

Provides the necessary implementation for a factory for the specified BASE class type.

Definition at line 1051 of file factory.h.

#define INFACT_ADD_PARAM (   param)    initializers.Add(#param, &_ ## param)

A macro to make it easy to register a parameter for initialization inside a RegisterInitializers implementation, in a very readable way.

This macro assumes that you want to register a parameter with the name "param" for a data member with the underscore-initial name _param. It also asumes that the sole parameter in your FactoryConstructible::RegisterInitializers implementation is called initializers.

See Also
infact::FactoryConstructible::RegisterInitializers

Definition at line 62 of file factory.h.

#define INFACT_ADD_PARAM_ (   param)    initializers.Add(#param, &param ## _)

A macro to make it easy to register a parameter for initialization inside a RegisterInitializers implementation, in a very readable way.

This macro assumes that you want to register a parameter with the name "param" for a data member with the underscore-final name param_. It also asumes that the sole parameter in your FactoryConstructible::RegisterInitializers implementation is called initializers.

See Also
infact::FactoryConstructible::RegisterInitializers

Definition at line 75 of file factory.h.

#define INFACT_ADD_REQUIRED_PARAM (   param)    initializers.Add(#param, &_ ## param, true)

Identical to INFACT_ADD_PARAM but for a required parameter.

Definition at line 79 of file factory.h.

#define INFACT_ADD_REQUIRED_PARAM_ (   param)    initializers.Add(#param, &param ## _, true)

Identical to INFACT_ADD_PARAM_ but for a required parameter.

Definition at line 83 of file factory.h.

#define INFACT_ADD_REQUIRED_TEMPORARY (   type,
  var 
)    initializers.Add(#var, static_cast<type *>(nullptr), true)

Identical to INFACT_ADD_TEMPORARY but for a required temporary.

While the phrase “required temporary” might sound like an oxymoron, it is not; rather, it simply refers to a named variable that must be specified when constructing a particular type of Factory-constructible object, but still a variable that can only be accessed from the Environment available in that class’ PostInit method. For example, the current definition of Sheep::RegisterInitializers has a variable named "age" that is a non-required temporary. As such, it need not be specified when constructing a Sheep:

s = Sheep(name("Sleepy")); // A currently legal Sheep spec.

If we changed the line in Sheep::RegisterInitializers from INFACT_ADD_TEMPORARY(int, age) to be INFACT_ADD_REQUIRED_TEMPORARY(int, age) then the above would cause an error:

// Sheep specs if age were a required temporary.
s = Sheep(name("Sleepy")); // illegal: age not specified
s = Sheep(name("Sleepy"), age(3)); // legal
See Also
infact::FactoryConstructible::PostInit

Definition at line 124 of file factory.h.

#define INFACT_ADD_TEMPORARY (   type,
  var 
)    initializers.Add(#var, static_cast<type *>(nullptr))

A macro to make it easier to register a temporary variable inside a RegisterInitializers implementation, for extraction from the Environment inside a PostInit implementation.

See Also
infact::FactoryConstructible::RegisterInitializers
infact::FactoryConstructible::PostInit

Definition at line 93 of file factory.h.

#define REGISTER_NAMED (   TYPE,
  NAME,
  BASE 
)
Value:
DEFINE_CONS_CLASS(TYPE,NAME,BASE) \
static const infact::Constructor<BASE> *NAME ## _my_protoype = \
infact::Factory<BASE>::Register(string(#NAME), new NAME ## Constructor());
An interface with a single virtual method that constructs a concrete instance of the abstract type T...
Definition: factory.h:531
#define DEFINE_CONS_CLASS(TYPE, NAME, BASE)
A macro to define a subclass of Constructor whose NewInstance method constructs an instance of TYPE...
Definition: factory.h:1030
static const Constructor< T > * Register(const string &type, const Constructor< T > *p)
The method used by the REGISTER_NAMED macro to ensure that subclasses add themselves to the factory...
Definition: factory.h:974

This macro registers the concrete subtype TYPE with the specified factory for instances of type BASE; the TYPE is associated with the specified NAME.

This macro—or a macro defined using this macro—should be used in the implementation file for a concrete subclass TYPE of the baseclass BASE. Often, TYPE and NAME may be the exact same string; however, they must be different when TYPE contains characters that may not appear in C++ identifiers, such as colons (e.g., when TYPE is the fully-qualified name of an inner class).

Definition at line 1044 of file factory.h.