On Wed, 17 Aug 2011 14:15:52 -0400, Steven Schveighoffer wrote: > On Wed, 17 Aug 2011 13:15:27 -0400, Lars T. Kyllingstad > <[email protected]> wrote: > >> On Wed, 17 Aug 2011 10:19:31 -0400, Steven Schveighoffer wrote: >> >>> On Wed, 17 Aug 2011 00:05:54 -0400, Jonathan M Davis >>> <[email protected]> wrote: >>> >>>> So, the question is, should a range-based function have the same >>>> behavior for >>>> all forward ranges regardless of whether they're value types or >>>> reference types? Or should the caller be aware of whether a range is >>>> a value type or a >>>> reference type and call save if necessary? Or should the caller just >>>> always >>>> call save when passing a forward range to a function? >>>> >>>> >>> Probably not helpful, since the establishment seems to be set in their >>> opinions, but I'd recommend saying ranges are always structs, and get >>> rid of the save concept, replacing it with an enum solution. The >>> current save regime is a fallacy, because it's not enforced. It's as >>> bad as c++ const. >>> >>> At the very least, let's wait until someone actually comes up with a >>> valid use case for reference-based forward ranges before changing any >>> code. So far, all I've seen is boilerplate *RangeObject, no real >>> usages. >> >> As long as most functions in std.algorithm don't take the ranges as ref >> arguments, you need to use a reference-based range whenever you want >> the function to consume the original range. >> >> BTW, this is why I suggested earlier that we add a byRef range. If you >> absolutely want the function foo() to consume your range, write >> >> foo(byRef(myRange)); > > Do you have a real example besides foo which makes sense on both byRef > and by value ranges?
Well, I did try my hand at writing a parser for a wiki-style markup language a while ago, which got its input from an input range. It would look at the front of the range, determine what kind of element was there (paragraph, heading, bullet list, etc.), and pass the range on to a specialised function for dealing with that kind of element (parseHeading(), etc.). Of course, those functions had to consume the original range, otherwise the same element would be repeated over and over again. For simple cases, this was only a matter of parseWhatever() taking the range by ref, and everything would work nicely. Sometimes, however, the range would be wrapped by another range (such as Take or Until). If I wanted these to keep consuming the original range, I had to wrap it with byRef(). This happened often enough, and became annoying enough, that I ended up using InputRange objects everywhere instead. -Lars
