Rename traits module to trait

This commit is contained in:
Eugen Wissner 2017-08-19 11:28:08 +02:00
parent 9355c54163
commit a188f8b6e2
4 changed files with 253 additions and 8 deletions

View File

@ -17,7 +17,7 @@ module tanya.meta.metafunction;
version (unittest)
{
import std.traits;
import tanya.meta.trait;
}
/**
@ -206,3 +206,248 @@ pure nothrow @safe @nogc unittest
static assert(staticIndexOf!(int, float, double, int, real) == 2);
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)
* evaluates to $(D_INLINECODE Preds[0] && Preds[1] && Preds[2]) and so on.
*
* Empty $(D_PARAM Preds) evaluates to $(D_KEYWORD true).
*
* Params:
* Preds = Template predicates.
*
* Returns: The constructed template.
*/
template templateAnd(Preds...)
{
template templateAnd(T...)
{
static if (Preds.length == 0)
{
enum bool templateAnd = true;
}
else static if (Instantiate!(Preds[0], T))
{
alias templateAnd = Instantiate!(.templateAnd!(Preds[1 .. $]), T);
}
else
{
enum bool templateAnd = false;
}
}
}
///
pure nothrow @safe @nogc unittest
{
alias isMutableInt = templateAnd!(isIntegral, isMutable);
static assert(isMutableInt!int);
static assert(!isMutableInt!(const int));
static assert(!isMutableInt!float);
alias alwaysTrue = templateAnd!();
static assert(alwaysTrue!int);
alias isIntegral = templateAnd!(.isIntegral);
static assert(isIntegral!int);
static assert(isIntegral!(const int));
static assert(!isIntegral!float);
}
/**
* Combines multiple templates with logical OR. So $(D_PSYMBOL templateOr)
* evaluates to $(D_INLINECODE Preds[0] || Preds[1] || Preds[2]) and so on.
*
* Empty $(D_PARAM Preds) evaluates to $(D_KEYWORD false).
*
* Params:
* Preds = Template predicates.
*
* Returns: The constructed template.
*/
template templateOr(Preds...)
{
template templateOr(T...)
{
static if (Preds.length == 0)
{
enum bool templateOr = false;
}
else static if (Instantiate!(Preds[0], T))
{
enum bool templateOr = true;
}
else
{
alias templateOr = Instantiate!(.templateOr!(Preds[1 .. $]), T);
}
}
}
///
pure nothrow @safe @nogc unittest
{
alias isMutableOrInt = templateOr!(isIntegral, isMutable);
static assert(isMutableOrInt!int);
static assert(isMutableOrInt!(const int));
static assert(isMutableOrInt!float);
static assert(!isMutableOrInt!(const float));
alias alwaysFalse = templateOr!();
static assert(!alwaysFalse!int);
alias isIntegral = templateOr!(.isIntegral);
static assert(isIntegral!int);
static assert(isIntegral!(const int));
static assert(!isIntegral!float);
}
/**
* Params:
* pred = Template predicate.
*
* Returns: Negated $(D_PARAM pred).
*/
template templateNot(alias pred)
{
enum bool templateNot(T...) = !pred!T;
}
///
pure nothrow @safe @nogc unittest
{
alias isNotIntegral = templateNot!isIntegral;
static assert(!isNotIntegral!int);
static assert(isNotIntegral!(char[]));
}
/**
* Tests whether $(D_PARAM L) is sorted in ascending order according to
* $(D_PARAM cmp).
*
* $(D_PARAM cmp) can evaluate to:
* $(UL
* $(LI $(D_KEYWORD bool): $(D_KEYWORD true) means
* $(D_INLINECODE a[i] < a[i + 1]).)
* $(LI $(D_KEYWORD int): a negative number means that
* $(D_INLINECODE a[i] < a[i + 1]), a positive number that
* $(D_INLINECODE a[i] > a[i + 1]), `0` if they equal.)
* )
*
* Params:
* cmp = Comparison template.
* L = Arguments.
*
* Returns: $(D_KEYWORD true) if $(D_PARAM L) is sorted, $(D_KEYWORD false)
* if not.
*/
template staticIsSorted(alias cmp, L...)
{
static if (L.length <= 1)
{
enum bool staticIsSorted = true;
}
else
{
// `L` is sorted if the both halves are sorted.
enum bool halves = staticIsSorted!(cmp, L[0 .. $ / 2])
&& staticIsSorted!(cmp, L[$ / 2 .. $]);
// Compare the boundary values of the havles.
enum result = cmp!(L[$ / 2], L[$ / 2 - 1]);
static if (is(typeof(result) == bool))
{
enum bool staticIsSorted = !result && halves;
}
else
{
enum bool staticIsSorted = result >= 0 && halves;
}
}
}
///
pure nothrow @safe @nogc unittest
{
enum cmp(T, U) = T.sizeof < U.sizeof;
static assert(staticIsSorted!(cmp));
static assert(staticIsSorted!(cmp, byte));
static assert(staticIsSorted!(cmp, byte, ubyte, short, uint));
static assert(!staticIsSorted!(cmp, long, byte, ubyte, short, uint));
}
private pure nothrow @safe @nogc unittest
{
enum cmp(int x, int y) = x - y;
static assert(staticIsSorted!(cmp));
static assert(staticIsSorted!(cmp, 1));
static assert(staticIsSorted!(cmp, 1, 2, 2));
static assert(staticIsSorted!(cmp, 1, 2, 2, 4));
static assert(staticIsSorted!(cmp, 1, 2, 2, 4, 8));
static assert(!staticIsSorted!(cmp, 32, 2, 2, 4, 8));
static assert(staticIsSorted!(cmp, 32, 32));
}
private pure nothrow @safe @nogc unittest
{
enum cmp(int x, int y) = x < y;
static assert(staticIsSorted!(cmp));
static assert(staticIsSorted!(cmp, 1));
static assert(staticIsSorted!(cmp, 1, 2, 2));
static assert(staticIsSorted!(cmp, 1, 2, 2, 4));
static assert(staticIsSorted!(cmp, 1, 2, 2, 4, 8));
static assert(!staticIsSorted!(cmp, 32, 2, 2, 4, 8));
static assert(staticIsSorted!(cmp, 32, 32));
}
/**
* Params:
* T = A template.
* Args = The first arguments for $(D_PARAM T).
*
* Returns: $(D_PARAM T) with $(D_PARAM Args) applied to it as its first
* arguments.
*/
template ApplyLeft(alias T, Args...)
{
alias ApplyLeft(U...) = T!(Args, U);
}
///
pure nothrow @safe @nogc unittest
{
alias allAreIntegral = ApplyLeft!(allSatisfy, isIntegral);
static assert(allAreIntegral!(int, uint));
static assert(!allAreIntegral!(int, float, uint));
}
/**
* Params:
* T = A template.
* Args = The last arguments for $(D_PARAM T).
*
* Returns: $(D_PARAM T) with $(D_PARAM Args) applied to it as itslast
* arguments.
*/
template ApplyRight(alias T, Args...)
{
alias ApplyRight(U...) = T!(U, Args);
}
///
pure nothrow @safe @nogc unittest
{
alias intIs = ApplyRight!(allSatisfy, int);
static assert(intIs!(isIntegral));
static assert(!intIs!(isUnsigned));
}

View File

@ -15,5 +15,5 @@
module tanya.meta;
public import tanya.meta.metafunction;
public import tanya.meta.traits;
public import tanya.meta.trait;
public import tanya.meta.transform;

View File

@ -12,10 +12,10 @@
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
* Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/meta/traits.d,
* tanya/meta/traits.d)
* Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/meta/trait.d,
* tanya/meta/trait.d)
*/
module tanya.meta.traits;
module tanya.meta.trait;
import tanya.meta.metafunction;
import tanya.meta.transform;
@ -631,7 +631,7 @@ pure nothrow @safe @nogc unittest
static assert(!isType!T);
static assert(isType!(T!()));
static assert(!isType!5);
static assert(!isType!(tanya.meta.traits));
static assert(!isType!(tanya.meta.trait));
}
/**
@ -1598,7 +1598,7 @@ pure nothrow @safe unittest
/**
* Params:
* T = A function.
* F = A function.
*
* Returns $(D_KEYWORD true) if the $(D_PARAM T) is a nested function,
* $(D_KEYWORD false) otherwise.

View File

@ -17,7 +17,7 @@
*/
module tanya.meta.transform;
import tanya.meta.traits;
import tanya.meta.trait;
/**
* Removes any type qualifiers from $(D_PARAM T).