On Fri, 29 Jan 2010 11:08:37 -0500, Michel Fortin <michel.for...@michelf.com> wrote:

On 2010-01-29 11:00:31 -0500, "Steven Schveighoffer" <schvei...@yahoo.com> said:

On Fri, 29 Jan 2010 10:53:50 -0500, Michel Fortin <michel.for...@michelf.com> wrote:

On 2010-01-29 10:49:34 -0500, "Steven Schveighoffer" <schvei...@yahoo.com> said:

ugh... much simpler with a true stream-like range that supports what is natural for streams:
 for(int i = 0; i < count && !range.empty; i++) {
    elements ~= range.get();
}
But of course, then this function doesn't work for other range types. I decided in that discussion long ago that stream ranges were going to suck.
 You can always define a generic take() like this:
        E take(R, E)(ref R range) {
                E element = range.front;
                range.popFront();
                return element;
        }
 This will work for any forward range.
 Except stream ranges.  I don't get it...

Hum, well I used 'take' while you defined 'get' as the basic function for stream ranges. They're the same thing. Rename 'take' for 'get', or the reverse, and all input ranges can work with the same 'get' or 'take' function.

(Note: I use 'take' instead of 'get' because it seems clearer to me that it also removes the element from the range.)

Oh, I get it now. Yes, you can define this (BTW, I agree take is better than get). Whether we will ever get x.fn() => fn(x) for ranges remains to be seen. Without that, you have boilerplate code in every forward range and beyond. The other possibility is to define an abstraction function like:

E take(R, E)(ref R range) {
   static if(isForwardRange!(R))
   {
       // repeat your code above
   }
   else
       return range.take();
}

and then use take(r) whenever you need that capability.

-Steve

Reply via email to