On Sunday, December 30, 2012 16:18:18 d coder wrote: > Ok, I thought I found the answer in an earlier thread > http://forum.dlang.org/thread/[email protected] > > auto range = find(list[], elem); > list.remove(take(range, 1)); > > But it does not work. Gives me: > > Error: function std.container.DList!(Foo).DList.remove (Range r) is not > callable using argument types (Take!(Range)) > Error: cannot implicitly convert expression (take(range, 1LU)) of type > Take!(Range) to Range > > I get similar issues if I try using std.algorithm.filter instead of find. > > I am using latest DMD snapshot from github.
For some reason, remove doesn't support take like it should, but linearRemove does. However, filter will never work. The remove function must operate on a range which refers to specific elements in the container, not a range which happens to hold elements which match elements in the container, so it needs either the exact range type that it gives you with opSlice or a range that it can recognize as wrapping the range type that it gives you. filter returns a range that no container recognizes, and its very nature means that the range won't necessarily hold a contiguous set of elements from the container, making it very problematic in general for the container functions to try and recognize it as being a wrapper around one of their ranges and operate on it. At this point, only the exact range type or the result of take* on the exact range type is going to work (and if any of those don't remove for a container's remove* function, then it's a bug). Some other range wrapper types (e.g. retro) may end up being recognized in the future, but the list of range wrapper types supported by std.container is likely to be very small - primarily to what's required to reasonably get the slice you need from one of its ranges. Transformative and filtering ranges are unlikely to ever be supported. - Jonathan M Davis
