Compile-time type transformation Meeting C++ 2019, Berlin dr Ivan - - PowerPoint PPT Presentation

compile time type transformation
SMART_READER_LITE
LIVE PREVIEW

Compile-time type transformation Meeting C++ 2019, Berlin dr Ivan - - PowerPoint PPT Presentation

Compile-time type transformation Meeting C++ 2019, Berlin dr Ivan uki KDAB ivan.cukic@kdab.com, ivan@cukic.co https://kdab.com, https://cukic.co Slow introduction Compile-time Meta information Generation The End About me KDAB senior


slide-1
SLIDE 1

Compile-time type transformation

Meeting C++ 2019, Berlin

dr Ivan Čukić

KDAB ivan.cukic@kdab.com, ivan@cukic.co https://kdab.com, https://cukic.co

slide-2
SLIDE 2

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

About me

KDAB senior software engineer Software Experts in Qt, C++ and 3D / OpenGL Trainer / consultant KDE developer Author of the ”Functional Programming in C++” book University lecturer

2

slide-3
SLIDE 3

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Disclaimer

Make your code readable. Pretend the next person who looks at your code is a psychopath and they know where you live. Philip Wadler

3

slide-4
SLIDE 4

SLOW INTRODUCTION

slide-5
SLIDE 5

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

String concatenation

