Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
Merge pull request #668 from yebblies/fixaarray
Browse files Browse the repository at this point in the history
Replace AssociativeArray struct with UFCS methods
  • Loading branch information
AndrejMitrovic committed Feb 9, 2014
2 parents bd54641 + 99407f4 commit 14fa404
Show file tree
Hide file tree
Showing 2 changed files with 194 additions and 181 deletions.
187 changes: 97 additions & 90 deletions src/object.di
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ class TypeInfo_AssociativeArray : TypeInfo
{
TypeInfo value;
TypeInfo key;
TypeInfo impl;
}

class TypeInfo_Vector : TypeInfo
Expand Down Expand Up @@ -354,18 +353,18 @@ extern (C)
{
// from druntime/src/rt/aaA.d

size_t _aaLen(in void* p) pure nothrow;
void* _aaGetX(void** pp, const TypeInfo keyti, in size_t valuesize, in void* pkey);
inout(void)* _aaGetRvalueX(inout void* p, in TypeInfo keyti, in size_t valuesize, in void* pkey);
// size_t _aaLen(in void* p) pure nothrow;
// void* _aaGetX(void** pp, const TypeInfo keyti, in size_t valuesize, in void* pkey);
// inout(void)* _aaGetRvalueX(inout void* p, in TypeInfo keyti, in size_t valuesize, in void* pkey);
inout(void)[] _aaValues(inout void* p, in size_t keysize, in size_t valuesize) pure nothrow;
inout(void)[] _aaKeys(inout void* p, in size_t keysize) pure nothrow;
void* _aaRehash(void** pp, in TypeInfo keyti) pure nothrow;

extern (D) alias scope int delegate(void *) _dg_t;
int _aaApply(void* aa, size_t keysize, _dg_t dg);
// extern (D) alias scope int delegate(void *) _dg_t;
// int _aaApply(void* aa, size_t keysize, _dg_t dg);

extern (D) alias scope int delegate(void *, void *) _dg2_t;
int _aaApply2(void* aa, size_t keysize, _dg2_t dg);
// extern (D) alias scope int delegate(void *, void *) _dg2_t;
// int _aaApply2(void* aa, size_t keysize, _dg2_t dg);

private struct AARange { void* impl, current; }
AARange _aaRange(void* aa);
Expand All @@ -375,112 +374,120 @@ extern (C)
void _aaRangePopFront(ref AARange r);
}

struct AssociativeArray(Key, Value)
alias AssociativeArray(Key, Value) = Value[Key];

Value[Key] rehash(T : Value[Key], Value, Key)(auto ref T aa)
{
private:
void* p;
_aaRehash(cast(void**)&aa, typeid(Value[Key]));
return aa;
}

public:
@property size_t length() const { return _aaLen(p); }
Value[Key] rehash(T : Value[Key], Value, Key)(T* aa)
{
__aaRehash(cast(void**)aa, typeid(Value[Key]));
return aa;
}

Value[Key] rehash()
Value[Key] dup(T : Value[Key], Value, Key)(T aa) if (is(typeof({
ref Value get(); // pseudo lvalue of Value
Value[Key] r; r[Key.init] = get();
// bug 10720 - check whether Value is copyable
})))
{
Value[Key] result;
foreach (k, v; aa)
{
auto p = _aaRehash(cast(void**) &p, typeid(Value[Key]));
return *cast(Value[Key]*)(&p);
result[k] = v;
}
return result;
}

// Note: can't make `values` and `keys` inout as it is used
// e.g. in Phobos like `ReturnType!(aa.keys)` instead of `typeof(aa.keys)`
// which will result in `inout` propagation.
Value[Key] dup(T : Value[Key], Value, Key)(T* aa) if (is(typeof((*aa).dup)))
{
return (*aa).dup;
}

inout(Value)[] inout_values() inout @property
{
auto a = _aaValues(p, Key.sizeof, Value.sizeof);
return *cast(inout Value[]*) &a;
}
@disable Value[Key] dup(T : Value[Key], Value, Key)(T aa) if (!is(typeof({
ref Value get(); // pseudo lvalue of Value
Value[Key] r; r[Key.init] = get();
// bug 10720 - check whether Value is copyable
})));

inout(Key)[] inout_keys() inout @property
{
auto a = _aaKeys(p, Key.sizeof);
return *cast(inout Key[]*) &a;
}
Value[Key] dup(T : Value[Key], Value, Key)(T* aa) if (!is(typeof((*aa).dup)));

Value[] values() @property
{ return inout_values; }
auto byKey(T : Value[Key], Value, Key)(T aa)
{
static struct Result
{
AARange r;

Key[] keys() @property
{ return inout_keys; }
@property bool empty() { return _aaRangeEmpty(r); }
@property ref Key front() { return *cast(Key*)_aaRangeFrontKey(r); }
void popFront() { _aaRangePopFront(r); }
Result save() { return this; }
}

const(Value)[] values() const @property
{ return inout_values; }
return Result(_aaRange(cast(void*)aa));
}

const(Key)[] keys() const @property
{ return inout_keys; }
auto byKey(T : Value[Key], Value, Key)(T *aa)
{
return (*aa).byKey();
}

int opApply(scope int delegate(ref Key, ref Value) dg)
auto byValue(T : Value[Key], Value, Key)(T aa)
{
static struct Result
{
return _aaApply2(p, Key.sizeof, cast(_dg2_t)dg);
}
AARange r;

int opApply(scope int delegate(ref Value) dg)
{
return _aaApply(p, Key.sizeof, cast(_dg_t)dg);
@property bool empty() { return _aaRangeEmpty(r); }
@property ref Value front() { return *cast(Value*)_aaRangeFrontValue(r); }
void popFront() { _aaRangePopFront(r); }
Result save() { return this; }
}

Value get(Key key, lazy Value defaultValue)
{
auto p = key in *cast(Value[Key]*)(&p);
return p ? *p : defaultValue;
}
return Result(_aaRange(cast(void*)aa));
}

static if (is(typeof({
ref Value get(); // pseudo lvalue of Value
Value[Key] r; r[Key.init] = get();
// bug 10720 - check whether Value is copyable
})))
{
Value[Key] dup()
{
Value[Key] result;
foreach (k, v; this)
{
result[k] = v;
}
return result;
}
}
else
@disable Value[Key] dup(); // for better error message
auto byValue(T : Value[Key], Value, Key)(T *aa)
{
return (*aa).byValue();
}

auto byKey()
{
static struct Result
{
AARange r;
Key[] keys(T : Value[Key], Value, Key)(T aa)
{
auto a = cast(void[])_aaKeys(cast(inout(void)*)aa, Key.sizeof);
return *cast(Key[]*)&a;
}

@property bool empty() { return _aaRangeEmpty(r); }
@property ref Key front() { return *cast(Key*)_aaRangeFrontKey(r); }
void popFront() { _aaRangePopFront(r); }
Result save() { return this; }
}
Key[] keys(T : Value[Key], Value, Key)(T *aa)
{
return (*aa).keys();
}

return Result(_aaRange(p));
}
Value[] values(T : Value[Key], Value, Key)(T aa)
{
auto a = cast(void[])_aaValues(cast(inout(void)*)aa, Key.sizeof, Value.sizeof);
return *cast(Value[]*)&a;
}

auto byValue()
{
static struct Result
{
AARange r;
Value[] values(T : Value[Key], Value, Key)(T *aa)
{
return (*aa).values();
}

@property bool empty() { return _aaRangeEmpty(r); }
@property ref Value front() { return *cast(Value*)_aaRangeFrontValue(r); }
void popFront() { _aaRangePopFront(r); }
Result save() { return this; }
}
Value get(T : Value[Key], Value, Key, K, V)(T aa, K key, lazy V defaultValue)
if (is(typeof(aa[key] = defaultValue)))
{
auto p = key in aa;
return p ? *p : cast(Value)defaultValue;
}

return Result(_aaRange(p));
}
Value get(T : Value[Key], Value, Key, K, V)(T* aa, K key, lazy V defaultValue)
if (is(typeof((*aa).get(key, defaultValue))))
{
return (*aa).get(key, defaultValue);
}

// Scheduled for deprecation in December 2012.
Expand Down

0 comments on commit 14fa404

Please sign in to comment.