Skip to content

Instantly share code, notes, and snippets.

@PetarKirov
Created September 9, 2017 22:37
Show Gist options
  • Save PetarKirov/6f9c0ea62d840983598419ea190c1eae to your computer and use it in GitHub Desktop.
Save PetarKirov/6f9c0ea62d840983598419ea190c1eae to your computer and use it in GitHub Desktop.
CTFE Keeping global state
size_t bsearch(alias pred, uint start, uint end)()
{
static if (end <= start)
static assert (0);
else static if (start + 1 == end && pred!start)
return start;
else
{
enum idx = start + (end - start) / 2;
static if (!pred!idx)
return bsearch!(pred, start, idx);
else
return bsearch!(pred, idx, end);
}
}
mixin template IotaMixin(uint end)
{
static if (!is(typeof(mixin("Iota7_" ~ end.stringof))))
{
pragma(msg, "> At IotaMixin!", end);
enum name(uint idx) = "IotaImpl_" ~ idx.stringof;
enum get(uint idx) = mixin(name!idx);
enum isDefined(uint idx) = is(typeof(mixin(name!idx)));
enum definition(uint idx) = "enum " ~ name!idx ~ " = " ~ end.stringof ~ ";";
enum maxName(uint ver) = "__iotaMax" ~ ver.stringof;
enum getMax(uint ver) = mixin(maxName!ver);
enum maxDefinition(uint value) = "enum " ~ maxName!end ~ " = " ~ value.stringof ~ ";";
static if (!isDefined!0)
{
mixin (definition!0);
mixin (maxDefinition!end);
pragma (msg, ">> Iota #0 was defined: ", end);
}
else
{
enum FixMeConstant = 1000;
enum lastIdx = bsearch!(isDefined, 0, FixMeConstant);
pragma (msg, ">> Iota - old max #", lastIdx, " = ", get!lastIdx);
static if (get!lastIdx < end)
{
pragma (msg, ">> Iota - adding new max #", lastIdx + 1, " = ", end);
mixin (definition!(lastIdx + 1));
mixin (maxDefinition!end);
}
else
{
pragma (msg, ">> Iota - using old max #", lastIdx, " = ", get!lastIdx);
mixin (maxDefinition!(get!lastIdx));
}
}
enum name2(uint idx) = "Iota7_" ~ idx.stringof;
static if (end < getMax!end)
{
pragma(msg, "> At IotaMixin!", end, ", maximum: ", getMax!end, " -> using old sequence: 0 .. ", getMax!end);
mixin ("alias " ~ name2!end ~ " = " ~ name2!(getMax!end) ~ "[0 .. end];");
}
else
{
pragma(msg, "> At IotaMixin!", end, ", maximum: ", getMax!end, " -> generating new sequence...");
mixin ("alias " ~ name2!end ~ " = Iota1!end;");
}
}
else
{
pragma (msg, "Using existing template instance: Iota7_", end);
}
}
import std.meta : AliasSeq;
private template Iota1(int end)
{
static if (end <= 0)
alias AliasSeq!() Iota1;
else
alias AliasSeq!(Iota1!(end - 1), end - 1) Iota1;
}
enum list = [12, 1, 5, 13, 4, 5, 1, 3, 2, 15, 2, 3, 15, 4];
pragma (msg, list, "\n");
static foreach (uint i; list)
{
mixin IotaMixin!i;
//pragma(msg, "Sequence: ", mixin ("Iota7_" ~ i.stringof));
pragma(msg, "Sequence length: ", mixin ("Iota7_" ~ i.stringof ~ ".length"));
//pragma(msg, "Sequence length: ", Iota1!i.length);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment