www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 14196] New: opApply and nothrow don't play along

https://issues.dlang.org/show_bug.cgi?id=14196

          Issue ID: 14196
           Summary: opApply and nothrow don't play along
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: major
          Priority: P1
         Component: DMD
          Assignee: nobody puremagic.com
          Reporter: pro.mathias.lang gmail.com

It's impossible to have both opApply with type inference and compiler-checked
nothrow for a user-defined type.

Say you've got a container of T, and you want to implement opApply. Fine, the
signature is, as you know (I only covert the first one, but it applies to
both):

int opApply(int delegate(ref T) del);

But the issue is, you can't pass it a nothrow delegate, so you'll have to make
it a template:

int opApply(DG)(DG del);

It works, but you loose type deduction, e.g for is(T == string):

foreach (ref elem; arr) // Doesn't compile anymore
foreach (ref string elem; arr) // So you'll have to use this.

Full example:


struct MyArray(T) {
        T[] data;
        int opApply(DG)(DG del) {
                for (size_t idx; idx < data.length; ++idx)
                        if (auto r = del(data[idx]))
                                return r;
                return 0;
        }
}

void neverThrow(string s) nothrow {}
void mightThrow(string s) {}

void testNothrow(T)(ref T arr) nothrow  {
        foreach (ref elem; arr)
                neverThrow(elem);
}
void testThrow(T)(ref T arr) {
        foreach (ref elem; arr)
                mightThrow(elem);
}

void main() {
        // Note that type deduction doesn't work here.
        auto arr = MyArray!string(["1", "2", "3", "4", "5", "42"]);
        testNothrow(arr);
        testThrow(arr);
}

--
Feb 17 2015