Bug 5055 – hasAssignableElements etc only check forward range primitives
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2010-10-15T00:36:58Z
Last change time
2017-10-18T14:55:06Z
Keywords
accepts-invalid
Assigned to
Andrei Alexandrescu
Creator
yebblies
Comments
Comment #0 by yebblies — 2010-10-15T00:36:58Z
Most of the hasSomething templates in std.range should check that range.back and/or range[i] fill the requirements. hasMobileElements already does this.
Also, should back/opIndex always return the same type as front?
If so, this should be added to the definitions of isBidirectionalRange and isRandomAccesRange.
List:
hasSwappableElements
hasAssignableElements
hasLvalueElements
Possible Implementations:
template hasSwappableElements(R)
{
enum bool hasSwappableElements = isForwardRange!(R) && is(typeof(
{
R r;
swap(r.front, r.front); // can swap elements of the range
})) && (!isBidirectionalRange!R || is(typeof(
{
R r;
swap(r.back, r.back);
}))) && (!isRandomAccessRange!R || is(typeof(
{
R r;
swap(r[0], r[0]);
})));
}
template hasAssignableElements(R)
{
enum bool hasAssignableElements = isInputRange!(R) && is(typeof(
{
R r;
auto e = r.front;
r.front = e; // can assign elements of the range
})) && (!isBidirectionalRange!R || is(typeof(
{
R r;
auto e = r.back;
r.back = e;
}))) && (!isRandomAccessRange!R || is(typeof(
{
R r;
auto e = r[0];
r[0] = e;
})));
}
template hasLvalueElements(R)
{
enum bool hasLvalueElements =
isInputRange && is(typeof(&R.init.front()) == ElementType!(R)*) &&
(!isBidirectionalRange!R || is(typeof(&R.init.back()) == ElementType!(R)*)) &&
(!isRandomAccessRange!R || is(typeof(&R.init[0]) == ElementType!(R)*));
}
Adding the appropriate asserts to ElementType, isBidirectionalRange and isRandomAccessRange should prevent ranges with mismatched element types from being used.
static assert(!isBidirectionalRange!R || is(typeof({return R.init.front();}()) == typeof({return R.init.back();}()), "Members front and back must have the same type");
static assert(!isRandomAccessRange!R || is(typeof({return R.init.front();}()) == typeof({return R.init[0];}()), "Members front and opIndex must have the same type");
Comment #1 by razvan.nitu1305 — 2017-10-18T14:55:06Z
I see that the issues have been addressed. All 3 has* enums now check that range.back and range[0] fill the requirements. Closing this as fixed. Please reopen if I'm missing something.