Top Banner
C++ Template Metaprogramming Practical Approach code::dive 2016 Szymon Gutaj
54

Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

Jun 21, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

C++ Template MetaprogrammingPractical Approach

code::dive 2016Szymon Gutaj

Page 2: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach2

In brief

● Introduction● Metaprogramming techniques● Questions / Discussion

Page 3: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach3

Introduction

Page 4: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach4

(My Humble) Definition

Shifting complexity from the user/client sideto the library/compiler side

Augmenting the compiler

Page 5: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach5

Aims

● Correctness (reducing human factor)– By generating code according to (tested) rules– By introspecting and checking code at compile time– By creating libraries smarter than their user– By avoiding repetition

Page 6: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach6

Aims

● Performance (self-optimisation)– By performing things at compile time– By generating fine-tuned code in particular situation– By performing optimisations cumbersome to handcraf

Page 7: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach7

Aims

● Portability (self-adaptability)– By automatically adapting to current hardware– By intelligently picking optimal code blocks– By keeping all code in the C++ realm

Page 8: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach8

Aims

● Expressive interfaces– By automatically deducing details for the user– By creating domain-specific languages

Page 9: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach9

Consequences (wink)

● You'll keep your job forever, having written metaprogrammed code(if your colleagues like you)

● You'll be happy to have trained karate for 15 years(if they don't like you)

● Nothing will happen (are you sure, that anyone has seen your commit?)

Page 10: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach10

Consequences

● Development time of your (metaprogrammed) librarydepends on skill and tools used

● Maintenance of your library requires some skill● Your user code becomes higher level● Your user code becomes smaller and more declarative● Changes to your library (bugfixes and new features)

propagate to all places of usage

Page 11: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach11

Approaches

● Handcrafted● With aid of C++ Standard Library (type_traits)● With aid of Boost (Boost Metaprogramming Library, Boost Hana)● With aid of higher level, domain-specific libraries

Page 12: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach12

How it works

● C++ Metaprogramming is purely functional● Mutation is replaced with copying (with changes applied)● Iteration is replaced with recursion● Computational complexity of a metaprogram is measured with the

amount of template instantiations (copies)

Page 13: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach13

Golden rules

● Keep your code orthogonal● Keep your conventions consistent● Solve things by adding one more level of indirection

Page 14: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach14

Handcrafed metaprogrammingBasics and conventions

Page 15: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach15

Disclaimer

Our examples are meant to be fun, easy and demonstrational

Page 16: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach16

Hello world!

1 // This is our metaprogram (actually quite useful!)2 template<typename T>3 struct return_as_is4 {5 typedef T type;6 };7 8 // This is our processed data9 class HelloWorld10 {11 };12 13 // What is the type of ‘helloWorld’? Yes, it’s HelloWorld!!!14 return_as_is<HelloWorld>::type helloWorld;

Page 17: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach17

Operating on types

● Template name is the operation name● Template parameters are the arguments● Nested definition named “type” is the result● The “struct” keyword is used to keep the syntax clean● We've just described a metafunction!

Page 18: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach18

Operating on types

1 // Adds a pointer to given type2 template<typename T>3 struct add_pointer4 {5 typedef T * type;6 };7 8 // ‘pointerToInt’ is of type ‘int *’9 add_pointer<int>::type pointerToInt {nullptr};

Page 19: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach19

Operating on values

● Template name is the operation name● Template parameters are the arguments● Nested member named “value” is the result● Nested member is static const / constepxr

Page 20: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach20

Operating on values

1 // Increments given value by one2 template<int V>3 struct increment4 {5 static constexpr int value = V + 1;6 };7 8 // Variable ‘four’ equals 49 // ‘3 + 1’ happened during compilation10 int four = increment<3>::value;

Page 21: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach21

Operating on values

