Created
September 9, 2017 22:37
-
-
Save PetarKirov/6f9c0ea62d840983598419ea190c1eae to your computer and use it in GitHub Desktop.
CTFE Keeping global state
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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