www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 11913] New: nothrow std.algorithm.zip

reply d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11913

           Summary: nothrow std.algorithm.zip
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: Phobos
        AssignedTo: nobody puremagic.com
        ReportedBy: bearophile_hugs eml.cc



void main() nothrow {
    import std.algorithm: zip;
    int[] a;
    foreach (p; zip(a, a)) {}
}



dmd 2.065alpha gives:

temp.d(4): Error: 'std.range.Zip!(int[], int[]).Zip.empty' is not nothrow
temp.d(4): Error: 'std.range.Zip!(int[], int[]).Zip.popFront' is not nothrow
temp.d(1): Error: function 'D main' is nothrow yet may throw


The signature of zip is:

auto zip(Ranges...)(Ranges ranges) if (Ranges.length &&
allSatisfy!(isInputRange, Ranges));

auto zip(Ranges...)(StoppingPolicy sp, Ranges ranges) if (Ranges.length &&
allSatisfy!(isInputRange, Ranges)); 


The empty() method of Zip:

 property bool empty() {
    import std.exception : enforce;

    final switch (stoppingPolicy) {
        case StoppingPolicy.shortest:
            foreach (i, Unused; R)
                if (ranges[i].empty) return true;
            return false;
        case StoppingPolicy.longest:
            foreach (i, Unused; R)
                if (!ranges[i].empty) return false;
            return true;
        case StoppingPolicy.requireSameLength:
            foreach (i, Unused; R[1 .. $])
                enforce(ranges[0].empty ==
                        ranges[i + 1].empty,
                        "Inequal-length ranges passed to Zip");
            return ranges[0].empty;
    }
    assert(false);
}


The case StoppingPolicy.requireSameLength can throw, so zip can't be nothrow.

But with a different API:

auto zip(StoppingPolicy = StoppingPolicy.requireSameLength, Ranges...)(Ranges
ranges)

You can use a "static if" inside Zip to tell apart the various cases (because D
doesn't have a static switch), allowing most times zip to be usable inside
nothrow functions.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 13 2014
parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11913


monarchdodra gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |monarchdodra gmail.com



AFAIK, requireSameLength shouldn't be throwing exceptions to begin with. So
this can probably be solved without changing the API.

Triggering the enforce requires calling popFront on an empty Zip, which is
illegal to begin with.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 18 2014