std::string statement{”I'm not”}; std::string number{”a number”}; std::string space{” ”}; std::string period{”. ”}; std::string result = statement + space + number + period;

5

slide-6
SLIDE 6

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

String concatenation

6

slide-7
SLIDE 7

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

String concatenation

std::string result; result.reserve(statement.size() + space.size() + number.size() + period.size()); result.append(statement); result.append(space); result.append(number); result.append(period);

7

slide-8
SLIDE 8

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

String concatenation

8

slide-9
SLIDE 9

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

String concatenation

std::string concatenate(const std::vector<std::string>& strs) { std::string result; result.reserve(accumulate( strs | transform(&std::string::size), 0)); for (const auto& str: strs) { ⋯ } return result; }

9

slide-10
SLIDE 10

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

String concatenation

10

slide-11
SLIDE 11

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

String concatenation

std::string concatenate(const std::vector<std::string>& strs) { std::string result; result.reserve(accumulate( strs | transform(&std::string::size), 0)); for (const auto& str: strs) { result.append(str); } return result; }

11

slide-12
SLIDE 12

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

String concatenation

std::string concatenate(const std::vector<std::string>& strs) { std::string result; result.resize(accumulate( strs | transform(&std::string::size), 0)); ??? return result; }

12

slide-13
SLIDE 13

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

String concatenation

std::string concatenate(const std::vector<std::string>& strs) { std::string result; result.resize(accumulate( strs | transform(&std::string::size), 0)); accumulate(strs, result.begin(), [] (const auto& dest, const std::string& s) { return copy(s, dest); }); return result; }

13

slide-14
SLIDE 14

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

String concatenation

14

slide-15
SLIDE 15

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Accumulate

15

slide-16
SLIDE 16

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Accumulate

16

slide-17
SLIDE 17

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Accumulate

What if we want to save all the intermediate iterators into a vector?

17

slide-18
SLIDE 18

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Accumulate

18

slide-19
SLIDE 19

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Accumulate

Accumulator type:

struct acc_t { std::string::iterator dest; std::vector<std::string::iterator> points; };

19

slide-20
SLIDE 20

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Accumulate

Initial accumulator value:

acc_t { result.begin(), {} };

20

slide-21
SLIDE 21

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Accumulate

Accumulation function:

[] (acc_t&& acc, const std::string& s) { acc.points.push_back(acc.dest); return acc_t { copy(s, acc.dest), std::move(acc.points) }; }

21

slide-22
SLIDE 22

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Accumulate

std::string concatenate(const std::vector<std::string>& strs) { ⋯ struct acc_t { std::string::iterator dest; std::vector<std::string::iterator> points; }; auto acc = accumulate(strs, acc_t { result.begin(), {} }, [] (acc_t&& acc, const std::string& s) { acc.points.push_back(acc.dest); return acc_t { copy(s, acc.dest), std::move(acc.points) }; }); acc.dest ⋯ acc.points ⋯ }

22

slide-23
SLIDE 23

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Accumulate

std::pair<std::string, std::vector<std::string_view>> concatenate(const std::vector<std::string>& strs) { ⋯ } Note: Beware of string_view and UB

23

slide-24
SLIDE 24

COMPILE-TIME

slide-25
SLIDE 25

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Compile-time

template <typename... Strings> auto concatenate(Strings&&... strs) { result.resize(accumulate(⋯)); }

25

slide-26
SLIDE 26

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Compile-time

What is a compile-time accumulate?

26

slide-27
SLIDE 27

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Compile-time

27

slide-28
SLIDE 28

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Compile-time

28

slide-29
SLIDE 29

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Compile-time

template <typename... Strings> auto concatenate(Strings&&... strs) { const auto total_size = (0 + ... + strs.size()); std::string result; result.resize(total_size); ⋯ }

29

slide-30
SLIDE 30

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Compile-time

template <typename... Strings> auto concatenate(Strings&&... strs) { const auto total_size = (0 + ... + strs.size()); std::string result; result.resize(total_size); (result.begin() << ... << strs); }

30

slide-31
SLIDE 31

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Compile-time

template <typename Dest, typename String> auto operator<< (Dest dest, const String& string) { return copy(string, dest); }

31

slide-32
SLIDE 32

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Compile-time

template <typename Init, typename Fun> struct accumulator_t { Init value; const Fun& f; accumulator_t(Init value, const Fun& f) : value{value}, f{f} {} ⋯ };

32

slide-33
SLIDE 33

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Compile-time

template <typename Init, typename Fun> struct accumulator_t { ⋯ template <typename T> auto operator<< (T&& t) const { return accumulator_t( std::invoke(f, value, std::forward<T>(t)), f); } ⋯ };

33

slide-34
SLIDE 34

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Compile-time

template <typename Init, typename Fun> struct accumulator_t { ⋯

  • perator Init() const

{ return value; } };

34

slide-35
SLIDE 35

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Compile-time

(accumulator_t(0, std::plus{}) << ... << strs.size());

35

slide-36
SLIDE 36

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Compile-time

auto add_size = [](int previous, const std::string &s) { return previous + s.size(); }; (accumulator_t(0, add_size) << ... << strs);

36

slide-37
SLIDE 37

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Compile-time

template <typename Init, typename Fun, typename... Vals> auto accumulate(Init&& init, const Fun& fun, Vals&&... vals) { return ( accumulator_t(std::forward<Init>(init), fun) << ... << std::forward<Vals>(vals)).value; }

37

slide-38
SLIDE 38

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

String concatenation

template <typename... Strings> std::string concatenate(Strings&& strs) { ⋯ result.resize(accumulate(0, add_size, strs...)); accumulate(result.begin(), [] (const auto& dest, const std::string& s) { return copy(s, dest); }, std::forward<Strings>(strs)...); ⋯ }

38

slide-39
SLIDE 39

META INFORMATION

slide-40
SLIDE 40

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Meta information

print_animals(const std::vector<animal*> animals); std::vector<dog*> dogs; print_animals(dogs); // ERROR

40

slide-41
SLIDE 41

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Meta information

template < typename From , typename To > concept covariant = ⋯;

41

slide-42
SLIDE 42

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Meta information

template < typename From , typename To , typename FromTPtr = typename From::value_type , typename ToTPtr = typename To::value_type > concept covariant = ⋯;

42

slide-43
SLIDE 43

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Meta information

template < typename From , typename To , typename FromTPtr = typename From::value_type , typename ToTPtr = typename To::value_type , typename FromT = std::remove_cvref_t< decltype(*std::declval<FromTPtr>())> , typename ToT = std::remove_cvref_t< decltype(*std::declval<ToTPtr>())> > concept covariant = std::is_base_of_v<ToT, FromT>;

43

slide-44
SLIDE 44

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Meta information

template <typename Collection> requires (covariant<Collection, std::vector<animal*>>) void print_animals(const Collection& xs) { } // or constexpr bool and enable_if

44

slide-45
SLIDE 45

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Meta information

void print_animals( covariant<std::vector<animal*>> auto const& xs) { }

45

slide-46
SLIDE 46

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Meta information

if constexpr (std::is_array_v<T>) { } else { }

46

slide-47
SLIDE 47

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Meta information

partition(ForwardIterator first, ForwardIterator last, Predicate pred, forward_iterator_tag) partition(ForwardIterator first, ForwardIterator last, Predicate pred, bidirectional_iterator_tag)

47

slide-48
SLIDE 48

GENERATION

slide-49
SLIDE 49

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

49

slide-50
SLIDE 50

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

Template expressions are usually binary trees Rope leaves can be quite different in types and sizes The tree can be, but does not need to be balanced

50

slide-51
SLIDE 51

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

template <typename Left, typename Right> struct node { Left left; Right right; };

51

slide-52
SLIDE 52

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

template <typename Left, typename Right> struct node { Left left; Right right; using node_count = int_val<node_count_v<Left> + node_count_v<Right>>; ⋯ };

52

slide-53
SLIDE 53

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

template <typename Left, typename Right> struct node { ⋯ template <size_t I> const auto& node_at() const { if constexpr (I < node_count_v<Left>) { return left.node_at<I>(); } else { return right.node_at<I - node_count_v<Left>>(); } } };

53

slide-54
SLIDE 54

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

template <typename Tree, size_t... Idx> auto tree_to_tuple_helper( const Tree& tree, std::index_sequence<Idx...>) return std::make_tuple(tree.node_at<Idx>()...); }

