hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/examples/functions.sfinae
blob: d73261ff5d68d66bd2ca8b379f52ace6174692b1 (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
// a function takes types and gives back a type. calling one is itself a type
// it sees nothing but its parameters, and every argument must be a ::decltype so it carries a value

::define<
    ::name<'s', 'q', 'u', 'a', 'r', 'e'>,
    ::parameters<::name<'x'>>,
    ::sequence<
        ::return<::decltype(::product<::value_of<::name<'x'>>, ::value_of<::name<'x'>>>)>::commit
    >
>::commit;

::emit<
    ::invoke_result_t<
        ::name<'s', 'q', 'u', 'a', 'r', 'e'>,
        ::arguments<::decltype(::difference<'F', 'A'>)>
    >
>::commit;

// a function can return anything a type can be, which includes a tuple of characters
::define<
    ::name<'g', 'r', 'e', 'e', 't'>,
    ::parameters<>,
    ::sequence<
        ::return<
            ::tuple<
                ::integral_constant<::char, ::difference<'h', '\0'>>,
                ::integral_constant<::char, ::difference<'e', '\0'>>,
                ::integral_constant<::char, ::difference<'y', '\0'>>
            >
        >::commit
    >
>::commit;

::emit<::invoke_result_t<::name<'g', 'r', 'e', 'e', 't'>, ::arguments<>>>::commit;

// a function that never returns gives back ::void, and emitting ::void prints nothing
::define<::name<'n', 'o', 'p'>, ::parameters<>, ::sequence<>>::commit;
::emit<::invoke_result_t<::name<'n', 'o', 'p'>, ::arguments<>>>::commit;

// a return inside a branch still leaves the function
::define<
    ::name<'s', 'i', 'g', 'n'>,
    ::parameters<::name<'n'>>,
    ::sequence<
        ::enable_if_t<
            ::less<::value_of<::name<'n'>>, ::difference<'A', 'A'>>::value,
            ::sequence<::return<::decltype(::difference<'A', 'B'>)>::commit>
        >::commit,
        ::return<::decltype(::difference<'B', 'A'>)>::commit
    >
>::commit;

::emit<
    ::invoke_result_t<::name<'s', 'i', 'g', 'n'>, ::arguments<::decltype(::difference<'A', 'Z'>)>>
>::commit;