Skip to content

Commit

Permalink
Fix dlang#10023 - Add ctEval to Phobos
Browse files Browse the repository at this point in the history
  • Loading branch information
0xEAB committed Jan 19, 2025
1 parent bea3184 commit 2631a8b
Showing 1 changed file with 50 additions and 0 deletions.
50 changes: 50 additions & 0 deletions std/functional.d
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ $(TR $(TH Function Name) $(TH Description)
$(TR $(TD $(LREF bind))
$(TD Passes the fields of a struct as arguments to a function.
))
$(TR $(TD $(LREF ctEval))
$(TD Enforces the execution of a function during compile-time.
))
))
Copyright: Copyright Andrei Alexandrescu 2008 - 2009.
Expand Down Expand Up @@ -2167,3 +2170,50 @@ template bind(alias fun)
static assert(!__traits(isRef, x));
});
}

/**
* Enforces the execution of a function during compile-time.
*
* Computes the return value of a function call during compilation (CTFE).
*
* This is useful for call chains in functional programming
* where no explicit `enum` can be placed inline and would require splitting
* the pipeline.
*
* Params:
* fun = callable to evaluate
* See_also:
* $(LINK https://dlang.org/spec/function.html#interpretation)
*/
enum ctEval(alias fun) = fun;

///
@safe unittest
{
import std.math : abs;

// No explicit `enum` needed.
float result = ctEval!(abs(-3));
assert(result == 3);

// Can be statically asserted.
static assert(ctEval!(abs(-4)) == 4);
static assert(ctEval!(abs( 9)) == 9);
}

///
@safe unittest
{
import core.stdc.math : round;
import std.conv : to;
import std.math : abs, PI, sin;

// `round` from the C standard library cannot be interpreted at compile
// time, because it has no available source code. However the function
// calls preceding `round` can be evaluated during compile time.
int result = ctEval!(abs(sin(1.0)) * 180 / PI)
.round()
.to!int();

assert(result == 48);
}

0 comments on commit 2631a8b

Please sign in to comment.