54

slide-55
SLIDE 55

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

template <typename Tree, size_t... Idx> auto tree_to_tuple_helper( const Tree& tree, std::index_sequence<Idx...>) return std::make_tuple(tree.node_at<Idx>()...); } template <typename Tree> auto tree_to_tuple(const Tree& tree) { tree_to_tuple_helper( tree, std::make_index_sequence<node_count_v<Tree>>()); }

55

slide-56
SLIDE 56

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

template <typename Tree, size_t... Idx> auto process(const Tree& tree, std::index_sequence<Idx...>) return (init << ... << tree.node_at<Idx>()); }

56

slide-57
SLIDE 57

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

template <typename... Ts> struct leaf { std::tuple<Ts...> data; template <size_t I> const auto& node_at() const { return std::get<I>(data); } }

57

slide-58
SLIDE 58

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

TMP

So far, nothing new. Just normal TMP.

58

slide-59
SLIDE 59

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

struct binary_node_tag; template <typename Left, typename Right> struct node { Left left; Right right; using node_type_tag = binary_node_tag; };

59

slide-60
SLIDE 60

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

struct binary_node_tag; template <typename Left, typename Right> struct node { Left left; Right right; using node_type_tag = binary_node_tag; using left_t = Left; using right_t = Right; };

60

slide-61
SLIDE 61

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

if constexpr ( is_detected_exact_v< binary_node_tag, has_node_type_tag, T>) { do something with T::left_t and T::right_t ⋯ }

61

slide-62
SLIDE 62

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

Unsafe Not scalable

62

slide-63
SLIDE 63

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

