Skip to content

Commit fcffbc0

Browse files
authored
Merge pull request #10625 from 0xEAB/ctEval
Fix #10023 - Add `ctEval` to Phobos
2 parents c5d074b + 4e21561 commit fcffbc0

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed

std/functional.d

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
5659
Copyright: 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

Comments
 (0)