Make KRBlock uncopyable

This commit is contained in:
Andrei Alexandrescu 2015-05-31 16:13:42 -07:00
parent 57e163001c
commit faecd0a95f
2 changed files with 58 additions and 8 deletions

View file

@ -305,6 +305,51 @@ unittest
a.deallocate(b2);
}
/*
Forwards an argument from one function to another
*/
private auto ref forward(alias arg)()
{
static if (__traits(isRef, arg))
{
return arg;
}
else
{
import std.algorithm : move;
return move(arg);
}
}
unittest
{
void fun(T)(auto ref T a, string b) { /* ... */ }
void gun(T...)(auto ref T args)
{
fun(forward!(args[0]), forward!(args[1]));
}
gun(42, "hello");
int x;
gun(x, "hello");
}
unittest
{
static void checkByRef(T)(auto ref T value)
{
static assert(__traits(isRef, value));
}
static void checkByVal(T)(auto ref T value)
{
static assert(!__traits(isRef, value));
}
static void test1(ref int a) { checkByRef(forward!a); }
static void test2(int a) { checkByVal(forward!a); }
static void test3() { int a; checkByVal(forward!a); }
}
/**
Convenience function that uses type deduction to return the appropriate
$(D FallbackAllocator) instance. To initialize with allocators that don't have
@ -313,16 +358,19 @@ state, use their $(D it) static member.
FallbackAllocator!(Primary, Fallback)
fallbackAllocator(Primary, Fallback)(auto ref Primary p, auto ref Fallback f)
{
alias R = FallbackAllocator!(Primary, Fallback);
import std.algorithm : move;
static if (stateSize!Primary)
static if (stateSize!Fallback)
return typeof(return)(p, f);
return R(forward!p, forward!f);
else
return typeof(return)(p);
return R(forward!p);
else
static if (stateSize!Fallback)
return typeof(return)(f);
return R(forward!f);
else
return typeof(return)();
return R();
}
///

View file

@ -13,6 +13,9 @@ famed allocator) described by Brian Kernighan and Dennis Ritchie in section 8.7
of the book $(WEB amazon.com/exec/obidos/ASIN/0131103628/classicempire, "The C
Programming Language"), Second Edition, Prentice Hall, 1988.
The recommended usage for $(D KRBlock) is as a simple means to add
$(D deallocate) to a region.
A $(D KRBlock) manages a single contiguous chunk of memory by embedding a free
blocks list onto it. It is a very simple allocator with good memory utilization.
$(D KRBlock) has a small control structure and no per-allocation overhead. Its
@ -75,7 +78,6 @@ copyable.
*/
struct KRBlock(ParentAllocator = NullAllocator)
{
import std.format : format;
import std.experimental.allocator.common : stateSize, alignedAt;
private static struct Node
@ -148,6 +150,7 @@ struct KRBlock(ParentAllocator = NullAllocator)
string toString()
{
import std.format : format;
string s = "KRBlock@";
s ~= format("%s-%s(0x%s[%s]", &this, &this + 1,
payload.ptr, payload.length);
@ -234,7 +237,6 @@ struct KRBlock(ParentAllocator = NullAllocator)
/*
Noncopyable
*/
static if (!is(ParentAllocator == NullAllocator))
@disable this(this);
/**
@ -290,11 +292,11 @@ struct KRBlock(ParentAllocator = NullAllocator)
{
debug(KRBlock) writefln("KRBlock@%s: deallocate(%s[%s])", &this,
b.ptr, b.length);
// Insert back in the freelist, keeping it sorted by address. Do not
// coalesce at this time. Instead, do it lazily during allocation.
if (!b.ptr) return;
assert(owns(b));
assert(b.ptr.alignedAt(Node.alignof));
// Insert back in the freelist, keeping it sorted by address. Do not
// coalesce at this time. Instead, do it lazily during allocation.
auto n = cast(Node*) b.ptr;
n.size = goodAllocSize(b.length);
// Linear search