On 02/25/2012 08:25 AM, Ashish Myles wrote:
> I want to define a general-purpose centroid computer for point containers
> and ran into a couple of challenges. Firstly, here is the basic code
>
>      Point3 computeCentroid(PointContainer)(const ref PointContainer C)
> if (...) // want a signature constraint for usability of foreach
>      {
>          Point3 c = Point3(0.0, 0.0, 0.0);
>          size_t total = 0;
> foreach(Point3 p; C) { // enforce that the container supports this
>              c += p; ++total;
>          }
>          if (total>  0)
>              c /= cast(double)(total);
>          return c;
>      }

...

> 2. Secondly, TDPL on page 381 says that foreach iterates over C[], if
>    C defines the opSlice() function without any arguments.

Although what you describe also seems useful, that heading seems to be about ranges and specifically about the three InputRange functions. The feature has indeed been implemented recently:

  http://d.puremagic.com/issues/show_bug.cgi?id=5605

>    However the code above doesn't seem to work and requires me to
>    explicitly invoke the slice operator myself like
>      foreach(p; C[]) { ... }
>    when my data structure clearly defines the following functions.
>      Point3[] opSlice() { return _cpts[]; }
>      const (Point3)[] opSlice() const { return _cpts[]; }
>    Is this a misunderstanding on my part or an unimplemented feature?

But I've just verified that the following works with dmd 2.058:

import std.stdio;

struct Point3
{}

struct MyCollection
{
    Point3[] _cpts;

    Point3[] opSlice() { return _cpts; }  // <-- _cpts[] works too

    const (Point3)[] opSlice() const { return _cpts; }
}

void main()
{
    auto coll = MyCollection();

    foreach (i; coll) {
        // ...
    }
}

Ali

Reply via email to