Skip to content

Instantly share code, notes, and snippets.

@dnadlinger
Created November 11, 2011 20:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dnadlinger/1359203 to your computer and use it in GitHub Desktop.
Save dnadlinger/1359203 to your computer and use it in GitHub Desktop.
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