Yet another const problem...

Chris Cain clcain at uncg.edu
Sun May 20 20:15:50 PDT 2012


On Monday, 21 May 2012 at 02:36:26 UTC, Mehrdad wrote:
> On Monday, 21 May 2012 at 00:39:13 UTC, Chris Cain wrote:
>> On Monday, 21 May 2012 at 00:07:06 UTC, Mehrdad wrote:
>>> How do you fix this without duplicating your code?
>>
>> Simple. Don't use const for input/forward ranges.
>
> I... guess that works...

If you want a better answer, you (might) can do it how you want, 
but it really can't be done without a bit of duplication (inout 
doesn't seem to work with my idea) and it depends highly on the 
types you're working with. Some types can do it relatively 
easily. Some types require some work.

(note: I've never written an opApply and I'm pretty sure yours 
isn't correct, so I'm doing my best to pseudocode it so it 
compiles correctly)

For instance, if p is a pointer to something ...
struct Foo(T)
{
     T * p = null;
     @property bool empty() const { return p == null; }
     @property auto front() inout { return p; }
     void popFront() { p--; }

     // Can't use inout here ... bug?
     auto save() const {
         // Transfer const to the contents
         return Foo!(const(T))(this.tupleof);
     }

     auto save() {
         return typeof(this)(this.tupleof);
     }

     int opApply(int delegate(size_t, inout typeof(p)) dg) inout
     {
         size_t i = 0;
         int r = 0;

         for (auto me = this.save(); !r && !me.empty; 
me.popFront())
         {
             r = dg(i, me.front);
         }

         return r;
     }
}


But overall, doing stuff with a const or immutable input or 
forward range is just messy because, as I said, it's really not 
something that can be considered const and actually do something 
useful.

You might can make an argument that a Random Access Range could 
be const, and I'd agree. There's some useful things you can do 
with a const random access range. But an input range? I honestly 
can't think of a single use other than a really expensive pointer 
that you "deref" by calling front and check to see if it points 
to null by calling empty.


More information about the Digitalmars-d mailing list