Summary: std.range.take does not always return Take!R
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Phobos

--- Comment #0 from yebblies <> 2010-07-15 05:46:13 PDT ---
When used with a range that supports slicing, take(r, n) returns r[0..n], which
unfortunately makes it impossible to declare a variable of type Take!R and have
it work in all situations.
I do consider this a bug and not an intended part of the design, please correct
me if this is not the case.

int[] a;
Take!R r = take(a, 3); // type mismatch error

In most situations this is not a problem as type inference can be used, but
when the type need to be known (as in a struct declaration) it won't work.
Because take is an auto function, typeof(take(r, n)) does not work either.

To fix this without disabling the slicing optimisation:

1. Change the template constraint on 'Take'

-  struct Take(R) if (isInputRange!(R))
+  struct Take(R) if (isInputRange!(R) && !hasSlicing!R)

2. Add a template to handle the other case

+  template Take(R) if (isInputRange!R && hasSlicing!R)
+  {
+     alias typeof(R.init[0..R.init.length]) Take;
+  };

3. Change the return type of take from 'auto' to 'Take!R'

-  auto take(R)(R input, size_t n) if (isInputRange!R && hasSlicing!R)
+  Take!R take(R)(R input, size_t n) if (isInputRange!R && hasSlicing!R)

With these changes take and Take work properly with everything.
I _will_ learn how to make real diffs one day.

Configure issuemail:
------- You are receiving this mail because: -------

Reply via email to