1

/*

2

* Created: 27012016

3

* Modified: Wed 27 Jan 2016 17:57:28 CET

4

* Author: Jonas R. Glesaaen (jonas@glesaaen.com)

5

*/

6


7

#include<iostream>

8

#include<utility>

9

#include<boost/type_index.hpp>

10


11

//Simple names for the operators

12

struct plus {};

13

struct minus {};

14

struct times {};

15

struct divide {};

16


17

//Base expression used to only need a single

18

//operator overload for every operator

19

template <typename Expr>

20

struct base_expr {};

21


22

//A binary expression storing an operator and the

23

//two expressions on either side

24

template <typename Op, typename Le, typename Re>

25

struct binary_expr : base_expr<binary_expr<Op,Le,Re>> {};

26


27

//A leaf class

28

struct val : base_expr<val> {};

29


30

//Operator that does nothing, only builds the expression tree

31

//Trailing return type not really needed, mostly for a cleaner syntax

32

template <typename Le, typename Re>

33

auto operator+(base_expr<Le>, base_expr<Re>)

34

> binary_expr<plus,Le,Re>

35

{

36

return {};

37

}

38


39

template <typename Le, typename Re>

40

auto operator(base_expr<Le>, base_expr<Re>)

41

> binary_expr<minus,Le,Re>

42

{

43

return {};

44

}

45


46

template <typename Le, typename Re>

47

auto operator*(base_expr<Le>, base_expr<Re>)

48

> binary_expr<times,Le,Re>

49

{

50

return {};

51

}

52


53

template <typename Le, typename Re>

54

auto operator/(base_expr<Le>, base_expr<Re>)

55

> binary_expr<divide,Le,Re>

56

{

57

return {};

58

}

59


60

//Prints out the expression tree of an arbitrary expression

61

int main(int, char**)

62

{

63

val v;

64

std::cout << boost::typeindex::type_id<decltype(v + v  v*v/(v+v))>().pretty_name() << std::endl;

65

}
