Created
November 11, 2011 20:50
-
-
Save dnadlinger/1359203 to your computer and use it in GitHub Desktop.
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
import std.typetuple; | |
template ConfinedTuple(T...) { | |
alias T Tuple; | |
enum length = T.length; | |
} | |
template PApply(alias Target, T...) { | |
template PApply(U...) { | |
alias Target!(MergeArgs!(ConfinedTuple!T, U).Result) PApply; | |
} | |
} | |
template PApplySkip() {} | |
private template MergeArgs(alias Preset, Args...) { | |
static if (Preset.length == 0) { | |
alias Args Result; | |
} else { | |
enum nextSkip = staticIndexOf!(PApplySkip, Preset.Tuple); | |
static if (nextSkip == -1) { | |
alias TypeTuple!(Preset.Tuple, Args) Result; | |
} else static if (Args.length == 0) { | |
// Have to use a static if clause instead of putting the condition | |
// directly into the assert to avoid DMD trying to access Args[0] | |
// nevertheless below. | |
static assert(false, | |
"PArgsSkip encountered, but no argument left to bind."); | |
} else { | |
alias TypeTuple!( | |
Preset.Tuple[0 .. nextSkip], | |
Args[0], | |
MergeArgs!( | |
ConfinedTuple!(Preset.Tuple[nextSkip + 1 .. $]), | |
Args[1 .. $] | |
).Result | |
) Result; | |
} | |
} | |
} | |
unittest { | |
struct Test(T, U, V) {} | |
alias PApply!(Test, int, long) PartialTest; | |
static assert(is(PartialTest!float == Test!(int, long, float))); | |
alias PApply!(Test, int, PApplySkip, float) SkippedTest; | |
static assert(is(SkippedTest!long == Test!(int, long, float))); | |
alias PApply!(Test, int, PApplySkip, PApplySkip) TwoSkipped; | |
static assert(!__traits(compiles, TwoSkipped!long)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment