summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2017-08-19 11:28:08 +0200
committerEugen Wissner <belka@caraus.de>2017-08-19 11:28:08 +0200
commita188f8b6e29e64b56881f13046e997f3844b41a8 (patch)
tree42e8872e805d912132c4ee5016621c829ab15f9a
parent9355c541632a1e39a4ef8daefda49f8cc8055ff9 (diff)
downloadtanya-0.7.2.tar.gz
Rename traits module to traitv0.7.2
-rw-r--r--source/tanya/meta/metafunction.d247
-rw-r--r--source/tanya/meta/package.d2
-rw-r--r--source/tanya/meta/trait.d (renamed from source/tanya/meta/traits.d)10
-rw-r--r--source/tanya/meta/transform.d2
4 files changed, 253 insertions, 8 deletions
diff --git a/source/tanya/meta/metafunction.d b/source/tanya/meta/metafunction.d
index 75c717c..ac25768 100644
--- a/source/tanya/meta/metafunction.d
+++ b/source/tanya/meta/metafunction.d
@@ -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));
+}
diff --git a/source/tanya/meta/package.d b/source/tanya/meta/package.d
index 4b74287..18edbc3 100644
--- a/source/tanya/meta/package.d
+++ b/source/tanya/meta/package.d
@@ -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;
diff --git a/source/tanya/meta/traits.d b/source/tanya/meta/trait.d
index a15b5db..c4a79b8 100644
--- a/source/tanya/meta/traits.d
+++ b/source/tanya/meta/trait.d
@@ -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.
diff --git a/source/tanya/meta/transform.d b/source/tanya/meta/transform.d
index bdefd4e..ac6a773 100644
--- a/source/tanya/meta/transform.d
+++ b/source/tanya/meta/transform.d
@@ -17,7 +17,7 @@
*/
module tanya.meta.transform;
-import tanya.meta.traits;
+import tanya.meta.trait;
/**
* Removes any type qualifiers from $(D_PARAM T).