@@ -51,6 +51,9 @@ $(TR $(TH Function Name) $(TH Description)
5151 $(TR $(TD $(LREF bind))
5252 $(TD Passes the fields of a struct as arguments to a function.
5353 ))
54+ $(TR $(TD $(LREF ctEval))
55+ $(TD Enforces the evaluation of an expression during compile-time.
56+ ))
5457))
5558
5659Copyright: Copyright Andrei Alexandrescu 2008 - 2009.
@@ -2175,3 +2178,50 @@ template bind(alias fun)
21752178 static assert (! __traits(isRef, x));
21762179 });
21772180}
2181+
2182+ /**
2183+ * Enforces the evaluation of an expression during compile-time.
2184+ *
2185+ * Computes the value of an expression during compilation (CTFE).
2186+ *
2187+ * This is useful for call chains in functional programming
2188+ * where declaring an `enum` constant would require splitting
2189+ * the pipeline.
2190+ *
2191+ * Params:
2192+ * expr = expression to evaluate
2193+ * See_also:
2194+ * $(LINK https://dlang.org/spec/function.html#interpretation)
2195+ */
2196+ enum ctEval (alias expr) = expr;
2197+
2198+ // /
2199+ @safe unittest
2200+ {
2201+ import std.math : abs;
2202+
2203+ // No explicit `enum` needed.
2204+ float result = ctEval! (abs(- 3 ));
2205+ assert (result == 3 );
2206+
2207+ // Can be statically asserted.
2208+ static assert (ctEval! (abs(- 4 )) == 4 );
2209+ static assert (ctEval! (abs( 9 )) == 9 );
2210+ }
2211+
2212+ // /
2213+ @safe unittest
2214+ {
2215+ import core.stdc.math : round;
2216+ import std.conv : to;
2217+ import std.math : abs, PI , sin;
2218+
2219+ // `round` from the C standard library cannot be interpreted at compile
2220+ // time, because it has no available source code. However the function
2221+ // calls preceding `round` can be evaluated during compile time.
2222+ int result = ctEval! (abs(sin(1.0 )) * 180 / PI )
2223+ .round()
2224+ .to! int ();
2225+
2226+ assert (result == 48 );
2227+ }
0 commit comments