Merge os, middle and meta subpackages
This commit is contained in:
8
dub.json
8
dub.json
@@ -10,18 +10,12 @@
|
|||||||
"targetType": "library",
|
"targetType": "library",
|
||||||
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tanya:meta": "*",
|
|
||||||
"tanya:os": "*",
|
|
||||||
"tanya:middle": "*",
|
"tanya:middle": "*",
|
||||||
"tanya:test": "*",
|
|
||||||
"mir-linux-kernel": "~>1.0.0"
|
"mir-linux-kernel": "~>1.0.0"
|
||||||
},
|
},
|
||||||
|
|
||||||
"subPackages": [
|
"subPackages": [
|
||||||
"./meta",
|
"./middle"
|
||||||
"./os",
|
|
||||||
"./middle",
|
|
||||||
"./test"
|
|
||||||
],
|
],
|
||||||
|
|
||||||
"configurations": [
|
"configurations": [
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "meta",
|
|
||||||
"description": "Template metaprogramming",
|
|
||||||
"targetType": "library",
|
|
||||||
|
|
||||||
"sourcePaths": [
|
|
||||||
"."
|
|
||||||
],
|
|
||||||
"importPaths": [
|
|
||||||
"."
|
|
||||||
],
|
|
||||||
"dflags-dmd": ["-dip1000"]
|
|
||||||
}
|
|
@@ -1,22 +0,0 @@
|
|||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Template metaprogramming.
|
|
||||||
*
|
|
||||||
* This package contains utilities to acquire type information at compile-time,
|
|
||||||
* to transform from one type to another. It has also different algorithms for
|
|
||||||
* iterating, searching and modifying template arguments.
|
|
||||||
*
|
|
||||||
* Copyright: Eugene Wissner 2017-2025.
|
|
||||||
* 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/meta/tanya/meta/package.d,
|
|
||||||
* tanya/meta/package.d)
|
|
||||||
*/
|
|
||||||
module tanya.meta;
|
|
||||||
|
|
||||||
public import tanya.meta.metafunction;
|
|
||||||
public import tanya.meta.trait;
|
|
@@ -1,150 +0,0 @@
|
|||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type traits.
|
|
||||||
*
|
|
||||||
* Templates in this module are used to obtain type information at compile
|
|
||||||
* time.
|
|
||||||
*
|
|
||||||
* Copyright: Eugene Wissner 2017-2025.
|
|
||||||
* 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/meta/tanya/meta/trait.d,
|
|
||||||
* tanya/meta/trait.d)
|
|
||||||
*/
|
|
||||||
module tanya.meta.trait;
|
|
||||||
|
|
||||||
import std.traits : OriginalType, Unqual, isStaticArray, isUnsigned;
|
|
||||||
import tanya.meta.metafunction;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether $(D_PARAM T) is a wide string, i.e. consists of
|
|
||||||
* $(D_KEYWORD dchar).
|
|
||||||
*
|
|
||||||
* The character type of the string and the string itself can have any type
|
|
||||||
* qualifiers.
|
|
||||||
*
|
|
||||||
* Static $(D_KEYWORD dchar) arrays are not considered strings.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* T = A type.
|
|
||||||
*
|
|
||||||
* Returns: $(D_KEYWORD true) if $(D_PARAM T) is a wide string,
|
|
||||||
* $(D_KEYWORD false) otherwise.
|
|
||||||
*/
|
|
||||||
enum bool isWideString(T) = is(immutable T == immutable dchar[]);
|
|
||||||
|
|
||||||
///
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
static assert(isWideString!(dchar[]));
|
|
||||||
static assert(!isWideString!(char[]));
|
|
||||||
static assert(!isWideString!(wchar[]));
|
|
||||||
|
|
||||||
static assert(isWideString!dstring);
|
|
||||||
static assert(!isWideString!string);
|
|
||||||
static assert(!isWideString!wstring);
|
|
||||||
|
|
||||||
static assert(isWideString!(const dstring));
|
|
||||||
static assert(!isWideString!(const string));
|
|
||||||
static assert(!isWideString!(const wstring));
|
|
||||||
|
|
||||||
static assert(isWideString!(shared dstring));
|
|
||||||
static assert(!isWideString!(shared string));
|
|
||||||
static assert(!isWideString!(shared wstring));
|
|
||||||
|
|
||||||
static assert(isWideString!(const(dchar)[]));
|
|
||||||
static assert(isWideString!(inout(dchar)[]));
|
|
||||||
static assert(isWideString!(shared(const(dchar))[]));
|
|
||||||
static assert(isWideString!(shared(dchar)[]));
|
|
||||||
static assert(!isWideString!(dchar[10]));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Tests whether $(D_PARAM T) is an interface.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* T = A type.
|
|
||||||
*
|
|
||||||
* Returns: $(D_KEYWORD true) if $(D_PARAM T) is an interface,
|
|
||||||
* $(D_KEYWORD false) otherwise.
|
|
||||||
*/
|
|
||||||
private enum bool isInterface(T) = is(T == interface);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether $(D_PARAM T) is a polymorphic type, i.e. a
|
|
||||||
* $(D_KEYWORD class) or an $(D_KEYWORD interface).
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* T = A type.
|
|
||||||
*
|
|
||||||
* Returns: $(D_KEYWORD true) if $(D_PARAM T) is a $(D_KEYWORD class) or an
|
|
||||||
* $(D_KEYWORD interface), $(D_KEYWORD false) otherwise.
|
|
||||||
*/
|
|
||||||
enum bool isPolymorphicType(T) = is(T == class) || is(T == interface);
|
|
||||||
|
|
||||||
///
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
interface I
|
|
||||||
{
|
|
||||||
}
|
|
||||||
static assert(isPolymorphicType!Object);
|
|
||||||
static assert(isPolymorphicType!I);
|
|
||||||
static assert(!isPolymorphicType!short);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the size in bytes of the state that needs to be allocated to hold an
|
|
||||||
* object of type $(D_PARAM T).
|
|
||||||
*
|
|
||||||
* There is a difference between the `.sizeof`-property and
|
|
||||||
* $(D_PSYMBOL stateSize) if $(D_PARAM T) is a class or an interface.
|
|
||||||
* `T.sizeof` is constant on the given architecture then and is the same as
|
|
||||||
* `size_t.sizeof` and `ptrdiff_t.sizeof`. This is because classes and
|
|
||||||
* interfaces are reference types and `.sizeof` returns the size of the
|
|
||||||
* reference which is the same as the size of a pointer. $(D_PSYMBOL stateSize)
|
|
||||||
* returns the size of the instance itself.
|
|
||||||
*
|
|
||||||
* The size of a dynamic array is `size_t.sizeof * 2` since a dynamic array
|
|
||||||
* stores its length and a data pointer. The size of the static arrays is
|
|
||||||
* calculated differently since they are value types. It is the array length
|
|
||||||
* multiplied by the element size.
|
|
||||||
*
|
|
||||||
* `stateSize!void` is `1` since $(D_KEYWORD void) is mostly used as a synonym
|
|
||||||
* for $(D_KEYWORD byte)/$(D_KEYWORD ubyte) in `void*`.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* T = Object type.
|
|
||||||
*
|
|
||||||
* Returns: Size of an instance of type $(D_PARAM T).
|
|
||||||
*/
|
|
||||||
template stateSize(T)
|
|
||||||
{
|
|
||||||
static if (isPolymorphicType!T)
|
|
||||||
{
|
|
||||||
enum size_t stateSize = __traits(classInstanceSize, T);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
enum size_t stateSize = T.sizeof;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
static assert(stateSize!int == 4);
|
|
||||||
static assert(stateSize!bool == 1);
|
|
||||||
static assert(stateSize!(int[]) == (size_t.sizeof * 2));
|
|
||||||
static assert(stateSize!(short[3]) == 6);
|
|
||||||
|
|
||||||
static struct Empty
|
|
||||||
{
|
|
||||||
}
|
|
||||||
static assert(stateSize!Empty == 1);
|
|
||||||
static assert(stateSize!void == 1);
|
|
||||||
}
|
|
@@ -3,11 +3,6 @@
|
|||||||
"description": "Runtime, middle-level utilities",
|
"description": "Runtime, middle-level utilities",
|
||||||
"targetType": "library",
|
"targetType": "library",
|
||||||
|
|
||||||
"dependencies": {
|
|
||||||
"tanya:meta": "*",
|
|
||||||
"tanya:os": "*"
|
|
||||||
},
|
|
||||||
|
|
||||||
"dependencies-linux": {
|
"dependencies-linux": {
|
||||||
"mir-linux-kernel": "~>1.0.0"
|
"mir-linux-kernel": "~>1.0.0"
|
||||||
},
|
},
|
||||||
|
@@ -17,9 +17,9 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.memory.allocator;
|
module tanya.memory.allocator;
|
||||||
|
|
||||||
import std.traits : hasElaborateDestructor, isAssociativeArray, isArray;
|
import std.traits;
|
||||||
import tanya.memory.lifetime;
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract class implementing a basic allocator.
|
* Abstract class implementing a basic allocator.
|
||||||
|
@@ -14,11 +14,10 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.memory.lifetime;
|
module tanya.memory.lifetime;
|
||||||
|
|
||||||
import std.traits : isInnerClass, hasElaborateAssign, hasElaborateCopyConstructor, hasElaborateDestructor,
|
import std.traits;
|
||||||
isAssignable, isNested, isAbstractClass, isAggregateType, isStaticArray;
|
import std.meta : AliasSeq;
|
||||||
import tanya.memory.allocator;
|
import tanya.memory.allocator;
|
||||||
import tanya.meta.metafunction;
|
import tanya.meta;
|
||||||
import tanya.meta.trait;
|
|
||||||
|
|
||||||
package(tanya) void destroyAllImpl(R, E)(R p)
|
package(tanya) void destroyAllImpl(R, E)(R p)
|
||||||
{
|
{
|
||||||
|
@@ -23,10 +23,10 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.memory.smartref;
|
module tanya.memory.smartref;
|
||||||
|
|
||||||
import std.traits : isPointer, isAbstractClass, isAssociativeArray, isDynamicArray, isArray;
|
import std.traits;
|
||||||
import tanya.memory.allocator;
|
import tanya.memory.allocator;
|
||||||
import tanya.memory.lifetime;
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
|
|
||||||
private template Payload(T)
|
private template Payload(T)
|
||||||
{
|
{
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.os.error;
|
module tanya.os.error;
|
||||||
|
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
|
|
||||||
// Socket API error.
|
// Socket API error.
|
||||||
private template SAError(int posix, int wsa = posix)
|
private template SAError(int posix, int wsa = posix)
|
17
os/dub.json
17
os/dub.json
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "os",
|
|
||||||
"description": "Platform-independent interfaces to operating system functionality",
|
|
||||||
"targetType": "library",
|
|
||||||
|
|
||||||
"dependencies": {
|
|
||||||
"tanya:meta": "*"
|
|
||||||
},
|
|
||||||
|
|
||||||
"sourcePaths": [
|
|
||||||
"."
|
|
||||||
],
|
|
||||||
"importPaths": [
|
|
||||||
"."
|
|
||||||
],
|
|
||||||
"dflags-dmd": ["-dip1000"]
|
|
||||||
}
|
|
@@ -20,10 +20,10 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.algorithm.iteration;
|
module tanya.algorithm.iteration;
|
||||||
|
|
||||||
import std.traits : Unqual, isMutable;
|
import std.traits;
|
||||||
import std.typecons;
|
import std.typecons;
|
||||||
import tanya.memory.lifetime;
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
import tanya.range;
|
import tanya.range;
|
||||||
|
|
||||||
private struct SingletonByValue(E)
|
private struct SingletonByValue(E)
|
||||||
|
@@ -14,11 +14,10 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.algorithm.mutation;
|
module tanya.algorithm.mutation;
|
||||||
|
|
||||||
import std.traits : Unqual, hasElaborateAssign, hasElaborateCopyConstructor, hasElaborateDestructor, isAssignable,
|
import std.traits;
|
||||||
isDynamicArray;
|
|
||||||
static import tanya.memory.lifetime;
|
static import tanya.memory.lifetime;
|
||||||
static import tanya.memory.op;
|
static import tanya.memory.op;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
import tanya.range;
|
import tanya.range;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -18,11 +18,11 @@ import core.checkedint;
|
|||||||
import std.algorithm.comparison;
|
import std.algorithm.comparison;
|
||||||
import std.algorithm.iteration;
|
import std.algorithm.iteration;
|
||||||
import std.algorithm.mutation : bringToFront;
|
import std.algorithm.mutation : bringToFront;
|
||||||
import std.traits : PointerTarget, Unqual, hasElaborateDestructor, isImplicitlyConvertible, isCopyable;
|
import std.traits;
|
||||||
import tanya.algorithm.mutation;
|
import tanya.algorithm.mutation;
|
||||||
import tanya.memory.allocator;
|
import tanya.memory.allocator;
|
||||||
import tanya.memory.lifetime;
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
import tanya.range;
|
import tanya.range;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -16,7 +16,7 @@ module tanya.container.buffer;
|
|||||||
|
|
||||||
import std.traits : isScalarType;
|
import std.traits : isScalarType;
|
||||||
import tanya.memory.allocator;
|
import tanya.memory.allocator;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
|
|
||||||
version (unittest)
|
version (unittest)
|
||||||
{
|
{
|
||||||
|
@@ -14,11 +14,11 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.container.entry;
|
module tanya.container.entry;
|
||||||
|
|
||||||
import std.traits : Unqual, hasElaborateDestructor;
|
import std.traits;
|
||||||
import tanya.container.array;
|
import tanya.container.array;
|
||||||
import tanya.memory.allocator;
|
import tanya.memory.allocator;
|
||||||
import tanya.memory.lifetime;
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
|
|
||||||
package struct SEntry(T)
|
package struct SEntry(T)
|
||||||
{
|
{
|
||||||
|
@@ -15,14 +15,14 @@
|
|||||||
module tanya.container.hashtable;
|
module tanya.container.hashtable;
|
||||||
|
|
||||||
import std.algorithm.iteration;
|
import std.algorithm.iteration;
|
||||||
import std.traits : CopyConstness, Unqual, ifTestable, isMutable;
|
import std.traits;
|
||||||
import tanya.algorithm.mutation;
|
import tanya.algorithm.mutation;
|
||||||
import tanya.container.array;
|
import tanya.container.array;
|
||||||
import tanya.container.entry;
|
import tanya.container.entry;
|
||||||
import tanya.hash.lookup;
|
import tanya.hash.lookup;
|
||||||
import tanya.memory.allocator;
|
import tanya.memory.allocator;
|
||||||
import tanya.memory.lifetime;
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
import tanya.range.primitive;
|
import tanya.range.primitive;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -17,11 +17,11 @@ module tanya.container.list;
|
|||||||
|
|
||||||
import std.algorithm.comparison;
|
import std.algorithm.comparison;
|
||||||
import std.algorithm.iteration;
|
import std.algorithm.iteration;
|
||||||
import std.traits : Unqual, isImplicitlyConvertible, isCopyable;
|
import std.traits;
|
||||||
import tanya.container.entry;
|
import tanya.container.entry;
|
||||||
import tanya.memory.allocator;
|
import tanya.memory.allocator;
|
||||||
import tanya.memory.lifetime;
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
import tanya.range.array;
|
import tanya.range.array;
|
||||||
import tanya.range.primitive;
|
import tanya.range.primitive;
|
||||||
|
|
||||||
|
@@ -15,13 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.container.set;
|
module tanya.container.set;
|
||||||
|
|
||||||
import std.traits : CopyConstness, Unqual, ifTestable, isImplicitlyConvertible, isMutable;
|
import std.traits;
|
||||||
import tanya.container.array;
|
import tanya.container.array;
|
||||||
import tanya.container.entry;
|
import tanya.container.entry;
|
||||||
import tanya.hash.lookup;
|
import tanya.hash.lookup;
|
||||||
import tanya.memory.allocator;
|
import tanya.memory.allocator;
|
||||||
import tanya.memory.lifetime;
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
import tanya.range.primitive;
|
import tanya.range.primitive;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -28,12 +28,12 @@ module tanya.container.string;
|
|||||||
|
|
||||||
import std.algorithm.comparison;
|
import std.algorithm.comparison;
|
||||||
import std.algorithm.mutation : bringToFront;
|
import std.algorithm.mutation : bringToFront;
|
||||||
import std.traits : CopyConstness, Unqual, isInstanceOf, isSomeChar, isNarrowString;
|
import std.traits;
|
||||||
import tanya.algorithm.mutation;
|
import tanya.algorithm.mutation;
|
||||||
import tanya.hash.lookup;
|
import tanya.hash.lookup;
|
||||||
import tanya.memory.allocator;
|
import tanya.memory.allocator;
|
||||||
import tanya.memory.lifetime;
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
import tanya.range.array;
|
import tanya.range.array;
|
||||||
import tanya.range.primitive;
|
import tanya.range.primitive;
|
||||||
|
|
||||||
|
@@ -14,11 +14,10 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.conv;
|
module tanya.conv;
|
||||||
|
|
||||||
import std.traits : Unsigned, isNumeric, Largest, Unqual, EnumMembers, isFloatingPoint, isSomeChar, isSigned,
|
import std.traits;
|
||||||
isUnsigned, isIntegral, isSomeString;
|
|
||||||
import tanya.container.string;
|
import tanya.container.string;
|
||||||
import tanya.memory.allocator;
|
import tanya.memory.allocator;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
import tanya.range;
|
import tanya.range;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -49,12 +49,13 @@ module tanya.format;
|
|||||||
|
|
||||||
import std.algorithm.comparison;
|
import std.algorithm.comparison;
|
||||||
import std.ascii;
|
import std.ascii;
|
||||||
import std.traits : Unqual, isPointer, isSomeChar, isFloatingPoint, isSomeFunction, isIntegral, isSomeString;
|
import std.math : signbit;
|
||||||
|
import std.meta;
|
||||||
|
import std.traits;
|
||||||
import tanya.container.string;
|
import tanya.container.string;
|
||||||
import tanya.math;
|
import tanya.math;
|
||||||
static import tanya.memory.op;
|
static import tanya.memory.op;
|
||||||
import tanya.meta.metafunction;
|
import tanya.meta;
|
||||||
import tanya.meta.trait;
|
|
||||||
import tanya.range;
|
import tanya.range;
|
||||||
|
|
||||||
// Returns the last part of buffer with converted number.
|
// Returns the last part of buffer with converted number.
|
||||||
@@ -1952,7 +1953,7 @@ private const(char)[] real2String(double value,
|
|||||||
const FloatBits!double bits = { value };
|
const FloatBits!double bits = { value };
|
||||||
|
|
||||||
exponent = (bits.integral >> 52) & 0x7ff;
|
exponent = (bits.integral >> 52) & 0x7ff;
|
||||||
sign = signBit(value);
|
sign = !!signbit(value);
|
||||||
if (sign)
|
if (sign)
|
||||||
{
|
{
|
||||||
value = -value;
|
value = -value;
|
||||||
|
@@ -14,8 +14,8 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.hash.lookup;
|
module tanya.hash.lookup;
|
||||||
|
|
||||||
import std.traits : isScalarType, isPointer, isSomeChar, isArray, isIntegral, isBoolean;
|
import std.traits;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
import tanya.range.primitive;
|
import tanya.range.primitive;
|
||||||
|
|
||||||
private struct Hasher
|
private struct Hasher
|
||||||
|
@@ -22,8 +22,8 @@
|
|||||||
module tanya.math;
|
module tanya.math;
|
||||||
|
|
||||||
import std.math;
|
import std.math;
|
||||||
import std.traits : Unqual, isFloatingPoint;
|
import std.traits;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
|
|
||||||
/// Floating-point number precisions according to IEEE-754.
|
/// Floating-point number precisions according to IEEE-754.
|
||||||
enum IEEEPrecision : ubyte
|
enum IEEEPrecision : ubyte
|
||||||
@@ -113,433 +113,3 @@ package(tanya) union FloatBits(F)
|
|||||||
static assert(false, "Unsupported IEEE 754 floating point precision");
|
static assert(false, "Unsupported IEEE 754 floating point precision");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Floating-point number classifications.
|
|
||||||
*/
|
|
||||||
enum FloatingPointClass : ubyte
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Not a Number.
|
|
||||||
*
|
|
||||||
* See_Also: $(D_PSYMBOL isNaN).
|
|
||||||
*/
|
|
||||||
nan,
|
|
||||||
|
|
||||||
/// Zero.
|
|
||||||
zero,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Infinity.
|
|
||||||
*
|
|
||||||
* See_Also: $(D_PSYMBOL isInfinity).
|
|
||||||
*/
|
|
||||||
infinite,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Denormalized number.
|
|
||||||
*
|
|
||||||
* See_Also: $(D_PSYMBOL isSubnormal).
|
|
||||||
*/
|
|
||||||
subnormal,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Normalized number.
|
|
||||||
*
|
|
||||||
* See_Also: $(D_PSYMBOL isNormal).
|
|
||||||
*/
|
|
||||||
normal,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether $(D_PARAM x) is a NaN, zero, infinity, subnormal or
|
|
||||||
* normalized number.
|
|
||||||
*
|
|
||||||
* This function doesn't distinguish between negative and positive infinity,
|
|
||||||
* negative and positive NaN or negative and positive zero.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* F = Type of the floating point number.
|
|
||||||
* x = Floating point number.
|
|
||||||
*
|
|
||||||
* Returns: Classification of $(D_PARAM x).
|
|
||||||
*/
|
|
||||||
FloatingPointClass classify(F)(F x)
|
|
||||||
if (isFloatingPoint!F)
|
|
||||||
{
|
|
||||||
if (x == 0)
|
|
||||||
{
|
|
||||||
return FloatingPointClass.zero;
|
|
||||||
}
|
|
||||||
FloatBits!F bits;
|
|
||||||
bits.floating = abs(x);
|
|
||||||
|
|
||||||
static if (ieeePrecision!F == IEEEPrecision.single)
|
|
||||||
{
|
|
||||||
if (bits.integral > bits.expMask)
|
|
||||||
{
|
|
||||||
return FloatingPointClass.nan;
|
|
||||||
}
|
|
||||||
else if (bits.integral == bits.expMask)
|
|
||||||
{
|
|
||||||
return FloatingPointClass.infinite;
|
|
||||||
}
|
|
||||||
else if (bits.integral < (1 << 23))
|
|
||||||
{
|
|
||||||
return FloatingPointClass.subnormal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else static if (ieeePrecision!F == IEEEPrecision.double_)
|
|
||||||
{
|
|
||||||
if (bits.integral > bits.expMask)
|
|
||||||
{
|
|
||||||
return FloatingPointClass.nan;
|
|
||||||
}
|
|
||||||
else if (bits.integral == bits.expMask)
|
|
||||||
{
|
|
||||||
return FloatingPointClass.infinite;
|
|
||||||
}
|
|
||||||
else if (bits.integral < (1L << 52))
|
|
||||||
{
|
|
||||||
return FloatingPointClass.subnormal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else static if (ieeePrecision!F == IEEEPrecision.doubleExtended)
|
|
||||||
{
|
|
||||||
if (bits.exp == bits.expMask)
|
|
||||||
{
|
|
||||||
if ((bits.mantissa & bits.mantissaMask) == 0)
|
|
||||||
{
|
|
||||||
return FloatingPointClass.infinite;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return FloatingPointClass.nan;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (bits.exp == 0)
|
|
||||||
{
|
|
||||||
return FloatingPointClass.subnormal;
|
|
||||||
}
|
|
||||||
else if (bits.mantissa < (1L << 63)) // "Unnormal".
|
|
||||||
{
|
|
||||||
return FloatingPointClass.nan;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FloatingPointClass.normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
assert(classify(0.0) == FloatingPointClass.zero);
|
|
||||||
assert(classify(double.nan) == FloatingPointClass.nan);
|
|
||||||
assert(classify(double.infinity) == FloatingPointClass.infinite);
|
|
||||||
assert(classify(-double.infinity) == FloatingPointClass.infinite);
|
|
||||||
assert(classify(1.4) == FloatingPointClass.normal);
|
|
||||||
assert(classify(1.11254e-307 / 10) == FloatingPointClass.subnormal);
|
|
||||||
|
|
||||||
assert(classify(0.0f) == FloatingPointClass.zero);
|
|
||||||
assert(classify(float.nan) == FloatingPointClass.nan);
|
|
||||||
assert(classify(float.infinity) == FloatingPointClass.infinite);
|
|
||||||
assert(classify(-float.infinity) == FloatingPointClass.infinite);
|
|
||||||
assert(classify(0.3) == FloatingPointClass.normal);
|
|
||||||
assert(classify(5.87747e-38f / 10) == FloatingPointClass.subnormal);
|
|
||||||
|
|
||||||
assert(classify(0.0L) == FloatingPointClass.zero);
|
|
||||||
assert(classify(real.nan) == FloatingPointClass.nan);
|
|
||||||
assert(classify(real.infinity) == FloatingPointClass.infinite);
|
|
||||||
assert(classify(-real.infinity) == FloatingPointClass.infinite);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether $(D_PARAM x) is a finite number.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* F = Type of the floating point number.
|
|
||||||
* x = Floating point number.
|
|
||||||
*
|
|
||||||
* Returns: $(D_KEYWORD true) if $(D_PARAM x) is a finite number,
|
|
||||||
* $(D_KEYWORD false) otherwise.
|
|
||||||
*
|
|
||||||
* See_Also: $(D_PSYMBOL isInfinity).
|
|
||||||
*/
|
|
||||||
bool isFinite(F)(F x)
|
|
||||||
if (isFloatingPoint!F)
|
|
||||||
{
|
|
||||||
FloatBits!F bits;
|
|
||||||
static if (ieeePrecision!F == IEEEPrecision.single
|
|
||||||
|| ieeePrecision!F == IEEEPrecision.double_)
|
|
||||||
{
|
|
||||||
bits.floating = x;
|
|
||||||
bits.integral &= bits.expMask;
|
|
||||||
return bits.integral != bits.expMask;
|
|
||||||
}
|
|
||||||
else static if (ieeePrecision!F == IEEEPrecision.doubleExtended)
|
|
||||||
{
|
|
||||||
bits.floating = abs(x);
|
|
||||||
return (bits.exp != bits.expMask)
|
|
||||||
&& (bits.exp == 0 || bits.mantissa >= (1L << 63));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
assert(!isFinite(float.infinity));
|
|
||||||
assert(!isFinite(-double.infinity));
|
|
||||||
assert(isFinite(0.0));
|
|
||||||
assert(!isFinite(float.nan));
|
|
||||||
assert(isFinite(5.87747e-38f / 10));
|
|
||||||
assert(isFinite(1.11254e-307 / 10));
|
|
||||||
assert(isFinite(0.5));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether $(D_PARAM x) is $(B n)ot $(B a) $(B n)umber (NaN).
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* F = Type of the floating point number.
|
|
||||||
* x = Floating point number.
|
|
||||||
*
|
|
||||||
* Returns: $(D_KEYWORD true) if $(D_PARAM x) is not a number,
|
|
||||||
* $(D_KEYWORD false) otherwise.
|
|
||||||
*/
|
|
||||||
bool isNaN(F)(F x)
|
|
||||||
if (isFloatingPoint!F)
|
|
||||||
{
|
|
||||||
FloatBits!F bits;
|
|
||||||
bits.floating = abs(x);
|
|
||||||
|
|
||||||
static if (ieeePrecision!F == IEEEPrecision.single
|
|
||||||
|| ieeePrecision!F == IEEEPrecision.double_)
|
|
||||||
{
|
|
||||||
return bits.integral > bits.expMask;
|
|
||||||
}
|
|
||||||
else static if (ieeePrecision!F == IEEEPrecision.doubleExtended)
|
|
||||||
{
|
|
||||||
const maskedMantissa = bits.mantissa & bits.mantissaMask;
|
|
||||||
if ((bits.exp == bits.expMask && maskedMantissa != 0)
|
|
||||||
|| ((bits.exp != 0) && (bits.mantissa < (1L << 63))))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
assert(isNaN(float.init));
|
|
||||||
assert(isNaN(double.init));
|
|
||||||
assert(isNaN(real.init));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether $(D_PARAM x) is a positive or negative infinity.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* F = Type of the floating point number.
|
|
||||||
* x = Floating point number.
|
|
||||||
*
|
|
||||||
* Returns: $(D_KEYWORD true) if $(D_PARAM x) is infinity, $(D_KEYWORD false)
|
|
||||||
* otherwise.
|
|
||||||
*
|
|
||||||
* See_Also: $(D_PSYMBOL isFinite).
|
|
||||||
*/
|
|
||||||
bool isInfinity(F)(F x)
|
|
||||||
if (isFloatingPoint!F)
|
|
||||||
{
|
|
||||||
FloatBits!F bits;
|
|
||||||
bits.floating = abs(x);
|
|
||||||
static if (ieeePrecision!F == IEEEPrecision.single
|
|
||||||
|| ieeePrecision!F == IEEEPrecision.double_)
|
|
||||||
{
|
|
||||||
return bits.integral == bits.expMask;
|
|
||||||
}
|
|
||||||
else static if (ieeePrecision!F == IEEEPrecision.doubleExtended)
|
|
||||||
{
|
|
||||||
return (bits.exp == bits.expMask)
|
|
||||||
&& ((bits.mantissa & bits.mantissaMask) == 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
assert(isInfinity(float.infinity));
|
|
||||||
assert(isInfinity(-float.infinity));
|
|
||||||
assert(isInfinity(double.infinity));
|
|
||||||
assert(isInfinity(-double.infinity));
|
|
||||||
assert(isInfinity(real.infinity));
|
|
||||||
assert(isInfinity(-real.infinity));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether $(D_PARAM x) is a denormilized number or not.
|
|
||||||
*
|
|
||||||
* Denormalized number is a number between `0` and `1` that cannot be
|
|
||||||
* represented as
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* m*2<sup>e</sup>
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* where $(I m) is the mantissa and $(I e) is an exponent that fits into the
|
|
||||||
* exponent field of the type $(D_PARAM F).
|
|
||||||
*
|
|
||||||
* `0` is neither normalized nor denormalized.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* F = Type of the floating point number.
|
|
||||||
* x = Floating point number.
|
|
||||||
*
|
|
||||||
* Returns: $(D_KEYWORD true) if $(D_PARAM x) is a denormilized number,
|
|
||||||
* $(D_KEYWORD false) otherwise.
|
|
||||||
*
|
|
||||||
* See_Also: $(D_PSYMBOL isNormal).
|
|
||||||
*/
|
|
||||||
bool isSubnormal(F)(F x)
|
|
||||||
if (isFloatingPoint!F)
|
|
||||||
{
|
|
||||||
FloatBits!F bits;
|
|
||||||
bits.floating = abs(x);
|
|
||||||
static if (ieeePrecision!F == IEEEPrecision.single)
|
|
||||||
{
|
|
||||||
return bits.integral < (1 << 23) && bits.integral > 0;
|
|
||||||
}
|
|
||||||
else static if (ieeePrecision!F == IEEEPrecision.double_)
|
|
||||||
{
|
|
||||||
return bits.integral < (1L << 52) && bits.integral > 0;
|
|
||||||
}
|
|
||||||
else static if (ieeePrecision!F == IEEEPrecision.doubleExtended)
|
|
||||||
{
|
|
||||||
return bits.exp == 0 && bits.mantissa != 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
assert(!isSubnormal(0.0f));
|
|
||||||
assert(!isSubnormal(float.nan));
|
|
||||||
assert(!isSubnormal(float.infinity));
|
|
||||||
assert(!isSubnormal(0.3f));
|
|
||||||
assert(isSubnormal(5.87747e-38f / 10));
|
|
||||||
|
|
||||||
assert(!isSubnormal(0.0));
|
|
||||||
assert(!isSubnormal(double.nan));
|
|
||||||
assert(!isSubnormal(double.infinity));
|
|
||||||
assert(!isSubnormal(1.4));
|
|
||||||
assert(isSubnormal(1.11254e-307 / 10));
|
|
||||||
|
|
||||||
assert(!isSubnormal(0.0L));
|
|
||||||
assert(!isSubnormal(real.nan));
|
|
||||||
assert(!isSubnormal(real.infinity));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether $(D_PARAM x) is a normilized number or not.
|
|
||||||
*
|
|
||||||
* Normalized number is a number that can be represented as
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* m*2<sup>e</sup>
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* where $(I m) is the mantissa and $(I e) is an exponent that fits into the
|
|
||||||
* exponent field of the type $(D_PARAM F).
|
|
||||||
*
|
|
||||||
* `0` is neither normalized nor denormalized.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* F = Type of the floating point number.
|
|
||||||
* x = Floating point number.
|
|
||||||
*
|
|
||||||
* Returns: $(D_KEYWORD true) if $(D_PARAM x) is a normilized number,
|
|
||||||
* $(D_KEYWORD false) otherwise.
|
|
||||||
*
|
|
||||||
* See_Also: $(D_PSYMBOL isSubnormal).
|
|
||||||
*/
|
|
||||||
bool isNormal(F)(F x)
|
|
||||||
if (isFloatingPoint!F)
|
|
||||||
{
|
|
||||||
static if (ieeePrecision!F == IEEEPrecision.single
|
|
||||||
|| ieeePrecision!F == IEEEPrecision.double_)
|
|
||||||
{
|
|
||||||
FloatBits!F bits;
|
|
||||||
bits.floating = x;
|
|
||||||
bits.integral &= bits.expMask;
|
|
||||||
return bits.integral != 0 && bits.integral != bits.expMask;
|
|
||||||
}
|
|
||||||
else static if (ieeePrecision!F == IEEEPrecision.doubleExtended)
|
|
||||||
{
|
|
||||||
return classify(x) == FloatingPointClass.normal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
assert(!isNormal(0.0f));
|
|
||||||
assert(!isNormal(float.nan));
|
|
||||||
assert(!isNormal(float.infinity));
|
|
||||||
assert(isNormal(0.3f));
|
|
||||||
assert(!isNormal(5.87747e-38f / 10));
|
|
||||||
|
|
||||||
assert(!isNormal(0.0));
|
|
||||||
assert(!isNormal(double.nan));
|
|
||||||
assert(!isNormal(double.infinity));
|
|
||||||
assert(isNormal(1.4));
|
|
||||||
assert(!isNormal(1.11254e-307 / 10));
|
|
||||||
|
|
||||||
assert(!isNormal(0.0L));
|
|
||||||
assert(!isNormal(real.nan));
|
|
||||||
assert(!isNormal(real.infinity));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the sign bit of $(D_PARAM x) is set or not.
|
|
||||||
*
|
|
||||||
* If the sign bit, $(D_PARAM x) is a negative number, otherwise positive.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* F = Type of the floating point number.
|
|
||||||
* x = Floating point number.
|
|
||||||
*
|
|
||||||
* Returns: $(D_KEYWORD true) if the sign bit of $(D_PARAM x) is set,
|
|
||||||
* $(D_KEYWORD false) otherwise.
|
|
||||||
*/
|
|
||||||
bool signBit(F)(F x)
|
|
||||||
if (isFloatingPoint!F)
|
|
||||||
{
|
|
||||||
FloatBits!F bits;
|
|
||||||
bits.floating = x;
|
|
||||||
static if (ieeePrecision!F == IEEEPrecision.single)
|
|
||||||
{
|
|
||||||
return (bits.integral & (1 << 31)) != 0;
|
|
||||||
}
|
|
||||||
else static if (ieeePrecision!F == IEEEPrecision.double_)
|
|
||||||
{
|
|
||||||
return (bits.integral & (1L << 63)) != 0;
|
|
||||||
}
|
|
||||||
else static if (ieeePrecision!F == IEEEPrecision.doubleExtended)
|
|
||||||
{
|
|
||||||
return (bits.exp & (1 << 15)) != 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
assert(signBit(-1.0f));
|
|
||||||
assert(!signBit(1.0f));
|
|
||||||
|
|
||||||
assert(signBit(-1.0));
|
|
||||||
assert(!signBit(1.0));
|
|
||||||
|
|
||||||
assert(signBit(-1.0L));
|
|
||||||
assert(!signBit(1.0L));
|
|
||||||
}
|
|
||||||
|
@@ -14,10 +14,10 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.net.iface;
|
module tanya.net.iface;
|
||||||
|
|
||||||
import std.traits : Unqual;
|
import std.traits;
|
||||||
import tanya.algorithm.mutation;
|
import tanya.algorithm.mutation;
|
||||||
import tanya.container.string;
|
import tanya.container.string;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
import tanya.range;
|
import tanya.range;
|
||||||
|
|
||||||
version (Windows)
|
version (Windows)
|
||||||
|
@@ -14,8 +14,8 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.net.inet;
|
module tanya.net.inet;
|
||||||
|
|
||||||
import std.traits : Unqual, isUnsigned;
|
import std.traits;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
import tanya.range;
|
import tanya.range;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -18,14 +18,14 @@ import std.algorithm.comparison;
|
|||||||
import std.ascii;
|
import std.ascii;
|
||||||
import std.sumtype;
|
import std.sumtype;
|
||||||
import std.typecons;
|
import std.typecons;
|
||||||
import std.traits : Unqual;
|
import std.traits;
|
||||||
import tanya.algorithm.iteration;
|
import tanya.algorithm.iteration;
|
||||||
import tanya.algorithm.mutation;
|
import tanya.algorithm.mutation;
|
||||||
import tanya.container.string;
|
import tanya.container.string;
|
||||||
import tanya.conv;
|
import tanya.conv;
|
||||||
import tanya.format;
|
import tanya.format;
|
||||||
import tanya.memory.lifetime;
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
import tanya.net.iface;
|
import tanya.net.iface;
|
||||||
import tanya.net.inet;
|
import tanya.net.inet;
|
||||||
import tanya.range;
|
import tanya.range;
|
||||||
|
@@ -14,10 +14,10 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.range.adapter;
|
module tanya.range.adapter;
|
||||||
|
|
||||||
import std.traits : hasMember, isArray;
|
import std.traits;
|
||||||
import tanya.algorithm.mutation;
|
import tanya.algorithm.mutation;
|
||||||
import tanya.memory.lifetime;
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
import tanya.range;
|
import tanya.range;
|
||||||
|
|
||||||
private mixin template InserterCtor()
|
private mixin template InserterCtor()
|
||||||
|
@@ -15,9 +15,9 @@
|
|||||||
module tanya.range.primitive;
|
module tanya.range.primitive;
|
||||||
|
|
||||||
import std.algorithm.comparison;
|
import std.algorithm.comparison;
|
||||||
import std.traits : FunctionAttribute, ReturnType, hasElaborateCopyConstructor, functionAttributes;
|
import std.traits;
|
||||||
import tanya.memory.lifetime;
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
import tanya.range.array;
|
import tanya.range.array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -22,9 +22,9 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.test.assertion;
|
module tanya.test.assertion;
|
||||||
|
|
||||||
import std.traits : isSomeFunction;
|
import std.traits;
|
||||||
import tanya.memory.allocator;
|
import tanya.memory.allocator;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asserts whether the function $(D_PARAM expr) throws an exception of type
|
* Asserts whether the function $(D_PARAM expr) throws an exception of type
|
@@ -91,7 +91,7 @@ struct WithLvalueElements
|
|||||||
mixin template InputRangeStub(E = int)
|
mixin template InputRangeStub(E = int)
|
||||||
{
|
{
|
||||||
import std.traits : hasUDA, getUDAs;
|
import std.traits : hasUDA, getUDAs;
|
||||||
import tanya.meta.metafunction : Alias;
|
import std.meta : Alias;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Aliases for the attribute lookups to access them faster
|
* Aliases for the attribute lookups to access them faster
|
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "test",
|
|
||||||
"description": "Test suite for unittest-blocks",
|
|
||||||
"targetType": "library",
|
|
||||||
|
|
||||||
"dependencies": {
|
|
||||||
"tanya:middle": "*"
|
|
||||||
},
|
|
||||||
|
|
||||||
"sourcePaths": [
|
|
||||||
"."
|
|
||||||
],
|
|
||||||
"importPaths": [
|
|
||||||
"."
|
|
||||||
],
|
|
||||||
"dflags-dmd": ["-dip1000"]
|
|
||||||
}
|
|
@@ -4,16 +4,3 @@
|
|||||||
module tanya.math.tests;
|
module tanya.math.tests;
|
||||||
|
|
||||||
import tanya.math;
|
import tanya.math;
|
||||||
|
|
||||||
static if (ieeePrecision!float == IEEEPrecision.doubleExtended)
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
assert(classify(1.68105e-10) == FloatingPointClass.normal);
|
|
||||||
assert(classify(1.68105e-4932L) == FloatingPointClass.subnormal);
|
|
||||||
|
|
||||||
// Emulate unnormals, because they aren't generated anymore since i386
|
|
||||||
FloatBits!real unnormal;
|
|
||||||
unnormal.exp = 0x123;
|
|
||||||
unnormal.mantissa = 0x1;
|
|
||||||
assert(classify(unnormal) == FloatingPointClass.subnormal);
|
|
||||||
}
|
|
||||||
|
@@ -3,10 +3,10 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
module tanya.memory.tests.smartref;
|
module tanya.memory.tests.smartref;
|
||||||
|
|
||||||
import std.traits : ReturnType;
|
import std.traits;
|
||||||
import tanya.memory.allocator;
|
import tanya.memory.allocator;
|
||||||
import tanya.memory.smartref;
|
import tanya.memory.smartref;
|
||||||
import tanya.meta.trait;
|
import tanya.meta;
|
||||||
import tanya.test.stub;
|
import tanya.test.stub;
|
||||||
|
|
||||||
@nogc @system unittest
|
@nogc @system unittest
|
||||||
|
@@ -1,30 +0,0 @@
|
|||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
module tanya.meta.tests.metafunction;
|
|
||||||
|
|
||||||
import tanya.meta.metafunction;
|
|
||||||
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
enum cmp(int x, int y) = x - y;
|
|
||||||
static assert(isSorted!(cmp));
|
|
||||||
static assert(isSorted!(cmp, 1));
|
|
||||||
static assert(isSorted!(cmp, 1, 2, 2));
|
|
||||||
static assert(isSorted!(cmp, 1, 2, 2, 4));
|
|
||||||
static assert(isSorted!(cmp, 1, 2, 2, 4, 8));
|
|
||||||
static assert(!isSorted!(cmp, 32, 2, 2, 4, 8));
|
|
||||||
static assert(isSorted!(cmp, 32, 32));
|
|
||||||
}
|
|
||||||
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
enum cmp(int x, int y) = x < y;
|
|
||||||
static assert(isSorted!(cmp));
|
|
||||||
static assert(isSorted!(cmp, 1));
|
|
||||||
static assert(isSorted!(cmp, 1, 2, 2));
|
|
||||||
static assert(isSorted!(cmp, 1, 2, 2, 4));
|
|
||||||
static assert(isSorted!(cmp, 1, 2, 2, 4, 8));
|
|
||||||
static assert(!isSorted!(cmp, 32, 2, 2, 4, 8));
|
|
||||||
static assert(isSorted!(cmp, 32, 32));
|
|
||||||
}
|
|
Reference in New Issue
Block a user