1 // Wraps an integer in a type2 template<3 typename T,4 T Value5 >6 struct integral_constant 7 {8 typedef integral_constant type;9 10 static constexpr T value = Value;11 };12 13 // Dressing values as types can be useful14 typedef integral_constant<int, 1> one;15 typedef integral_constant<int, 2> two;

Page 22: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach22

Simple processing

● Pattern matching is used for “flow control”● Patterns are defined with partial template spacialisations

Page 23: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach23

Simple processing1  template< // Primary template: “true” case2      bool Condition,3      typename TrueType,4      typename FalseType5  >6  struct if_7  {8      typedef TrueType type; // TrueType is the result9  };10  11 template< // Partially specialised: “false” case12     typename TrueType,13     typename FalseType14 >15 struct if_<false, TrueType, FalseType>16 {17     typedef FalseType type; // FalseType is the result18 };

Page 24: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach24

Simple processing#include <cstdint> // For INT8_MAX, int8_t and int_least16_t

#include "wild_wild_world/constants.h" // SOME_CONSTANT comes from here

typedef if_<    (SOME_CONSTANT < INT8_MAX),    int8_t,    int_least16_t>::type smallest_type;

// ‘myConstant’ has the smallest type, that fits the valuesmallest_type myConstant = SOME_CONSTANT;

Page 25: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach25

Simple processing

1  #include "configuration.h" // For WANT_SPEED2  #include "algorithm_speedy.h" // For algorithm_speedy3  #include "algorithm_tiny.h" // For algorithm_tiny4  5  typedef if_<6      WANT_SPEED,7      algorithm_speedy,8      algorithm_tiny9  >::type algorithm;10  11 algorithm a;12 13 a.run(); // Runs the selected algorithm

Page 26: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach26

Simple recursion

● Pattern matching with a “terminal case” allow for recursion● Patterns are defined with partial template spacialisations

Page 27: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach27

Simple recursion1  template<typename T>2  struct rank // Terminal case: T is not a table anymore3  {4      static constexpr int value = 0;5  };6  template<typename T, int N>7  struct rank<T[N]> // Case: T is a table8  {9      static constexpr int value = rank<T>::value + 1;10 };11 template<typename T>12 struct rank<T[]> // Case: T is a table (of unknown size)13 {14     static constexpr int value = rank<T>::value + 1;15 };16 auto rank0 = rank<std::string>::value; // Equals 017 auto rank1 = rank<int[2][4]>::value;   // Equals 218 auto rank2 = rank<int[4][3][]>::value; // Equals 3

Page 28: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach28

Metafunction forwarding

● Inheritance is a neat way to compose metaprograms● Code and conventions are automatically propagated

Page 29: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach29

Metafunction forwarding

1  // ‘false_type’ is an alias for ‘bool’ equal ‘false’2  struct false_type :3      integral_constant<4          bool,5          false,6      > {};7  8  // ‘true_type’ is an alias for ‘bool’ equal ‘true’9  struct true_type :10     integral_constant<11         bool,12         true,13     > {};

Page 30: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach30

Metafunction forwarding

1  template<typename T>2  struct is_byte_sized :3      if_<4          (sizeof(T) == 1),5          true_type,6          false_type7      > {};8  9  bool byteSized = is_byte_sized<char>::value; // true1011 bool notByteSized = is_byte_sized<int>::value; // false

Page 31: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach31

Lazy evaluation

● Lazy evaluation gives more flexibility● Invalid, but unneeded branches of code still compile● Lazy evaluation leads to faster code● Stay lazy, whenever you can

Page 32: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach32

Lazy evaluation

1  // Eager!!!2  template<typename T>3  struct my_favourite :4      if_<5          is_good_enough<T>::value,6          take_it<T>::type, // 'take_it' always evaluated7          fix_it<T>::type // 'fix_it' always evaluated8      > {};9  10 // Lazy...11 template<typename T>12 struct my_favourite :13     if_<14         is_good_enough<T>::value,15         take_it<T>, // 'take_it' evaluated for ‘true’16         fix_it<T> // 'fix_it' evaluated for ‘false’17     >::type {};

