hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/tutorial/04_conditions.sfinae
blob: 94e0cbfdc02051a6545f6e79c0da8e3cd0abb9af (plain)
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;