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