Supporting and signature-checking all foreach variations
Ali Çehreli
acehreli at yahoo.com
Sun Feb 26 02:25:07 PST 2012
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
More information about the Digitalmars-d-learn
mailing list