LILAC
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Classes | Public Types | Static Public Member Functions | List of all members
type_constructor< Tin > Class Template Reference

Class for constructing statically-typed classes when type is determined at runtime. More...

#include <type_constructor.hpp>

Classes

class  _ttype
 This is an internal polymorphic base class. It returns a pointer of type tout. More...
class  ttype
 This is the actual creator class. It creates a pointer of Tin with the template parameter Tval. More...

Public Types

typedef typelist< comp, double,
float, example_type
std_type_list

Static Public Member Functions

template<class Tout , class = typename std::enable_if<std::is_base_of<vartype, Tout>::value >::type>
static void create (std::shared_ptr< Tout > *in, const vartype *tval)
 Creates a Tout* pointing to a Tin<type>*, where type is the type of the vartype tval.
template<class Tl , class Tout , class = typename std::enable_if<std::is_base_of<vartype, Tout>::value >::type, class = typename std::enable_if<std::is_base_of<blacklist_checker, Tl>::value >::type>
static void create (std::shared_ptr< Tout > *in, const vartype *tval)
template<class Tout >
static std::shared_ptr< Tout > create (const vartype *tval)
 Version of create that requires more template parameters, but directly returns a value.
template<class Tl , class Tout >
static std::shared_ptr< Tout > create (const vartype *tval, const Tl blist)
 shortened version of blacklist function

Detailed Description

template<template< class > class Tin>
class type_constructor< Tin >

Class for constructing statically-typed classes when type is determined at runtime.

This engine faces two issues-the numerical type (complex, double, float) is decided at runtime. This problem is fairly simple to solve with runtime polymorphism-a base numerical class that makes virtual calls out to add, multiply, etc functions

However, all of the functions need to be instantiated at compile time, to ensure optimal performance. A solution based on runtime polymorphism would be unacceptably slow, probably by orders of magnitude

To get past this, a type-independent class can hold a pointer to a template class, where this class is selected at runtime. This hides the type-dependent functionality from the rest of the program.

There is still one problem, which is instantiating this template class. Currently, this can just be with a series of if statements:

if(type == complex){
return new template_class<complex>
}
else if(type == double){
return new template_class<double>
}
else if(type == float)...

This works, but has two big problems. We must statically list the types that can be transformed to in every location where this occurs. This is a headache, and prone to different lists in various places of code. Imagine creating a new type, and having to trawl the entire codebase editing this list

However, we can create a type constructor. This means that it takes a concrete type at runtime, such as complex, double, etc and returns a new concrete type such as a rk45 integrator of type complex, or double.

With templates, we can implement that in C++ as well, and as a bonus for arbitrary template and base classes as long as they inherit from one another, and as long as they inherit from vartype.

For example, say you want to initiate an rk45 integrator to the same type as an rhs functions.

You have a base class rk45, which represents the family of rk45 integrators and is the polymorphic base class

You also have a template class rk45_tmpl<T>, which is a template class inheriting from rk45 and actually implementing the integrator routines for type T.

Your function also has access to the right hand side being integrated, but only knows about the type information at runtime. Say that the type of ths rhs is T. To get a pointer to an rk45_tmpl<T> at runtime (in the form of an rk45*), you only have to make a single function call.

You can do either:

rk45* integ, *integ2;
rhs* some_typed_rhs; //in real code will have been instantiated
type_constructor<rk45_tmpl>::create(&integ, some_typed_rhs);
//or
integ2 = type_constructor<rk45_tmpl>::create<rk45>(some_typed_rhs);

You can also pass your own non-standard list of types to check, allowing for specialized routines that don't need to operate on the standard numerical types

Parameters
Tinthe template class that is being instaniated

Definition at line 161 of file type_constructor.hpp.

Member Typedef Documentation

template<template< class > class Tin>
typedef typelist<comp, double, float, example_type> type_constructor< Tin >::std_type_list

This defines the standard allowed types. Simply add your own type to the list if it plays nicely with all the standard integrators. This means that it supports basic arithmetic operations with itself and doubles, and has an abs function (absolute value) definied in the global namespace

Definition at line 187 of file type_constructor.hpp.

Member Function Documentation

template<template< class > class Tin>
template<class Tout , class = typename std::enable_if<std::is_base_of<vartype, Tout>::value >::type>
static void type_constructor< Tin >::create ( std::shared_ptr< Tout > *  in,
const vartype tval 
)
inlinestatic

Creates a Tout* pointing to a Tin<type>*, where type is the type of the vartype tval.

This function is the core of the type constructor. If the type of the parameter tval is type, then it returns a Tin<type>* casted up to a Tout. Notice that all instances of Tin must be able to be casted up to a Tout. This is also only useful if the needed functionality is polymorphic.

This version of the function is nice because it doesn't require that the user specify a second template parameter, namely the Tout parameter.

Supported types are currently: comp, double, long double, and float. To add your own, simply add another type to the typedef std_type_list. To prevent a type from being created, pass a blacklist

Definition at line 206 of file type_constructor.hpp.

Here is the call graph for this function:

template<template< class > class Tin>
template<class Tl , class Tout , class = typename std::enable_if<std::is_base_of<vartype, Tout>::value >::type, class = typename std::enable_if<std::is_base_of<blacklist_checker, Tl>::value >::type>
static void type_constructor< Tin >::create ( std::shared_ptr< Tout > *  in,
const vartype tval 
)
inlinestatic

Definition at line 216 of file type_constructor.hpp.

Here is the call graph for this function:

template<template< class > class Tin>
template<class Tout >
static std::shared_ptr<Tout> type_constructor< Tin >::create ( const vartype tval)
inlinestatic

Version of create that requires more template parameters, but directly returns a value.

Definition at line 233 of file type_constructor.hpp.

template<template< class > class Tin>
template<class Tl , class Tout >
static std::shared_ptr<Tout> type_constructor< Tin >::create ( const vartype tval,
const Tl  blist 
)
inlinestatic

shortened version of blacklist function

Definition at line 240 of file type_constructor.hpp.


The documentation for this class was generated from the following file: