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

Commit

Permalink
Implement AA byKeyValue.
Browse files Browse the repository at this point in the history
  • Loading branch information
H. S. Teoh committed Jan 2, 2015
1 parent c5d48c9 commit 089b2ed
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/object.di
Expand Up @@ -527,6 +527,34 @@ Value[] values(T : Value[Key], Value, Key)(T *aa) @property
return (*aa).values;
}

auto byKeyValue(T : Value[Key], Value, Key)(T aa) pure nothrow @nogc @property
{
static struct Result
{
AARange r;

pure nothrow @nogc:
@property bool empty() { return _aaRangeEmpty(r); }
@property auto front() @trusted
{
static struct Pair
{
private Key* keyp;
private Value* valp;

@property ref Key key() { return *keyp; }
@property ref Value value() { return *valp; }
}
return Pair(cast(Key*)_aaRangeFrontKey(r),
cast(Value*)_aaRangeFrontValue(r));
}
void popFront() { _aaRangePopFront(r); }
Result save() { return this; }
}

return Result(_aaRange(p));
}

inout(V) get(K, V)(inout(V[K]) aa, K key, lazy inout(V) defaultValue)
{
auto p = key in aa;
Expand Down
65 changes: 65 additions & 0 deletions src/object_.d
Expand Up @@ -2125,6 +2125,36 @@ Value[] values(T : Value[Key], Value, Key)(T *aa) @property
return (*aa).values;
}

auto byKeyValue(T : Value[Key], Value, Key)(T aa) pure nothrow @nogc @property
{
static struct Result
{
AARange r;

pure nothrow @nogc:
@property bool empty() { return _aaRangeEmpty(r); }
@property auto front() @trusted
{
static struct Pair
{
// We save the pointers here so that the Pair we return
// won't mutate when Result.popFront is called afterwards.
private Key* keyp;
private Value* valp;

@property ref Key key() { return *keyp; }
@property ref Value value() { return *valp; }
}
return Pair(cast(Key*)_aaRangeFrontKey(r),
cast(Value*)_aaRangeFrontValue(r));
}
void popFront() { _aaRangePopFront(r); }
Result save() { return this; }
}

return Result(_aaRange(cast(void*)aa));
}

inout(V) get(K, V)(inout(V[K]) aa, K key, lazy inout(V) defaultValue)
{
auto p = key in aa;
Expand Down Expand Up @@ -2354,6 +2384,41 @@ pure nothrow unittest
//testFwdRange(aa.byPair, tuple("a", 1));
}

unittest
{
// Issue 9119
int[string] aa;
assert(aa.byKeyValue.empty);

aa["a"] = 1;
aa["b"] = 2;
aa["c"] = 3;

auto pairs = aa.byKeyValue;

auto savedPairs = pairs.save;
size_t count = 0;
while (!pairs.empty)
{
assert(pairs.front.key in aa);
assert(pairs.front.value == aa[pairs.front.key]);
count++;
pairs.popFront();
}
assert(count == aa.length);

// Verify that saved range can iterate over the AA again
count = 0;
while (!savedPairs.empty)
{
assert(savedPairs.front.key in aa);
assert(savedPairs.front.value == aa[savedPairs.front.key]);
count++;
savedPairs.popFront();
}
assert(count == aa.length);
}

// Explicitly undocumented. It will be removed in March 2015.
deprecated("Please use destroy instead of clear.")
alias destroy clear;
Expand Down

0 comments on commit 089b2ed

Please sign in to comment.