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.