Is it possible to return mutable and const range from a single method?
Ali Çehreli
acehreli at yahoo.com
Mon Aug 22 19:16:30 UTC 2022
On 8/22/22 09:36, realhet wrote:
> It gives the protection I was needed but is it possible to make this
> prettier?
> auto allParents(){
> struct ParentRange{
> A act;
> @property bool empty() const{ return act is null; }
> @property A front() { return act; }
> void popFront(){ act = act.getParent; }
> }
> return ParentRange(getParent);
> }
>
> auto allParents()const {
> struct ConstParentRange{
> A act;
> @property bool empty() const{ return act is null; }
> @property const(A) front() inout { return act; }
> void popFront(){ act = act.getParent; }
> }
> return ConstParentRange(cast()getParent);
> }
In other words, is it possible to combine the double implementation
above? The following looks at typeof(this) to pick the type. My test
asserts seem to pass:
import std;
class A{
inout(A) getParent() inout{ return null; }
void nonConstMemberFunc() {}
void constMemberFunc() const {}
this(A p){
}
}
class B : A{
A parent;
override inout(A) getParent() inout{ return parent; }
struct ConstOrMutable(T) {
// This alias is not strictly necessary; 'static if'
// could define 'act' instead.
static if (is (T == const)) {
alias X = const(A);
} else {
alias X = A;
}
X act;
@property auto empty() const { return act is null; }
@property auto front() { return act; }
void popFront() { act = act.getParent; }
}
auto allParents() inout {
return ConstOrMutable!(typeof(this))(cast()getParent());
}
this(A p){
super(p);
parent = p;
}
}
auto test(inout A a, void delegate(inout A) fun){
auto p = a.getParent;
fun(p);
}
void main()
{
auto a = new A(null);
auto b = new B(a);
assert( __traits(compiles, b.constMemberFunc()));
assert( __traits(compiles, b.nonConstMemberFunc()));
const c = b;
assert( __traits(compiles, c.constMemberFunc()));
assert(!__traits(compiles, c.nonConstMemberFunc()));
}
Ali
More information about the Digitalmars-d-learn
mailing list