LDMX Software
Factory.h File Reference

Header holding Factory class and supporting macros. More...

#include <algorithm>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <unordered_map>
#include <vector>
#include "Framework/Exception/Exception.h"

Go to the source code of this file.

Classes

class  framework::Factory< Prototype, PrototypePtr, PrototypeConstructorArgs >
 Factory to dynamically create objects derived from a specific prototype class. More...
 
class  framework::FactoryWithWarehouse< Prototype, PrototypePtr, PrototypeConstructorArgs >
 A Factory with a warehouse to hold created objects. More...
 

Namespaces

namespace  framework
 All classes in the ldmx-sw project use this namespace.
 

Macros

#define DECLARE_FACTORY(...)
 This macro is used in the public portion of your prototype class declaration.
 
#define DECLARE_FACTORY_WITH_WAREHOUSE(...)
 This macro is used in the public portion of your prototype class declaration.
 
#define DEFINE_FACTORY(classtype)
 This should go into an implementation file for your prototype class.
 
#define _CONCAT_INTERNAL(a, b)
 Concatenate two pieces of text into one.
 
#define _CONCAT(a, b)
 Concatenate two pieces of text into one with indirection.
 
#define UNIQUE(a)
 Add a number suffix to the input variable name so that it is unique.
 
#define FACTORY_REGISTRATION(prototype, derived)
 Register a new class with a specific factory.
 

Detailed Description

Header holding Factory class and supporting macros.

Definition in file Factory.h.

Macro Definition Documentation

◆ _CONCAT

#define _CONCAT ( a,
b )
Value:
#define _CONCAT_INTERNAL(a, b)
Concatenate two pieces of text into one.
Definition Factory.h:425

Concatenate two pieces of text into one with indirection.

We use the __COUNTER__ macro to uniquely define variable names within a translation unit (file) but we need to pass __COUNTER__ through a macro argument in order to have it resolved into a number.

Definition at line 435 of file Factory.h.

◆ _CONCAT_INTERNAL

#define _CONCAT_INTERNAL ( a,
b )
Value:
a##b

Concatenate two pieces of text into one.

We use the __COUNTER__ macro to uniquely define variable names within a translation unit (file) but we need to pass __COUNTER__ through a macro argument in order to have it resolved into a number.

Definition at line 425 of file Factory.h.

◆ DECLARE_FACTORY

#define DECLARE_FACTORY ( ...)
Value:
struct Factory : public ::framework::Factory<__VA_ARGS__> { \
static Factory& get(); \
}
Factory to dynamically create objects derived from a specific prototype class.
Definition Factory.h:181

This macro is used in the public portion of your prototype class declaration.

public:
DECLARE_FACTORY(MyProto, std::shared_ptr<MyProto>);
#define DECLARE_FACTORY(...)
This macro is used in the public portion of your prototype class declaration.
Definition Factory.h:377

The arguments to this macro are the template arguments to the framework::Factory class and should at minimum define the base class the Factory will construct for and the type of pointer the Factory should return.

Definition at line 377 of file Factory.h.

377#define DECLARE_FACTORY(...) \
378 struct Factory : public ::framework::Factory<__VA_ARGS__> { \
379 static Factory& get(); \
380 }

◆ DECLARE_FACTORY_WITH_WAREHOUSE

#define DECLARE_FACTORY_WITH_WAREHOUSE ( ...)
Value:
struct Factory : public ::framework::FactoryWithWarehouse<__VA_ARGS__> { \
static Factory& get(); \
}
A Factory with a warehouse to hold created objects.
Definition Factory.h:300

This macro is used in the public portion of your prototype class declaration.

public:
DECLARE_FACTORY_WITH_WAREHOUSE(MyProto, std::shared_ptr<MyProto>);
#define DECLARE_FACTORY_WITH_WAREHOUSE(...)
This macro is used in the public portion of your prototype class declaration.
Definition Factory.h:395

The arguments to this macro are the template arguments to the framework::Factory class and should at minimum define the base class the Factory will construct for and the type of pointer the Factory should return.

Definition at line 395 of file Factory.h.

395#define DECLARE_FACTORY_WITH_WAREHOUSE(...) \
396 struct Factory : public ::framework::FactoryWithWarehouse<__VA_ARGS__> { \
397 static Factory& get(); \
398 }

◆ DEFINE_FACTORY

#define DEFINE_FACTORY ( classtype)
Value:
classtype::Factory& classtype::Factory::get() { \
static classtype::Factory the_factory; \
return the_factory; \
}

This should go into an implementation file for your prototype class.

DEFINE_FACTORY(MyProto);
#define DEFINE_FACTORY(classtype)
This should go into an implementation file for your prototype class.
Definition Factory.h:411

We need this to be separate from the declaration so that there is a unique single factory for the class across any of the C++ libraries that may use it.

Definition at line 411 of file Factory.h.

411#define DEFINE_FACTORY(classtype) \
412 classtype::Factory& classtype::Factory::get() { \
413 static classtype::Factory the_factory; \
414 return the_factory; \
415 }

◆ FACTORY_REGISTRATION

#define FACTORY_REGISTRATION ( prototype,
derived )
Value:
namespace { \
auto UNIQUE(v) = ::prototype::Factory::get().declare<::derived>(#derived); \
}
#define UNIQUE(a)
Add a number suffix to the input variable name so that it is unique.
Definition Factory.h:444

Register a new class with a specific factory.

This macro should be used where the derived class is defined. This macro avoids typing all this out and making sure that the string passed as an argument to framework::Factory::declare is the same characters as the actual class. If you want the name for a specific object to not be the full-specified class name, then you need to write the contents of this macro yourself.

Using an unnamed namespace defines the variables inside it as having internal linkage and as implicitly static. Having internal linkage allows us to have repeat variable names across different source files. Being static means that the variable is guaranteed to be constructed during library load time. The details of how this is handled is documented in Storage Class Specifiers.

Parameters
[in]prototypefully-specified base class
[in]derivedfully-specified derived class

Definition at line 469 of file Factory.h.

469#define FACTORY_REGISTRATION(prototype, derived) \
470 namespace { \
471 auto UNIQUE(v) = ::prototype::Factory::get().declare<::derived>(#derived); \
472 }

◆ UNIQUE

#define UNIQUE ( a)
Value:
_CONCAT(a, __COUNTER__)
#define _CONCAT(a, b)
Concatenate two pieces of text into one with indirection.
Definition Factory.h:435

Add a number suffix to the input variable name so that it is unique.

We use the __COUNTER__ macro which counts up from 0 everytime it is called so these variables can be unique within a specific translation unit.

Definition at line 444 of file Factory.h.