Move memory/package.d into memory.allocator
This commit is contained in:
parent
a36b51f0c3
commit
ad46afb10b
@ -8,7 +8,6 @@ language: d
|
|||||||
|
|
||||||
d:
|
d:
|
||||||
- dmd-2.085.0
|
- dmd-2.085.0
|
||||||
- dmd-2.084.1
|
|
||||||
- dmd-2.082.1
|
- dmd-2.082.1
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
10
README.md
10
README.md
@ -172,12 +172,10 @@ parameter is used)
|
|||||||
|
|
||||||
### Supported compilers
|
### Supported compilers
|
||||||
|
|
||||||
| DMD | GCC |
|
| DMD | GCC |
|
||||||
|:-------:|:---------------:|
|
|:-----------------:|:---------------:|
|
||||||
| 2.085.0 | gdc-8 (2.081.2) |
|
| 2.081.2 — 2.085.0 | gdc-8 (2.081.2) |
|
||||||
| 2.084.1 | gdc-7 (2.081.2) |
|
| | gdc-7 (2.081.2) |
|
||||||
| 2.083.1 | |
|
|
||||||
| 2.082.1 | |
|
|
||||||
|
|
||||||
### Release management
|
### Release management
|
||||||
|
|
||||||
|
@ -9,12 +9,6 @@ environment:
|
|||||||
- DC: dmd
|
- DC: dmd
|
||||||
DVersion: 2.085.0
|
DVersion: 2.085.0
|
||||||
arch: x86
|
arch: x86
|
||||||
- DC: dmd
|
|
||||||
DVersion: 2.084.1
|
|
||||||
arch: x64
|
|
||||||
- DC: dmd
|
|
||||||
DVersion: 2.084.1
|
|
||||||
arch: x86
|
|
||||||
- DC: dmd
|
- DC: dmd
|
||||||
DVersion: 2.082.1
|
DVersion: 2.082.1
|
||||||
arch: x64
|
arch: x64
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.memory.allocator;
|
module tanya.memory.allocator;
|
||||||
|
|
||||||
|
import tanya.memory.lifetime;
|
||||||
|
import tanya.meta.trait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract class implementing a basic allocator.
|
* Abstract class implementing a basic allocator.
|
||||||
*/
|
*/
|
||||||
@ -79,3 +82,416 @@ package template GetPureInstance(T : Allocator)
|
|||||||
alias GetPureInstance = shared(T) function()
|
alias GetPureInstance = shared(T) function()
|
||||||
pure nothrow @nogc;
|
pure nothrow @nogc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mixin generates common methods for classes and structs using
|
||||||
|
* allocators. It provides a protected member, constructor and a read-only property,
|
||||||
|
* that checks if an allocator was already set and sets it to the default
|
||||||
|
* one, if not (useful for structs which don't have a default constructor).
|
||||||
|
*/
|
||||||
|
mixin template DefaultAllocator()
|
||||||
|
{
|
||||||
|
/// Allocator.
|
||||||
|
protected shared Allocator allocator_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Params:
|
||||||
|
* allocator = The allocator should be used.
|
||||||
|
*
|
||||||
|
* Precondition: $(D_INLINECODE allocator_ !is null)
|
||||||
|
*/
|
||||||
|
this(shared Allocator allocator) @nogc nothrow pure @safe
|
||||||
|
in (allocator !is null)
|
||||||
|
{
|
||||||
|
this.allocator_ = allocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This property checks if the allocator was set in the constructor
|
||||||
|
* and sets it to the default one, if not.
|
||||||
|
*
|
||||||
|
* Returns: Used allocator.
|
||||||
|
*
|
||||||
|
* Postcondition: $(D_INLINECODE allocator !is null)
|
||||||
|
*/
|
||||||
|
@property shared(Allocator) allocator() @nogc nothrow pure @safe
|
||||||
|
out (allocator; allocator !is null)
|
||||||
|
{
|
||||||
|
if (allocator_ is null)
|
||||||
|
{
|
||||||
|
allocator_ = defaultAllocator;
|
||||||
|
}
|
||||||
|
return allocator_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ditto
|
||||||
|
@property shared(Allocator) allocator() const @nogc nothrow pure @trusted
|
||||||
|
out (allocator; allocator !is null)
|
||||||
|
{
|
||||||
|
if (allocator_ is null)
|
||||||
|
{
|
||||||
|
return defaultAllocator;
|
||||||
|
}
|
||||||
|
return cast(shared Allocator) allocator_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shared Allocator allocator;
|
||||||
|
|
||||||
|
private shared(Allocator) getAllocatorInstance() @nogc nothrow
|
||||||
|
{
|
||||||
|
if (allocator is null)
|
||||||
|
{
|
||||||
|
version (TanyaNative)
|
||||||
|
{
|
||||||
|
import tanya.memory.mmappool : MmapPool;
|
||||||
|
defaultAllocator = MmapPool.instance;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
import tanya.memory.mallocator : Mallocator;
|
||||||
|
defaultAllocator = Mallocator.instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns: Default allocator.
|
||||||
|
*
|
||||||
|
* Postcondition: $(D_INLINECODE allocator !is null).
|
||||||
|
*/
|
||||||
|
@property shared(Allocator) defaultAllocator() @nogc nothrow pure @trusted
|
||||||
|
out (allocator; allocator !is null)
|
||||||
|
{
|
||||||
|
return (cast(GetPureInstance!Allocator) &getAllocatorInstance)();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the default allocator.
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* allocator = $(D_PSYMBOL Allocator) instance.
|
||||||
|
*
|
||||||
|
* Precondition: $(D_INLINECODE allocator !is null).
|
||||||
|
*/
|
||||||
|
@property void defaultAllocator(shared(Allocator) allocator) @nogc nothrow @safe
|
||||||
|
in (allocator !is null)
|
||||||
|
{
|
||||||
|
.allocator = allocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Params:
|
||||||
|
* size = Raw size.
|
||||||
|
* alignment = Alignment.
|
||||||
|
*
|
||||||
|
* Returns: Aligned size.
|
||||||
|
*/
|
||||||
|
size_t alignedSize(const size_t size, const size_t alignment = 8)
|
||||||
|
pure nothrow @safe @nogc
|
||||||
|
{
|
||||||
|
return (size - 1) / alignment * alignment + alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error thrown if memory allocation fails.
|
||||||
|
*/
|
||||||
|
final class OutOfMemoryError : Error
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Constructs new error.
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* msg = The message for the exception.
|
||||||
|
* file = The file where the exception occurred.
|
||||||
|
* line = The line number where the exception occurred.
|
||||||
|
* next = The previous exception in the chain of exceptions, if any.
|
||||||
|
*/
|
||||||
|
this(string msg = "Out of memory",
|
||||||
|
string file = __FILE__,
|
||||||
|
size_t line = __LINE__,
|
||||||
|
Throwable next = null) @nogc nothrow pure @safe
|
||||||
|
{
|
||||||
|
super(msg, file, line, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ditto
|
||||||
|
this(string msg,
|
||||||
|
Throwable next,
|
||||||
|
string file = __FILE__,
|
||||||
|
size_t line = __LINE__) @nogc nothrow pure @safe
|
||||||
|
{
|
||||||
|
super(msg, file, line, next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys and deallocates $(D_PARAM p) of type $(D_PARAM T).
|
||||||
|
* It is assumed the respective entities had been allocated with the same
|
||||||
|
* allocator.
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* T = Type of $(D_PARAM p).
|
||||||
|
* allocator = Allocator the $(D_PARAM p) was allocated with.
|
||||||
|
* p = Object or array to be destroyed.
|
||||||
|
*/
|
||||||
|
void dispose(T)(shared Allocator allocator, auto ref T p)
|
||||||
|
{
|
||||||
|
() @trusted { allocator.deallocate(finalize(p)); }();
|
||||||
|
p = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new class instance of type $(D_PARAM T) using $(D_PARAM args)
|
||||||
|
* as the parameter list for the constructor of $(D_PARAM T).
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* T = Class type.
|
||||||
|
* A = Types of the arguments to the constructor of $(D_PARAM T).
|
||||||
|
* allocator = Allocator.
|
||||||
|
* args = Constructor arguments of $(D_PARAM T).
|
||||||
|
*
|
||||||
|
* Returns: Newly created $(D_PSYMBOL T).
|
||||||
|
*
|
||||||
|
* Precondition: $(D_INLINECODE allocator !is null)
|
||||||
|
*/
|
||||||
|
T make(T, A...)(shared Allocator allocator, auto ref A args)
|
||||||
|
if (is(T == class))
|
||||||
|
in (allocator !is null)
|
||||||
|
{
|
||||||
|
auto mem = (() @trusted => allocator.allocate(stateSize!T))();
|
||||||
|
if (mem is null)
|
||||||
|
{
|
||||||
|
onOutOfMemoryError();
|
||||||
|
}
|
||||||
|
scope (failure)
|
||||||
|
{
|
||||||
|
() @trusted { allocator.deallocate(mem); }();
|
||||||
|
}
|
||||||
|
|
||||||
|
return emplace!T(mem[0 .. stateSize!T], args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a value object of type $(D_PARAM T) using $(D_PARAM args)
|
||||||
|
* as the parameter list for the constructor of $(D_PARAM T) and returns a
|
||||||
|
* pointer to the new object.
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* T = Object type.
|
||||||
|
* A = Types of the arguments to the constructor of $(D_PARAM T).
|
||||||
|
* allocator = Allocator.
|
||||||
|
* args = Constructor arguments of $(D_PARAM T).
|
||||||
|
*
|
||||||
|
* Returns: Pointer to the created object.
|
||||||
|
*
|
||||||
|
* Precondition: $(D_INLINECODE allocator !is null)
|
||||||
|
*/
|
||||||
|
T* make(T, A...)(shared Allocator allocator, auto ref A args)
|
||||||
|
if (!isPolymorphicType!T && !isAssociativeArray!T && !isArray!T)
|
||||||
|
in (allocator !is null)
|
||||||
|
{
|
||||||
|
auto mem = (() @trusted => allocator.allocate(stateSize!T))();
|
||||||
|
if (mem is null)
|
||||||
|
{
|
||||||
|
onOutOfMemoryError();
|
||||||
|
}
|
||||||
|
scope (failure)
|
||||||
|
{
|
||||||
|
() @trusted { allocator.deallocate(mem); }();
|
||||||
|
}
|
||||||
|
return emplace!T(mem[0 .. stateSize!T], args);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
int* i = defaultAllocator.make!int(5);
|
||||||
|
assert(*i == 5);
|
||||||
|
defaultAllocator.dispose(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new array with $(D_PARAM n) elements.
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* T = Array type.
|
||||||
|
* E = Array element type.
|
||||||
|
* allocator = Allocator.
|
||||||
|
* n = Array size.
|
||||||
|
*
|
||||||
|
* Returns: Newly created array.
|
||||||
|
*
|
||||||
|
* Precondition: $(D_INLINECODE allocator !is null
|
||||||
|
* && n <= size_t.max / E.sizeof)
|
||||||
|
*/
|
||||||
|
T make(T : E[], E)(shared Allocator allocator, size_t n)
|
||||||
|
in (allocator !is null)
|
||||||
|
in (n <= size_t.max / E.sizeof)
|
||||||
|
{
|
||||||
|
auto ret = allocator.resize!E(null, n);
|
||||||
|
|
||||||
|
static if (hasElaborateDestructor!E)
|
||||||
|
{
|
||||||
|
for (auto range = ret; range.length != 0; range = range[1 .. $])
|
||||||
|
{
|
||||||
|
emplace!E(cast(void[]) range[0 .. 1], E.init);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret[] = E.init;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
int[] i = defaultAllocator.make!(int[])(2);
|
||||||
|
assert(i.length == 2);
|
||||||
|
assert(i[0] == int.init && i[1] == int.init);
|
||||||
|
defaultAllocator.dispose(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Destroys the object.
|
||||||
|
* Returns the memory should be freed.
|
||||||
|
*/
|
||||||
|
package void[] finalize(T)(ref T* p)
|
||||||
|
{
|
||||||
|
if (p is null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
static if (hasElaborateDestructor!T)
|
||||||
|
{
|
||||||
|
destroy(*p);
|
||||||
|
}
|
||||||
|
return (cast(void*) p)[0 .. T.sizeof];
|
||||||
|
}
|
||||||
|
|
||||||
|
package void[] finalize(T)(ref T p)
|
||||||
|
if (isPolymorphicType!T)
|
||||||
|
{
|
||||||
|
if (p is null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
static if (is(T == interface))
|
||||||
|
{
|
||||||
|
version(Windows)
|
||||||
|
{
|
||||||
|
import core.sys.windows.unknwn : IUnknown;
|
||||||
|
static assert(!is(T : IUnknown), "COM interfaces can't be destroyed in "
|
||||||
|
~ __PRETTY_FUNCTION__);
|
||||||
|
}
|
||||||
|
auto ob = cast(Object) p;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
alias ob = p;
|
||||||
|
}
|
||||||
|
auto ptr = cast(void*) ob;
|
||||||
|
auto support = ptr[0 .. typeid(ob).initializer.length];
|
||||||
|
|
||||||
|
auto ppv = cast(void**) ptr;
|
||||||
|
if (!*ppv)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
auto pc = cast(ClassInfo*) *ppv;
|
||||||
|
scope (exit)
|
||||||
|
{
|
||||||
|
*ppv = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto c = *pc;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Assume the destructor is @nogc. Leave it nothrow since the destructor
|
||||||
|
// shouldn't throw and if it does, it is an error anyway.
|
||||||
|
if (c.destructor)
|
||||||
|
{
|
||||||
|
alias DtorType = void function(Object) pure nothrow @safe @nogc;
|
||||||
|
(cast(DtorType) c.destructor)(ob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ((c = c.base) !is null);
|
||||||
|
|
||||||
|
if (ppv[1]) // if monitor is not null
|
||||||
|
{
|
||||||
|
_d_monitordelete(cast(Object) ptr, true);
|
||||||
|
}
|
||||||
|
return support;
|
||||||
|
}
|
||||||
|
|
||||||
|
package void[] finalize(T)(ref T[] p)
|
||||||
|
{
|
||||||
|
destroyAllImpl!(T[], T)(p);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates $(D_PSYMBOL OutOfMemoryError) in a static storage and throws it.
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* msg = Custom error message.
|
||||||
|
*
|
||||||
|
* Throws: $(D_PSYMBOL OutOfMemoryError).
|
||||||
|
*/
|
||||||
|
void onOutOfMemoryError(string msg = "Out of memory")
|
||||||
|
@nogc nothrow pure @trusted
|
||||||
|
{
|
||||||
|
static ubyte[stateSize!OutOfMemoryError] memory;
|
||||||
|
alias PureType = OutOfMemoryError function(string) @nogc nothrow pure;
|
||||||
|
throw (cast(PureType) () => emplace!OutOfMemoryError(memory))(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// From druntime
|
||||||
|
extern (C)
|
||||||
|
private void _d_monitordelete(Object h, bool det) @nogc nothrow pure;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internal function used to create, resize or destroy a dynamic array. It
|
||||||
|
* may throw $(D_PSYMBOL OutOfMemoryError). The new
|
||||||
|
* allocated part of the array isn't initialized. This function can be trusted
|
||||||
|
* only in the data structures that can ensure that the array is
|
||||||
|
* allocated/rellocated/deallocated with the same allocator.
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* T = Element type of the array being created.
|
||||||
|
* allocator = The allocator used for getting memory.
|
||||||
|
* array = A reference to the array being changed.
|
||||||
|
* length = New array length.
|
||||||
|
*
|
||||||
|
* Returns: $(D_PARAM array).
|
||||||
|
*/
|
||||||
|
package(tanya) T[] resize(T)(shared Allocator allocator,
|
||||||
|
auto ref T[] array,
|
||||||
|
const size_t length) @trusted
|
||||||
|
{
|
||||||
|
if (length == 0)
|
||||||
|
{
|
||||||
|
if (allocator.deallocate(array))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
onOutOfMemoryError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void[] buf = array;
|
||||||
|
if (!allocator.reallocate(buf, length * T.sizeof))
|
||||||
|
{
|
||||||
|
onOutOfMemoryError();
|
||||||
|
}
|
||||||
|
// Casting from void[] is unsafe, but we know we cast to the original type.
|
||||||
|
array = cast(T[]) buf;
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
@ -14,183 +14,10 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.memory.lifetime;
|
module tanya.memory.lifetime;
|
||||||
|
|
||||||
import tanya.memory : defaultAllocator;
|
|
||||||
import tanya.memory.allocator;
|
import tanya.memory.allocator;
|
||||||
import tanya.meta.metafunction;
|
import tanya.meta.metafunction;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
|
|
||||||
/**
|
|
||||||
* Error thrown if memory allocation fails.
|
|
||||||
*/
|
|
||||||
final class OutOfMemoryError : Error
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Constructs new error.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* msg = The message for the exception.
|
|
||||||
* file = The file where the exception occurred.
|
|
||||||
* line = The line number where the exception occurred.
|
|
||||||
* next = The previous exception in the chain of exceptions, if any.
|
|
||||||
*/
|
|
||||||
this(string msg = "Out of memory",
|
|
||||||
string file = __FILE__,
|
|
||||||
size_t line = __LINE__,
|
|
||||||
Throwable next = null) @nogc nothrow pure @safe
|
|
||||||
{
|
|
||||||
super(msg, file, line, next);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ditto
|
|
||||||
this(string msg,
|
|
||||||
Throwable next,
|
|
||||||
string file = __FILE__,
|
|
||||||
size_t line = __LINE__) @nogc nothrow pure @safe
|
|
||||||
{
|
|
||||||
super(msg, file, line, next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocates $(D_PSYMBOL OutOfMemoryError) in a static storage and throws it.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* msg = Custom error message.
|
|
||||||
*
|
|
||||||
* Throws: $(D_PSYMBOL OutOfMemoryError).
|
|
||||||
*/
|
|
||||||
void onOutOfMemoryError(string msg = "Out of memory")
|
|
||||||
@nogc nothrow pure @trusted
|
|
||||||
{
|
|
||||||
static ubyte[stateSize!OutOfMemoryError] memory;
|
|
||||||
alias PureType = OutOfMemoryError function(string) @nogc nothrow pure;
|
|
||||||
throw (cast(PureType) () => emplace!OutOfMemoryError(memory))(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// From druntime
|
|
||||||
extern (C)
|
|
||||||
private void _d_monitordelete(Object h, bool det) @nogc nothrow pure;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Internal function used to create, resize or destroy a dynamic array. It
|
|
||||||
* may throw $(D_PSYMBOL OutOfMemoryError). The new
|
|
||||||
* allocated part of the array isn't initialized. This function can be trusted
|
|
||||||
* only in the data structures that can ensure that the array is
|
|
||||||
* allocated/rellocated/deallocated with the same allocator.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* T = Element type of the array being created.
|
|
||||||
* allocator = The allocator used for getting memory.
|
|
||||||
* array = A reference to the array being changed.
|
|
||||||
* length = New array length.
|
|
||||||
*
|
|
||||||
* Returns: $(D_PARAM array).
|
|
||||||
*/
|
|
||||||
package(tanya) T[] resize(T)(shared Allocator allocator,
|
|
||||||
auto ref T[] array,
|
|
||||||
const size_t length) @trusted
|
|
||||||
{
|
|
||||||
if (length == 0)
|
|
||||||
{
|
|
||||||
if (allocator.deallocate(array))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
onOutOfMemoryError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void[] buf = array;
|
|
||||||
if (!allocator.reallocate(buf, length * T.sizeof))
|
|
||||||
{
|
|
||||||
onOutOfMemoryError();
|
|
||||||
}
|
|
||||||
// Casting from void[] is unsafe, but we know we cast to the original type.
|
|
||||||
array = cast(T[]) buf;
|
|
||||||
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Destroys the object.
|
|
||||||
* Returns the memory should be freed.
|
|
||||||
*/
|
|
||||||
package(tanya.memory) void[] finalize(T)(ref T* p)
|
|
||||||
{
|
|
||||||
if (p is null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
static if (hasElaborateDestructor!T)
|
|
||||||
{
|
|
||||||
destroy(*p);
|
|
||||||
}
|
|
||||||
return (cast(void*) p)[0 .. T.sizeof];
|
|
||||||
}
|
|
||||||
|
|
||||||
package(tanya.memory) void[] finalize(T)(ref T p)
|
|
||||||
if (isPolymorphicType!T)
|
|
||||||
{
|
|
||||||
if (p is null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
static if (is(T == interface))
|
|
||||||
{
|
|
||||||
version(Windows)
|
|
||||||
{
|
|
||||||
import core.sys.windows.unknwn : IUnknown;
|
|
||||||
static assert(!is(T : IUnknown), "COM interfaces can't be destroyed in "
|
|
||||||
~ __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
auto ob = cast(Object) p;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
alias ob = p;
|
|
||||||
}
|
|
||||||
auto ptr = cast(void*) ob;
|
|
||||||
auto support = ptr[0 .. typeid(ob).initializer.length];
|
|
||||||
|
|
||||||
auto ppv = cast(void**) ptr;
|
|
||||||
if (!*ppv)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
auto pc = cast(ClassInfo*) *ppv;
|
|
||||||
scope (exit)
|
|
||||||
{
|
|
||||||
*ppv = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto c = *pc;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// Assume the destructor is @nogc. Leave it nothrow since the destructor
|
|
||||||
// shouldn't throw and if it does, it is an error anyway.
|
|
||||||
if (c.destructor)
|
|
||||||
{
|
|
||||||
alias DtorType = void function(Object) pure nothrow @safe @nogc;
|
|
||||||
(cast(DtorType) c.destructor)(ob);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while ((c = c.base) !is null);
|
|
||||||
|
|
||||||
if (ppv[1]) // if monitor is not null
|
|
||||||
{
|
|
||||||
_d_monitordelete(cast(Object) ptr, true);
|
|
||||||
}
|
|
||||||
return support;
|
|
||||||
}
|
|
||||||
|
|
||||||
package(tanya.memory) void[] finalize(T)(ref T[] p)
|
|
||||||
{
|
|
||||||
destroyAllImpl!(T[], T)(p);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
package(tanya) void destroyAllImpl(R, E)(R p)
|
package(tanya) void destroyAllImpl(R, E)(R p)
|
||||||
{
|
{
|
||||||
static if (hasElaborateDestructor!E)
|
static if (hasElaborateDestructor!E)
|
||||||
@ -202,136 +29,6 @@ package(tanya) void destroyAllImpl(R, E)(R p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroys and deallocates $(D_PARAM p) of type $(D_PARAM T).
|
|
||||||
* It is assumed the respective entities had been allocated with the same
|
|
||||||
* allocator.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* T = Type of $(D_PARAM p).
|
|
||||||
* allocator = Allocator the $(D_PARAM p) was allocated with.
|
|
||||||
* p = Object or array to be destroyed.
|
|
||||||
*/
|
|
||||||
void dispose(T)(shared Allocator allocator, auto ref T p)
|
|
||||||
{
|
|
||||||
() @trusted { allocator.deallocate(finalize(p)); }();
|
|
||||||
p = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new class instance of type $(D_PARAM T) using $(D_PARAM args)
|
|
||||||
* as the parameter list for the constructor of $(D_PARAM T).
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* T = Class type.
|
|
||||||
* A = Types of the arguments to the constructor of $(D_PARAM T).
|
|
||||||
* allocator = Allocator.
|
|
||||||
* args = Constructor arguments of $(D_PARAM T).
|
|
||||||
*
|
|
||||||
* Returns: Newly created $(D_PSYMBOL T).
|
|
||||||
*
|
|
||||||
* Precondition: $(D_INLINECODE allocator !is null)
|
|
||||||
*/
|
|
||||||
T make(T, A...)(shared Allocator allocator, auto ref A args)
|
|
||||||
if (is(T == class))
|
|
||||||
in (allocator !is null)
|
|
||||||
{
|
|
||||||
auto mem = (() @trusted => allocator.allocate(stateSize!T))();
|
|
||||||
if (mem is null)
|
|
||||||
{
|
|
||||||
onOutOfMemoryError();
|
|
||||||
}
|
|
||||||
scope (failure)
|
|
||||||
{
|
|
||||||
() @trusted { allocator.deallocate(mem); }();
|
|
||||||
}
|
|
||||||
|
|
||||||
return emplace!T(mem[0 .. stateSize!T], args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a value object of type $(D_PARAM T) using $(D_PARAM args)
|
|
||||||
* as the parameter list for the constructor of $(D_PARAM T) and returns a
|
|
||||||
* pointer to the new object.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* T = Object type.
|
|
||||||
* A = Types of the arguments to the constructor of $(D_PARAM T).
|
|
||||||
* allocator = Allocator.
|
|
||||||
* args = Constructor arguments of $(D_PARAM T).
|
|
||||||
*
|
|
||||||
* Returns: Pointer to the created object.
|
|
||||||
*
|
|
||||||
* Precondition: $(D_INLINECODE allocator !is null)
|
|
||||||
*/
|
|
||||||
T* make(T, A...)(shared Allocator allocator, auto ref A args)
|
|
||||||
if (!isPolymorphicType!T && !isAssociativeArray!T && !isArray!T)
|
|
||||||
in (allocator !is null)
|
|
||||||
{
|
|
||||||
auto mem = (() @trusted => allocator.allocate(stateSize!T))();
|
|
||||||
if (mem is null)
|
|
||||||
{
|
|
||||||
onOutOfMemoryError();
|
|
||||||
}
|
|
||||||
scope (failure)
|
|
||||||
{
|
|
||||||
() @trusted { allocator.deallocate(mem); }();
|
|
||||||
}
|
|
||||||
return emplace!T(mem[0 .. stateSize!T], args);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
int* i = defaultAllocator.make!int(5);
|
|
||||||
assert(*i == 5);
|
|
||||||
defaultAllocator.dispose(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new array with $(D_PARAM n) elements.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* T = Array type.
|
|
||||||
* E = Array element type.
|
|
||||||
* allocator = Allocator.
|
|
||||||
* n = Array size.
|
|
||||||
*
|
|
||||||
* Returns: Newly created array.
|
|
||||||
*
|
|
||||||
* Precondition: $(D_INLINECODE allocator !is null
|
|
||||||
* && n <= size_t.max / E.sizeof)
|
|
||||||
*/
|
|
||||||
T make(T : E[], E)(shared Allocator allocator, size_t n)
|
|
||||||
in (allocator !is null)
|
|
||||||
in (n <= size_t.max / E.sizeof)
|
|
||||||
{
|
|
||||||
auto ret = allocator.resize!E(null, n);
|
|
||||||
|
|
||||||
static if (hasElaborateDestructor!E)
|
|
||||||
{
|
|
||||||
for (auto range = ret; range.length != 0; range = range[1 .. $])
|
|
||||||
{
|
|
||||||
emplace!E(cast(void[]) range[0 .. 1], E.init);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret[] = E.init;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
int[] i = defaultAllocator.make!(int[])(2);
|
|
||||||
assert(i.length == 2);
|
|
||||||
assert(i[0] == int.init && i[1] == int.init);
|
|
||||||
defaultAllocator.dispose(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new object of type $(D_PARAM T) in $(D_PARAM memory) with the
|
* Constructs a new object of type $(D_PARAM T) in $(D_PARAM memory) with the
|
||||||
* given arguments.
|
* given arguments.
|
||||||
@ -594,11 +291,7 @@ private void deinitialize(bool zero, T)(ref T value)
|
|||||||
* Precondition: `&source !is &target`.
|
* Precondition: `&source !is &target`.
|
||||||
*/
|
*/
|
||||||
void moveEmplace(T)(ref T source, ref T target) @system
|
void moveEmplace(T)(ref T source, ref T target) @system
|
||||||
in
|
in (&source !is &target, "Source and target must be different")
|
||||||
{
|
|
||||||
assert(&source !is &target, "Source and target must be different");
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
static if (is(T == struct) || isStaticArray!T)
|
static if (is(T == struct) || isStaticArray!T)
|
||||||
{
|
{
|
||||||
|
@ -52,13 +52,9 @@ private enum alignMask = size_t.sizeof - 1;
|
|||||||
* Precondition: $(D_INLINECODE source.length <= target.length).
|
* Precondition: $(D_INLINECODE source.length <= target.length).
|
||||||
*/
|
*/
|
||||||
void copy(const void[] source, void[] target) @nogc nothrow pure @trusted
|
void copy(const void[] source, void[] target) @nogc nothrow pure @trusted
|
||||||
in
|
in (source.length <= target.length)
|
||||||
{
|
in (source.length == 0 || source.ptr !is null)
|
||||||
assert(source.length <= target.length);
|
in (target.length == 0 || target.ptr !is null)
|
||||||
assert(source.length == 0 || source.ptr !is null);
|
|
||||||
assert(target.length == 0 || target.ptr !is null);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
version (TanyaNative)
|
version (TanyaNative)
|
||||||
{
|
{
|
||||||
@ -102,11 +98,7 @@ private template filledBytes(ubyte Byte, ubyte I = 0)
|
|||||||
* memory = Memory block.
|
* memory = Memory block.
|
||||||
*/
|
*/
|
||||||
void fill(ubyte c = 0)(void[] memory) @trusted
|
void fill(ubyte c = 0)(void[] memory) @trusted
|
||||||
in
|
in (memory.length == 0 || memory.ptr !is null)
|
||||||
{
|
|
||||||
assert(memory.length == 0 || memory.ptr !is null);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
version (TanyaNative)
|
version (TanyaNative)
|
||||||
{
|
{
|
||||||
@ -152,13 +144,9 @@ do
|
|||||||
* Precondition: $(D_INLINECODE source.length <= target.length).
|
* Precondition: $(D_INLINECODE source.length <= target.length).
|
||||||
*/
|
*/
|
||||||
void copyBackward(const void[] source, void[] target) @nogc nothrow pure @trusted
|
void copyBackward(const void[] source, void[] target) @nogc nothrow pure @trusted
|
||||||
in
|
in (source.length <= target.length)
|
||||||
{
|
in (source.length == 0 || source.ptr !is null)
|
||||||
assert(source.length <= target.length);
|
in (target.length == 0 || target.ptr !is null)
|
||||||
assert(source.length == 0 || source.ptr !is null);
|
|
||||||
assert(target.length == 0 || target.ptr !is null);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
version (TanyaNative)
|
version (TanyaNative)
|
||||||
{
|
{
|
||||||
@ -194,11 +182,7 @@ do
|
|||||||
*/
|
*/
|
||||||
inout(void[]) find(return inout void[] haystack, ubyte needle)
|
inout(void[]) find(return inout void[] haystack, ubyte needle)
|
||||||
@nogc nothrow pure @trusted
|
@nogc nothrow pure @trusted
|
||||||
in
|
in (haystack.length == 0 || haystack.ptr !is null)
|
||||||
{
|
|
||||||
assert(haystack.length == 0 || haystack.ptr !is null);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
auto length = haystack.length;
|
auto length = haystack.length;
|
||||||
const size_t needleWord = size_t.max * needle;
|
const size_t needleWord = size_t.max * needle;
|
||||||
@ -276,11 +260,7 @@ do
|
|||||||
*/
|
*/
|
||||||
inout(char[]) findNullTerminated(return inout char[] haystack)
|
inout(char[]) findNullTerminated(return inout char[] haystack)
|
||||||
@nogc nothrow pure @trusted
|
@nogc nothrow pure @trusted
|
||||||
in
|
in (haystack.length == 0 || haystack.ptr !is null)
|
||||||
{
|
|
||||||
assert(haystack.length == 0 || haystack.ptr !is null);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
auto length = haystack.length;
|
auto length = haystack.length;
|
||||||
enum size_t highBits = filledBytes!(0x01, 0);
|
enum size_t highBits = filledBytes!(0x01, 0);
|
||||||
@ -347,12 +327,8 @@ do
|
|||||||
* $(D_KEYWORD false) otherwise.
|
* $(D_KEYWORD false) otherwise.
|
||||||
*/
|
*/
|
||||||
bool equal(const void[] r1, const void[] r2) @nogc nothrow pure @trusted
|
bool equal(const void[] r1, const void[] r2) @nogc nothrow pure @trusted
|
||||||
in
|
in (r1.length == 0 || r1.ptr !is null)
|
||||||
{
|
in (r2.length == 0 || r2.ptr !is null)
|
||||||
assert(r1.length == 0 || r1.ptr !is null);
|
|
||||||
assert(r2.length == 0 || r2.ptr !is null);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
version (TanyaNative)
|
version (TanyaNative)
|
||||||
{
|
{
|
||||||
|
@ -16,117 +16,5 @@ module tanya.memory;
|
|||||||
|
|
||||||
public import tanya.memory.allocator;
|
public import tanya.memory.allocator;
|
||||||
public import tanya.memory.lifetime;
|
public import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
|
||||||
deprecated("Use tanya.meta.trait.stateSize instead")
|
deprecated("Use tanya.meta.trait.stateSize instead")
|
||||||
public import tanya.meta.trait : stateSize;
|
public import tanya.meta.trait : stateSize;
|
||||||
|
|
||||||
/**
|
|
||||||
* The mixin generates common methods for classes and structs using
|
|
||||||
* allocators. It provides a protected member, constructor and a read-only property,
|
|
||||||
* that checks if an allocator was already set and sets it to the default
|
|
||||||
* one, if not (useful for structs which don't have a default constructor).
|
|
||||||
*/
|
|
||||||
mixin template DefaultAllocator()
|
|
||||||
{
|
|
||||||
/// Allocator.
|
|
||||||
protected shared Allocator allocator_;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Params:
|
|
||||||
* allocator = The allocator should be used.
|
|
||||||
*
|
|
||||||
* Precondition: $(D_INLINECODE allocator_ !is null)
|
|
||||||
*/
|
|
||||||
this(shared Allocator allocator) @nogc nothrow pure @safe
|
|
||||||
in (allocator !is null)
|
|
||||||
{
|
|
||||||
this.allocator_ = allocator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This property checks if the allocator was set in the constructor
|
|
||||||
* and sets it to the default one, if not.
|
|
||||||
*
|
|
||||||
* Returns: Used allocator.
|
|
||||||
*
|
|
||||||
* Postcondition: $(D_INLINECODE allocator !is null)
|
|
||||||
*/
|
|
||||||
@property shared(Allocator) allocator() @nogc nothrow pure @safe
|
|
||||||
out (allocator; allocator !is null)
|
|
||||||
{
|
|
||||||
if (allocator_ is null)
|
|
||||||
{
|
|
||||||
allocator_ = defaultAllocator;
|
|
||||||
}
|
|
||||||
return allocator_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ditto
|
|
||||||
@property shared(Allocator) allocator() const @nogc nothrow pure @trusted
|
|
||||||
out (allocator; allocator !is null)
|
|
||||||
{
|
|
||||||
if (allocator_ is null)
|
|
||||||
{
|
|
||||||
return defaultAllocator;
|
|
||||||
}
|
|
||||||
return cast(shared Allocator) allocator_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shared Allocator allocator;
|
|
||||||
|
|
||||||
private shared(Allocator) getAllocatorInstance() @nogc nothrow
|
|
||||||
{
|
|
||||||
if (allocator is null)
|
|
||||||
{
|
|
||||||
version (TanyaNative)
|
|
||||||
{
|
|
||||||
import tanya.memory.mmappool;
|
|
||||||
defaultAllocator = MmapPool.instance;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
import tanya.memory.mallocator;
|
|
||||||
defaultAllocator = Mallocator.instance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return allocator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns: Default allocator.
|
|
||||||
*
|
|
||||||
* Postcondition: $(D_INLINECODE allocator !is null).
|
|
||||||
*/
|
|
||||||
@property shared(Allocator) defaultAllocator() @nogc nothrow pure @trusted
|
|
||||||
out (allocator; allocator !is null)
|
|
||||||
{
|
|
||||||
return (cast(GetPureInstance!Allocator) &getAllocatorInstance)();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the default allocator.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* allocator = $(D_PSYMBOL Allocator) instance.
|
|
||||||
*
|
|
||||||
* Precondition: $(D_INLINECODE allocator !is null).
|
|
||||||
*/
|
|
||||||
@property void defaultAllocator(shared(Allocator) allocator) @nogc nothrow @safe
|
|
||||||
in (allocator !is null)
|
|
||||||
{
|
|
||||||
.allocator = allocator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Params:
|
|
||||||
* size = Raw size.
|
|
||||||
* alignment = Alignment.
|
|
||||||
*
|
|
||||||
* Returns: Aligned size.
|
|
||||||
*/
|
|
||||||
size_t alignedSize(const size_t size, const size_t alignment = 8)
|
|
||||||
pure nothrow @safe @nogc
|
|
||||||
{
|
|
||||||
return (size - 1) / alignment * alignment + alignment;
|
|
||||||
}
|
|
||||||
|
@ -23,7 +23,8 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.memory.smartref;
|
module tanya.memory.smartref;
|
||||||
|
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
|
|
||||||
private template Payload(T)
|
private template Payload(T)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
/**
|
/**
|
||||||
* Event loop implementation for Linux.
|
* Event loop implementation for Linux.
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2016-2018.
|
* Copyright: Eugene Wissner 2016-2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
@ -30,7 +30,7 @@ import tanya.async.protocol;
|
|||||||
import tanya.async.transport;
|
import tanya.async.transport;
|
||||||
import tanya.async.watcher;
|
import tanya.async.watcher;
|
||||||
import tanya.container.array;
|
import tanya.container.array;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
import tanya.network.socket;
|
import tanya.network.socket;
|
||||||
|
|
||||||
extern (C) nothrow @nogc
|
extern (C) nothrow @nogc
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
/**
|
/**
|
||||||
* Event loop implementation for Windows.
|
* Event loop implementation for Windows.
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2016-2018.
|
* Copyright: Eugene Wissner 2016-2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
@ -26,7 +26,7 @@ import tanya.async.protocol;
|
|||||||
import tanya.async.transport;
|
import tanya.async.transport;
|
||||||
import tanya.async.watcher;
|
import tanya.async.watcher;
|
||||||
import tanya.container.buffer;
|
import tanya.container.buffer;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
import tanya.network.socket;
|
import tanya.network.socket;
|
||||||
import tanya.sys.windows.winbase;
|
import tanya.sys.windows.winbase;
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
/*
|
/*
|
||||||
* Event loop implementation for *BSD.
|
* Event loop implementation for *BSD.
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2016-2018.
|
* Copyright: Eugene Wissner 2016-2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
@ -58,7 +58,7 @@ import tanya.async.loop;
|
|||||||
import tanya.async.transport;
|
import tanya.async.transport;
|
||||||
import tanya.async.watcher;
|
import tanya.async.watcher;
|
||||||
import tanya.container.array;
|
import tanya.container.array;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
import tanya.network.socket;
|
import tanya.network.socket;
|
||||||
|
|
||||||
void EV_SET(kevent_t* kevp, typeof(kevent_t.tupleof) args) pure nothrow @nogc
|
void EV_SET(kevent_t* kevp, typeof(kevent_t.tupleof) args) pure nothrow @nogc
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
/*
|
/*
|
||||||
* This module contains base implementations for reactor event loops.
|
* This module contains base implementations for reactor event loops.
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2016-2018.
|
* Copyright: Eugene Wissner 2016-2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
@ -25,7 +25,7 @@ import tanya.async.transport;
|
|||||||
import tanya.async.watcher;
|
import tanya.async.watcher;
|
||||||
import tanya.container.array;
|
import tanya.container.array;
|
||||||
import tanya.container.buffer;
|
import tanya.container.buffer;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
import tanya.network.socket;
|
import tanya.network.socket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* Note: Available only on Windows.
|
* Note: Available only on Windows.
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2016-2018.
|
* Copyright: Eugene Wissner 2016-2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
* }
|
* }
|
||||||
* ---
|
* ---
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2016-2018.
|
* Copyright: Eugene Wissner 2016-2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
@ -77,7 +77,7 @@ import tanya.async.watcher;
|
|||||||
import tanya.bitmanip;
|
import tanya.bitmanip;
|
||||||
import tanya.container.buffer;
|
import tanya.container.buffer;
|
||||||
import tanya.container.list;
|
import tanya.container.list;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
import tanya.network.socket;
|
import tanya.network.socket;
|
||||||
|
|
||||||
version (DisableBackends)
|
version (DisableBackends)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
/**
|
/**
|
||||||
* This package provides asynchronous capabilities.
|
* This package provides asynchronous capabilities.
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2016-2018.
|
* Copyright: Eugene Wissner 2016-2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* When an event from the network arrives, a protocol method gets
|
* When an event from the network arrives, a protocol method gets
|
||||||
* called and can respond to the event.
|
* called and can respond to the event.
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2016-2018.
|
* Copyright: Eugene Wissner 2016-2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* This module contains transports which are responsible for data dilvery
|
* This module contains transports which are responsible for data dilvery
|
||||||
* between two parties of an asynchronous communication.
|
* between two parties of an asynchronous communication.
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2016-2018.
|
* Copyright: Eugene Wissner 2016-2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
/**
|
/**
|
||||||
* Watchers register user's interest in some event.
|
* Watchers register user's interest in some event.
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2016-2018.
|
* Copyright: Eugene Wissner 2016-2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
@ -19,7 +19,7 @@ import tanya.async.protocol;
|
|||||||
import tanya.async.transport;
|
import tanya.async.transport;
|
||||||
import tanya.container.buffer;
|
import tanya.container.buffer;
|
||||||
import tanya.container.list;
|
import tanya.container.list;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
import tanya.network.socket;
|
import tanya.network.socket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,7 +17,8 @@ module tanya.container.array;
|
|||||||
import core.checkedint;
|
import core.checkedint;
|
||||||
import tanya.algorithm.comparison;
|
import tanya.algorithm.comparison;
|
||||||
import tanya.algorithm.mutation;
|
import tanya.algorithm.mutation;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
import tanya.meta.transform;
|
import tanya.meta.transform;
|
||||||
import tanya.range;
|
import tanya.range;
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.container.buffer;
|
module tanya.container.buffer;
|
||||||
|
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
|
|
||||||
version (unittest)
|
version (unittest)
|
||||||
|
@ -18,7 +18,8 @@ import tanya.algorithm.mutation;
|
|||||||
import tanya.container.array;
|
import tanya.container.array;
|
||||||
import tanya.container.entry;
|
import tanya.container.entry;
|
||||||
import tanya.hash.lookup;
|
import tanya.hash.lookup;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
import tanya.meta.transform;
|
import tanya.meta.transform;
|
||||||
import tanya.range.primitive;
|
import tanya.range.primitive;
|
||||||
|
@ -17,7 +17,8 @@ module tanya.container.list;
|
|||||||
|
|
||||||
import tanya.algorithm.comparison;
|
import tanya.algorithm.comparison;
|
||||||
import tanya.container.entry;
|
import tanya.container.entry;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
import tanya.meta.transform;
|
import tanya.meta.transform;
|
||||||
import tanya.range.array;
|
import tanya.range.array;
|
||||||
|
@ -18,7 +18,8 @@ module tanya.container.set;
|
|||||||
import tanya.container.array;
|
import tanya.container.array;
|
||||||
import tanya.container.entry;
|
import tanya.container.entry;
|
||||||
import tanya.hash.lookup;
|
import tanya.hash.lookup;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
import tanya.meta.transform;
|
import tanya.meta.transform;
|
||||||
import tanya.range.primitive;
|
import tanya.range.primitive;
|
||||||
|
@ -29,7 +29,8 @@ module tanya.container.string;
|
|||||||
import tanya.algorithm.comparison;
|
import tanya.algorithm.comparison;
|
||||||
import tanya.algorithm.mutation;
|
import tanya.algorithm.mutation;
|
||||||
import tanya.hash.lookup;
|
import tanya.hash.lookup;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
import tanya.meta.transform;
|
import tanya.meta.transform;
|
||||||
import tanya.range.array;
|
import tanya.range.array;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
module tanya.conv;
|
module tanya.conv;
|
||||||
|
|
||||||
import tanya.container.string;
|
import tanya.container.string;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
deprecated("Use tanya.memory.lifetime.emplace instead")
|
deprecated("Use tanya.memory.lifetime.emplace instead")
|
||||||
public import tanya.memory.lifetime : emplace;
|
public import tanya.memory.lifetime : emplace;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
@ -64,12 +64,8 @@ if (isInputRange!R
|
|||||||
&& isSomeChar!(ElementType!R)
|
&& isSomeChar!(ElementType!R)
|
||||||
&& isIntegral!T
|
&& isIntegral!T
|
||||||
&& isUnsigned!T)
|
&& isUnsigned!T)
|
||||||
in
|
in (base >= 2)
|
||||||
{
|
in (base <= 36)
|
||||||
assert(base >= 2);
|
|
||||||
assert(base <= 36);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
T boundary = cast(T) (T.max / base);
|
T boundary = cast(T) (T.max / base);
|
||||||
if (range.empty)
|
if (range.empty)
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/exception.d,
|
* Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/exception.d,
|
||||||
* tanya/exception.d)
|
* tanya/exception.d)
|
||||||
*/
|
*/
|
||||||
deprecated("Use tanya.memory.lifetimeinstead")
|
deprecated("Use tanya.memory.allocator instead")
|
||||||
module tanya.exception;
|
module tanya.exception;
|
||||||
|
|
||||||
public import tanya.memory.lifetime : onOutOfMemoryError, OutOfMemoryError;
|
public import tanya.memory.allocator : onOutOfMemoryError, OutOfMemoryError;
|
||||||
|
@ -1175,11 +1175,7 @@ private struct uint128
|
|||||||
}
|
}
|
||||||
|
|
||||||
Tuple!(uint128, uint128) divMod(ulong rhs) const @nogc nothrow pure @safe
|
Tuple!(uint128, uint128) divMod(ulong rhs) const @nogc nothrow pure @safe
|
||||||
in
|
in (rhs != uint128(), "Division by 0")
|
||||||
{
|
|
||||||
assert(rhs != uint128(), "Division by 0");
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
if (rhs == 1)
|
if (rhs == 1)
|
||||||
{
|
{
|
||||||
@ -1279,11 +1275,7 @@ private int indexMismatch(ulong low, ulong high) @nogc nothrow pure @safe
|
|||||||
private char[] errol2(double value,
|
private char[] errol2(double value,
|
||||||
return ref char[512] buffer,
|
return ref char[512] buffer,
|
||||||
out int exponent) @nogc nothrow pure @safe
|
out int exponent) @nogc nothrow pure @safe
|
||||||
in
|
in (value > 9.007199254740992e15 && value < 3.40282366920938e38)
|
||||||
{
|
|
||||||
assert(value > 9.007199254740992e15 && value < 3.40282366920938e38);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
auto v = uint128(value);
|
auto v = uint128(value);
|
||||||
auto leftBoundary = v + raise2ToExp((value - previous(value)) / 2.0);
|
auto leftBoundary = v + raise2ToExp((value - previous(value)) / 2.0);
|
||||||
@ -1368,11 +1360,7 @@ do
|
|||||||
private char[] errolFixed(double value,
|
private char[] errolFixed(double value,
|
||||||
return ref char[512] buffer,
|
return ref char[512] buffer,
|
||||||
out int exponent) @nogc nothrow pure @safe
|
out int exponent) @nogc nothrow pure @safe
|
||||||
in
|
in (value >= 16.0 && value <= 9.007199254740992e15)
|
||||||
{
|
|
||||||
assert(value >= 16.0 && value <= 9.007199254740992e15);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
auto decimal = cast(ulong) value;
|
auto decimal = cast(ulong) value;
|
||||||
auto n = cast(double) decimal;
|
auto n = cast(double) decimal;
|
||||||
|
@ -19,7 +19,8 @@ import tanya.algorithm.iteration;
|
|||||||
import tanya.algorithm.mutation;
|
import tanya.algorithm.mutation;
|
||||||
import tanya.container.array;
|
import tanya.container.array;
|
||||||
import tanya.encoding.ascii;
|
import tanya.encoding.ascii;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
import tanya.meta.transform;
|
import tanya.meta.transform;
|
||||||
import tanya.range;
|
import tanya.range;
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.math.random;
|
module tanya.math.random;
|
||||||
|
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
import tanya.typecons;
|
import tanya.typecons;
|
||||||
|
|
||||||
/// Maximum amount gathered from the entropy sources.
|
/// Maximum amount gathered from the entropy sources.
|
||||||
|
@ -16,7 +16,7 @@ module tanya.net.uri;
|
|||||||
|
|
||||||
import tanya.conv;
|
import tanya.conv;
|
||||||
import tanya.encoding.ascii;
|
import tanya.encoding.ascii;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown if an invalid URI was specified.
|
* Thrown if an invalid URI was specified.
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
/**
|
/**
|
||||||
* Network programming.
|
* Network programming.
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2016-2018.
|
* Copyright: Eugene Wissner 2016-2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
* For an example of an asynchronous server refer to the documentation of the
|
* For an example of an asynchronous server refer to the documentation of the
|
||||||
* $(D_PSYMBOL tanya.async.loop) module.
|
* $(D_PSYMBOL tanya.async.loop) module.
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2016-2018.
|
* Copyright: Eugene Wissner 2016-2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
@ -55,7 +55,7 @@ import core.time;
|
|||||||
public import std.socket : SocketOption, SocketOptionLevel;
|
public import std.socket : SocketOption, SocketOptionLevel;
|
||||||
import tanya.algorithm.comparison;
|
import tanya.algorithm.comparison;
|
||||||
import tanya.bitmanip;
|
import tanya.bitmanip;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
import tanya.os.error;
|
import tanya.os.error;
|
||||||
|
|
||||||
|
@ -296,11 +296,7 @@ struct Option(T)
|
|||||||
/// ditto
|
/// ditto
|
||||||
bool opEquals(U)(auto ref const U that) const
|
bool opEquals(U)(auto ref const U that) const
|
||||||
if (ifTestable!(U, a => a == T.init) && !is(U == Option))
|
if (ifTestable!(U, a => a == T.init) && !is(U == Option))
|
||||||
in
|
in (!isNothing)
|
||||||
{
|
|
||||||
assert(!isNothing);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
return get == that;
|
return get == that;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* The functions can cause segmentation fault if the module is compiled
|
* The functions can cause segmentation fault if the module is compiled
|
||||||
* in production mode and the condition fails.
|
* in production mode and the condition fails.
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2017-2018.
|
* Copyright: Eugene Wissner 2017-2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
@ -22,7 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.test.assertion;
|
module tanya.test.assertion;
|
||||||
|
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
/**
|
/**
|
||||||
* Test suite for $(D_KEYWORD unittest)-blocks.
|
* Test suite for $(D_KEYWORD unittest)-blocks.
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2017-2018.
|
* Copyright: Eugene Wissner 2017-2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
/**
|
/**
|
||||||
* Range and generic type generators.
|
* Range and generic type generators.
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2018.
|
* Copyright: Eugene Wissner 2018-2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
|
@ -6,7 +6,7 @@ module tanya.async.tests.loop;
|
|||||||
import core.time;
|
import core.time;
|
||||||
import tanya.async.loop;
|
import tanya.async.loop;
|
||||||
import tanya.async.watcher;
|
import tanya.async.watcher;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
|
|
||||||
private final class DummyWatcher : Watcher
|
private final class DummyWatcher : Watcher
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,7 @@ module tanya.container.tests.array;
|
|||||||
|
|
||||||
import tanya.algorithm.comparison;
|
import tanya.algorithm.comparison;
|
||||||
import tanya.container.array;
|
import tanya.container.array;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
import tanya.test.stub;
|
import tanya.test.stub;
|
||||||
|
|
||||||
// const arrays return usable ranges
|
// const arrays return usable ranges
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
module tanya.container.tests.set;
|
module tanya.container.tests.set;
|
||||||
|
|
||||||
import tanya.container.set;
|
import tanya.container.set;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
import tanya.test.stub;
|
import tanya.test.stub;
|
||||||
|
|
||||||
// Basic insertion logic.
|
// Basic insertion logic.
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
module tanya.math.tests.random;
|
module tanya.math.tests.random;
|
||||||
|
|
||||||
import tanya.math.random;
|
import tanya.math.random;
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
|
|
||||||
static if (is(PlatformEntropySource)) @nogc @system unittest
|
static if (is(PlatformEntropySource)) @nogc @system unittest
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
module tanya.memory.tests.lifetime;
|
module tanya.memory.tests.lifetime;
|
||||||
|
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
|
import tanya.memory.lifetime;
|
||||||
import tanya.test.stub;
|
import tanya.test.stub;
|
||||||
|
|
||||||
@nogc nothrow pure @safe unittest
|
@nogc nothrow pure @safe unittest
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
module tanya.memory.tests.smartref;
|
module tanya.memory.tests.smartref;
|
||||||
|
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
import tanya.memory.smartref;
|
import tanya.memory.smartref;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
import tanya.test.stub;
|
import tanya.test.stub;
|
||||||
|
@ -175,7 +175,7 @@ import tanya.range;
|
|||||||
// Aggregate types
|
// Aggregate types
|
||||||
@system unittest // Object.toString has no attributes.
|
@system unittest // Object.toString has no attributes.
|
||||||
{
|
{
|
||||||
import tanya.memory;
|
import tanya.memory.allocator;
|
||||||
import tanya.memory.smartref;
|
import tanya.memory.smartref;
|
||||||
|
|
||||||
interface I
|
interface I
|
||||||
|
Loading…
Reference in New Issue
Block a user