On Monday, April 16, 2018 21:10:03 Johannes Loher via Digitalmars-d-learn wrote: > Is there a way to do this? Here is a naive implementation: > https://run.dlang.io/is/JKvL80 . > > It does not pass `isInputRange` (I think, because the free functions are > not visible in the scope of `isInputRange`). > > Trying to iterate over it with a foreach loop results in a compile error: > Error: invalid foreach aggregate NoRange(0, 0).this(5), define > opApply(), range primitives, or use .tupleof > > Thanks for your help!
It doesn't work unless the module using the range either contains the free functions or imports them. So, I believe that that would mean that for isInputRange to pass, std.range.primitives would have to have access to the functions, which isn't going to happen for anything but dynamic arrays. It's a limitation of UFCS in general (it's similar to why using string lambdas with std.functional has become fairly rare - you can only use functions in them that std.functional already knows about). The only way for the functions to be associated with the type and thus always be available is if they're member functions. So, if you want a type to be a range, you have to declare the range functions as member functions. - Jonathan M Davis