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