1 module fixedstring.opapplymixin;
2 
3 package(fixedstring):
4 
5 string opApplyWorkaround() nothrow pure @safe
6 {
7 	// dfmt off
8 	return paramNumbers("") ~
9 	paramNumbers("@safe") ~
10 	paramNumbers("@nogc") ~
11 	paramNumbers("@safe @nogc") ~
12 	paramNumbers("nothrow") ~
13 	paramNumbers("@safe nothrow") ~
14 	paramNumbers("@nogc nothrow") ~
15 	paramNumbers("@safe @nogc nothrow") ~
16 	paramNumbers("pure") ~
17 	paramNumbers("pure @safe") ~
18 	paramNumbers("pure @nogc") ~
19 	paramNumbers("pure @safe @nogc") ~
20 	paramNumbers("pure nothrow") ~
21 	paramNumbers("pure @safe nothrow") ~
22 	paramNumbers("pure @nogc nothrow") ~
23 	paramNumbers("pure @safe @nogc nothrow");
24 	// dfmt on
25 }
26 
27 private string paramNumbers(in string params) nothrow pure @safe
28 {
29 	// dfmt off
30 	return good(1, params, true) ~
31 	good(2, params, true) ~
32 	good(1, params, false) ~
33 	good(2, params, false);
34 	// dfmt on
35 }
36 
37 private string delegateType(in int n, in string attributes) nothrow pure @safe
38 {
39 	string params;
40 	switch (n)
41 	{
42 	case 1:
43 		params = "ref CharT";
44 		break;
45 	case 2:
46 		params = "ref int, ref CharT";
47 		break;
48 	default:
49 		assert(false, "unsupported number of parameters.");
50 	}
51 
52 	return "delegate(" ~ params ~ ") " ~ attributes;
53 }
54 
55 private string good(in int n, in string parameters, in bool isConst) nothrow pure @safe
56 {
57 	string s;
58 	if (isConst)
59 	{
60 		s = "const";
61 	}
62 	else
63 	{
64 		s = "";
65 	}
66 
67 	string result = "
68 		int opApply(scope int " ~ delegateType(n, parameters) ~ " dg) " ~ s ~ "
69 		{
70 			int result = 0;
71 
72 			for (int i = 0; i != length; ++i)
73 			{
74 				CharT temp = data[i];
75 				" ~ resultAssign(n) ~ "
76 				if (result)
77 				{
78 					break;
79 				}
80 			}
81 
82 			return result;
83 		}";
84 
85 	return result;
86 }
87 
88 private string resultAssign(in int n) nothrow pure @safe
89 {
90 	switch (n)
91 	{
92 	case 1:
93 		return "result = dg(temp);";
94 	case 2:
95 		return "result = dg(i, temp);";
96 	default:
97 		assert(false, "this will never happen.");
98 	}
99 }