1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
// lesson 4: conditions
//
// a condition is ::true_type::value, ::false_type::value, ::equal<V, V>::value,
// ::less<V, V>::value, or ::is_same<T, T>::value. the ::value is mandatory
// a condition without it is a type, and a type is not a condition.
// ::conditional_t<C, T, T> picks a type. this prints 1
::emit<
::conditional_t<
::true_type::value,
::decltype(::difference<'B', 'A'>),
::void
>
>::commit;
// this picks ::void, and emitting ::void prints nothing at all. not even a newline
::emit<
::conditional_t<
::less<
::difference<'B', 'A'>,
::difference<'A', 'A'>
>::value,
::decltype(::difference<'Z', 'A'>),
::void
>
>::commit;
// ::enable_if_t<C, ::sequence<...>> runs the statements when C holds
// the statements inside a sequence are separated by commas, and each one is
// still committed on its own
::enable_if_t<
::is_same<
::remove_cv_t<::int32_t>,
::int32_t
>::value,
::sequence<
::emit<
::tuple<
::integral_constant<::char, ::difference<'s', '\0'>>,
::integral_constant<::char, ::difference<'a', '\0'>>,
::integral_constant<::char, ::difference<'m', '\0'>>,
::integral_constant<::char, ::difference<'e', '\0'>>
>
>::commit
>
>::commit;
// ::static_assert<C> stops the program when C does not hold. it does this at
// runtime, because that is when we know
::static_assert<
::equal<
::difference<'C', 'A'>,
::sum<
::difference<'B', 'A'>,
::difference<'B', 'A'>
>
>::value
>::commit;
// ::conditional<C, V, V> is the same idea for values. this prints 9
::emit<
::decltype(
::conditional<
::false_type::value,
::difference<'A', 'A'>,
::difference<'J', 'A'>
>
)
>::commit;
|