1 /**
2     Numem meta templates.
3 
4     Most of these are taken directly from the D runtime.
5     
6     Copyright:
7         Copyright © 2005-2009, The D Language Foundation.
8         Copyright © 2023-2025, Kitsunebi Games
9         Copyright © 2023-2025, Inochi2D Project
10     
11     License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
12     Authors:
13         $(HTTP digitalmars.com, Walter Bright),
14         $(HTTP klickverbot.at, David Nadlinger)
15         Luna Nielsen
16 */
17 module numem.core.meta;
18 
19 /**
20     Equivalent to D runtime's AliasSeq.
21 */
22 alias AliasSeq(AliasList...) = AliasList;
23 
24 /**
25     A template which gets whether all the inputs satisfy the condition
26     outlined in $(D F).
27 */
28 template allSatisfy(alias F, T...) {
29     static foreach(U; T) {
30         static if (!is(typeof(allSatisfy) == bool) && is(typeof(F!U)) && !F!(U))
31             enum allSatisfy = false;
32     }
33 
34     static if (!is(typeof(allSatisfy) == bool))
35         enum allSatisfy = true;
36 }
37 
38 /**
39     A template which gets whether any of the inputs satisfy the 
40     condition outlined in $(D F).
41 */
42 template anySatisfy(alias F, T...) {
43     static foreach(U; T) {
44         static if (!is(typeof(anySatisfy) == bool) && is(typeof(F!U)) && F!U)
45             enum anySatisfy = true;
46     }
47 
48     static if (!is(typeof(anySatisfy) == bool))
49         enum anySatisfy = false;
50 }
51 
52 /**
53     Returns a sequence of F!(T[0]), F!(T[1]), ..., F!(T[$-1])
54 */
55 template staticMap(alias F, T...) {
56     static if (T.length == 0)
57         alias staticMap = AliasSeq!();
58     else static if (T.length == 1)
59         alias staticMap = AliasSeq!(F!(T[0]));
60     else static if (T.length == 2)
61         alias staticMap = AliasSeq!(F!(T[0]), F!(T[1]));
62     else static if (T.length == 3)
63         alias staticMap = AliasSeq!(F!(T[0]), F!(T[1]), F!(T[2]));
64     else static if (T.length == 4)
65         alias staticMap = AliasSeq!(F!(T[0]), F!(T[1]), F!(T[2]), F!(T[3]));
66     else static if (T.length == 5)
67         alias staticMap = AliasSeq!(F!(T[0]), F!(T[1]), F!(T[2]), F!(T[3]), F!(T[4]));
68     else static if (T.length == 6)
69         alias staticMap = AliasSeq!(F!(T[0]), F!(T[1]), F!(T[2]), F!(T[3]), F!(T[4]), F!(T[5]));
70     else static if (T.length == 7)
71         alias staticMap = AliasSeq!(F!(T[0]), F!(T[1]), F!(T[2]), F!(T[3]), F!(T[4]), F!(T[5]), F!(T[6]));
72     else static if (T.length == 8)
73         alias staticMap = AliasSeq!(F!(T[0]), F!(T[1]), F!(T[2]), F!(T[3]), F!(T[4]), F!(T[5]), F!(T[6]), F!(T[7]));
74     else {
75         alias staticMap =
76             AliasSeq!(
77                 staticMap!(F, T[ 0  .. $/2]),
78                 staticMap!(F, T[$/2 ..  $ ]));
79     }
80 }
81 
82 /**
83     Returns a sequence containing the provided sequence after filtering by $(D F).
84 */
85 template Filter(alias F, T...) {
86     alias Filter = AliasSeq!();
87     static foreach(Arg; T) {
88         static if (F!Arg)
89             Filter = AliasSeq!(Filter, Arg);
90     }
91 }