Merge os, middle and meta subpackages
This commit is contained in:
8
dub.json
8
dub.json
@@ -10,18 +10,12 @@
|
||||
"targetType": "library",
|
||||
|
||||
"dependencies": {
|
||||
"tanya:meta": "*",
|
||||
"tanya:os": "*",
|
||||
"tanya:middle": "*",
|
||||
"tanya:test": "*",
|
||||
"mir-linux-kernel": "~>1.0.0"
|
||||
},
|
||||
|
||||
"subPackages": [
|
||||
"./meta",
|
||||
"./os",
|
||||
"./middle",
|
||||
"./test"
|
||||
"./middle"
|
||||
],
|
||||
|
||||
"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",
|
||||
"targetType": "library",
|
||||
|
||||
"dependencies": {
|
||||
"tanya:meta": "*",
|
||||
"tanya:os": "*"
|
||||
},
|
||||
|
||||
"dependencies-linux": {
|
||||
"mir-linux-kernel": "~>1.0.0"
|
||||
},
|
||||
|
@@ -17,9 +17,9 @@
|
||||
*/
|
||||
module tanya.memory.allocator;
|
||||
|
||||
import std.traits : hasElaborateDestructor, isAssociativeArray, isArray;
|
||||
import std.traits;
|
||||
import tanya.memory.lifetime;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
|
||||
/**
|
||||
* Abstract class implementing a basic allocator.
|
||||
|
@@ -14,11 +14,10 @@
|
||||
*/
|
||||
module tanya.memory.lifetime;
|
||||
|
||||
import std.traits : isInnerClass, hasElaborateAssign, hasElaborateCopyConstructor, hasElaborateDestructor,
|
||||
isAssignable, isNested, isAbstractClass, isAggregateType, isStaticArray;
|
||||
import std.traits;
|
||||
import std.meta : AliasSeq;
|
||||
import tanya.memory.allocator;
|
||||
import tanya.meta.metafunction;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
|
||||
package(tanya) void destroyAllImpl(R, E)(R p)
|
||||
{
|
||||
|
@@ -23,10 +23,10 @@
|
||||
*/
|
||||
module tanya.memory.smartref;
|
||||
|
||||
import std.traits : isPointer, isAbstractClass, isAssociativeArray, isDynamicArray, isArray;
|
||||
import std.traits;
|
||||
import tanya.memory.allocator;
|
||||
import tanya.memory.lifetime;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
|
||||
private template Payload(T)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
module tanya.os.error;
|
||||
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
|
||||
// Socket API error.
|
||||
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;
|
||||
|
||||
import std.traits : Unqual, isMutable;
|
||||
import std.traits;
|
||||
import std.typecons;
|
||||
import tanya.memory.lifetime;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
import tanya.range;
|
||||
|
||||
private struct SingletonByValue(E)
|
||||
|
@@ -14,11 +14,10 @@
|
||||
*/
|
||||
module tanya.algorithm.mutation;
|
||||
|
||||
import std.traits : Unqual, hasElaborateAssign, hasElaborateCopyConstructor, hasElaborateDestructor, isAssignable,
|
||||
isDynamicArray;
|
||||
import std.traits;
|
||||
static import tanya.memory.lifetime;
|
||||
static import tanya.memory.op;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
import tanya.range;
|
||||
|
||||
/**
|
||||
|
@@ -18,11 +18,11 @@ import core.checkedint;
|
||||
import std.algorithm.comparison;
|
||||
import std.algorithm.iteration;
|
||||
import std.algorithm.mutation : bringToFront;
|
||||
import std.traits : PointerTarget, Unqual, hasElaborateDestructor, isImplicitlyConvertible, isCopyable;
|
||||
import std.traits;
|
||||
import tanya.algorithm.mutation;
|
||||
import tanya.memory.allocator;
|
||||
import tanya.memory.lifetime;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
import tanya.range;
|
||||
|
||||
/**
|
||||
|
@@ -16,7 +16,7 @@ module tanya.container.buffer;
|
||||
|
||||
import std.traits : isScalarType;
|
||||
import tanya.memory.allocator;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
|
||||
version (unittest)
|
||||
{
|
||||
|
@@ -14,11 +14,11 @@
|
||||
*/
|
||||
module tanya.container.entry;
|
||||
|
||||
import std.traits : Unqual, hasElaborateDestructor;
|
||||
import std.traits;
|
||||
import tanya.container.array;
|
||||
import tanya.memory.allocator;
|
||||
import tanya.memory.lifetime;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
|
||||
package struct SEntry(T)
|
||||
{
|
||||
|
@@ -15,14 +15,14 @@
|
||||
module tanya.container.hashtable;
|
||||
|
||||
import std.algorithm.iteration;
|
||||
import std.traits : CopyConstness, Unqual, ifTestable, isMutable;
|
||||
import std.traits;
|
||||
import tanya.algorithm.mutation;
|
||||
import tanya.container.array;
|
||||
import tanya.container.entry;
|
||||
import tanya.hash.lookup;
|
||||
import tanya.memory.allocator;
|
||||
import tanya.memory.lifetime;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
import tanya.range.primitive;
|
||||
|
||||
/**
|
||||
|
@@ -17,11 +17,11 @@ module tanya.container.list;
|
||||
|
||||
import std.algorithm.comparison;
|
||||
import std.algorithm.iteration;
|
||||
import std.traits : Unqual, isImplicitlyConvertible, isCopyable;
|
||||
import std.traits;
|
||||
import tanya.container.entry;
|
||||
import tanya.memory.allocator;
|
||||
import tanya.memory.lifetime;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
import tanya.range.array;
|
||||
import tanya.range.primitive;
|
||||
|
||||
|
@@ -15,13 +15,13 @@
|
||||
*/
|
||||
module tanya.container.set;
|
||||
|
||||
import std.traits : CopyConstness, Unqual, ifTestable, isImplicitlyConvertible, isMutable;
|
||||
import std.traits;
|
||||
import tanya.container.array;
|
||||
import tanya.container.entry;
|
||||
import tanya.hash.lookup;
|
||||
import tanya.memory.allocator;
|
||||
import tanya.memory.lifetime;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
import tanya.range.primitive;
|
||||
|
||||
/**
|
||||
|
@@ -28,12 +28,12 @@ module tanya.container.string;
|
||||
|
||||
import std.algorithm.comparison;
|
||||
import std.algorithm.mutation : bringToFront;
|
||||
import std.traits : CopyConstness, Unqual, isInstanceOf, isSomeChar, isNarrowString;
|
||||
import std.traits;
|
||||
import tanya.algorithm.mutation;
|
||||
import tanya.hash.lookup;
|
||||
import tanya.memory.allocator;
|
||||
import tanya.memory.lifetime;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
import tanya.range.array;
|
||||
import tanya.range.primitive;
|
||||
|
||||
|
@@ -14,11 +14,10 @@
|
||||
*/
|
||||
module tanya.conv;
|
||||
|
||||
import std.traits : Unsigned, isNumeric, Largest, Unqual, EnumMembers, isFloatingPoint, isSomeChar, isSigned,
|
||||
isUnsigned, isIntegral, isSomeString;
|
||||
import std.traits;
|
||||
import tanya.container.string;
|
||||
import tanya.memory.allocator;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
import tanya.range;
|
||||
|
||||
/**
|
||||
|
@@ -49,12 +49,13 @@ module tanya.format;
|
||||
|
||||
import std.algorithm.comparison;
|
||||
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.math;
|
||||
static import tanya.memory.op;
|
||||
import tanya.meta.metafunction;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
import tanya.range;
|
||||
|
||||
// Returns the last part of buffer with converted number.
|
||||
@@ -1952,7 +1953,7 @@ private const(char)[] real2String(double value,
|
||||
const FloatBits!double bits = { value };
|
||||
|
||||
exponent = (bits.integral >> 52) & 0x7ff;
|
||||
sign = signBit(value);
|
||||
sign = !!signbit(value);
|
||||
if (sign)
|
||||
{
|
||||
value = -value;
|
||||
|
@@ -14,8 +14,8 @@
|
||||
*/
|
||||
module tanya.hash.lookup;
|
||||
|
||||
import std.traits : isScalarType, isPointer, isSomeChar, isArray, isIntegral, isBoolean;
|
||||
import tanya.meta.trait;
|
||||
import std.traits;
|
||||
import tanya.meta;
|
||||
import tanya.range.primitive;
|
||||
|
||||
private struct Hasher
|
||||
|
@@ -22,8 +22,8 @@
|
||||
module tanya.math;
|
||||
|
||||
import std.math;
|
||||
import std.traits : Unqual, isFloatingPoint;
|
||||
import tanya.meta.trait;
|
||||
import std.traits;
|
||||
import tanya.meta;
|
||||
|
||||
/// Floating-point number precisions according to IEEE-754.
|
||||
enum IEEEPrecision : ubyte
|
||||
@@ -113,433 +113,3 @@ package(tanya) union FloatBits(F)
|
||||
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;
|
||||
|
||||
import std.traits : Unqual;
|
||||
import std.traits;
|
||||
import tanya.algorithm.mutation;
|
||||
import tanya.container.string;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
import tanya.range;
|
||||
|
||||
version (Windows)
|
||||
|
@@ -14,8 +14,8 @@
|
||||
*/
|
||||
module tanya.net.inet;
|
||||
|
||||
import std.traits : Unqual, isUnsigned;
|
||||
import tanya.meta.trait;
|
||||
import std.traits;
|
||||
import tanya.meta;
|
||||
import tanya.range;
|
||||
|
||||
/**
|
||||
|
@@ -18,14 +18,14 @@ import std.algorithm.comparison;
|
||||
import std.ascii;
|
||||
import std.sumtype;
|
||||
import std.typecons;
|
||||
import std.traits : Unqual;
|
||||
import std.traits;
|
||||
import tanya.algorithm.iteration;
|
||||
import tanya.algorithm.mutation;
|
||||
import tanya.container.string;
|
||||
import tanya.conv;
|
||||
import tanya.format;
|
||||
import tanya.memory.lifetime;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
import tanya.net.iface;
|
||||
import tanya.net.inet;
|
||||
import tanya.range;
|
||||
|
@@ -14,10 +14,10 @@
|
||||
*/
|
||||
module tanya.range.adapter;
|
||||
|
||||
import std.traits : hasMember, isArray;
|
||||
import std.traits;
|
||||
import tanya.algorithm.mutation;
|
||||
import tanya.memory.lifetime;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
import tanya.range;
|
||||
|
||||
private mixin template InserterCtor()
|
||||
|
@@ -15,9 +15,9 @@
|
||||
module tanya.range.primitive;
|
||||
|
||||
import std.algorithm.comparison;
|
||||
import std.traits : FunctionAttribute, ReturnType, hasElaborateCopyConstructor, functionAttributes;
|
||||
import std.traits;
|
||||
import tanya.memory.lifetime;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
import tanya.range.array;
|
||||
|
||||
/**
|
||||
|
@@ -22,9 +22,9 @@
|
||||
*/
|
||||
module tanya.test.assertion;
|
||||
|
||||
import std.traits : isSomeFunction;
|
||||
import std.traits;
|
||||
import tanya.memory.allocator;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
|
||||
/**
|
||||
* Asserts whether the function $(D_PARAM expr) throws an exception of type
|
@@ -91,7 +91,7 @@ struct WithLvalueElements
|
||||
mixin template InputRangeStub(E = int)
|
||||
{
|
||||
import std.traits : hasUDA, getUDAs;
|
||||
import tanya.meta.metafunction : Alias;
|
||||
import std.meta : Alias;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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/. */
|
||||
module tanya.memory.tests.smartref;
|
||||
|
||||
import std.traits : ReturnType;
|
||||
import std.traits;
|
||||
import tanya.memory.allocator;
|
||||
import tanya.memory.smartref;
|
||||
import tanya.meta.trait;
|
||||
import tanya.meta;
|
||||
import tanya.test.stub;
|
||||
|
||||
@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