Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
964a7af32f | |||
40c961867e | |||
3fee712c6c | |||
012c2d4c18 | |||
d267a9cc64 | |||
ddb02e41eb | |||
d157e88b7a | |||
d5064fa2b2 | |||
f15a90543f | |||
a0ac8355f9 | |||
9b1f72472f | |||
af45de842e |
12
.travis.yml
12
.travis.yml
@ -7,10 +7,9 @@ os:
|
||||
language: d
|
||||
|
||||
d:
|
||||
- dmd-2.079.0
|
||||
- dmd-2.079.1
|
||||
- dmd-2.078.3
|
||||
- dmd-2.077.1
|
||||
- dmd-2.076.1
|
||||
|
||||
env:
|
||||
matrix:
|
||||
@ -23,12 +22,17 @@ addons:
|
||||
- gcc-multilib
|
||||
|
||||
before_script:
|
||||
- if [ "$PS1" = '(dmd-2.079.0)' ]; then
|
||||
- if [ "`$DC --version | head -n 1 | grep 'v2.079.1'`" ]; then
|
||||
export UNITTEST="unittest-cov";
|
||||
fi
|
||||
|
||||
script:
|
||||
- dub test -b ${UNITTEST:-unittest} --arch=$ARCH --compiler=$DC
|
||||
- if [ "$UNITTEST" ] && [ "$ARCH" = "x86_64" ] && [ "$TRAVIS_OS_NAME" = "linux" ];
|
||||
then
|
||||
dub fetch dscanner;
|
||||
dub run dscanner -- --styleCheck ./source/;
|
||||
fi
|
||||
|
||||
after_success:
|
||||
- test "$UNITTEST" = "unittest-cov" && bash <(curl -s https://codecov.io/bash)
|
||||
- test "$UNITTEST" && bash <(curl -s https://codecov.io/bash)
|
||||
|
@ -172,10 +172,9 @@ parameter is used)
|
||||
|
||||
| DMD | GCC |
|
||||
|:-------:|:---------:|
|
||||
| 2.079.0 | *master* |
|
||||
| 2.079.1 | *master* |
|
||||
| 2.078.3 | |
|
||||
| 2.077.1 | |
|
||||
| 2.076.1 | |
|
||||
|
||||
### Current status
|
||||
|
||||
|
10
appveyor.yml
10
appveyor.yml
@ -4,10 +4,10 @@ os: Visual Studio 2015
|
||||
environment:
|
||||
matrix:
|
||||
- DC: dmd
|
||||
DVersion: 2.079.0
|
||||
DVersion: 2.079.1
|
||||
arch: x64
|
||||
- DC: dmd
|
||||
DVersion: 2.079.0
|
||||
DVersion: 2.079.1
|
||||
arch: x86
|
||||
- DC: dmd
|
||||
DVersion: 2.078.3
|
||||
@ -21,12 +21,6 @@ environment:
|
||||
- DC: dmd
|
||||
DVersion: 2.077.1
|
||||
arch: x86
|
||||
- DC: dmd
|
||||
DVersion: 2.076.1
|
||||
arch: x64
|
||||
- DC: dmd
|
||||
DVersion: 2.076.1
|
||||
arch: x86
|
||||
|
||||
skip_tags: true
|
||||
|
||||
|
@ -279,7 +279,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
@trusted @nogc unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v1 = Array!int([1, 2, 3]);
|
||||
auto v2 = Array!int(v1);
|
||||
@ -291,19 +291,6 @@ struct Array(T)
|
||||
assert(v3.capacity == 3);
|
||||
}
|
||||
|
||||
private @trusted @nogc unittest // const constructor tests
|
||||
{
|
||||
auto v1 = const Array!int([1, 2, 3]);
|
||||
auto v2 = Array!int(v1);
|
||||
assert(v1.data !is v2.data);
|
||||
assert(v1 == v2);
|
||||
|
||||
auto v3 = const Array!int(Array!int([1, 2, 3]));
|
||||
assert(v1 == v3);
|
||||
assert(v3.length == 3);
|
||||
assert(v3.capacity == 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new $(D_PSYMBOL Array).
|
||||
*
|
||||
@ -339,7 +326,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v = Array!int([3, 8, 2]);
|
||||
|
||||
@ -349,7 +336,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v = Array!int(3, 5);
|
||||
|
||||
@ -358,11 +345,6 @@ struct Array(T)
|
||||
assert(v[0] == 5 && v[1] == 5 && v[2] == 5);
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
auto v1 = Array!int(defaultAllocator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys this $(D_PSYMBOL Array).
|
||||
*/
|
||||
@ -392,7 +374,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v = Array!int([18, 20, 15]);
|
||||
v.clear();
|
||||
@ -409,7 +391,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
@safe @nogc unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v = Array!int(4);
|
||||
assert(v.capacity == 4);
|
||||
@ -461,7 +443,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
Array!int v;
|
||||
|
||||
@ -529,7 +511,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
@nogc @safe unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
Array!int v;
|
||||
assert(v.capacity == 0);
|
||||
@ -564,7 +546,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
@nogc @safe unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
Array!int v;
|
||||
assert(v.capacity == 0);
|
||||
@ -629,7 +611,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v = Array!int([5, 18, 17]);
|
||||
|
||||
@ -674,7 +656,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
@safe @nogc unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v = Array!int([5, 18, 17, 2, 4, 6, 1]);
|
||||
|
||||
@ -759,7 +741,7 @@ struct Array(T)
|
||||
alias insert = insertBack;
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
struct TestRange
|
||||
{
|
||||
@ -927,7 +909,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure unittest
|
||||
{
|
||||
Array!int v1;
|
||||
v1.insertAfter(v1[], [2, 8]);
|
||||
@ -963,7 +945,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure unittest
|
||||
{
|
||||
Array!int v1;
|
||||
v1.insertBefore(v1[], [2, 8]);
|
||||
@ -1022,7 +1004,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
nothrow @safe @nogc unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
Array!int a = Array!int(1);
|
||||
a[0] = 5;
|
||||
@ -1052,7 +1034,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
@nogc unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v1 = Array!int([12, 1, 7]);
|
||||
|
||||
@ -1101,7 +1083,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
const v1 = Array!int([6, 123, 34, 5]);
|
||||
|
||||
@ -1156,7 +1138,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
Array!int v1, v2;
|
||||
assert(v1 == v2);
|
||||
@ -1191,7 +1173,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
@safe unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v = Array!int([5]);
|
||||
|
||||
@ -1218,7 +1200,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v = Array!int([5]);
|
||||
|
||||
@ -1263,16 +1245,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
{
|
||||
Array!int v;
|
||||
auto r = v[];
|
||||
assert(r.length == 0);
|
||||
assert(r.empty);
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v = Array!int([1, 2, 3]);
|
||||
auto r = v[];
|
||||
@ -1290,7 +1263,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v = Array!int([1, 2, 3, 4]);
|
||||
auto r = v[1 .. 4];
|
||||
@ -1363,7 +1336,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
@nogc @safe unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v1 = Array!int([3, 3, 3]);
|
||||
auto v2 = Array!int([1, 2]);
|
||||
@ -1397,7 +1370,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v = Array!int([1, 2, 4]);
|
||||
auto data = v.get();
|
||||
@ -1464,7 +1437,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
@safe @nogc unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v1 = const Array!int([5, 15, 8]);
|
||||
Array!int v2;
|
||||
@ -1472,22 +1445,6 @@ struct Array(T)
|
||||
assert(v1 == v2);
|
||||
}
|
||||
|
||||
///
|
||||
@safe @nogc unittest
|
||||
{
|
||||
auto v1 = const Array!int([5, 15, 8]);
|
||||
Array!int v2;
|
||||
v2 = v1[0 .. 2];
|
||||
assert(equal(v1[0 .. 2], v2[]));
|
||||
}
|
||||
|
||||
// Move assignment.
|
||||
private @safe @nogc unittest
|
||||
{
|
||||
Array!int v1;
|
||||
v1 = Array!int([5, 15, 8]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a static array.
|
||||
*
|
||||
@ -1503,7 +1460,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
@safe @nogc unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v1 = Array!int([5, 15, 8]);
|
||||
Array!int v2;
|
||||
@ -1516,7 +1473,7 @@ struct Array(T)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v = Array!int([5, 15, 8]);
|
||||
|
||||
@ -1530,7 +1487,7 @@ unittest
|
||||
assert(r.front == v.front);
|
||||
}
|
||||
|
||||
@nogc unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
const v1 = Array!int();
|
||||
const Array!int v2;
|
||||
@ -1538,7 +1495,7 @@ unittest
|
||||
static assert(is(PointerTarget!(typeof(v3.data)) == const(int)));
|
||||
}
|
||||
|
||||
@nogc unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
// Test that const arrays return usable ranges.
|
||||
auto v = const Array!int([1, 2, 4]);
|
||||
@ -1559,7 +1516,7 @@ unittest
|
||||
static assert(is(typeof(r2[])));
|
||||
}
|
||||
|
||||
@nogc unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
Array!int v1;
|
||||
const Array!int v2;
|
||||
@ -1581,18 +1538,18 @@ unittest
|
||||
assert(!v1[].equal(v2[]));
|
||||
}
|
||||
|
||||
@nogc unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
struct MutableEqualsStruct
|
||||
{
|
||||
int opEquals(typeof(this) that) @nogc
|
||||
int opEquals(typeof(this) that) @nogc nothrow pure @safe
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
struct ConstEqualsStruct
|
||||
{
|
||||
int opEquals(const typeof(this) that) const @nogc
|
||||
int opEquals(const typeof(this) that) const @nogc nothrow pure @safe
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -1619,18 +1576,18 @@ unittest
|
||||
assert(v7[].equal(v8[]));
|
||||
}
|
||||
|
||||
@nogc unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
struct SWithDtor
|
||||
{
|
||||
~this() @nogc
|
||||
~this() @nogc nothrow pure @safe
|
||||
{
|
||||
}
|
||||
}
|
||||
auto v = Array!SWithDtor(); // Destructor can destroy empty arrays.
|
||||
}
|
||||
|
||||
private unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
class A
|
||||
{
|
||||
@ -1642,7 +1599,7 @@ private unittest
|
||||
static assert(is(Array!(A*)));
|
||||
}
|
||||
|
||||
private @safe @nogc unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v = Array!int([5, 15, 8]);
|
||||
{
|
||||
@ -1670,3 +1627,45 @@ private @safe @nogc unittest
|
||||
assert(i == 0);
|
||||
}
|
||||
}
|
||||
|
||||
// const constructor tests
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v1 = const Array!int([1, 2, 3]);
|
||||
auto v2 = Array!int(v1);
|
||||
assert(v1.data !is v2.data);
|
||||
assert(v1 == v2);
|
||||
|
||||
auto v3 = const Array!int(Array!int([1, 2, 3]));
|
||||
assert(v1 == v3);
|
||||
assert(v3.length == 3);
|
||||
assert(v3.capacity == 3);
|
||||
}
|
||||
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v1 = Array!int(defaultAllocator);
|
||||
}
|
||||
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
Array!int v;
|
||||
auto r = v[];
|
||||
assert(r.length == 0);
|
||||
assert(r.empty);
|
||||
}
|
||||
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto v1 = const Array!int([5, 15, 8]);
|
||||
Array!int v2;
|
||||
v2 = v1[0 .. 2];
|
||||
assert(equal(v1[0 .. 2], v2[]));
|
||||
}
|
||||
|
||||
// Move assignment
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
Array!int v1;
|
||||
v1 = Array!int([5, 15, 8]);
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ struct ReadBuffer(T = ubyte)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
ReadBuffer!ubyte b;
|
||||
assert(b.capacity == 0);
|
||||
@ -165,7 +165,7 @@ struct ReadBuffer(T = ubyte)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure unittest
|
||||
{
|
||||
ReadBuffer!ubyte b;
|
||||
size_t numberRead;
|
||||
@ -197,7 +197,7 @@ struct ReadBuffer(T = ubyte)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure unittest
|
||||
{
|
||||
ReadBuffer!ubyte b;
|
||||
size_t numberRead;
|
||||
@ -272,7 +272,7 @@ struct ReadBuffer(T = ubyte)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure unittest
|
||||
{
|
||||
ReadBuffer!ubyte b;
|
||||
size_t numberRead;
|
||||
@ -293,7 +293,7 @@ struct ReadBuffer(T = ubyte)
|
||||
mixin DefaultAllocator;
|
||||
}
|
||||
|
||||
private unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
static assert(is(ReadBuffer!int));
|
||||
}
|
||||
@ -399,7 +399,7 @@ struct WriteBuffer(T = ubyte)
|
||||
alias opDollar = length;
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure unittest
|
||||
{
|
||||
auto b = WriteBuffer!ubyte(4);
|
||||
ubyte[3] buf = [48, 23, 255];
|
||||
@ -498,42 +498,6 @@ struct WriteBuffer(T = ubyte)
|
||||
return this;
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
{
|
||||
auto b = WriteBuffer!ubyte(4);
|
||||
ubyte[3] buf = [48, 23, 255];
|
||||
|
||||
b ~= buf;
|
||||
assert(b.capacity == 4);
|
||||
assert(b.buffer_[0] == 48 && b.buffer_[1] == 23 && b.buffer_[2] == 255);
|
||||
|
||||
b += 2;
|
||||
b ~= buf;
|
||||
assert(b.capacity == 4);
|
||||
assert(b.buffer_[0] == 23 && b.buffer_[1] == 255
|
||||
&& b.buffer_[2] == 255 && b.buffer_[3] == 48);
|
||||
|
||||
b += 2;
|
||||
b ~= buf;
|
||||
assert(b.capacity == 8);
|
||||
assert(b.buffer_[0] == 23 && b.buffer_[1] == 255
|
||||
&& b.buffer_[2] == 48 && b.buffer_[3] == 23 && b.buffer_[4] == 255);
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
{
|
||||
auto b = WriteBuffer!ubyte(2);
|
||||
ubyte[3] buf = [48, 23, 255];
|
||||
|
||||
b ~= buf;
|
||||
assert(b.start == 0);
|
||||
assert(b.capacity == 4);
|
||||
assert(b.ring == 3);
|
||||
assert(b.position == 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets how many bytes were written. It will shrink the buffer
|
||||
* appropriately. Always call it after $(D_PSYMBOL opIndex).
|
||||
@ -607,7 +571,7 @@ struct WriteBuffer(T = ubyte)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure unittest
|
||||
{
|
||||
auto b = WriteBuffer!ubyte(6);
|
||||
ubyte[6] buf = [23, 23, 255, 128, 127, 9];
|
||||
@ -648,7 +612,7 @@ struct WriteBuffer(T = ubyte)
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
@nogc nothrow pure unittest
|
||||
{
|
||||
auto b = WriteBuffer!ubyte(6);
|
||||
ubyte[6] buf = [23, 23, 255, 128, 127, 9];
|
||||
@ -686,7 +650,41 @@ struct WriteBuffer(T = ubyte)
|
||||
mixin DefaultAllocator;
|
||||
}
|
||||
|
||||
private unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
static assert(is(typeof(WriteBuffer!int(5))));
|
||||
}
|
||||
|
||||
@nogc nothrow pure unittest
|
||||
{
|
||||
auto b = WriteBuffer!ubyte(4);
|
||||
ubyte[3] buf = [48, 23, 255];
|
||||
|
||||
b ~= buf;
|
||||
assert(b.capacity == 4);
|
||||
assert(b.buffer_[0] == 48 && b.buffer_[1] == 23 && b.buffer_[2] == 255);
|
||||
|
||||
b += 2;
|
||||
b ~= buf;
|
||||
assert(b.capacity == 4);
|
||||
assert(b.buffer_[0] == 23 && b.buffer_[1] == 255
|
||||
&& b.buffer_[2] == 255 && b.buffer_[3] == 48);
|
||||
|
||||
b += 2;
|
||||
b ~= buf;
|
||||
assert(b.capacity == 8);
|
||||
assert(b.buffer_[0] == 23 && b.buffer_[1] == 255
|
||||
&& b.buffer_[2] == 48 && b.buffer_[3] == 23 && b.buffer_[4] == 255);
|
||||
}
|
||||
|
||||
@nogc nothrow pure unittest
|
||||
{
|
||||
auto b = WriteBuffer!ubyte(2);
|
||||
ubyte[3] buf = [48, 23, 255];
|
||||
|
||||
b ~= buf;
|
||||
assert(b.start == 0);
|
||||
assert(b.capacity == 4);
|
||||
assert(b.ring == 3);
|
||||
assert(b.position == 3);
|
||||
}
|
||||
|
@ -156,7 +156,8 @@ struct SList(T)
|
||||
* init = Initial value to fill the list with.
|
||||
* allocator = Allocator.
|
||||
*/
|
||||
this(const size_t len, T init, shared Allocator allocator = defaultAllocator) @trusted
|
||||
this(size_t len, T init, shared Allocator allocator = defaultAllocator)
|
||||
@trusted
|
||||
{
|
||||
this(allocator);
|
||||
if (len == 0)
|
||||
@ -181,7 +182,7 @@ struct SList(T)
|
||||
}
|
||||
|
||||
/// ditto
|
||||
this(const size_t len, shared Allocator allocator = defaultAllocator)
|
||||
this(size_t len, shared Allocator allocator = defaultAllocator)
|
||||
{
|
||||
this(len, T.init, allocator);
|
||||
}
|
||||
@ -434,15 +435,19 @@ struct SList(T)
|
||||
assert(l2.front == 9);
|
||||
}
|
||||
|
||||
version (assert)
|
||||
private bool checkRangeBelonging(ref const Range r) const
|
||||
{
|
||||
private bool checkRangeBelonging(ref Range r) const
|
||||
version (assert)
|
||||
{
|
||||
const(Entry*)* pos = &this.head;
|
||||
for (; pos != r.head && *pos !is null; pos = &(*pos).next)
|
||||
const(Entry)* pos = this.head;
|
||||
for (; pos !is *r.head && pos !is null; pos = pos.next)
|
||||
{
|
||||
}
|
||||
return pos == r.head;
|
||||
return pos is *r.head;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -560,28 +565,12 @@ struct SList(T)
|
||||
assert(l1 == l2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns: How many elements are in the list.
|
||||
*/
|
||||
deprecated
|
||||
@property size_t length() const
|
||||
{
|
||||
return count(this[]);
|
||||
}
|
||||
|
||||
///
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
SList!int l;
|
||||
|
||||
l.insertFront(8);
|
||||
l.insertFront(9);
|
||||
assert(l.length == 2);
|
||||
l.removeFront();
|
||||
assert(l.length == 1);
|
||||
l.removeFront();
|
||||
assert(l.length == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison for equality.
|
||||
*
|
||||
@ -672,7 +661,7 @@ struct SList(T)
|
||||
*
|
||||
* Returns: The number of elements removed.
|
||||
*/
|
||||
size_t removeFront(const size_t howMany)
|
||||
size_t removeFront(size_t howMany)
|
||||
out (removed)
|
||||
{
|
||||
assert(removed <= howMany);
|
||||
@ -735,6 +724,50 @@ struct SList(T)
|
||||
assert(l1 == l2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the front element of the $(D_PARAM range) from the list.
|
||||
*
|
||||
* Params:
|
||||
* range = Range whose front element should be removed.
|
||||
*
|
||||
* Returns: $(D_PSYMBOL range) with its front element removed.
|
||||
*
|
||||
* Precondition: $(D_INLINECODE !range.empty).
|
||||
* $(D_PARAM range) is extracted from this list.
|
||||
*/
|
||||
Range popFirstOf(Range range)
|
||||
in
|
||||
{
|
||||
assert(!range.empty);
|
||||
assert(checkRangeBelonging(range));
|
||||
}
|
||||
do
|
||||
{
|
||||
auto next = (*range.head).next;
|
||||
|
||||
allocator.dispose(*range.head);
|
||||
*range.head = next;
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
///
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto list = SList!int([5, 234, 30]);
|
||||
auto range = list[];
|
||||
|
||||
range.popFront();
|
||||
assert(list.popFirstOf(range).front == 30);
|
||||
|
||||
range = list[];
|
||||
assert(range.front == 5);
|
||||
range.popFront;
|
||||
assert(range.front == 30);
|
||||
range.popFront;
|
||||
assert(range.empty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns: Range that iterates over all elements of the container, in
|
||||
* forward order.
|
||||
@ -941,6 +974,7 @@ struct DRange(L)
|
||||
invariant
|
||||
{
|
||||
assert(this.head !is null);
|
||||
assert(this.tail !is null);
|
||||
}
|
||||
|
||||
private this(ref EntryPointer head, ref EntryPointer tail) @trusted
|
||||
@ -1096,7 +1130,8 @@ struct DList(T)
|
||||
* init = Initial value to fill the list with.
|
||||
* allocator = Allocator.
|
||||
*/
|
||||
this(const size_t len, T init, shared Allocator allocator = defaultAllocator) @trusted
|
||||
this(size_t len, T init, shared Allocator allocator = defaultAllocator)
|
||||
@trusted
|
||||
{
|
||||
this(allocator);
|
||||
if (len == 0)
|
||||
@ -1124,7 +1159,7 @@ struct DList(T)
|
||||
}
|
||||
|
||||
/// ditto
|
||||
this(const size_t len, shared Allocator allocator = defaultAllocator)
|
||||
this(size_t len, shared Allocator allocator = defaultAllocator)
|
||||
{
|
||||
this(len, T.init, allocator);
|
||||
}
|
||||
@ -1571,15 +1606,19 @@ struct DList(T)
|
||||
/// ditto
|
||||
alias insert = insertBack;
|
||||
|
||||
version (assert)
|
||||
private bool checkRangeBelonging(ref const Range r) const
|
||||
{
|
||||
private bool checkRangeBelonging(ref Range r) const
|
||||
version (assert)
|
||||
{
|
||||
const(Entry*)* pos = &this.head;
|
||||
for (; pos != r.head && *pos !is null; pos = &(*pos).next)
|
||||
const(Entry)* pos = this.head;
|
||||
for (; pos !is *r.head && pos !is null; pos = pos.next)
|
||||
{
|
||||
}
|
||||
return pos == r.head;
|
||||
return pos is *r.head;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1815,28 +1854,12 @@ struct DList(T)
|
||||
return insertAfter!(T[])(r, el[]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns: How many elements are in the list.
|
||||
*/
|
||||
deprecated
|
||||
@property size_t length() const
|
||||
{
|
||||
return count(this[]);
|
||||
}
|
||||
|
||||
///
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
DList!int l;
|
||||
|
||||
l.insertFront(8);
|
||||
l.insertFront(9);
|
||||
assert(l.length == 2);
|
||||
l.removeFront();
|
||||
assert(l.length == 1);
|
||||
l.removeFront();
|
||||
assert(l.length == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison for equality.
|
||||
*
|
||||
@ -1897,7 +1920,7 @@ struct DList(T)
|
||||
{
|
||||
auto n = this.head.next;
|
||||
|
||||
this.allocator_.dispose(this.head);
|
||||
allocator.dispose(this.head);
|
||||
this.head = n;
|
||||
if (this.head is null)
|
||||
{
|
||||
@ -1970,7 +1993,7 @@ struct DList(T)
|
||||
*
|
||||
* Returns: The number of elements removed.
|
||||
*/
|
||||
size_t removeFront(const size_t howMany)
|
||||
size_t removeFront(size_t howMany)
|
||||
out (removed)
|
||||
{
|
||||
assert(removed <= howMany);
|
||||
@ -1997,7 +2020,7 @@ struct DList(T)
|
||||
}
|
||||
|
||||
/// ditto
|
||||
size_t removeBack(const size_t howMany)
|
||||
size_t removeBack(size_t howMany)
|
||||
out (removed)
|
||||
{
|
||||
assert(removed <= howMany);
|
||||
@ -2057,11 +2080,7 @@ struct DList(T)
|
||||
while (e !is *tailNext)
|
||||
{
|
||||
auto next = e.next;
|
||||
/* Workaround for dmd 2.076.1 bug on OSX. Invariants fail when
|
||||
the allocator is called. Here it should be safe to use
|
||||
allocator_ directory, since the list isn't empty.
|
||||
See also removeFront. */
|
||||
this.allocator_.dispose(e);
|
||||
allocator.dispose(e);
|
||||
e = next;
|
||||
}
|
||||
|
||||
@ -2101,6 +2120,57 @@ struct DList(T)
|
||||
assert(l1 == l2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the front or back element of the $(D_PARAM range) from the list
|
||||
* respectively.
|
||||
*
|
||||
* Params:
|
||||
* range = Range whose element should be removed.
|
||||
*
|
||||
* Returns: $(D_PSYMBOL range) with its front or back element removed.
|
||||
*
|
||||
* Precondition: $(D_INLINECODE !range.empty).
|
||||
* $(D_PARAM range) is extracted from this list.
|
||||
*/
|
||||
Range popFirstOf(Range range)
|
||||
in
|
||||
{
|
||||
assert(!range.empty);
|
||||
}
|
||||
do
|
||||
{
|
||||
remove(Range(*range.head, *range.head));
|
||||
return range;
|
||||
}
|
||||
|
||||
/// ditto
|
||||
Range popLastOf(Range range)
|
||||
in
|
||||
{
|
||||
assert(!range.empty);
|
||||
}
|
||||
do
|
||||
{
|
||||
remove(Range(*range.tail, *range.tail));
|
||||
return range;
|
||||
}
|
||||
|
||||
///
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto list = DList!int([5, 234, 30]);
|
||||
auto range = list[];
|
||||
|
||||
range.popFront();
|
||||
range = list.popFirstOf(range);
|
||||
assert(range.front == 30);
|
||||
assert(range.back == 30);
|
||||
|
||||
assert(list.popLastOf(range).empty);
|
||||
assert(list[].front == 5);
|
||||
assert(list[].back == 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns: Range that iterates over all elements of the container, in
|
||||
* forward order.
|
||||
|
@ -17,7 +17,6 @@ module tanya.container;
|
||||
public import tanya.container.array;
|
||||
public import tanya.container.buffer;
|
||||
public import tanya.container.list;
|
||||
public import tanya.container.queue;
|
||||
public import tanya.container.set;
|
||||
public import tanya.container.string;
|
||||
|
||||
|
@ -1,291 +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/. */
|
||||
|
||||
/**
|
||||
* FIFO queue.
|
||||
*
|
||||
* Copyright: Eugene Wissner 2016-2018.
|
||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||
* Mozilla Public License, v. 2.0).
|
||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||
* Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/container/queue.d,
|
||||
* tanya/container/queue.d)
|
||||
*/
|
||||
deprecated("Use tanya.container.list.DList instead")
|
||||
module tanya.container.queue;
|
||||
|
||||
import tanya.algorithm.mutation;
|
||||
import tanya.container.entry;
|
||||
import tanya.exception;
|
||||
import tanya.memory;
|
||||
import tanya.meta.trait;
|
||||
|
||||
/**
|
||||
* FIFO queue.
|
||||
*
|
||||
* Params:
|
||||
* T = Content type.
|
||||
*/
|
||||
struct Queue(T)
|
||||
{
|
||||
/**
|
||||
* Removes all elements from the queue.
|
||||
*/
|
||||
~this()
|
||||
{
|
||||
while (!empty)
|
||||
{
|
||||
dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns how many elements are in the queue. It iterates through the queue
|
||||
* to count the elements.
|
||||
*
|
||||
* Returns: How many elements are in the queue.
|
||||
*/
|
||||
size_t length() const
|
||||
{
|
||||
size_t len;
|
||||
for (const(SEntry!T)* i = first; i !is null; i = i.next)
|
||||
{
|
||||
++len;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
{
|
||||
Queue!int q;
|
||||
|
||||
assert(q.length == 0);
|
||||
q.enqueue(5);
|
||||
assert(q.length == 1);
|
||||
q.enqueue(4);
|
||||
assert(q.length == 2);
|
||||
q.enqueue(9);
|
||||
assert(q.length == 3);
|
||||
|
||||
q.dequeue();
|
||||
assert(q.length == 2);
|
||||
q.dequeue();
|
||||
assert(q.length == 1);
|
||||
q.dequeue();
|
||||
assert(q.length == 0);
|
||||
}
|
||||
|
||||
private void enqueueEntry(ref SEntry!T* entry)
|
||||
{
|
||||
if (empty)
|
||||
{
|
||||
first = rear = entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
rear.next = entry;
|
||||
rear = rear.next;
|
||||
}
|
||||
}
|
||||
|
||||
private SEntry!T* allocateEntry()
|
||||
{
|
||||
auto temp = cast(SEntry!T*) allocator.allocate(SEntry!T.sizeof);
|
||||
if (temp is null)
|
||||
{
|
||||
onOutOfMemoryError();
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a new element.
|
||||
*
|
||||
* Params:
|
||||
* x = New element.
|
||||
*/
|
||||
void enqueue(ref T x)
|
||||
{
|
||||
auto temp = allocateEntry();
|
||||
|
||||
*temp = SEntry!T.init;
|
||||
temp.content = x;
|
||||
|
||||
enqueueEntry(temp);
|
||||
}
|
||||
|
||||
/// ditto
|
||||
void enqueue(T x)
|
||||
{
|
||||
auto temp = allocateEntry();
|
||||
|
||||
moveEmplace(x, (*temp).content);
|
||||
(*temp).next = null;
|
||||
|
||||
enqueueEntry(temp);
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
{
|
||||
Queue!int q;
|
||||
|
||||
assert(q.empty);
|
||||
q.enqueue(8);
|
||||
q.enqueue(9);
|
||||
assert(q.dequeue() == 8);
|
||||
assert(q.dequeue() == 9);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns: $(D_KEYWORD true) if the queue is empty.
|
||||
*/
|
||||
@property bool empty() const
|
||||
{
|
||||
return first is null;
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
{
|
||||
Queue!int q;
|
||||
int value = 7;
|
||||
|
||||
assert(q.empty);
|
||||
q.enqueue(value);
|
||||
assert(!q.empty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the position to the next element.
|
||||
*
|
||||
* Returns: Dequeued element.
|
||||
*/
|
||||
T dequeue()
|
||||
in
|
||||
{
|
||||
assert(!empty);
|
||||
}
|
||||
do
|
||||
{
|
||||
auto n = first.next;
|
||||
T ret = move(first.content);
|
||||
|
||||
allocator.dispose(first);
|
||||
first = n;
|
||||
return ret;
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
{
|
||||
Queue!int q;
|
||||
|
||||
q.enqueue(8);
|
||||
q.enqueue(9);
|
||||
assert(q.dequeue() == 8);
|
||||
assert(q.dequeue() == 9);
|
||||
}
|
||||
|
||||
/**
|
||||
* $(D_KEYWORD foreach) iteration. The elements will be automatically
|
||||
* dequeued.
|
||||
*
|
||||
* Params:
|
||||
* dg = $(D_KEYWORD foreach) body.
|
||||
*
|
||||
* Returns: The value returned from $(D_PARAM dg).
|
||||
*/
|
||||
int opApply(scope int delegate(ref size_t i, ref T) @nogc dg)
|
||||
{
|
||||
int result;
|
||||
|
||||
for (size_t i; !empty; ++i)
|
||||
{
|
||||
auto e = dequeue();
|
||||
if ((result = dg(i, e)) != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// ditto
|
||||
int opApply(scope int delegate(ref T) @nogc dg)
|
||||
{
|
||||
int result;
|
||||
|
||||
while (!empty)
|
||||
{
|
||||
auto e = dequeue();
|
||||
if ((result = dg(e)) != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
{
|
||||
Queue!int q;
|
||||
|
||||
size_t j;
|
||||
q.enqueue(5);
|
||||
q.enqueue(4);
|
||||
q.enqueue(9);
|
||||
foreach (i, e; q)
|
||||
{
|
||||
assert(i != 2 || e == 9);
|
||||
assert(i != 1 || e == 4);
|
||||
assert(i != 0 || e == 5);
|
||||
++j;
|
||||
}
|
||||
assert(j == 3);
|
||||
assert(q.empty);
|
||||
|
||||
j = 0;
|
||||
q.enqueue(5);
|
||||
q.enqueue(4);
|
||||
q.enqueue(9);
|
||||
foreach (e; q)
|
||||
{
|
||||
assert(j != 2 || e == 9);
|
||||
assert(j != 1 || e == 4);
|
||||
assert(j != 0 || e == 5);
|
||||
++j;
|
||||
}
|
||||
assert(j == 3);
|
||||
assert(q.empty);
|
||||
}
|
||||
|
||||
private SEntry!T* first;
|
||||
private SEntry!T* rear;
|
||||
|
||||
mixin DefaultAllocator;
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
{
|
||||
Queue!int q;
|
||||
|
||||
q.enqueue(5);
|
||||
assert(!q.empty);
|
||||
|
||||
q.enqueue(4);
|
||||
q.enqueue(9);
|
||||
|
||||
assert(q.dequeue() == 5);
|
||||
|
||||
foreach (i, ref e; q)
|
||||
{
|
||||
assert(i != 0 || e == 4);
|
||||
assert(i != 1 || e == 9);
|
||||
}
|
||||
assert(q.empty);
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
/**
|
||||
* Arbitrary precision arithmetic.
|
||||
*
|
||||
* Copyright: Eugene Wissner 2016-2017.
|
||||
* Copyright: Eugene Wissner 2016-2018.
|
||||
* 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)
|
||||
|
@ -5,7 +5,7 @@
|
||||
/**
|
||||
* Number theory.
|
||||
*
|
||||
* Copyright: Eugene Wissner 2017.
|
||||
* Copyright: Eugene Wissner 2017-2018.
|
||||
* 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)
|
||||
|
@ -12,7 +12,7 @@
|
||||
* be found in its submodules. $(D_PSYMBOL tanya.math) doesn't import any
|
||||
* submodules publically, they should be imported explicitly.
|
||||
*
|
||||
* Copyright: Eugene Wissner 2016-2017.
|
||||
* Copyright: Eugene Wissner 2016-2018.
|
||||
* 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)
|
||||
|
@ -5,7 +5,7 @@
|
||||
/**
|
||||
* Random number generator.
|
||||
*
|
||||
* Copyright: Eugene Wissner 2016.
|
||||
* Copyright: Eugene Wissner 2016-2018.
|
||||
* 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)
|
||||
@ -234,9 +234,12 @@ else version (SecureARC4Random)
|
||||
else version (Windows)
|
||||
{
|
||||
import core.sys.windows.basetsd : ULONG_PTR;
|
||||
import core.sys.windows.windef : BOOL, DWORD, PBYTE;
|
||||
import core.sys.windows.winnt : LPCSTR, LPCWSTR;
|
||||
import core.sys.windows.winbase : GetLastError;
|
||||
import core.sys.windows.wincrypt;
|
||||
import core.sys.windows.windef : BOOL, DWORD, PBYTE;
|
||||
import core.sys.windows.winerror : NTE_BAD_KEYSET;
|
||||
import core.sys.windows.winnt : LPCSTR, LPCWSTR;
|
||||
|
||||
private extern(Windows) @nogc nothrow
|
||||
{
|
||||
BOOL CryptGenRandom(HCRYPTPROV, DWORD, PBYTE);
|
||||
@ -247,9 +250,6 @@ else version (Windows)
|
||||
|
||||
private bool initCryptGenRandom(scope ref HCRYPTPROV hProvider) @nogc nothrow @trusted
|
||||
{
|
||||
import core.sys.windows.winbase : GetLastError;
|
||||
import core.sys.windows.winerror : NTE_BAD_KEYSET;
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa379886(v=vs.85).aspx
|
||||
// For performance reasons, we recommend that you set the pszContainer
|
||||
// parameter to NULL and the dwFlags parameter to CRYPT_VERIFYCONTEXT
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Allocators are classes encapsulating memory allocation strategy. This allows
|
||||
* to decouple memory management from the algorithms and the data.
|
||||
*
|
||||
* Copyright: Eugene Wissner 2016-2017.
|
||||
* Copyright: Eugene Wissner 2016-2018.
|
||||
* 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)
|
||||
|
@ -5,7 +5,7 @@
|
||||
/**
|
||||
* Allocator based on $(D_PSYMBOL malloc), $(D_PSYMBOL realloc) and $(D_PSYMBOL free).
|
||||
*
|
||||
* Copyright: Eugene Wissner 2017.
|
||||
* Copyright: Eugene Wissner 2017-2018.
|
||||
* 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)
|
||||
|
@ -3,9 +3,9 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* Native allocator for Posix and Windows.
|
||||
* Native allocator.
|
||||
*
|
||||
* Copyright: Eugene Wissner 2016-2017.
|
||||
* Copyright: Eugene Wissner 2016-2018.
|
||||
* 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)
|
||||
@ -18,68 +18,41 @@ import std.algorithm.comparison;
|
||||
import tanya.memory.allocator;
|
||||
import tanya.memory.op;
|
||||
|
||||
version (Posix)
|
||||
version (TanyaNative):
|
||||
|
||||
import core.sys.posix.sys.mman : MAP_ANON,
|
||||
MAP_FAILED,
|
||||
MAP_PRIVATE,
|
||||
PROT_READ,
|
||||
PROT_WRITE;
|
||||
import core.sys.posix.unistd;
|
||||
|
||||
extern(C)
|
||||
private void* mmap(void* addr,
|
||||
size_t len,
|
||||
int prot,
|
||||
int flags,
|
||||
int fd,
|
||||
off_t offset) pure nothrow @system @nogc;
|
||||
|
||||
extern(C)
|
||||
private int munmap(void* addr, size_t len) pure nothrow @system @nogc;
|
||||
|
||||
private void* mapMemory(const size_t len) pure nothrow @system @nogc
|
||||
{
|
||||
import core.sys.posix.sys.mman : MAP_ANON,
|
||||
MAP_FAILED,
|
||||
MAP_PRIVATE,
|
||||
PROT_READ,
|
||||
PROT_WRITE;
|
||||
import core.sys.posix.unistd;
|
||||
|
||||
extern(C)
|
||||
private void* mmap(void* addr,
|
||||
size_t len,
|
||||
int prot,
|
||||
int flags,
|
||||
int fd,
|
||||
off_t offset) pure nothrow @system @nogc;
|
||||
|
||||
extern(C)
|
||||
private int munmap(void* addr, size_t len) pure nothrow @system @nogc;
|
||||
|
||||
private void* mapMemory(const size_t len) pure nothrow @system @nogc
|
||||
{
|
||||
void* p = mmap(null,
|
||||
len,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANON,
|
||||
-1,
|
||||
0);
|
||||
return p is MAP_FAILED ? null : p;
|
||||
}
|
||||
|
||||
private bool unmapMemory(shared void* addr, const size_t len)
|
||||
pure nothrow @system @nogc
|
||||
{
|
||||
return munmap(cast(void*) addr, len) == 0;
|
||||
}
|
||||
void* p = mmap(null,
|
||||
len,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANON,
|
||||
-1,
|
||||
0);
|
||||
return p is MAP_FAILED ? null : p;
|
||||
}
|
||||
else version (Windows)
|
||||
|
||||
private bool unmapMemory(shared void* addr, const size_t len)
|
||||
pure nothrow @system @nogc
|
||||
{
|
||||
import core.sys.windows.winbase : GetSystemInfo, SYSTEM_INFO;
|
||||
|
||||
extern(Windows)
|
||||
private void* VirtualAlloc(void*, size_t, uint, uint)
|
||||
pure nothrow @system @nogc;
|
||||
|
||||
extern(Windows)
|
||||
private int VirtualFree(void* addr, size_t len, uint)
|
||||
pure nothrow @system @nogc;
|
||||
|
||||
private void* mapMemory(const size_t len) pure nothrow @system @nogc
|
||||
{
|
||||
return VirtualAlloc(null,
|
||||
len,
|
||||
0x00001000, // MEM_COMMIT
|
||||
0x04); // PAGE_READWRITE
|
||||
}
|
||||
|
||||
private bool unmapMemory(shared void* addr, const size_t len)
|
||||
pure nothrow @system @nogc
|
||||
{
|
||||
return VirtualFree(cast(void*) addr, 0, 0x8000) == 0;
|
||||
}
|
||||
return munmap(cast(void*) addr, len) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -106,7 +79,6 @@ else version (Windows)
|
||||
* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* </pre>
|
||||
*/
|
||||
deprecated("Use tanya.memory.mallocator instead")
|
||||
final class MmapPool : Allocator
|
||||
{
|
||||
version (none)
|
||||
@ -156,7 +128,7 @@ final class MmapPool : Allocator
|
||||
return data is null ? null : data[0 .. size];
|
||||
}
|
||||
|
||||
version (TanyaNative) @nogc nothrow pure unittest
|
||||
@nogc nothrow pure unittest
|
||||
{
|
||||
auto p = MmapPool.instance.allocate(20);
|
||||
assert(p);
|
||||
@ -167,7 +139,7 @@ final class MmapPool : Allocator
|
||||
}
|
||||
|
||||
// Issue 245: https://issues.caraus.io/issues/245.
|
||||
version (TanyaNative) @nogc nothrow pure unittest
|
||||
@nogc nothrow pure unittest
|
||||
{
|
||||
// allocate() check.
|
||||
size_t tooMuchMemory = size_t.max
|
||||
@ -299,7 +271,7 @@ final class MmapPool : Allocator
|
||||
return true;
|
||||
}
|
||||
|
||||
version (TanyaNative) @nogc nothrow pure unittest
|
||||
@nogc nothrow pure unittest
|
||||
{
|
||||
auto p = MmapPool.instance.allocate(20);
|
||||
|
||||
@ -382,7 +354,7 @@ final class MmapPool : Allocator
|
||||
return true;
|
||||
}
|
||||
|
||||
version (TanyaNative) @nogc nothrow pure unittest
|
||||
@nogc nothrow pure unittest
|
||||
{
|
||||
void[] p;
|
||||
assert(!MmapPool.instance.reallocateInPlace(p, 5));
|
||||
@ -447,7 +419,7 @@ final class MmapPool : Allocator
|
||||
return true;
|
||||
}
|
||||
|
||||
version (TanyaNative) @nogc nothrow pure unittest
|
||||
@nogc nothrow pure unittest
|
||||
{
|
||||
void[] p;
|
||||
MmapPool.instance.reallocate(p, 10 * int.sizeof);
|
||||
@ -480,19 +452,10 @@ final class MmapPool : Allocator
|
||||
if (instance_ is null)
|
||||
{
|
||||
// Get system dependend page size.
|
||||
version (Posix)
|
||||
size_t pageSize = sysconf(_SC_PAGE_SIZE);
|
||||
if (pageSize < 65536)
|
||||
{
|
||||
size_t pageSize = sysconf(_SC_PAGE_SIZE);
|
||||
if (pageSize < 65536)
|
||||
{
|
||||
pageSize = pageSize * 65536 / pageSize;
|
||||
}
|
||||
}
|
||||
else version (Windows)
|
||||
{
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
size_t pageSize = si.dwPageSize;
|
||||
pageSize = pageSize * 65536 / pageSize;
|
||||
}
|
||||
|
||||
const instanceSize = addAlignment(__traits(classInstanceSize,
|
||||
@ -521,7 +484,7 @@ final class MmapPool : Allocator
|
||||
return (cast(GetPureInstance!MmapPool) &instantiate)();
|
||||
}
|
||||
|
||||
version (TanyaNative) @nogc nothrow pure unittest
|
||||
@nogc nothrow pure unittest
|
||||
{
|
||||
assert(instance is instance);
|
||||
}
|
||||
@ -626,7 +589,7 @@ final class MmapPool : Allocator
|
||||
return alignment_;
|
||||
}
|
||||
|
||||
version (TanyaNative) @nogc nothrow pure unittest
|
||||
@nogc nothrow pure unittest
|
||||
{
|
||||
assert(MmapPool.instance.alignment == MmapPool.alignment_);
|
||||
}
|
||||
@ -657,8 +620,6 @@ final class MmapPool : Allocator
|
||||
private alias Block = shared BlockEntry*;
|
||||
}
|
||||
|
||||
version (TanyaNative):
|
||||
|
||||
// A lot of allocations/deallocations, but it is the minimum caused a
|
||||
// segmentation fault because MmapPool reallocateInPlace moves a block wrong.
|
||||
@nogc nothrow pure unittest
|
||||
|
@ -5,7 +5,7 @@
|
||||
/**
|
||||
* Set of operations on memory blocks.
|
||||
*
|
||||
* Copyright: Eugene Wissner 2017.
|
||||
* Copyright: Eugene Wissner 2017-2018.
|
||||
* 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)
|
||||
|
@ -5,7 +5,7 @@
|
||||
/**
|
||||
* Dynamic memory management.
|
||||
*
|
||||
* Copyright: Eugene Wissner 2016-2017.
|
||||
* Copyright: Eugene Wissner 2016-2018.
|
||||
* 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)
|
||||
|
@ -14,7 +14,7 @@
|
||||
* $(LI Unique ownership)
|
||||
* )
|
||||
*
|
||||
* Copyright: Eugene Wissner 2016-2017.
|
||||
* Copyright: Eugene Wissner 2016-2018.
|
||||
* 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)
|
||||
|
@ -44,7 +44,7 @@ import tanya.meta.transform;
|
||||
* See_Also: $(D_PSYMBOL isLess).
|
||||
*/
|
||||
template Min(alias pred, Args...)
|
||||
if (Args.length > 0 && isTemplate!pred)
|
||||
if (Args.length > 0 && __traits(isTemplate, pred))
|
||||
{
|
||||
static if (Args.length == 1)
|
||||
{
|
||||
@ -91,7 +91,7 @@ if (Args.length > 0 && isTemplate!pred)
|
||||
* See_Also: $(D_PSYMBOL isLess).
|
||||
*/
|
||||
template Max(alias pred, Args...)
|
||||
if (Args.length > 0 && isTemplate!pred)
|
||||
if (Args.length > 0 && __traits(isTemplate, pred))
|
||||
{
|
||||
static if (Args.length == 1)
|
||||
{
|
||||
@ -148,7 +148,7 @@ if (Args.length > 0 && isTemplate!pred)
|
||||
*/
|
||||
template ZipWith(alias f, Tuples...)
|
||||
if (Tuples.length > 0
|
||||
&& isTemplate!f
|
||||
&& __traits(isTemplate, f)
|
||||
&& allSatisfy!(ApplyLeft!(isInstanceOf, Tuple), Tuples))
|
||||
{
|
||||
private template GetIth(size_t i, Args...)
|
||||
@ -448,7 +448,7 @@ if (isInstanceOf!(Set, S1) && isInstanceOf!(Set, S2))
|
||||
* to $(D_INLINECODE Args[1]), $(D_KEYWORD false) otherwise.
|
||||
*/
|
||||
template isLessEqual(alias cmp, Args...)
|
||||
if (Args.length == 2 && isTemplate!cmp)
|
||||
if (Args.length == 2 && __traits(isTemplate, cmp))
|
||||
{
|
||||
private enum result = cmp!(Args[1], Args[0]);
|
||||
static if (is(typeof(result) == bool))
|
||||
@ -495,7 +495,7 @@ if (Args.length == 2 && isTemplate!cmp)
|
||||
* equal to $(D_INLINECODE Args[1]), $(D_KEYWORD false) otherwise.
|
||||
*/
|
||||
template isGreaterEqual(alias cmp, Args...)
|
||||
if (Args.length == 2 && isTemplate!cmp)
|
||||
if (Args.length == 2 && __traits(isTemplate, cmp))
|
||||
{
|
||||
private enum result = cmp!Args;
|
||||
static if (is(typeof(result) == bool))
|
||||
@ -542,7 +542,7 @@ if (Args.length == 2 && isTemplate!cmp)
|
||||
* $(D_INLINECODE Args[1]), $(D_KEYWORD false) otherwise.
|
||||
*/
|
||||
template isLess(alias cmp, Args...)
|
||||
if (Args.length == 2 && isTemplate!cmp)
|
||||
if (Args.length == 2 && __traits(isTemplate, cmp))
|
||||
{
|
||||
private enum result = cmp!Args;
|
||||
static if (is(typeof(result) == bool))
|
||||
@ -589,7 +589,7 @@ if (Args.length == 2 && isTemplate!cmp)
|
||||
* $(D_INLINECODE Args[1]), $(D_KEYWORD false) otherwise.
|
||||
*/
|
||||
template isGreater(alias cmp, Args...)
|
||||
if (Args.length == 2 && isTemplate!cmp)
|
||||
if (Args.length == 2 && __traits(isTemplate, cmp))
|
||||
{
|
||||
private enum result = cmp!Args;
|
||||
static if (is(typeof(result) == bool))
|
||||
@ -637,7 +637,7 @@ if (Args.length == 2)
|
||||
{
|
||||
static if ((is(typeof(Args[0] == Args[1])) && (Args[0] == Args[1]))
|
||||
|| (isTypeTuple!Args && is(Args[0] == Args[1]))
|
||||
|| isSame!Args)
|
||||
|| __traits(isSame, Args[0], Args[1]))
|
||||
{
|
||||
enum bool isEqual = true;
|
||||
}
|
||||
@ -804,7 +804,7 @@ alias AliasSeq(Args...) = Args;
|
||||
* $(D_PARAM F), $(D_KEYWORD false) otherwise.
|
||||
*/
|
||||
template allSatisfy(alias F, L...)
|
||||
if (isTemplate!F)
|
||||
if (__traits(isTemplate, F))
|
||||
{
|
||||
static if (L.length == 0)
|
||||
{
|
||||
@ -842,7 +842,7 @@ if (isTemplate!F)
|
||||
* $(D_PARAM F), $(D_KEYWORD false) otherwise.
|
||||
*/
|
||||
template anySatisfy(alias F, L...)
|
||||
if (isTemplate!F)
|
||||
if (__traits(isTemplate, F))
|
||||
{
|
||||
static if (L.length == 0)
|
||||
{
|
||||
@ -945,6 +945,32 @@ template canFind(alias T, L...)
|
||||
static assert(canFind!(3, () {}, uint, 5, 3));
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests whether $(D_PARAM T) is a template.
|
||||
*
|
||||
* $(D_PSYMBOL isTemplate) isn't $(D_KEYWORD true) for template instances,
|
||||
* since the latter already represent some type. Only not instantiated
|
||||
* templates, i.e. that accept some template parameters, are considered
|
||||
* templates.
|
||||
*
|
||||
* Params:
|
||||
* T = A symbol.
|
||||
*
|
||||
* Returns: $(D_KEYWORD true) if $(D_PARAM T) is a template,
|
||||
* $(D_KEYWORD false) otherwise.
|
||||
*/
|
||||
private enum bool isTemplate(alias T) = __traits(isTemplate, T);
|
||||
|
||||
///
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
static struct S(T)
|
||||
{
|
||||
}
|
||||
static assert(isTemplate!S);
|
||||
static assert(!isTemplate!(S!int));
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines multiple templates with logical AND. So $(D_PSYMBOL templateAnd)
|
||||
* evaluates to $(D_INLINECODE Preds[0] && Preds[1] && Preds[2]) and so on.
|
||||
@ -1049,7 +1075,7 @@ if (allSatisfy!(isTemplate, Preds))
|
||||
* Returns: Negated $(D_PARAM pred).
|
||||
*/
|
||||
template templateNot(alias pred)
|
||||
if (isTemplate!pred)
|
||||
if (__traits(isTemplate, pred))
|
||||
{
|
||||
enum bool templateNot(T...) = !pred!T;
|
||||
}
|
||||
@ -1083,7 +1109,7 @@ if (isTemplate!pred)
|
||||
* if not.
|
||||
*/
|
||||
template isSorted(alias cmp, L...)
|
||||
if (isTemplate!cmp)
|
||||
if (__traits(isTemplate, cmp))
|
||||
{
|
||||
static if (L.length <= 1)
|
||||
{
|
||||
@ -1359,7 +1385,7 @@ template Reverse(L...)
|
||||
* Returns: Elements $(D_PARAM T) after applying $(D_PARAM F) to them.
|
||||
*/
|
||||
template Map(alias F, T...)
|
||||
if (isTemplate!F)
|
||||
if (__traits(isTemplate, F))
|
||||
{
|
||||
static if (T.length == 0)
|
||||
{
|
||||
@ -1401,7 +1427,7 @@ if (isTemplate!F)
|
||||
* See_Also: $(LINK2 https://en.wikipedia.org/wiki/Merge_sort, Merge sort).
|
||||
*/
|
||||
template Sort(alias cmp, L...)
|
||||
if (isTemplate!cmp)
|
||||
if (__traits(isTemplate, cmp))
|
||||
{
|
||||
private template merge(size_t A, size_t B)
|
||||
{
|
||||
|
@ -150,137 +150,7 @@ enum bool isComplex(T) = is(Unqual!(OriginalType!T) == cfloat)
|
||||
static assert(!isComplex!real);
|
||||
}
|
||||
|
||||
/**
|
||||
* POD (Plain Old Data) is a $(D_KEYWORD struct) without constructors,
|
||||
* destructors and member functions.
|
||||
*
|
||||
* Params:
|
||||
* T = A type.
|
||||
*
|
||||
* Returns: $(D_KEYWORD true) if $(D_PARAM T) is a POD type,
|
||||
* $(D_KEYWORD false) otherwise.
|
||||
*/
|
||||
deprecated("Use __traits(isPOD) instead")
|
||||
enum bool isPOD(T) = __traits(isPOD, T);
|
||||
|
||||
///
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
struct S1
|
||||
{
|
||||
void method()
|
||||
{
|
||||
}
|
||||
}
|
||||
static assert(!isPOD!S1);
|
||||
|
||||
struct S2
|
||||
{
|
||||
void function() val; // Function pointer, not a member function.
|
||||
}
|
||||
static assert(isPOD!S2);
|
||||
|
||||
struct S3
|
||||
{
|
||||
this(this)
|
||||
{
|
||||
}
|
||||
}
|
||||
static assert(!isPOD!S3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns size of the type $(D_PARAM T).
|
||||
*
|
||||
* Params:
|
||||
* T = A type.
|
||||
*
|
||||
* Returns: Size of the type $(D_PARAM T).
|
||||
*/
|
||||
deprecated("Use T.sizeof instead")
|
||||
enum size_t sizeOf(T) = T.sizeof;
|
||||
|
||||
///
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
static assert(sizeOf!(bool function()) == size_t.sizeof);
|
||||
static assert(sizeOf!bool == 1);
|
||||
static assert(sizeOf!short == 2);
|
||||
static assert(sizeOf!int == 4);
|
||||
static assert(sizeOf!long == 8);
|
||||
static assert(sizeOf!(void[16]) == 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the alignment of the type $(D_PARAM T).
|
||||
*
|
||||
* Params:
|
||||
* T = A type.
|
||||
*
|
||||
* Returns: Alignment of the type $(D_PARAM T).
|
||||
*/
|
||||
deprecated("Use T.alignof instead")
|
||||
enum size_t alignOf(T) = T.alignof;
|
||||
|
||||
///
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
static assert(alignOf!bool == bool.alignof);
|
||||
static assert(is(typeof(alignOf!bool) == typeof(bool.alignof)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether $(D_INLINECODE Args[0]) and $(D_INLINECODE Args[1]) are the
|
||||
* same symbol.
|
||||
*
|
||||
* Params:
|
||||
* Args = Two symbols to be tested.
|
||||
*
|
||||
* Returns: $(D_KEYWORD true) if $(D_PARAM Args) are the same symbol,
|
||||
* $(D_KEYWORD false) otherwise.
|
||||
*/
|
||||
deprecated("Use __traits(isSame) instead")
|
||||
template isSame(Args...)
|
||||
if (Args.length == 2)
|
||||
{
|
||||
enum bool isSame = __traits(isSame, Args[0], Args[1]);
|
||||
}
|
||||
|
||||
///
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
static assert(isSame!("string", "string"));
|
||||
static assert(!isSame!(string, immutable(char)[]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether $(D_PARAM T) is a template.
|
||||
*
|
||||
* $(D_PSYMBOL isTemplate) isn't $(D_KEYWORD true) for template instances,
|
||||
* since the latter already represent some type. Only not instantiated
|
||||
* templates, i.e. that accept some template parameters, are considered
|
||||
* templates.
|
||||
*
|
||||
* Params:
|
||||
* T = A symbol.
|
||||
*
|
||||
* Returns: $(D_KEYWORD true) if $(D_PARAM T) is a template,
|
||||
* $(D_KEYWORD false) otherwise.
|
||||
*/
|
||||
deprecated("Use __traits(isTemplate) instead")
|
||||
enum bool isTemplate(alias T) = __traits(isTemplate, T);
|
||||
|
||||
///
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
static struct S(T)
|
||||
{
|
||||
}
|
||||
static assert(isTemplate!S);
|
||||
static assert(!isTemplate!(S!int));
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Tests whether $(D_PARAM T) is an interface.
|
||||
*
|
||||
* Params:
|
||||
@ -289,44 +159,7 @@ enum bool isTemplate(alias T) = __traits(isTemplate, T);
|
||||
* Returns: $(D_KEYWORD true) if $(D_PARAM T) is an interface,
|
||||
* $(D_KEYWORD false) otherwise.
|
||||
*/
|
||||
deprecated("Use is(T == interface) instead")
|
||||
enum bool isInterface(T) = is(T == interface);
|
||||
|
||||
/**
|
||||
* Tests whether $(D_PARAM T) is a class.
|
||||
*
|
||||
* Params:
|
||||
* T = A type.
|
||||
*
|
||||
* Returns: $(D_KEYWORD true) if $(D_PARAM T) is a class,
|
||||
* $(D_KEYWORD false) otherwise.
|
||||
*/
|
||||
deprecated("Use is(T == class) instead")
|
||||
enum bool isClass(T) = is(T == class);
|
||||
|
||||
/**
|
||||
* Tests whether $(D_PARAM T) is a struct.
|
||||
*
|
||||
* Params:
|
||||
* T = A type.
|
||||
*
|
||||
* Returns: $(D_KEYWORD true) if $(D_PARAM T) is a struct,
|
||||
* $(D_KEYWORD false) otherwise.
|
||||
*/
|
||||
deprecated("Use is(T == struct) instead")
|
||||
enum bool isStruct(T) = is(T == struct);
|
||||
|
||||
/**
|
||||
* Tests whether $(D_PARAM T) is a enum.
|
||||
*
|
||||
* Params:
|
||||
* T = A type.
|
||||
*
|
||||
* Returns: $(D_KEYWORD true) if $(D_PARAM T) is an enum,
|
||||
* $(D_KEYWORD false) otherwise.
|
||||
*/
|
||||
deprecated("Use is(T == enum) instead")
|
||||
enum bool isEnum(T) = is(T == enum);
|
||||
private enum bool isInterface(T) = is(T == interface);
|
||||
|
||||
/**
|
||||
* Determines whether $(D_PARAM T) is a polymorphic type, i.e. a
|
||||
@ -2007,17 +1840,17 @@ alias TemplateOf(alias T : Base!Args, alias Base, Args...) = Base;
|
||||
static struct S(T)
|
||||
{
|
||||
}
|
||||
static assert(isSame!(TemplateOf!(S!int), S));
|
||||
static assert(__traits(isSame, TemplateOf!(S!int), S));
|
||||
|
||||
static void func(T)()
|
||||
{
|
||||
}
|
||||
static assert(isSame!(TemplateOf!(func!int), func));
|
||||
static assert(__traits(isSame, TemplateOf!(func!int), func));
|
||||
|
||||
template T(U)
|
||||
{
|
||||
}
|
||||
static assert(isSame!(TemplateOf!(T!int), T));
|
||||
static assert(__traits(isSame, TemplateOf!(T!int), T));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2049,7 +1882,7 @@ template isInstanceOf(alias T, alias I)
|
||||
{
|
||||
static if (is(typeof(TemplateOf!I)))
|
||||
{
|
||||
enum bool isInstanceOf = isSame!(TemplateOf!I, T);
|
||||
enum bool isInstanceOf = __traits(isSame, TemplateOf!I, T);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -701,7 +701,7 @@ alias TypeOf(T) = T;
|
||||
|
||||
/// ditto
|
||||
template TypeOf(alias T)
|
||||
if (isExpressions!T || isTemplate!T)
|
||||
if (isExpressions!T || __traits(isTemplate, T))
|
||||
{
|
||||
alias TypeOf = typeof(T);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
/**
|
||||
* Internet utilities.
|
||||
*
|
||||
* Copyright: Eugene Wissner 2016-2017.
|
||||
* Copyright: Eugene Wissner 2016-2018.
|
||||
* 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)
|
||||
@ -170,7 +170,7 @@ struct NetworkOrder(uint L)
|
||||
}
|
||||
|
||||
///
|
||||
pure nothrow @safe @nogc unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
auto networkOrder = NetworkOrder!3(0xae34e2u);
|
||||
assert(!networkOrder.empty);
|
||||
@ -190,8 +190,8 @@ pure nothrow @safe @nogc unittest
|
||||
assert(networkOrder.empty);
|
||||
}
|
||||
|
||||
// Static.
|
||||
private unittest
|
||||
// Static tests
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
static assert(isBidirectionalRange!(NetworkOrder!4));
|
||||
static assert(isBidirectionalRange!(NetworkOrder!8));
|
||||
@ -238,7 +238,7 @@ T toHostOrder(T = size_t, R)(R range)
|
||||
}
|
||||
|
||||
///
|
||||
pure nothrow @safe @nogc unittest
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
const value = 0xae34e2u;
|
||||
auto networkOrder = NetworkOrder!4(value);
|
||||
|
@ -5,7 +5,7 @@
|
||||
/**
|
||||
* Network programming.
|
||||
*
|
||||
* Copyright: Eugene Wissner 2017.
|
||||
* Copyright: Eugene Wissner 2017-2018.
|
||||
* 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)
|
||||
|
@ -5,7 +5,7 @@
|
||||
/**
|
||||
* URL parser.
|
||||
*
|
||||
* Copyright: Eugene Wissner 2017.
|
||||
* Copyright: Eugene Wissner 2017-2018.
|
||||
* 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)
|
||||
@ -460,7 +460,6 @@ struct URL
|
||||
assertThrown!URIException(() => URL("http://blah.com:66000"));
|
||||
}
|
||||
|
||||
// Issue 254: https://issues.caraus.io/issues/254.
|
||||
@nogc pure @system unittest
|
||||
{
|
||||
auto u = URL("ftp://");
|
||||
|
@ -31,7 +31,7 @@
|
||||
* (D_INLINECODE dchar[])) are treated as any other normal array, they aren't
|
||||
* auto-decoded.
|
||||
*
|
||||
* Copyright: Eugene Wissner 2017.
|
||||
* Copyright: Eugene Wissner 2017-2018.
|
||||
* 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)
|
||||
|
@ -6,7 +6,7 @@
|
||||
* This package contains generic functions and templates to be used with D
|
||||
* ranges.
|
||||
*
|
||||
* Copyright: Eugene Wissner 2017.
|
||||
* Copyright: Eugene Wissner 2017-2018.
|
||||
* 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)
|
||||
|
@ -5,7 +5,7 @@
|
||||
/**
|
||||
* This module defines primitives for working with ranges.
|
||||
*
|
||||
* Copyright: Eugene Wissner 2017.
|
||||
* Copyright: Eugene Wissner 2017-2018.
|
||||
* 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)
|
||||
@ -1464,11 +1464,7 @@ if (isBidirectionalRange!R)
|
||||
ElementType!R moveFront(R)(R range)
|
||||
if (isInputRange!R)
|
||||
{
|
||||
static if (__traits(hasMember, R, "moveFront"))
|
||||
{
|
||||
return range.moveFront();
|
||||
}
|
||||
else static if (!hasElaborateCopyConstructor!(ElementType!R))
|
||||
static if (!hasElaborateCopyConstructor!(ElementType!R))
|
||||
{
|
||||
return range.front;
|
||||
}
|
||||
@ -1485,48 +1481,24 @@ if (isInputRange!R)
|
||||
///
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
// Defines moveFront.
|
||||
static struct R1
|
||||
{
|
||||
enum bool empty = false;
|
||||
|
||||
int moveFront() @nogc nothrow pure @safe
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
alias front = moveFront;
|
||||
|
||||
void popFront() @nogc nothrow pure @safe
|
||||
{
|
||||
}
|
||||
}
|
||||
assert(moveFront(R1()) == 5);
|
||||
|
||||
// Has elements without a postblit constructor.
|
||||
static struct R2
|
||||
{
|
||||
enum bool empty = false;
|
||||
int[2] a = 5;
|
||||
|
||||
int front() const @nogc nothrow pure @safe
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
void popFront() @nogc nothrow pure @safe
|
||||
{
|
||||
}
|
||||
}
|
||||
assert(moveFront(R2()) == 5);
|
||||
assert(moveFront(a[]) == 5);
|
||||
}
|
||||
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
static struct Element
|
||||
{
|
||||
this(this)
|
||||
this(this) @nogc nothrow pure @safe
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns its elements by reference.
|
||||
static struct R3
|
||||
static struct R1
|
||||
{
|
||||
Element element;
|
||||
enum bool empty = false;
|
||||
@ -1540,10 +1512,10 @@ if (isInputRange!R)
|
||||
{
|
||||
}
|
||||
}
|
||||
static assert(is(typeof(moveFront(R3()))));
|
||||
static assert(is(typeof(moveFront(R1()))));
|
||||
|
||||
// Returns elements with a postblit constructor by value. moveFront fails.
|
||||
static struct R4
|
||||
static struct R2
|
||||
{
|
||||
enum bool empty = false;
|
||||
|
||||
@ -1556,7 +1528,7 @@ if (isInputRange!R)
|
||||
{
|
||||
}
|
||||
}
|
||||
static assert(!is(typeof(moveFront(R4()))));
|
||||
static assert(!is(typeof(moveFront(R2()))));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1577,11 +1549,7 @@ if (isInputRange!R)
|
||||
ElementType!R moveBack(R)(R range)
|
||||
if (isBidirectionalRange!R)
|
||||
{
|
||||
static if (__traits(hasMember, R, "moveBack"))
|
||||
{
|
||||
return range.moveBack();
|
||||
}
|
||||
else static if (!hasElaborateCopyConstructor!(ElementType!R))
|
||||
static if (!hasElaborateCopyConstructor!(ElementType!R))
|
||||
{
|
||||
return range.back;
|
||||
}
|
||||
@ -1598,62 +1566,24 @@ if (isBidirectionalRange!R)
|
||||
///
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
// Defines moveBack.
|
||||
static struct R1
|
||||
{
|
||||
enum bool empty = false;
|
||||
|
||||
int moveBack() @nogc nothrow pure @safe
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
alias back = moveBack;
|
||||
alias front = moveBack;
|
||||
|
||||
void popBack() @nogc nothrow pure @safe
|
||||
{
|
||||
}
|
||||
alias popFront = popBack;
|
||||
|
||||
R1 save() @nogc nothrow pure @safe
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
assert(moveBack(R1()) == 5);
|
||||
|
||||
// Has elements without a postblit constructor.
|
||||
static struct R2
|
||||
{
|
||||
enum bool empty = false;
|
||||
int[2] a = 5;
|
||||
|
||||
int back() const @nogc nothrow pure @safe
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
alias front = back;
|
||||
|
||||
void popBack() @nogc nothrow pure @safe
|
||||
{
|
||||
}
|
||||
alias popFront = popBack;
|
||||
|
||||
R2 save() @nogc nothrow pure @safe
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
assert(moveBack(R2()) == 5);
|
||||
assert(moveBack(a[]) == 5);
|
||||
}
|
||||
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
static struct Element
|
||||
{
|
||||
this(this)
|
||||
this(this) @nogc nothrow pure @safe
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns its elements by reference.
|
||||
static struct R3
|
||||
static struct R1
|
||||
{
|
||||
Element element;
|
||||
enum bool empty = false;
|
||||
@ -1669,15 +1599,15 @@ if (isBidirectionalRange!R)
|
||||
}
|
||||
alias popFront = popBack;
|
||||
|
||||
R3 save() @nogc nothrow pure @safe
|
||||
R1 save() @nogc nothrow pure @safe
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
static assert(is(typeof(moveBack(R3()))));
|
||||
static assert(is(typeof(moveBack(R1()))));
|
||||
|
||||
// Returns elements with a postblit constructor by value. moveBack fails.
|
||||
static struct R4
|
||||
static struct R2
|
||||
{
|
||||
enum bool empty = false;
|
||||
|
||||
@ -1692,12 +1622,12 @@ if (isBidirectionalRange!R)
|
||||
}
|
||||
alias popFront = popBack;
|
||||
|
||||
R4 save() @nogc nothrow pure @safe
|
||||
R2 save() @nogc nothrow pure @safe
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
static assert(!is(typeof(moveBack(R4()))));
|
||||
static assert(!is(typeof(moveBack(R2()))));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1717,11 +1647,7 @@ if (isBidirectionalRange!R)
|
||||
ElementType!R moveAt(R)(R range, size_t n)
|
||||
if (isRandomAccessRange!R)
|
||||
{
|
||||
static if (__traits(hasMember, R, "moveAt"))
|
||||
{
|
||||
return range.moveAt(n);
|
||||
}
|
||||
else static if (!hasElaborateCopyConstructor!(ElementType!R))
|
||||
static if (!hasElaborateCopyConstructor!(ElementType!R))
|
||||
{
|
||||
return range[n];
|
||||
}
|
||||
@ -1731,65 +1657,31 @@ if (isRandomAccessRange!R)
|
||||
}
|
||||
else
|
||||
{
|
||||
static assert(false, "Back element cannot be moved");
|
||||
static assert(false, "Random element cannot be moved");
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
// Defines moveAt.
|
||||
static struct R1
|
||||
{
|
||||
enum bool empty = false;
|
||||
|
||||
int front() @nogc nothrow pure @safe
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
void popFront() @nogc nothrow pure @safe
|
||||
{
|
||||
}
|
||||
|
||||
int moveAt(size_t) @nogc nothrow pure @safe
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
alias opIndex = moveAt;
|
||||
}
|
||||
assert(moveAt(R1(), 0) == 5);
|
||||
|
||||
// Has elements without a postblit constructor.
|
||||
static struct R2
|
||||
{
|
||||
enum bool empty = false;
|
||||
int[3] a = 5;
|
||||
|
||||
int front() const @nogc nothrow pure @safe
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
void popFront() @nogc nothrow pure @safe
|
||||
{
|
||||
}
|
||||
|
||||
int opIndex(size_t) const @nogc nothrow pure @safe
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
assert(moveAt(R2(), 0) == 5);
|
||||
assert(moveAt(a[], 1) == 5);
|
||||
}
|
||||
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
static struct Element
|
||||
{
|
||||
this(this)
|
||||
this(this) @nogc nothrow pure @safe
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns its elements by reference.
|
||||
static struct R3
|
||||
static struct R1
|
||||
{
|
||||
Element element;
|
||||
enum bool empty = false;
|
||||
@ -1808,10 +1700,10 @@ if (isRandomAccessRange!R)
|
||||
return element;
|
||||
}
|
||||
}
|
||||
static assert(is(typeof(moveAt(R3(), 0))));
|
||||
static assert(is(typeof(moveAt(R1(), 0))));
|
||||
|
||||
// Returns elements with a postblit constructor by value. moveAt fails.
|
||||
static struct R4
|
||||
static struct R2
|
||||
{
|
||||
enum bool empty = false;
|
||||
|
||||
@ -1829,7 +1721,7 @@ if (isRandomAccessRange!R)
|
||||
return Element();
|
||||
}
|
||||
}
|
||||
static assert(!is(typeof(moveAt(R4(), 0))));
|
||||
static assert(!is(typeof(moveAt(R2(), 0))));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1871,32 +1763,20 @@ template hasMobileElements(R)
|
||||
///
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
// Input range with elements without a postblit constructor.
|
||||
// These can be moved.
|
||||
static struct InputRange
|
||||
{
|
||||
enum bool empty = false;
|
||||
|
||||
int front() @nogc nothrow pure @safe
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
void popFront() @nogc nothrow pure @safe
|
||||
{
|
||||
}
|
||||
}
|
||||
static assert(hasMobileElements!InputRange);
|
||||
static assert(hasMobileElements!(int[]));
|
||||
}
|
||||
|
||||
///
|
||||
@nogc nothrow pure @safe unittest
|
||||
{
|
||||
static struct Element
|
||||
{
|
||||
this(this)
|
||||
this(this) @nogc nothrow pure @safe
|
||||
{
|
||||
}
|
||||
}
|
||||
// Bidirectional range, whose elements cannot be moved. The range defines
|
||||
// only moveFront, but not moveBack. So it doesn't have mobile elements.
|
||||
static struct BidirectionalRange
|
||||
|
||||
static struct R1
|
||||
{
|
||||
enum bool empty = false;
|
||||
|
||||
@ -1904,44 +1784,28 @@ template hasMobileElements(R)
|
||||
{
|
||||
return Element();
|
||||
}
|
||||
alias back = front;
|
||||
alias moveFront = front;
|
||||
|
||||
void popFront() @nogc nothrow pure @safe
|
||||
{
|
||||
}
|
||||
alias popBack = popFront;
|
||||
|
||||
BidirectionalRange save() @nogc nothrow pure @safe
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
static assert(!hasMobileElements!BidirectionalRange);
|
||||
static assert(!hasMobileElements!R1);
|
||||
|
||||
// Access-random range, whose elements cannot be moved, but the range
|
||||
// defines both, moveFront and moveAt.
|
||||
static struct RandomAccessRange
|
||||
static struct R2
|
||||
{
|
||||
enum bool empty = false;
|
||||
private Element front_;
|
||||
|
||||
Element front() @nogc nothrow pure @safe
|
||||
ref Element front() @nogc nothrow pure @safe
|
||||
{
|
||||
return Element();
|
||||
return front_;
|
||||
}
|
||||
alias moveFront = front;
|
||||
|
||||
void popFront() @nogc nothrow pure @safe
|
||||
{
|
||||
}
|
||||
|
||||
Element opIndex(size_t) @nogc nothrow pure @safe
|
||||
{
|
||||
return Element();
|
||||
}
|
||||
alias moveAt = opIndex;
|
||||
}
|
||||
static assert(hasMobileElements!RandomAccessRange);
|
||||
static assert(hasMobileElements!R2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user