113
Template Metaprogramming in C++ CS242, Fall 2009 Keith Schwarz

Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

  • Upload
    others

  • View
    10

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Template Metaprogramming in C++

CS242, Fall 2009Keith Schwarz

Page 2: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Preliminaries

Page 3: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

constants.

Page 4: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

Page 5: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

Page 6: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

Page 7: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

occurs at compile-time.

Page 8: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

One Two

PairOne Two

Pair

int charPair<int, char>

One Two

Pair

float longPair<float, long>

Page 9: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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.

Page 10: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

/* 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 };

Page 11: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

/* 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 };

Page 12: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

/* 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 };

Page 13: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

Page 14: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

A template metaprogram is a C++ program that uses templates to generate customized C++ code

at compile-time.

Page 15: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Why would you ever want to do this?

Page 16: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Machine Code

Assembly

C

C++

C++ TMP

Page 17: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Template Metaprogramming In Action

Part One: Policy Classes

Page 18: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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. ... */};

Page 19: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Vector

Type T

Range Checking

Synchronization

Page 20: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Templates are parameterized over types, not behaviors.

Page 21: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

Page 22: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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. ... */};

Page 23: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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. ... */};

Page 24: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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. ... */};

Page 25: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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!"); }};

Page 26: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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;};

Page 27: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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;};

Page 28: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

template <typename T, typename RangePolicy, typename LockingPolicy>T& Vector<T, RangePolicy, LockingPolicy>:: operator[] (size_t position){ LockingPolicy::Lock lock; ErrorPolicy::CheckBounds(position, this->size); return this->elems[position];}

Implementer Code

Page 29: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

template <typename T, typename RangePolicy, typename LockingPolicy>T& Vector<T, RangePolicy, LockingPolicy>:: operator[] (size_t position){ LockingPolicy::Lock lock; ErrorPolicy::CheckBounds(position, this->size); return this->elems[position];}

Implementer Code

Page 30: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

template <typename T, typename RangePolicy, typename LockingPolicy>T& Vector<T, RangePolicy, LockingPolicy>:: operator[] (size_t position){ LockingPolicy::Lock lock; RangePolicy::CheckRange(position, this->size); return this->elems[position];}

Implementer Code

Page 31: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Client Code

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

/* ... etc. ... */

return 0;}

Page 32: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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. ... */};

Page 33: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Updated Client Code

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

/* ... etc. ... */

return 0;}

Page 34: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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.

Page 35: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Template Metaprogramming In Action

Part Two: Traits Classes and Tag Dispatching

Page 36: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

template <typename IteratorType> void insert(iterator where, IteratorType start, IteratorType stop); /* ... */};

Page 37: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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);}

Page 38: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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);}

Page 39: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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; };

Page 40: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

Page 41: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Schematic of Traits Classes

Language Construct Metainformation

Traits Class

Page 42: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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; };

Page 43: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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; };

Page 44: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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 {};

Page 45: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

Page 46: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Tag dispatching is function overloading on tag classes.

Page 47: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

Page 48: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

Page 49: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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... */}

Page 50: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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... */}

Page 51: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Schematic of Tag Dispatching

Tag Dispatch

Implementation 1

Implementation 2

Implementation 3

Caller Code

Page 52: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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.

Page 53: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Template Metaprogramming In Action

Part Three: Typelists

Page 54: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

The Typelist

Page 55: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

Sample Typelist

Page 56: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

#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

Page 57: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Car/Cdr Recursion with Templates

template <typename> struct Length;

Page 58: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Car/Cdr Recursion with Templates

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

Page 59: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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; };

Page 60: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Length<LIST3(int, double, string)>

result

Length<LIST2(double, string)>

result

Length<LIST1(string)>

result

Length<LIST0()>

result

Page 61: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Length<LIST3(int, double, string)>

3result

Length<LIST2(double, string)>

2result

Length<LIST1(string)>

1result

Length<LIST0()>

0result

Page 62: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Typelists and template specialization allow us to write templates whose instantiation causes a

chain reaction of further instantiations.

Page 63: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

Page 64: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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&);};

Page 65: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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;}

Page 66: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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*)}

Page 67: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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. ... */

Page 68: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

Page 69: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Can we automatically generate a visitor for a type hierarchy?

Page 70: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Yes!

Page 71: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

type in the list.

Page 72: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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; };

Page 73: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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; };

Page 74: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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; };

Page 75: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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*)

Page 76: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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*)

Page 77: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Summary of Typelists● Construct types corresponding to LISP-style

lists whose elements are types.● Use template specialization to model car/cdr

recursion.

Page 78: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

The Limits of Template Metaprogramming

Page 79: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

Page 80: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Page 81: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

Page 82: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

XXX$q0

Page 83: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

XXX$q0

Page 84: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

XXX$q0

Page 85: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

XX$XXq0

Page 86: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

XX$XXq0

Page 87: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

X$XXXXq0

Page 88: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

$XXXXXXq0

Page 89: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

XXXXXXq1

Page 90: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

XXXXX$q1

Page 91: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

XXXX$$q1

Page 92: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

XXX$$$q1

Page 93: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

XX$$$$q1

Page 94: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

X$$$$$q1

Page 95: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

$$$$$$q1

Page 96: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

$$$$$q1

Page 97: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

$$$$q1

Page 98: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

$$$q1

Page 99: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

$$q1

Page 100: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

$q1

Page 101: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

q1

Page 102: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Queue Automaton Example

X $q0

q1

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

δ

Input: XXX

q1

ACCEPT

Page 103: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Can we simulate a queue automaton with a template metaprogram?

Page 104: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Yes!

Page 105: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

Page 106: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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{};

Page 107: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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. ...*/

Page 108: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Running the Queue Automatontemplate <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;};

Page 109: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Starting the Queue Automaton

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

typedef typename RunAutomaton<StartState, initialQueue>::result result;};

Page 110: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

A Turing machine can simulate C++ templates.

C++ templates can simulate queue automata.

Queue automata can simulate Turing machines.

C++ templates are Turing-complete.

Page 111: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

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

Page 112: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Applications of TMP● Compile-time dimensional analysis.● Multiple dispatch.● Optimized matrix operations.● Domain-specific parsers.● Compiler-enforced code annotations.● Optimized FFT.

Page 113: Template Metaprogramming in C++ - KeithSchwarz.comA C++ template is a type or function parameterized over a set of types, functions, or constants

Questions?