Page 33: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach33

Toolset

● Compile-time operators are the low-level means for code introspection– sizeof, decltype, alignof, ternary operator, template template parameters, ...

● Language rules are your worst enemy and best friend– resolution/conversion rules, SFINAE, variadic templates, ...

Page 34: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach34

Toolset

1  struct NeighbourRomek // A well behaved guy2  {3      void howdy();4  };5  6  struct ManInBlack // Well, who knows...7  {8  };9  10 // Let’s check contents of some types11 bool doesnt = has_howdy<int>::value; // false12  13 bool does = has_howdy<NeighbourRomek>::value; // true14  15 bool afraidToCheck = has_howdy<ManInBlack>::value; // ?!

Page 35: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach35

Toolset

1  template<typename T, void(T::*)() = &T::howdy>2  char hasHowdy(int); // Helper: SFINAE sensitive3  4  template<typename T>5  long hasHowdy(...); // Helper: less sensitive6  7  // Returns ‘true’ if ‘T’ has a member function ‘howdy’8  template<typename T>9  struct has_howdy :10     integral_constant<11         bool,12         sizeof(char) == sizeof(hasHowdy<T>(0))13     > {};

Page 36: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach36

Toolset

1  template<typename T> // Helper: matches a pointer 2  true_type hasHowdy(decltype(&T::howdy));3  4  template<typename T>5  false_type hasHowdy(...); // Helper: matches everything6  7  // Returns ‘true’ if ‘T’ has a member function ‘howdy’8  template<typename T>9  struct has_howdy :10     decltype(hasHowdy<T>(nullptr))11 {};

Page 37: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach37

Homework

● Metafunction classes (first step to passing metafunctions around)● Higher order metafunctions (composed metafunctions)● Tag based dispatch (adding a second level of abstraction)● Variadic template parameter pack access (very useful)

Page 38: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach38

Asertive code

● Assertive code makes error messages better● Assertive code prevents abuse of your metaprogram● Use “static_assert”● Use “std::is_same” or alike● Wait for a standardised C++ feature: concepts!

Page 39: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach39

Testing

● Can be done in a regular cpp file● Compile that file with your code for early testing

Page 40: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach40

Testing

1  #include <type_traits>2  #include "pass_optimally.h" // Code under test34  static_assert( // Test case 15      std::is_same< // More on ‘std::is_same’ in a minute6          pass_optimally<VeryBigClass>::type,7          VeryBigClass const &8      >::value,9      "Expected passing large arguments by reference"10 );11 static_assert( // Test case 212     std::is_same<13         pass_optimally<int>::type,14         int15     >::value,16     "Expected passing small arguments by value"17 );

Page 41: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach41

Asertive code

