atilaneves / automem

C++-style automatic memory management smart pointers for D
BSD 3-Clause "New" or "Revised" License
86 stars 15 forks source link

Cannot foreach over Unique or RefCounted ranges #37

Closed jpf91 closed 4 years ago

jpf91 commented 4 years ago

Example:

/+ dub.sdl:
       dependency "automem" version="~>0.6.1"
 +/
import automem;

void main()
{
    auto r = S();
    auto rc = RefCounted!S();
    auto un = Unique!S();
    foreach(i; r) {} //works
    foreach(i; rc) {}
    foreach(i; un) {}
}

struct S
{
    @property int front() {return 0;}
    void popFront(){}
    @property bool empty(){return false;}
}
dub test.d                                                                                             :(
test.d(13,5): Error: invalid foreach aggregate rc, define opApply(), range primitives, or use .tupleof
test.d(14,5): Error: invalid foreach aggregate un, define opApply(), range primitives, or use .tupleof

Same thing happens if front is a data member. For unique it's probably not possible to fix this, because of this DMD problem: https://issues.dlang.org/show_bug.cgi?id=15413 But I don't know why it doesn't work for RefCounted.

atilaneves commented 4 years ago

I'm not sure the smart pointers should satisfy template constraints on the enclosed type. It's not the case in C++:

        auto ints = make_shared<vector<int>>();
        ints->push_back(4);
        ints->push_back(5);
        ints->push_back(6);
        for(auto i: *ints) {
            cout << i << endl;
        }

Notice that ints must be dereferenced in the range for loop. It won't compile with for(auti i: ints). Likewise, this D code works:

foreach(i; *rc) {}
foreach(i; *un) {}