Thread overview
const-correctness in std.range
Sep 01, 2014
Vlad Levenfeld
Sep 01, 2014
Jonathan M Davis
Sep 03, 2014
Vlad Levenfeld
September 01, 2014
I notice that some of the range adapters in std.range (iota, takeExactly) have a const empty property, while others (take, retro) don't. This makes maintaining const-correctness downstream (with my own range adapters atop phobos') more difficult. I'm wondering if there is a rationale for this, if there is some use for a non-const empty?
September 01, 2014
On Monday, 1 September 2014 at 03:45:25 UTC, Vlad Levenfeld wrote:
> I notice that some of the range adapters in std.range (iota, takeExactly) have a const empty property, while others (take, retro) don't. This makes maintaining const-correctness downstream (with my own range adapters atop phobos') more difficult. I'm wondering if there is a rationale for this, if there is some use for a non-const empty?

 If a range is wrapping another range, you generally can't mark anything const without using static ifs to check whether those functions are const for the range being wrapped, otherwise the wrapper will fail to compile if the functions aren't const, and they often aren't - either because the person who wrote the code didn't bother or because an implementation detail makes it problematic or impossible. It would be really nice if we had some kind of const or inout inferrence, but unfortunately, we don't.

It's quite possible that some of the ranges in Phobos have const functions where they shouldn't be const and that some of them should have const functions but don't. empty can frequently be const, but there's no guarantee that it can be (e.g. some ranges might actually do work in their empty, even though that's usually not the best place to do it; however, there are cases wher it may be forced). In general though, at this point, to get it right, you need to use static if to switch between const and non-const implementation depending on the range being wrapped.

- Jonathan M Davis
September 03, 2014
Thanks for the reply.

And indeed, I recently found that ByLine.empty can't be const because it writes and removes a character from the stream or something... and when I compile with optimizations, const empty gets totally wrecked.

I suppose that making empty const doesn't really gain me anything, as its generally used in conjunction with popFront which is obviously non-const.