Add new metafunctions: Min, Max, ZipWith
Documentation follow
This commit is contained in:
parent
25d59ffdda
commit
4dbfbe9874
@ -15,6 +15,109 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.meta.metafunction;
|
module tanya.meta.metafunction;
|
||||||
|
|
||||||
|
import tanya.meta.trait;
|
||||||
|
|
||||||
|
template Min(alias pred, Args...)
|
||||||
|
if (Args.length > 0 && isTemplate!pred)
|
||||||
|
{
|
||||||
|
static if (Args.length == 1)
|
||||||
|
{
|
||||||
|
alias Min = Alias!(Args[0]);
|
||||||
|
}
|
||||||
|
else static if (isLess!(pred, Args[1], Args[0]))
|
||||||
|
{
|
||||||
|
alias Min = Min!(pred, Args[1], Args[2 .. $]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
alias Min = Min!(pred, Args[0], Args[2 .. $]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pure nothrow @safe @nogc unittest
|
||||||
|
{
|
||||||
|
enum bool cmp(alias T, alias U) = T < U;
|
||||||
|
static assert(Min!(cmp, 8, 4, 5, 3, 13) == 3);
|
||||||
|
static assert(Min!(cmp, 8) == 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
template Max(alias pred, Args...)
|
||||||
|
if (Args.length > 0 && isTemplate!pred)
|
||||||
|
{
|
||||||
|
static if (Args.length == 1)
|
||||||
|
{
|
||||||
|
alias Max = Alias!(Args[0]);
|
||||||
|
}
|
||||||
|
else static if (isGreater!(pred, Args[1], Args[0]))
|
||||||
|
{
|
||||||
|
alias Max = Max!(pred, Args[1], Args[2 .. $]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
alias Max = Max!(pred, Args[0], Args[2 .. $]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pure nothrow @safe @nogc unittest
|
||||||
|
{
|
||||||
|
enum bool cmp(alias T, alias U) = T < U;
|
||||||
|
static assert(Max!(cmp, 8, 4, 5, 3, 13) == 13);
|
||||||
|
static assert(Max!(cmp, 8) == 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
template ZipWith(alias pred, Tuples...)
|
||||||
|
if (Tuples.length > 0
|
||||||
|
&& isTemplate!pred
|
||||||
|
&& allSatisfy!(ApplyLeft!(isInstanceOf, AliasTuple), Tuples))
|
||||||
|
{
|
||||||
|
private template GetIth(size_t i, Args...)
|
||||||
|
{
|
||||||
|
static if ((Args.length == 0) || (Args[0].Seq.length <= i))
|
||||||
|
{
|
||||||
|
alias GetIth = AliasSeq!();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
alias GetIth = AliasSeq!(Args[0].Seq[i], GetIth!(i, Args[1 .. $]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private template Iterate(size_t i, Args...)
|
||||||
|
{
|
||||||
|
alias Tuple = GetIth!(i, Args);
|
||||||
|
|
||||||
|
static if (Tuple.length < Tuples.length)
|
||||||
|
{
|
||||||
|
alias Iterate = AliasSeq!();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
alias Iterate = AliasSeq!(pred!Tuple,
|
||||||
|
Iterate!(i + 1, Args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
alias ZipWith = Iterate!(0, Tuples);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pure nothrow @safe @nogc unittest
|
||||||
|
{
|
||||||
|
alias Result1 = ZipWith!(AliasSeq,
|
||||||
|
AliasTuple!(1, 2),
|
||||||
|
AliasTuple!(5, 6),
|
||||||
|
AliasTuple!(9, 10));
|
||||||
|
static assert(Result1 == AliasSeq!(1, 5, 9, 2, 6, 10));
|
||||||
|
|
||||||
|
alias Result2 = ZipWith!(AliasSeq,
|
||||||
|
AliasTuple!(1, 2, 3),
|
||||||
|
AliasTuple!(4, 5));
|
||||||
|
static assert(Result2 == AliasSeq!(1, 4, 2, 5));
|
||||||
|
|
||||||
|
alias Result3 = ZipWith!(AliasSeq, AliasTuple!(), AliasTuple!(4, 5));
|
||||||
|
static assert(Result3.length == 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds a typed sequence of template parameters.
|
* Holds a typed sequence of template parameters.
|
||||||
*
|
*
|
||||||
@ -98,7 +201,7 @@ pure nothrow @safe @nogc unittest
|
|||||||
* to $(D_INLINECODE Args[1]), $(D_KEYWORD false) otherwise.
|
* to $(D_INLINECODE Args[1]), $(D_KEYWORD false) otherwise.
|
||||||
*/
|
*/
|
||||||
template isLessEqual(alias cmp, Args...)
|
template isLessEqual(alias cmp, Args...)
|
||||||
if (Args.length == 2)
|
if (Args.length == 2 && isTemplate!cmp)
|
||||||
{
|
{
|
||||||
private enum result = cmp!(Args[1], Args[0]);
|
private enum result = cmp!(Args[1], Args[0]);
|
||||||
static if (is(typeof(result) == bool))
|
static if (is(typeof(result) == bool))
|
||||||
@ -145,7 +248,7 @@ pure nothrow @safe @nogc unittest
|
|||||||
* equal to $(D_INLINECODE Args[1]), $(D_KEYWORD false) otherwise.
|
* equal to $(D_INLINECODE Args[1]), $(D_KEYWORD false) otherwise.
|
||||||
*/
|
*/
|
||||||
template isGreaterEqual(alias cmp, Args...)
|
template isGreaterEqual(alias cmp, Args...)
|
||||||
if (Args.length == 2)
|
if (Args.length == 2 && isTemplate!cmp)
|
||||||
{
|
{
|
||||||
private enum result = cmp!Args;
|
private enum result = cmp!Args;
|
||||||
static if (is(typeof(result) == bool))
|
static if (is(typeof(result) == bool))
|
||||||
@ -192,7 +295,7 @@ pure nothrow @safe @nogc unittest
|
|||||||
* $(D_INLINECODE Args[1]), $(D_KEYWORD false) otherwise.
|
* $(D_INLINECODE Args[1]), $(D_KEYWORD false) otherwise.
|
||||||
*/
|
*/
|
||||||
template isLess(alias cmp, Args...)
|
template isLess(alias cmp, Args...)
|
||||||
if (Args.length == 2)
|
if (Args.length == 2 && isTemplate!cmp)
|
||||||
{
|
{
|
||||||
private enum result = cmp!Args;
|
private enum result = cmp!Args;
|
||||||
static if (is(typeof(result) == bool))
|
static if (is(typeof(result) == bool))
|
||||||
@ -239,7 +342,7 @@ pure nothrow @safe @nogc unittest
|
|||||||
* $(D_INLINECODE Args[1]), $(D_KEYWORD false) otherwise.
|
* $(D_INLINECODE Args[1]), $(D_KEYWORD false) otherwise.
|
||||||
*/
|
*/
|
||||||
template isGreater(alias cmp, Args...)
|
template isGreater(alias cmp, Args...)
|
||||||
if (Args.length == 2)
|
if (Args.length == 2 && isTemplate!cmp)
|
||||||
{
|
{
|
||||||
private enum result = cmp!Args;
|
private enum result = cmp!Args;
|
||||||
static if (is(typeof(result) == bool))
|
static if (is(typeof(result) == bool))
|
||||||
@ -329,6 +432,17 @@ pure nothrow @safe @nogc unittest
|
|||||||
static assert(isNotEqual!(5, 8));
|
static assert(isNotEqual!(5, 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates the template $(D_PARAM T) with $(D_PARAM ARGS).
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* T = Template.
|
||||||
|
* Args = Template parameters.
|
||||||
|
*
|
||||||
|
* Returns: Instantiated template.
|
||||||
|
*/
|
||||||
|
alias Instantiate(alias T, Args...) = T!Args;
|
||||||
|
|
||||||
version (TanyaPhobos)
|
version (TanyaPhobos)
|
||||||
{
|
{
|
||||||
public import std.meta : Alias,
|
public import std.meta : Alias,
|
||||||
@ -402,7 +516,6 @@ pure nothrow @safe @nogc unittest
|
|||||||
static assert(is(typeof(Alias!i)));
|
static assert(is(typeof(Alias!i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds a sequence of aliases.
|
* Holds a sequence of aliases.
|
||||||
*
|
*
|
||||||
@ -454,6 +567,7 @@ pure nothrow @safe @nogc unittest
|
|||||||
* $(D_PARAM F), $(D_KEYWORD false) otherwise.
|
* $(D_PARAM F), $(D_KEYWORD false) otherwise.
|
||||||
*/
|
*/
|
||||||
template allSatisfy(alias F, L...)
|
template allSatisfy(alias F, L...)
|
||||||
|
if (isTemplate!F)
|
||||||
{
|
{
|
||||||
static if (L.length == 0)
|
static if (L.length == 0)
|
||||||
{
|
{
|
||||||
@ -491,6 +605,7 @@ pure nothrow @safe @nogc unittest
|
|||||||
* $(D_PARAM F), $(D_KEYWORD false) otherwise.
|
* $(D_PARAM F), $(D_KEYWORD false) otherwise.
|
||||||
*/
|
*/
|
||||||
template anySatisfy(alias F, L...)
|
template anySatisfy(alias F, L...)
|
||||||
|
if (isTemplate!F)
|
||||||
{
|
{
|
||||||
static if (L.length == 0)
|
static if (L.length == 0)
|
||||||
{
|
{
|
||||||
@ -562,17 +677,6 @@ pure nothrow @safe @nogc unittest
|
|||||||
static assert(staticIndexOf!(3, () {}, uint, 5, 3) == 3);
|
static assert(staticIndexOf!(3, () {}, uint, 5, 3) == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Instantiates the template $(D_PARAM T) with $(D_PARAM ARGS).
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* T = Template.
|
|
||||||
* Args = Template parameters.
|
|
||||||
*
|
|
||||||
* Returns: Instantiated template.
|
|
||||||
*/
|
|
||||||
alias Instantiate(alias T, Args...) = T!Args;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Combines multiple templates with logical AND. So $(D_PSYMBOL templateAnd)
|
* Combines multiple templates with logical AND. So $(D_PSYMBOL templateAnd)
|
||||||
* evaluates to $(D_INLINECODE Preds[0] && Preds[1] && Preds[2]) and so on.
|
* evaluates to $(D_INLINECODE Preds[0] && Preds[1] && Preds[2]) and so on.
|
||||||
@ -585,6 +689,7 @@ alias Instantiate(alias T, Args...) = T!Args;
|
|||||||
* Returns: The constructed template.
|
* Returns: The constructed template.
|
||||||
*/
|
*/
|
||||||
template templateAnd(Preds...)
|
template templateAnd(Preds...)
|
||||||
|
if (allSatisfy!(isTemplate, Preds))
|
||||||
{
|
{
|
||||||
template templateAnd(T...)
|
template templateAnd(T...)
|
||||||
{
|
{
|
||||||
@ -632,6 +737,7 @@ pure nothrow @safe @nogc unittest
|
|||||||
* Returns: The constructed template.
|
* Returns: The constructed template.
|
||||||
*/
|
*/
|
||||||
template templateOr(Preds...)
|
template templateOr(Preds...)
|
||||||
|
if (allSatisfy!(isTemplate, Preds))
|
||||||
{
|
{
|
||||||
template templateOr(T...)
|
template templateOr(T...)
|
||||||
{
|
{
|
||||||
@ -675,6 +781,7 @@ pure nothrow @safe @nogc unittest
|
|||||||
* Returns: Negated $(D_PARAM pred).
|
* Returns: Negated $(D_PARAM pred).
|
||||||
*/
|
*/
|
||||||
template templateNot(alias pred)
|
template templateNot(alias pred)
|
||||||
|
if (isTemplate!pred)
|
||||||
{
|
{
|
||||||
enum bool templateNot(T...) = !pred!T;
|
enum bool templateNot(T...) = !pred!T;
|
||||||
}
|
}
|
||||||
@ -708,6 +815,7 @@ pure nothrow @safe @nogc unittest
|
|||||||
* if not.
|
* if not.
|
||||||
*/
|
*/
|
||||||
template isSorted(alias cmp, L...)
|
template isSorted(alias cmp, L...)
|
||||||
|
if (isTemplate!cmp)
|
||||||
{
|
{
|
||||||
static if (L.length <= 1)
|
static if (L.length <= 1)
|
||||||
{
|
{
|
||||||
@ -986,6 +1094,7 @@ pure nothrow @safe @nogc unittest
|
|||||||
* Returns: Elements $(D_PARAM T) after applying $(D_PARAM F) to them.
|
* Returns: Elements $(D_PARAM T) after applying $(D_PARAM F) to them.
|
||||||
*/
|
*/
|
||||||
template Map(alias F, T...)
|
template Map(alias F, T...)
|
||||||
|
if (isTemplate!F)
|
||||||
{
|
{
|
||||||
static if (T.length == 0)
|
static if (T.length == 0)
|
||||||
{
|
{
|
||||||
@ -1027,6 +1136,7 @@ pure nothrow @safe @nogc unittest
|
|||||||
* See_Also: $(LINK2 https://en.wikipedia.org/wiki/Merge_sort, Merge sort).
|
* See_Also: $(LINK2 https://en.wikipedia.org/wiki/Merge_sort, Merge sort).
|
||||||
*/
|
*/
|
||||||
template Sort(alias cmp, L...)
|
template Sort(alias cmp, L...)
|
||||||
|
if (isTemplate!cmp)
|
||||||
{
|
{
|
||||||
private template merge(size_t A, size_t B)
|
private template merge(size_t A, size_t B)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user