1  template<class Agent, class Handler, class ...Args>2  void Base::call(Handler Agent::*handler, Args&&... args)3  {4      static_assert( // Check if calculated ‘handler’ and ‘args’ match5          std::is_constructible< // More on this in a second6              void(Agent::*)(Args...),7              decltype(handler)8          >::value,9          "Calling with bad arguments."10         "Args need to match the signature of Handler"11     );12     call(std::bind( // If assertion passed, make the call13         handler,14         static_cast<Agent * const>(this),15         std::forward<Args>(args)...)16     );17 }

Page 42: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach42

Standard Template Librarytype_traits

Page 43: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach43

Features

● Basic type instrospection:– is_integral, is_pointer, is_function, is_class, ...– is_same, is_base_of, is_move_constructible, is_convertible,

has_virtual_destructor, ...● Basic type processing:

– add_cv, remove_reference, make_signed, ...● Basic metaprogramming facilities:

– conditional, integral_constant, enable_if, result_of, ...

Page 44: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach44

Example – type_traits

1  #include <type_traits>2  // Return ‘as is’ for unsigned types3  template<typename T>4  typename std::enable_if<5      std::is_unsigned<T>::value, // The condition6      T                           // The return type7  >::type alwaysPositive(T t) { return t; }8  9  // Return absolute and unsigned10 template<typename T> 11 typename std::enable_if<12     !std::is_unsigned<T>::value, // The condition13     typename std::make_unsigned<T>::type // The return type14 >::type alwaysPositive(T t)15 {16    return (t < 0) ? ­t : t;17 }

Page 45: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach45

Boost Metaprogramming LibraryBoost MPL

Page 46: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach46

Features

● Mimicks C++ STL features at compile time● Containers and views:

– vector, list, map, set, string, ...● Algorithms:

– fold, transform, sort, copy, find, count, partition, ...● Functional processing (including higher order):

– lambda, quote, bind, apply, if_, ...● Basic metafunctions:

– and_, or_, not_, bitand_, less, min, ...● Basic runtime interfacing:

– for_each, c_str, ...

Page 47: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach47

Example – Boost MPL

1  tuple<int, char const*, bool> myTuple; // Poor man’s tuple2  get<int>(myTuple) = 123; // Access elements by type3  get<char const*>(myTuple) = "hello";45  // (Implementation) Holds a tuple element of type T6  template<typename T>7  struct tuple_field8  {9      T field;10 };1112 // (Implementation) Accesses a tuple element by type13 template<typename T>14 T & get(tuple_field<T> & t)15 {16    return t.field;17 }

Page 48: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach48

Example – Boost MPL

1  #include <boost/mpl/empty_base.hpp>2  #include <boost/mpl/fold.hpp>3  #include <boost/mpl/inherit.hpp>4  #include <boost/mpl/placeholders.hpp>5  #include <boost/mpl/vector.hpp>67  using namespace boost;8  using namespace boost::mpl::placeholders;910 // Composes a tuple, inheriting tuple_field’s11 template<typename ...Fields>12 struct tuple :13     mpl::fold< // The algoritm: fold/accumulate14         mpl::vector<Fields...>,           // The data15         mpl::empty_base,                  // The initial value16         mpl::inherit<_1, tuple_field<_2>> // The operation17     >::type {};

Page 49: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach49

Boost Hana

Page 50: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach50

Features

● Can do compile-time computation (like Boost MPL)● Can do runtime computation (like STL)● Can do heterogeneous computation (like Boost Fusion)● Requires a (decent) C++14 compiler

Page 51: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach51

Example – Boost Hana

1  #include <boost/hana.hpp>2  using namespace boost;3  struct Fish { std::string name; };4  struct Cat  { std::string name; };5  struct Dog  { std::string name; };67  auto animals = hana::make_tuple(8      Fish{"Nemo"}, Cat{"Garfield"}, Dog{"Snoopy"}9  );10 // Applies a (heterogenous) algorithm in runtime11 auto names = hana::transform(animals, [](auto a) {12     return a.name;13 });1415 assert(hana::reverse(names) ==16     hana::make_tuple("Snoopy", "Garfield", "Nemo")17 );

Page 52: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach52

Example – Boost Hana

1  auto animal_types = hana::make_tuple(2     hana::type_c<Fish*>,3     hana::type_c<Cat&>,4     hana::type_c<Dog*>5  );6  // Applies an algorithm in compile time7  auto animal_ptrs = hana::filter(animal_types, [](auto a) {8      return hana::traits::is_pointer(a);9  });1011 static_assert(animal_ptrs == hana::make_tuple(12     hana::type_c<Fish*>, hana::type_c<Dog*>), ""13 );

Page 53: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach53

Thank you!

Page 54: Template Metaprogramming - Practical Approach · code::dive 2016 - C++ Template Metaprogramming - Practical Approach 10 Consequences Development time of your (metaprogrammed) library

code::dive 2016 - C++ Template Metaprogramming - Practical Approach54

Questions?