struct binary_node_tag; template <typename Left, typename Right> struct node { Left left; Right right; using node_type_tag = binary_node_tag; // using left_t = Left; // using right_t = Right; };

63

slide-64
SLIDE 64

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

template <typename Left, typename Right> struct binary_node_tag { using left = Left; using right = Right; }; template <typename Left, typename Right> struct node { Left left; Right right; using node_type_tag = binary_node_tag<Left, Right>; };

64

slide-65
SLIDE 65

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

Template instances as tags instead of types.

65

slide-66
SLIDE 66

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

Now, is_detected_exact_v is no longer an option

66

slide-67
SLIDE 67

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

template <typename Expected, template <typename...> typename Op, typename... Args> using is_detected_exact = is_same<Expected, detected_t<Op, Args...>>;

67

slide-68
SLIDE 68

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

We need to check whether a given template has been used to instantiate a type: std::vector is used for std::vector<int> std::basic_string is used for std::string std::basic_string is not used for std::vector<char>

68

slide-69
SLIDE 69

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

template <template <typename...> typename Template, typename Type> struct is_instance_of: ⋯

69

slide-70
SLIDE 70

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

template <template <typename...> typename Template, typename Type> struct is_instance_of: std::false_type {};

70

slide-71
SLIDE 71

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

template <template <typename...> typename Template, typename Type> struct is_instance_of: std::false_type {}; template <template <typename...> typename Template, typename... Args> struct is_instance_of<Template, Template<Args...>>: std::true_type {};

71

slide-72
SLIDE 72

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

template <template <typename...> typename Template, typename Type> struct is_instance_of: std::false_type {}; template <template <typename...> typename Template, typename... Args> struct is_instance_of<Template, Template<Args...>>: std::true_type {}; template <template <typename...> typename Template, typename Type> constexpr bool is_instance_of_v = is_instance_of<Template, Type>::value;

72

slide-73
SLIDE 73

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

template <template <typename...> typename Expected, template <typename...> typename Op, typename... Args> using is_detected_instance_of = is_instance_of<Expected, detected_t<Op, Args...>>;

73

slide-74
SLIDE 74

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

is_detected_instance_of<binary_node_tag, has_node_type_tag, T>

74

slide-75
SLIDE 75

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Ropes

template <typename Left, typename Right> struct binary_node_tag { using left = Left; using right = Right; }; template <typename Left, typename Right> struct node { Left left; Right right; using node_type_tag = binary_node_tag<Left, Right>; };

75

slide-76
SLIDE 76

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Extensibility

Tags are fjxed Extending a type is diffjcult

76

slide-77
SLIDE 77

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Extensibility

template <typename Left, typename Right, typename BaseMeta> struct node { Left left; Right right; using meta_t = tuple_prepend_t< binary_node_tag<Left, Right>, BaseMeta >; };

77

slide-78
SLIDE 78

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Extensibility

Does a type have a specifjc tag? (false || ... || is_instance_of<specific_tag, Ts>);

78

slide-79
SLIDE 79

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Extensibility

Finding a specifjc tag: if constexpr (is_instance_of<Tag, T>) { return tuple_append_t<Acc, T>{}; } else { return T{}; }

79

slide-80
SLIDE 80

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Extensibility

We have a way to check for a tag (like is_detected_v) And we can get the tag (like detected_t) Difference – multiple instances of the same tag, tag meta-data

80

slide-81
SLIDE 81

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Extensibility

template <typename SourceNode> struct enriched_node { using meta_t = tuple_prepend_t< enriched_node_tag<SourceNode>, some_common_tag<42>, typename SourceNode::meta inheritance? >; };

81

slide-82
SLIDE 82

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Pipes

82

slide-83
SLIDE 83

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Pipes

82

slide-84
SLIDE 84

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Pipes

82

slide-85
SLIDE 85

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Pipes

82

slide-86
SLIDE 86

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Pipes

82

slide-87
SLIDE 87

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Pipes

82

slide-88
SLIDE 88

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Pipes

82

slide-89
SLIDE 89

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Pipes

82

slide-90
SLIDE 90

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Pipes

82

slide-91
SLIDE 91

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Pipes

82

slide-92
SLIDE 92

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Pipes

82

slide-93
SLIDE 93

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Pipes

82

slide-94
SLIDE 94

@ivan_cukic Ivan Čukić Meeting C++ 2019, Berlin Slow introduction Compile-time Meta information Generation The End

Properties

Dynamic property system... at compile-time.

83

slide-95
SLIDE 95

Web: https://kdab.com Mail: ivan.cukic@kdab.com Web: https://cukic.co Mail: ivan@cukic.co Twitter: @ivan_cukic

Functional Programming in C++ cukic.co/to/fp-in-cpp