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

Reply via email to