Template Metaprogramming in C++ CS242, Fall 2009 Keith Schwarz - - PowerPoint PPT Presentation

template metaprogramming in c
SMART_READER_LITE
LIVE PREVIEW

Template Metaprogramming in C++ CS242, Fall 2009 Keith Schwarz - - PowerPoint PPT Presentation

Template Metaprogramming in C++ CS242, Fall 2009 Keith Schwarz Preliminaries A C++ template is a type or function parameterized over a set of types, functions, or constants. template <typename One, typename Two> struct Pair { One


slide-1
SLIDE 1

Template Metaprogramming in C++

CS242, Fall 2009 Keith Schwarz

slide-2
SLIDE 2

Preliminaries

slide-3
SLIDE 3

A C++ template is a type or function parameterized over a set of types, functions, or constants.

slide-4
SLIDE 4

template <typename One, typename Two> struct Pair { One first; Two second; };

slide-5
SLIDE 5

template <typename One, typename Two> struct Pair { One first; Two second; };

slide-6
SLIDE 6

template <typename One, typename Two> struct Pair { One first; Two second; };

slide-7
SLIDE 7

Providing arguments to a template instantiates the template with those arguments. Instantiation

  • ccurs at compile-time.
slide-8
SLIDE 8

One Two

Pair

One Two

Pair

int char

Pair<int, char>

One Two

Pair

float long

Pair<float, long>

slide-9
SLIDE 9

Template Specialization

  • A version of a template to use when a specific

pattern of arguments are supplied.

  • Structure independent of primary template.
  • Can add/remove functions from interface, etc.
  • Full specialization used when all arguments are

specified.

  • Partial specialization used when arguments

have a particular structure.

slide-10
SLIDE 10

/* Primary template */ template <typename T> class Set { // Use a binary tree }; /* Full specialization */ template <> class Set<char> { // Use a bit vector }; /* Partial specialzation */ Template <typename T> class Set<T*> { // Use a hash table };

slide-11
SLIDE 11

/* Primary template */ template <typename T> class Set { // Use a binary tree }; /* Full specialization */ template <> class Set<char> { // Use a bit vector }; /* Partial specialzation */ template <typename T> class Set<T*> { // Use a hash table };

slide-12
SLIDE 12

/* Primary template */ template <typename T> class Set { // Use a binary tree }; /* Full specialization */ template <> class Set<char> { // Use a bit vector }; /* Partial specialzation */ template <typename T> class Set<T*> { // Use a hash table };

slide-13
SLIDE 13

A metaprogram is a program that produces or manipulates constructs of a target language.

slide-14
SLIDE 14

A template metaprogram is a C++ program that uses templates to generate customized C++ code at compile-time.

slide-15
SLIDE 15

Why would you ever want to do this?

slide-16
SLIDE 16

Machine Code Assembly C C++ C++ TMP

slide-17
SLIDE 17

Template Metaprogramming In Action Part One: Policy Classes

slide-18
SLIDE 18

template <typename T> class Vector { public: /* ... ctors, dtor, etc. */ T& operator[] (size_t); const T& operator[] (size_t) const; void insert(iterator where, const T& what); /* ... etc. ... */ };

slide-19
SLIDE 19

Vector

Type T Range Checking Synchronization

slide-20
SLIDE 20

Templates are parameterized over types, not behaviors.

slide-21
SLIDE 21

A policy class is a type that implements a particular behavior.

slide-22
SLIDE 22

template <typename T> class Vector { public: /* ... ctors, dtor, etc. */ T& operator[] (size_t); const T& operator[] (size_t) const; void insert(iterator where, const T& what); /* ... etc. ... */ };

slide-23
SLIDE 23

template <typename T, typename RangePolicy, typename LockingPolicy> class Vector { public: /* ... ctors, dtor, etc. */ T& operator[] (size_t); const T& operator[] (size_t) const; void insert(iterator where, const T& what); /* ... etc. ... */ };

slide-24
SLIDE 24

template <typename T, typename RangePolicy, typename LockingPolicy> class Vector: public RangePolicy, public LockingPolicy { public: /* ... ctors, dtor, etc. */ T& operator[] (size_t); const T& operator[] (size_t) const; void insert(iterator where, const T& what); /* ... etc. ... */ };

slide-25
SLIDE 25

Sample Range Policy

class ThrowingErrorPolicy { protected: ~ThrowingErrorPolicy() {} static void CheckRange(size_t pos, size_t numElems) { if(pos >= numElems) throw std::out_of_bounds("Bad!"); } };

slide-26
SLIDE 26

Another Sample Range Policy

class LoggingErrorPolicy { public: void setLogFile(const std::string&); protected: ~LoggingErrorPolicy(); void CheckRange(size_t pos, size_t numElems) { if(pos >= numElems && output != 0) *log << "Error!" << std::endl; } private: std::ofstream* log; };

slide-27
SLIDE 27

Another Sample Range Policy

class LoggingErrorPolicy { public: void setLogFile(const std::string&); protected: ~LoggingErrorPolicy(); void CheckRange(size_t pos, size_t numElems) { if(pos >= numElems && output != 0) *log << "Error!" << std::endl; } private: std::ofstream* log; };

slide-28
SLIDE 28

template <typename T, typename RangePolicy, typename LockingPolicy> T& Vector<T, RangePolicy, LockingPolicy>::

  • perator[] (size_t position)

{ LockingPolicy::Lock lock; ErrorPolicy::CheckBounds(position, this->size); return this->elems[position]; }

Implementer Code

slide-29
SLIDE 29

template <typename T, typename RangePolicy, typename LockingPolicy> T& Vector<T, RangePolicy, LockingPolicy>::

  • perator[] (size_t position)

{ LockingPolicy::Lock lock; ErrorPolicy::CheckBounds(position, this->size); return this->elems[position]; }

Implementer Code

slide-30
SLIDE 30

template <typename T, typename RangePolicy, typename LockingPolicy> T& Vector<T, RangePolicy, LockingPolicy>::

  • perator[] (size_t position)

{ LockingPolicy::Lock lock; RangePolicy::CheckRange(position, this->size); return this->elems[position]; }

Implementer Code

slide-31
SLIDE 31

Client Code

int main() { Vector<int, ThrowingErrorPolicy, NoLockingPolicy> v; for(size_t k = 0; k < kNumElems; ++k) v.push_back(k); /* ... etc. ... */ return 0; }

slide-32
SLIDE 32

template < typename T, typename RangePolicy = NoErrorPolicy, typename LockingPolicy = NoLockingPolicy> class Vector: public RangePolicy, public LockingPolicy { public: /* ... ctors, dtor, etc. */ T& operator[] (size_t); const T& operator[] (size_t) const; void insert(iterator where, const T& what); void erase(iterator where); /* ... etc. ... */ };

slide-33
SLIDE 33

Updated Client Code

int main() { Vector<int, ThrowingErrorPolicy> v; for(size_t k = 0; k < kNumElems; ++k) v.push_back(k); /* ... etc. ... */ return 0; }

slide-34
SLIDE 34

Summary of Policy Classes

  • Identify mutually orthogonal behaviors in a

class.

  • Specify an implicit interface for those

behaviors.

  • Parameterize a host class over each policy.
  • Use multiple inheritance to import the policies

into the host.

slide-35
SLIDE 35

Template Metaprogramming In Action Part Two: Traits Classes and Tag Dispatching

slide-36
SLIDE 36

template </* ... */> class Vector: /* ... */ { public: void insert(iterator where, const T& what); template <typename IteratorType> void insert(iterator where, IteratorType start, IteratorType stop); /* ... */ };

slide-37
SLIDE 37

template <...> template <typename Iter> void Vector<...>::insert(iterator where, Iter start, Iter stop) { /* Insert elements one at a time. */ for(; start != stop; ++start, ++where) where = insert(where, start); }

slide-38
SLIDE 38

template <...> template <typename Iter> void Vector<...>::insert(iterator where, Iter start, Iter stop) { /* Insert elements one at a time. */ for(; start != stop; ++start, ++where) where = insert(where, start); }

slide-39
SLIDE 39

template <typename Iter> struct iterator_traits { typedef typename Iter::difference_type difference_type; typedef typename Iter::value_type value_type; typedef typename Iter::pointer pointer; typedef typename Iter::reference reference; typedef typename Iter::iterator_category iterator_category; }; /* Specialization for raw pointers */ template <typename T> struct iterator_traits<T*> { typedef ptrdiff_t difference_type; typedef T value_type; typedef T* pointer; typedef T& reference; typedef random_access_iterator_tag iterator_category; };

slide-40
SLIDE 40

A traits class is a template type that exports information about its parameters.

slide-41
SLIDE 41

Schematic of Traits Classes

Language Construct Metainformation

Traits Class

slide-42
SLIDE 42

template <typename Iter> struct iterator_traits { typedef typename Iter::difference_type difference_type; typedef typename Iter::value_type value_type; typedef typename Iter::pointer pointer; typedef typename Iter::reference reference; typedef typename Iter::iterator_category iterator_category; }; /* Specialization for raw pointers */ template <typename T> struct iterator_traits<T*> { typedef ptrdiff_t difference_type; typedef T value_type; typedef T* pointer; typedef T& reference; typedef random_access_iterator_tag iterator_category; };

slide-43
SLIDE 43

template <typename Iter> struct iterator_traits { typedef typename Iter::difference_type difference_type; typedef typename Iter::value_type value_type; typedef typename Iter::pointer pointer; typedef typename Iter::reference reference; typedef typename Iter::iterator_category iterator_category; }; /* Specialization for raw pointers */ template <typename T> struct iterator_traits<T*> { typedef ptrdiff_t difference_type; typedef T value_type; typedef T* pointer; typedef T& reference; typedef random_access_iterator_tag iterator_category; };

slide-44
SLIDE 44

struct input_iterator_tag {}; struct output_iterator_tag {}; struct forward_iterator_tag : input_iterator_tag, output_iterator_tag {}; struct bidirectional_iterator_tag : forward_iterator_tag {}; struct random_access_iterator_tag : bidirectional_iterator_tag {};

slide-45
SLIDE 45

A tag class is a (usually empty) type encoding semantic information.

slide-46
SLIDE 46

Tag dispatching is function overloading on tag classes.

slide-47
SLIDE 47

template <...> template <typename Iter> void Vector<...>::insert(iterator where, Iter start, Iter stop) { doInsert(where, start, stop, typename std::iterator_traits<Iter>::iterator_category()); }

slide-48
SLIDE 48

template <...> template <typename Iter> void Vector<...>::insert(iterator where, Iter start, Iter stop) { doInsert(where, start, stop, typename std::iterator_traits<Iter>::iterator_category()); }

slide-49
SLIDE 49

template <...> template <typename Iter> void Vector<...>::doInsert(iterator where, Iter start, Iter stop, std::input_iterator_tag) { /* Insert elements one at a time. */ for(; start != stop; ++start, ++where) where = insert(where, start); } template <...> template <typename Iter> void Vector<...>::doInsert(iterator where, Iter start, Iter stop, std::forward_iterator_tag) { /* ... more complex logic to shift everything * down at the same time... */ }

slide-50
SLIDE 50

template <...> template <typename Iter> void Vector<...>::doInsert(iterator where, Iter start, Iter stop, std::input_iterator_tag) { /* Insert elements one at a time. */ for(; start != stop; ++start, ++where) where = insert(where, start); } template <...> template <typename Iter> void Vector<...>::doInsert(iterator where, Iter start, Iter stop, std::forward_iterator_tag) { /* ... more complex logic to shift everything * down at the same time... */ }

slide-51
SLIDE 51

Schematic of Tag Dispatching

Tag Dispatch

Implementation 1 Implementation 2 Implementation 3

Caller Code

slide-52
SLIDE 52

Summary of Tag Dispatching

  • Define a set of tag classes encoding semantic

information.

  • Provide a means for obtaining a tag from each

relevant type (often using traits classes)

  • Overload the relevant function by accepting

different tag types as parameters.

  • Call the overloaded function using the tag

associated with each type.

slide-53
SLIDE 53

Template Metaprogramming In Action Part Three: Typelists

slide-54
SLIDE 54

struct Nil {}; template <typename Car, typename Cdr> struct Cons {};

The Typelist

slide-55
SLIDE 55

Cons<int, Cons<double, Cons<char, Cons<float, Cons<short, Cons<long, Nil> > > > > >

Sample Typelist

slide-56
SLIDE 56

#define LIST0() Nil #define LIST1(a) Cons<a, LIST0()> #define LIST2(a, b) Cons<a, LIST1(b)> #define LIST3(a, b, c) Cons<a, LIST2(b, c)> #define LIST4(a, b, c, d) Cons<a, LIST3(b, c, d)> /* ... etc. ... */ LIST6(int, double, float, char, short, long)

A Simplification

slide-57
SLIDE 57

Car/Cdr Recursion with Templates

template <typename> struct Length;

slide-58
SLIDE 58

Car/Cdr Recursion with Templates

template <typename> struct Length; template <> struct Length<Nil> { static const size_t result = 0; };

slide-59
SLIDE 59

Car/Cdr Recursion with Templates

template <typename> struct Length; template <> struct Length<Nil> { static const size_t result = 0; }; template <typename Car, typename Cdr> struct Length<Cons<Car, Cdr> > { static const size_t result = 1 + Length<Cdr>::result; };

slide-60
SLIDE 60

Length<LIST3(int, double, string)>

result

Length<LIST2(double, string)>

result

Length<LIST1(string)>

result

Length<LIST0()>

result

slide-61
SLIDE 61

Length<LIST3(int, double, string)> 3

result

Length<LIST2(double, string)> 2

result

Length<LIST1(string)> 1

result

Length<LIST0()>

result

slide-62
SLIDE 62

Typelists and template specialization allow us to write templates whose instantiation causes a chain reaction of further instantiations.

slide-63
SLIDE 63

This lets us construct arbitrarily complicated structures at compile-time.

slide-64
SLIDE 64

class ExprVisitor; class ExprNode { public: virtual void accept(ExprVisitor&); }; class AddExpr: public ExprNode { public: virtual void accept(ExprVisitor&); }; class MulExpr: public ExprNode { public: virtual void accept(ExprVisitor&); }; class SubExpr: public ExprNode { public: virtual void accept(ExprVisitor&); }; class DivExpr: public ExprNode { public: virtual void accept(ExprVisitor&); };

slide-65
SLIDE 65

class ExprVisitor { public: virtual void visit(ExprNode*) = 0; virtual void visit(AddExpr*) = 0; virtual void visit(MulExpr*) = 0; virtual void visit(SubExpr*) = 0; virtual void visit(DivExpr*) = 0; }

slide-66
SLIDE 66

void ExprNode::accept(ExprVisitor& v) { v.visit(this); // Calls ExprVisitor::Visit(ExprNode*) } void AddExpr::accept(ExprVisitor& v) { v.visit(this); // Calls ExprVisitor::Visit(AddExpr*) } void MulExpr::accept(ExprVisitor& v) { v.visit(this); // Calls ExprVisitor::Visit(MulExpr*) } void DivExpr::accept(ExprVisitor& v) { v.visit(this); // Calls ExprVisitor::Visit(DivExpr*) } void SubExpr::accept(ExprVisitor& v) { v.visit(this); // Calls ExprVisitor::Visit(SubExpr*) }

slide-67
SLIDE 67

class FSVisitor; class FileSystemEntity { public: virtual void accept(FSVisitor&); }; class File: public FileSystemEntity { public: virtual void accept(FSVisitor&); }; class Directory: public FileSystemEntity { public: virtual void accept(FSVisitor&); }; /* ... etc. ... */

slide-68
SLIDE 68

class FSVisitor { public: virtual void visit(FileSystemEntity*) = 0; virtual void visit(File*) = 0; virtual void visit(Directory*) = 0; /* ... etc. ... */ }

slide-69
SLIDE 69

Can we automatically generate a visitor for a type hierarchy?

slide-70
SLIDE 70

Yes!

slide-71
SLIDE 71

Idea: Create a type parameterized over a typelist that has one instance of visit for each type in the list.

slide-72
SLIDE 72

template <typename List> class Visitor; template <typename T> class Visitor<Cons<T, Nil> > { public: virtual void visit(T*) = 0; }; template <typename T, typename Cdr> class Visitor<Cons<T, Cdr> > : public Visitor<Cdr> { public: virtual void visit(T*) = 0; using Visitor<Cdr>::visit; };

slide-73
SLIDE 73

template <typename List> class Visitor; template <typename T> class Visitor<LIST1(T) > { public: virtual ~Visitor() {} virtual void visit(T*) = 0; }; template <typename T, typename Cdr> class Visitor<Cons<T, Cdr> > : public Visitor<Cdr> { public: virtual void visit(T*) = 0; using Visitor<Cdr>::visit; };

slide-74
SLIDE 74

template <typename List> class Visitor; template <typename T> class Visitor<LIST1(T) > { public: virtual ~Visitor() {} virtual void visit(T*) = 0; }; template <typename Car, typename Cdr> class Visitor<Cons<Car, Cdr> > : public Visitor<Cdr> { public: virtual void visit(Car*) = 0; using Visitor<Cdr>::visit; };

slide-75
SLIDE 75

Visitor<LIST5(AddExpr, MulExpr, SubExpr, DivExpr, ExprNode)> virtual void visit(AddExpr*) Visitor<LIST4(MulExpr, SubExpr, DivExpr, ExprNode)> virtual void visit(MulExpr*) Visitor<LIST3(SubExpr, DivExpr, ExprNode)> virtual void visit(SubExpr*) Visitor<LIST2(DivExpr, ExprNode)> virtual void visit(DivExpr*) Visitor<LIST1(ExprNode)> virtual void visit(ExprNode*)

slide-76
SLIDE 76

Visitor<LIST5(AddExpr, MulExpr, SubExpr, DivExpr, ExprNode)> virtual void visit(AddExpr*) virtual void visit(MulExpr*) virtual void visit(SubExpr*) virtual void visit(DivExpr*) virtual void visit(ExprNode*)

slide-77
SLIDE 77

Summary of Typelists

  • Construct types corresponding to LISP-style

lists whose elements are types.

  • Use template specialization to model car/cdr

recursion.

slide-78
SLIDE 78

The Limits of Template Metaprogramming

slide-79
SLIDE 79

Queue Automaton

  • A queue automaton is a finite-state machine

equipped with a queue.

  • Contrast to PDA with a stack.
  • Tuple (Q, Σ, Γ, $, q0, δ) where
  • Q is a set of states
  • Σ is the input alphabet
  • Γ is the tape alphabet
  • $ ∈ Γ – Σ is the start symbol
  • q0 ∈ Q is the start state
  • δ ∈ Q x Γ → Q x Γ* is the transition function

Source: http://en.wikipedia.org/wiki/Queue_machine

slide-80
SLIDE 80

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ

slide-81
SLIDE 81

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

slide-82
SLIDE 82

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

XXX$ q0

slide-83
SLIDE 83

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

XXX$ q0

slide-84
SLIDE 84

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

XXX$ q0

slide-85
SLIDE 85

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

XX$XX q0

slide-86
SLIDE 86

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

XX$XX q0

slide-87
SLIDE 87

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

X$XXXX q0

slide-88
SLIDE 88

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

$XXXXXX q0

slide-89
SLIDE 89

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

XXXXXX q1

slide-90
SLIDE 90

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

XXXXX$ q1

slide-91
SLIDE 91

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

XXXX$$ q1

slide-92
SLIDE 92

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

XXX$$$ q1

slide-93
SLIDE 93

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

XX$$$$ q1

slide-94
SLIDE 94

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

X$$$$$ q1

slide-95
SLIDE 95

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

$$$$$$ q1

slide-96
SLIDE 96

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

$$$$$ q1

slide-97
SLIDE 97

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

$$$$ q1

slide-98
SLIDE 98

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

$$$ q1

slide-99
SLIDE 99

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

$$ q1

slide-100
SLIDE 100

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

$ q1

slide-101
SLIDE 101

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

q1

slide-102
SLIDE 102

Queue Automaton Example

X $ q0 q1

q0, XX q1, ε q1, $ q1, ε

δ Input: XXX

q1

ACCEPT

slide-103
SLIDE 103

Can we simulate a queue automaton with a template metaprogram?

slide-104
SLIDE 104

Yes!

slide-105
SLIDE 105

template <typename, typename> struct Concat; template <typename T> struct Concat<Nil, T> { typedef T result; }; template <typename Car, typename Cdr, typename T> struct Concat<Cons<Car, Cdr>, T> { typedef Cons<Car, typename Concat<Cdr, T>::result> result; };

Concatenating Two Typelists

slide-106
SLIDE 106

Encoding Q, Σ, Γ, $, q0

/* Define a tag type for each state in Q */ struct State1 {}; struct State2 {}; ... struct StateN {}; /* Define a tag type for each symbol in Σ ∪ Γ */ struct Symbol1 {}; struct Symbol2 {}; ... struct SymbolN {}; /* Designate q0 and $. */ struct StartState {}; struct StartSymbol{};

slide-107
SLIDE 107

Encoding the Transition Table δ

template <typename, typename> struct Delta; /* Specialize Delta for each entry in δ */ template <> struct Delta<State1, Symbol1> { typedef State2 nextState; typedef LIST2(Symbol1, Symbol1) nextSymbols; }; template <> struct Delta<State1, Symbol2> { typedef State1 nextState; typedef LIST0() nextSymbols; }; /* ... etc. ...*/

slide-108
SLIDE 108

Running the Queue Automaton

template <typename State, typename Queue> struct RunAutomaton; template <typename State> struct RunAutomaton<State, Nil> { typedef void result; }; template <typename Car, typename Cdr, typename State> struct RunAutomaton<State, Cons<Car, Cdr> > { typedef typename Delta<State, Car>::nextState newState; typedef typename Delta<State, Car>::nextSymbols newSym; typedef typename Concat<Cdr, newSym>::result newQueue; typedef typename RunAutomaton<newState, newQueue>::result result; };

slide-109
SLIDE 109

Starting the Queue Automaton

template <typename T> struct SimulateQueueAutomaton { typedef typename Concat<T, LIST1(StartSymbol)>::result initialQueue; typedef typename RunAutomaton<StartState, initialQueue>::result result; };

slide-110
SLIDE 110

A Turing machine can simulate C++ templates. C++ templates can simulate queue automata. Queue automata can simulate Turing machines. C++ templates are Turing-complete.

slide-111
SLIDE 111

In other words, the C++ type system has the same computational capabilities as C++.

slide-112
SLIDE 112

Applications of TMP

  • Compile-time dimensional analysis.
  • Multiple dispatch.
  • Optimized matrix operations.
  • Domain-specific parsers.
  • Compiler-enforced code annotations.
  • Optimized FFT.
slide-113
SLIDE 113

Questions?