Remove opApply from containers

opApply requires additional overloads for the const containers (with a
const delegate). If using a templated opApply foreach cannot infer the
types for the variables. foreach with one argument still works
(opIndex() is used), for more complex cases slicing should be used.
This commit is contained in:
Eugen Wissner 2017-04-07 16:00:50 +02:00
parent ba6bf554fb
commit 6e2ce5d686
2 changed files with 48 additions and 173 deletions

View File

@ -704,64 +704,6 @@ struct SList(T)
assert(l1 == l2);
}
/**
* $(D_KEYWORD foreach) iteration.
*
* Params:
* dg = $(D_KEYWORD foreach) body.
*
* Returns: The value returned from $(D_PARAM dg).
*/
int opApply(scope int delegate(ref size_t i, ref T) @nogc dg)
{
int result;
size_t i;
for (auto pos = head; pos; pos = pos.next, ++i)
{
result = dg(i, pos.content);
if (result != 0)
{
return result;
}
}
return result;
}
/// Ditto.
int opApply(scope int delegate(ref T) @nogc dg)
{
int result;
for (auto pos = head; pos; pos = pos.next)
{
result = dg(pos.content);
if (result != 0)
{
return result;
}
}
return result;
}
///
@nogc unittest
{
SList!int l;
l.insertFront(5);
l.insertFront(4);
l.insertFront(9);
foreach (i, e; l)
{
assert(i != 0 || e == 9);
assert(i != 1 || e == 4);
assert(i != 2 || e == 5);
}
}
/**
* Returns: Range that iterates over all elements of the container, in
* forward order.
@ -901,3 +843,21 @@ struct SList(T)
}
static assert(is(SList!Stuff));
}
// foreach called using opIndex().
private @nogc @safe unittest
{
SList!int l;
size_t i;
l.insertFront(5);
l.insertFront(4);
l.insertFront(9);
foreach (e; l)
{
assert(i != 0 || e == 9);
assert(i != 1 || e == 4);
assert(i != 2 || e == 5);
++i;
}
}

View File

@ -1161,120 +1161,6 @@ struct Vector(T)
assert(v1 == v2);
}
/**
* $(D_KEYWORD foreach) iteration.
*
* Params:
* dg = $(D_KEYWORD foreach) body.
*
* Returns: The value returned from $(D_PARAM dg).
*/
int opApply(scope int delegate(ref T) @nogc dg)
{
T* end = this.data + length - 1;
for (T* begin = this.data; begin != end; ++begin)
{
int result = dg(*begin);
if (result != 0)
{
return result;
}
}
return 0;
}
/// Ditto.
int opApply(scope int delegate(ref size_t i, ref T) @nogc dg)
{
for (size_t i = 0; i < length; ++i)
{
assert(i < length);
int result = dg(i, *(this.data + i));
if (result != 0)
{
return result;
}
}
return 0;
}
/// Ditto.
int opApplyReverse(scope int delegate(ref T) dg)
{
for (T* end = this.data + length - 1; this.data != end; --end)
{
int result = dg(*end);
if (result != 0)
{
return result;
}
}
return 0;
}
/// Ditto.
int opApplyReverse(scope int delegate(ref size_t i, ref T) dg)
{
if (length > 0)
{
size_t i = length;
do
{
--i;
assert(i < length);
int result = dg(i, *(this.data + i));
if (result != 0)
{
return result;
}
}
while (i > 0);
}
return 0;
}
///
unittest
{
auto v = Vector!int([5, 15, 8]);
size_t i;
foreach (j, ref e; v)
{
i = j;
}
assert(i == 2);
foreach (j, e; v)
{
assert(j != 0 || e == 5);
assert(j != 1 || e == 15);
assert(j != 2 || e == 8);
}
}
///
unittest
{
auto v = Vector!int([5, 15, 8]);
size_t i;
foreach_reverse (j, ref e; v)
{
i = j;
}
assert(i == 0);
foreach_reverse (j, e; v)
{
assert(j != 2 || e == 8);
assert(j != 1 || e == 15);
assert(j != 0 || e == 5);
}
}
/**
* Returns: The first element.
*
@ -1730,7 +1616,7 @@ unittest
auto v = Vector!SWithDtor(); // Destructor can destroy empty vectors.
}
unittest
private unittest
{
class A
{
@ -1738,3 +1624,32 @@ unittest
A a1, a2;
auto v1 = Vector!A([a1, a2]);
}
private @safe @nogc unittest
{
auto v = Vector!int([5, 15, 8]);
{
size_t i;
foreach (e; v)
{
assert(i != 0 || e == 5);
assert(i != 1 || e == 15);
assert(i != 2 || e == 8);
++i;
}
assert(i == 3);
}
{
size_t i = 3;
foreach_reverse (e; v)
{
--i;
assert(i != 2 || e == 8);
assert(i != 1 || e == 15);
assert(i != 0 || e == 5);
}
assert(i == 0);
}
}