summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/tanya/format/conv.d36
-rw-r--r--source/tanya/math/mp.d3
-rw-r--r--source/tanya/math/package.d2
-rw-r--r--source/tanya/meta/metafunction.d6
-rw-r--r--source/tanya/meta/trait.d270
-rw-r--r--source/tanya/meta/transform.d208
-rw-r--r--source/tanya/net/inet.d116
-rw-r--r--source/tanya/typecons.d2
8 files changed, 495 insertions, 148 deletions
diff --git a/source/tanya/format/conv.d b/source/tanya/format/conv.d
index 82bcada..77b84e3 100644
--- a/source/tanya/format/conv.d
+++ b/source/tanya/format/conv.d
@@ -8,7 +8,7 @@
* Copyright: Eugene Wissner 2017.
* 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)
+ * Authors: Jeff Roberts, $(LINK2 mailto:info@caraus.de, Eugene Wissner)
* Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/format/conv.d,
* tanya/format/conv.d)
*/
@@ -611,13 +611,13 @@ private @nogc unittest
defaultAllocator.dispose(exception);
}
-package char[] number2String(T)(const T number, char[] buffer)
+// Returns the last part of buffer with converted number.
+package char[] number2String(T)(const T number, out char[20] buffer)
{
// abs the integer.
ulong n64 = number < 0 ? -cast(long) number : number;
- char[20] rightAligned;
- char* start = rightAligned.ptr + rightAligned.sizeof;
+ char* start = buffer.ptr + buffer.sizeof;
while (true)
{
@@ -644,8 +644,7 @@ package char[] number2String(T)(const T number, char[] buffer)
// Ignore the leading zero if it was the last part of the integer.
if (n64 == 0)
{
- if ((start[0] == '0')
- && (start != (rightAligned.ptr + rightAligned.sizeof)))
+ if ((start[0] == '0') && (start != (buffer.ptr + buffer.sizeof)))
{
++start;
}
@@ -659,34 +658,25 @@ package char[] number2String(T)(const T number, char[] buffer)
}
}
- // Get the length that we copied.
- auto l = cast(uint) ((rightAligned.ptr + rightAligned.sizeof) - start);
+ // Get the length that we have copied.
+ uint l = cast(uint) ((buffer.ptr + buffer.sizeof) - start);
if (l == 0)
{
*--start = '0';
l = 1;
}
-
- // Write the string.
- char* bp = buffer.ptr;
-
- // Set the sign.
- if (number < 0)
+ else if (number < 0) // Set the sign.
{
- *bp++ = '-';
+ *--start = '-';
+ ++l;
}
- // Copy the string into the target buffer.
- int i = l;
- copy(start[0 .. l], bp[0 .. l]);
- bp += l;
-
- return buffer[0 .. bp - buffer.ptr];
+ return buffer[$ - l .. $];
}
-private @nogc unittest
+private pure nothrow @system @nogc unittest
{
- char[21] buf;
+ char[20] buf;
assert(number2String(80, buf) == "80");
assert(number2String(-80, buf) == "-80");
diff --git a/source/tanya/math/mp.d b/source/tanya/math/mp.d
index c79ecea..98fb9bc 100644
--- a/source/tanya/math/mp.d
+++ b/source/tanya/math/mp.d
@@ -17,9 +17,10 @@ module tanya.math.mp;
import std.algorithm;
import std.ascii;
import std.range;
-import std.traits;
import tanya.container.array;
import tanya.memory;
+import tanya.meta.trait;
+import tanya.meta.transform;
/**
* Algebraic sign.
diff --git a/source/tanya/math/package.d b/source/tanya/math/package.d
index a7a0a3b..24dc2b0 100644
--- a/source/tanya/math/package.d
+++ b/source/tanya/math/package.d
@@ -14,9 +14,9 @@
*/
module tanya.math;
-import std.traits;
public import tanya.math.mp;
public import tanya.math.random;
+import tanya.meta.trait;
version (unittest)
{
diff --git a/source/tanya/meta/metafunction.d b/source/tanya/meta/metafunction.d
index 0466a12..37926a3 100644
--- a/source/tanya/meta/metafunction.d
+++ b/source/tanya/meta/metafunction.d
@@ -15,13 +15,9 @@
*/
module tanya.meta.metafunction;
+import tanya.meta.trait;
import tanya.meta.transform;
-version (unittest)
-{
- import tanya.meta.trait;
-}
-
/**
* Tests whether $(D_INLINECODE Args[0]) is less than or equal to
* $(D_INLINECODE Args[1]) according to $(D_PARAM cmp).
diff --git a/source/tanya/meta/trait.d b/source/tanya/meta/trait.d
index 7bb79e1..39acff0 100644
--- a/source/tanya/meta/trait.d
+++ b/source/tanya/meta/trait.d
@@ -1738,9 +1738,7 @@ pure nothrow @safe @nogc unittest
}
static assert(isInstanceOf!(S, S!int));
- static void func(T)()
- {
- }
+ static void func(T)();
static assert(isInstanceOf!(func, func!int));
template T(U)
@@ -2055,3 +2053,269 @@ pure nothrow @safe @nogc unittest
static assert(isAssignable!int);
static assert(!isAssignable!(const int, int));
}
+
+/**
+ * Returns template parameters of $(D_PARAM T).
+ *
+ * Params:
+ * T = Template instance.
+ *
+ * Returns: Template parameters of $(D_PARAM T).
+ */
+alias TemplateArgsOf(alias T : Base!Args, alias Base, Args...) = Args;
+
+///
+pure nothrow @safe @nogc unittest
+{
+ template T(A, B)
+ {
+ }
+ static assert(is(TemplateArgsOf!(T!(int, uint)) == AliasSeq!(int, uint)));
+}
+
+/**
+ * Returns a tuple with parameter types of a function.
+ *
+ * Params:
+ * F = A function.
+ *
+ * Returns: Tuple with parameter types of a function.
+ */
+template Parameters(F...)
+if (isCallable!F)
+{
+ static if (is(FunctionTypeOf!F T == function))
+ {
+ alias Parameters = T;
+ }
+ else
+ {
+ static assert(false, "Function has no parameters");
+ }
+}
+
+///
+pure nothrow @safe @nogc unittest
+{
+ int func(Object, uint[]);
+ static assert(is(Parameters!func == AliasSeq!(Object, uint[])));
+}
+
+/**
+ * Returns a string array with all parameter names of a function.
+ *
+ * If a parameter has no name, an empty string is placed into array.
+ *
+ * Params:
+ * F = A function.
+ *
+ * Returns: Function parameter names.
+ */
+template ParameterIdentifierTuple(F...)
+if (isCallable!F)
+{
+ static if (is(FunctionTypeOf!F Params == __parameters))
+ {
+ enum string[] Impl()
+ {
+ string[] tuple;
+
+ foreach (k, P; Params)
+ {
+ static if (is(typeof(__traits(identifier, Params[k .. $]))))
+ {
+ tuple ~= __traits(identifier, Params[k .. $]);
+ }
+ else
+ {
+ tuple ~= "";
+ }
+ }
+
+ return tuple;
+ }
+ enum string[] ParameterIdentifierTuple = Impl();
+ }
+ else
+ {
+ static assert(false, "Function has no parameters");
+ }
+}
+
+///
+pure nothrow @safe @nogc unittest
+{
+ int func(ref Object stuff, uint[] = null, scope uint k = 1);
+ alias P = ParameterIdentifierTuple!func;
+ static assert(P[0] == "stuff");
+ static assert(P[1] == "");
+ static assert(P[2] == "k");
+}
+
+/**
+ * Returns number of the arguments of the function $(D_PARAM F).
+ *
+ * For typesafe variadic functions variadic arguments count as one argument.
+ * For other variadic functions (D- and C-style) only non-variadic
+ * arguments count.
+ *
+ * Params:
+ * F = A function:
+ *
+ * Returns: Number of the arguments of $(D_PARAM F).
+ */
+template arity(F...)
+if (isCallable!F)
+{
+ static if (is(FunctionTypeOf!F T == function))
+ {
+ enum size_t arity = T.length;
+ }
+ else
+ {
+ static assert(false, "Function has no parameters");
+ }
+}
+
+///
+pure nothrow @safe @nogc unittest
+{
+ int func1(Object stuff = null, uint[] = null, uint k = 1);
+ static assert(arity!func1 == 3);
+
+ int func2();
+ static assert(arity!func2 == 0);
+
+ int func3(int, ...);
+ static assert(arity!func3 == 1);
+
+ int func4(int, int[]...);
+ static assert(arity!func4 == 2);
+}
+
+/// Attributes can be attached to a function.
+enum FunctionAttribute : uint
+{
+ none = 0x0000,
+ pure_ = 0x0001,
+ nothrow_ = 0x0002,
+ ref_ = 0x0004,
+ property = 0x0008,
+ trusted = 0x0010,
+ safe = 0x0020,
+ nogc = 0x0040,
+ system = 0x0080,
+ const_ = 0x0100,
+ immutable_ = 0x0200,
+ inout_ = 0x0400,
+ shared_ = 0x0800,
+ return_ = 0x1000,
+ scope_ = 0x2000,
+}
+
+/**
+ * Retrieves the attributes of the function $(D_PARAM F).
+ *
+ * The attributes are returned as a bit-mask of
+ * $(D_PSYMBOL FunctionAttribute) values.
+ *
+ * Params: A function.
+ *
+ * Returns: Attributes of the function $(D_PARAM F).
+ *
+ * See_Also: $(D_PSYMBOL FunctionAttribute).
+ */
+template functionAttributes(F...)
+if (isCallable!F)
+{
+ enum uint Impl()
+ {
+ uint attrs = FunctionAttribute.none;
+ foreach (a; __traits(getFunctionAttributes, F[0]))
+ {
+ static if (a == "const")
+ {
+ attrs |= FunctionAttribute.const_;
+ }
+ else static if (a == "immutable")
+ {
+ attrs |= FunctionAttribute.immutable_;
+ }
+ else static if (a == "inout")
+ {
+ attrs |= FunctionAttribute.inout_;
+ }
+ else static if (a == "@nogc")
+ {
+ attrs |= FunctionAttribute.nogc;
+ }
+ else static if (a == "nothrow")
+ {
+ attrs |= FunctionAttribute.nothrow_;
+ }
+ else static if (a == "@property")
+ {
+ attrs |= FunctionAttribute.property;
+ }
+ else static if (a == "pure")
+ {
+ attrs |= FunctionAttribute.pure_;
+ }
+ else static if (a == "ref")
+ {
+ attrs |= FunctionAttribute.ref_;
+ }
+ else static if (a == "return")
+ {
+ attrs |= FunctionAttribute.return_;
+ }
+ else static if (a == "@safe")
+ {
+ attrs |= FunctionAttribute.safe;
+ }
+ else static if (a == "scope")
+ {
+ attrs |= FunctionAttribute.scope_;
+ }
+ else static if (a == "shared")
+ {
+ attrs |= FunctionAttribute.shared_;
+ }
+ else static if (a == "system")
+ {
+ attrs |= FunctionAttribute.system;
+ }
+ else static if (a == "@trusted")
+ {
+ attrs |= FunctionAttribute.trusted;
+ }
+ }
+ return attrs;
+ }
+ enum uint functionAttributes = Impl();
+}
+
+///
+pure nothrow @safe @nogc unittest
+{
+ @property ref int func1() pure nothrow @safe @nogc shared scope;
+ static assert((functionAttributes!func1 & FunctionAttribute.pure_)
+ == FunctionAttribute.pure_);
+ static assert((functionAttributes!func1 & FunctionAttribute.nothrow_)
+ == FunctionAttribute.nothrow_);
+ static assert((functionAttributes!func1 & FunctionAttribute.safe)
+ == FunctionAttribute.safe);
+ static assert((functionAttributes!func1 & FunctionAttribute.nogc)
+ == FunctionAttribute.nogc);
+ static assert((functionAttributes!func1 & FunctionAttribute.shared_)
+ == FunctionAttribute.shared_);
+ static assert((functionAttributes!func1 & FunctionAttribute.ref_)
+ == FunctionAttribute.ref_);
+ static assert((functionAttributes!func1 & FunctionAttribute.property)
+ == FunctionAttribute.property);
+ static assert((functionAttributes!func1 & FunctionAttribute.scope_)
+ == FunctionAttribute.scope_);
+ static assert((functionAttributes!func1 & FunctionAttribute.system) == 0);
+ static assert((functionAttributes!func1 & FunctionAttribute.trusted) == 0);
+ static assert((functionAttributes!func1 & FunctionAttribute.return_) == 0);
+}
diff --git a/source/tanya/meta/transform.d b/source/tanya/meta/transform.d
index 82a5fc9..3499a13 100644
--- a/source/tanya/meta/transform.d
+++ b/source/tanya/meta/transform.d
@@ -617,3 +617,211 @@ pure nothrow @safe @nogc unittest
}
static assert(isSame!(TemplateOf!(T!int), T));
}
+
+/**
+ * Adds $(D_KEYWORD inout) qualifier to the type $(D_PARAM T).
+ *
+ * Params:
+ * T = A type.
+ *
+ * Returns: $(D_INLINECODE inout(T)).
+ */
+alias InoutOf(T) = inout(T);
+
+///
+pure nothrow @safe @nogc unittest
+{
+ static assert(is(InoutOf!int == inout int));
+}
+
+/**
+ * Adds $(D_KEYWORD inout) qualifier to the type $(D_PARAM T).
+ *
+ * Params:
+ * T = A type.
+ *
+ * Returns: $(D_INLINECODE inout(T)).
+ */
+alias ConstOf(T) = const(T);
+
+///
+pure nothrow @safe @nogc unittest
+{
+ static assert(is(ConstOf!int == const int));
+}
+
+/**
+ * Adds $(D_KEYWORD inout) qualifier to the type $(D_PARAM T).
+ *
+ * Params:
+ * T = A type.
+ *
+ * Returns: $(D_INLINECODE inout(T)).
+ */
+alias SharedOf(T) = shared(T);
+
+///
+pure nothrow @safe @nogc unittest
+{
+ static assert(is(SharedOf!int == shared int));
+}
+
+/**
+ * Adds $(D_KEYWORD inout) qualifier to the type $(D_PARAM T).
+ *
+ * Params:
+ * T = A type.
+ *
+ * Returns: $(D_INLINECODE inout(T)).
+ */
+alias SharedInoutOf(T) = shared(inout T);
+
+///
+pure nothrow @safe @nogc unittest
+{
+ static assert(is(SharedInoutOf!int == shared inout int));
+}
+
+/**
+ * Adds $(D_KEYWORD shared const) qualifier to the type $(D_PARAM T).
+ *
+ * Params:
+ * T = A type.
+ *
+ * Returns: $(D_INLINECODE shared(const T)).
+ */
+alias SharedConstOf(T) = shared(const T);
+
+///
+pure nothrow @safe @nogc unittest
+{
+ static assert(is(SharedConstOf!int == shared const int));
+}
+
+/**
+ * Adds $(D_KEYWORD immutable) qualifier to the type $(D_PARAM T).
+ *
+ * Params:
+ * T = A type.
+ *
+ * Returns: $(D_INLINECODE immutable(T)).
+ */
+alias ImmutableOf(T) = immutable(T);
+
+///
+pure nothrow @safe @nogc unittest
+{
+ static assert(is(ImmutableOf!int == immutable int));
+}
+
+/**
+ * Adds $(D_KEYWORD inout const) qualifier to the type $(D_PARAM T).
+ *
+ * Params:
+ * T = A type.
+ *
+ * Returns: $(D_INLINECODE inout(const T)).
+ */
+alias InoutConstOf(T) = inout(const T);
+
+///
+pure nothrow @safe @nogc unittest
+{
+ static assert(is(InoutConstOf!int == inout const int));
+}
+
+/**
+ * Adds $(D_KEYWORD shared inout const) qualifier to the type $(D_PARAM T).
+ *
+ * Params:
+ * T = A type.
+ *
+ * Returns: $(D_INLINECODE shared(inout const T)).
+ */
+alias SharedInoutConstOf(T) = shared(inout const T);
+
+///
+pure nothrow @safe @nogc unittest
+{
+ static assert(is(SharedInoutConstOf!int == shared inout const int));
+}
+
+/**
+ * Returns a template with one argument which applies all qualifiers of
+ * $(D_PARAM T) on its argument if instantiated.
+ *
+ * Params:
+ * T = A type.
+ *
+ * Returns: $(D_INLINECODE shared(inout const T)).
+ */
+template QualifierOf(T)
+{
+ static if (is(T U == const U))
+ {
+ alias QualifierOf = ConstOf;
+ }
+ else static if (is(T U == immutable U))
+ {
+ alias QualifierOf = ImmutableOf;
+ }
+ else static if (is(T U == inout U))
+ {
+ alias QualifierOf = InoutOf;
+ }
+ else static if (is(T U == inout const U))
+ {
+ alias QualifierOf = InoutConstOf;
+ }
+ else static if (is(T U == shared U))
+ {
+ alias QualifierOf = SharedOf;
+ }
+ else static if (is(T U == shared const U))
+ {
+ alias QualifierOf = SharedConstOf;
+ }
+ else static if (is(T U == shared inout U))
+ {
+ alias QualifierOf = SharedInoutOf;
+ }
+ else static if (is(T U == shared inout const U))
+ {
+ alias QualifierOf = SharedInoutConstOf;
+ }
+ else
+ {
+ alias QualifierOf(T) = T;
+ }
+}
+
+///
+pure nothrow @safe @nogc unittest
+{
+ alias MutableOf = QualifierOf!int;
+ static assert(is(MutableOf!uint == uint));
+
+ alias ConstOf = QualifierOf!(const int);
+ static assert(is(ConstOf!uint == const uint));
+
+ alias InoutOf = QualifierOf!(inout int);
+ static assert(is(InoutOf!uint == inout uint));
+
+ alias InoutConstOf = QualifierOf!(inout const int);
+ static assert(is(InoutConstOf!uint == inout const uint));
+
+ alias ImmutableOf = QualifierOf!(immutable int);
+ static assert(is(ImmutableOf!uint == immutable uint));
+
+ alias SharedOf = QualifierOf!(shared int);
+ static assert(is(SharedOf!uint == shared uint));
+
+ alias SharedConstOf = QualifierOf!(shared const int);
+ static assert(is(SharedConstOf!uint == shared const uint));
+
+ alias SharedInoutOf = QualifierOf!(shared inout int);
+ static assert(is(SharedInoutOf!uint == shared inout uint));
+
+ alias SharedInoutConstOf = QualifierOf!(shared inout const int);
+ static assert(is(SharedInoutConstOf!uint == shared inout const uint));
+}
diff --git a/source/tanya/net/inet.d b/source/tanya/net/inet.d
index 96b87f7..f88eb11 100644
--- a/source/tanya/net/inet.d
+++ b/source/tanya/net/inet.d
@@ -16,21 +16,8 @@ module tanya.net.inet;
import std.math;
import std.range.primitives;
-import std.traits;
-
-version (unittest)
-{
- version (Windows)
- {
- import core.sys.windows.winsock2;
- version = PlattformUnittest;
- }
- else version (Posix)
- {
- import core.sys.posix.arpa.inet;
- version = PlattformUnittest;
- }
-}
+import tanya.meta.trait;
+import tanya.meta.transform;
/**
* Represents an unsigned integer as an $(D_KEYWORD ubyte) range.
@@ -212,79 +199,6 @@ private unittest
static assert(!is(NetworkOrder!1));
}
-// Tests against the system's htonl, htons.
-version (PlattformUnittest)
-{
- private unittest
- {
- for (uint counter; counter <= 8 * uint.sizeof; ++counter)
- {
- const value = pow(2, counter) - 1;
- const inNetworkOrder = htonl(value);
- const p = cast(ubyte*) &inNetworkOrder;
- auto networkOrder = NetworkOrder!4(value);
-
- assert(networkOrder.length == 4);
- assert(!networkOrder.empty);
- assert(networkOrder.front == *p);
- assert(networkOrder.back == *(p + 3));
-
- networkOrder.popBack();
- assert(networkOrder.length == 3);
- assert(networkOrder.front == *p);
- assert(networkOrder.back == *(p + 2));
-
- networkOrder.popFront();
- assert(networkOrder.length == 2);
- assert(networkOrder.front == *(p + 1));
- assert(networkOrder.back == *(p + 2));
-
- networkOrder.popFront();
- assert(networkOrder.length == 1);
- assert(networkOrder.front == *(p + 2));
- assert(networkOrder.back == *(p + 2));
-
- networkOrder.popBack();
- assert(networkOrder.length == 0);
- assert(networkOrder.empty);
- }
-
- for (ushort counter; counter <= 8 * ushort.sizeof; ++counter)
- {
- const value = cast(ushort) (pow(2, counter) - 1);
- const inNetworkOrder = htons(value);
- const p = cast(ubyte*) &inNetworkOrder;
-
- auto networkOrder = NetworkOrder!2(value);
-
- assert(networkOrder.length == 2);
- assert(!networkOrder.empty);
- assert(networkOrder.front == *p);
- assert(networkOrder.back == *(p + 1));
-
- networkOrder.popBack();
- assert(networkOrder.length == 1);
- assert(networkOrder.front == *p);
- assert(networkOrder.back == *p);
-
- networkOrder.popBack();
- assert(networkOrder.length == 0);
- assert(networkOrder.empty);
-
- networkOrder = NetworkOrder!2(value);
-
- networkOrder.popFront();
- assert(networkOrder.length == 1);
- assert(networkOrder.front == *(p + 1));
- assert(networkOrder.back == *(p + 1));
-
- networkOrder.popFront();
- assert(networkOrder.length == 0);
- assert(networkOrder.empty);
- }
- }
-}
-
/**
* Converts the $(D_KEYWORD ubyte) input range $(D_PARAM range) to
* $(D_PARAM T).
@@ -330,29 +244,3 @@ pure nothrow @safe @nogc unittest
auto networkOrder = NetworkOrder!4(value);
assert(networkOrder.toHostOrder() == value);
}
-
-// Tests against the system's htonl, htons.
-version (PlattformUnittest)
-{
- private unittest
- {
- for (uint counter; counter <= 8 * uint.sizeof; ++counter)
- {
- const value = pow(2, counter) - 1;
- const inNetworkOrder = htonl(value);
- const p = cast(ubyte*) &inNetworkOrder;
- auto networkOrder = NetworkOrder!4(value);
-
- assert(p[0 .. uint.sizeof].toHostOrder() == value);
- }
- for (ushort counter; counter <= 8 * ushort.sizeof; ++counter)
- {
- const value = cast(ushort) (pow(2, counter) - 1);
- const inNetworkOrder = htons(value);
- const p = cast(ubyte*) &inNetworkOrder;
- auto networkOrder = NetworkOrder!2(value);
-
- assert(p[0 .. ushort.sizeof].toHostOrder() == value);
- }
- }
-}
diff --git a/source/tanya/typecons.d b/source/tanya/typecons.d
index d9d41fb..66ee8c9 100644
--- a/source/tanya/typecons.d
+++ b/source/tanya/typecons.d
@@ -17,7 +17,7 @@
*/
module tanya.typecons;
-import std.meta;
+import tanya.meta.metafunction;
/**
* $(D_PSYMBOL Pair) can store two heterogeneous objects.