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;
|