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); 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 Convenience function that uses type deduction to return the appropriate
$(D FallbackAllocator) instance. To initialize with allocators that don't have $(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)
fallbackAllocator(Primary, Fallback)(auto ref Primary p, auto ref Fallback f) 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!Primary)
static if (stateSize!Fallback) static if (stateSize!Fallback)
return typeof(return)(p, f); return R(forward!p, forward!f);
else else
return typeof(return)(p); return R(forward!p);
else else
static if (stateSize!Fallback) static if (stateSize!Fallback)
return typeof(return)(f); return R(forward!f);
else 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 of the book $(WEB amazon.com/exec/obidos/ASIN/0131103628/classicempire, "The C
Programming Language"), Second Edition, Prentice Hall, 1988. 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 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. 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 $(D KRBlock) has a small control structure and no per-allocation overhead. Its
@ -75,7 +78,6 @@ copyable.
*/ */
struct KRBlock(ParentAllocator = NullAllocator) struct KRBlock(ParentAllocator = NullAllocator)
{ {
import std.format : format;
import std.experimental.allocator.common : stateSize, alignedAt; import std.experimental.allocator.common : stateSize, alignedAt;
private static struct Node private static struct Node
@ -148,6 +150,7 @@ struct KRBlock(ParentAllocator = NullAllocator)
string toString() string toString()
{ {
import std.format : format;
string s = "KRBlock@"; string s = "KRBlock@";
s ~= format("%s-%s(0x%s[%s]", &this, &this + 1, s ~= format("%s-%s(0x%s[%s]", &this, &this + 1,
payload.ptr, payload.length); payload.ptr, payload.length);
@ -234,7 +237,6 @@ struct KRBlock(ParentAllocator = NullAllocator)
/* /*
Noncopyable Noncopyable
*/ */
static if (!is(ParentAllocator == NullAllocator))
@disable this(this); @disable this(this);
/** /**
@ -290,11 +292,11 @@ struct KRBlock(ParentAllocator = NullAllocator)
{ {
debug(KRBlock) writefln("KRBlock@%s: deallocate(%s[%s])", &this, debug(KRBlock) writefln("KRBlock@%s: deallocate(%s[%s])", &this,
b.ptr, b.length); 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; if (!b.ptr) return;
assert(owns(b)); assert(owns(b));
assert(b.ptr.alignedAt(Node.alignof)); 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; auto n = cast(Node*) b.ptr;
n.size = goodAllocSize(b.length); n.size = goodAllocSize(b.length);
// Linear search // Linear search