Small iterators/algorithm usage feedback

Denis Koroskin 2korden at gmail.com
Sun Apr 26 14:53:27 PDT 2009


I have just started using iterators and algorithms a little.
Given a full file path, a needed to get folder name where it is located, and a name of the that file.

Using C and its standard library, I can do it as follows:

auto pos = strrpos(fullFilePath, '/'); // strrpos = strpos-reverse
string dirName = fullFilePath[0..pos];
string fileName = fullFilePath[pos+1..$];

It's very simple, I'd use it, but there is no strrpos (nor strpos) in Phobos/druntime.
So I tried using the following code:

auto it = find(retro(fullFilePath), '/'); // returns Iterator!(Retro!(string))

The hardest part is complete, I thought, but I was wrong.

Now, I realized that I can't do anything with this iterator.
I tried get a position, but the following code failed:

int pos = rBegin(fullFilePath) - it;

Error: incompatible types for ((rBegin(fullFilePath)) - (it)): 'Iterator!(Retro!(string))' and 'Iterator!(Retro!(string))'

Apparently, there is no opSub() in an Iterator's method set.

Okay, let's take a row pointer to a char and calculate the position by hand:

int pos = &(*it) - fullFilePath.ptr; // a common C++ practice

But it failed, too:
Error: it.opStar() is not an lvalue.

Oh, well, you can't take an address of a temporary, let's store it first:

ref immutable(char) c = *it;
immutable(char)* ptr = &c;

Error: found 'ref' instead of statement

Oops, let's write a workaround:

immutable(char)* getAddress(ref immutable(char) c)
{
    return &c;
}

Error: function unwrap (ref immutable(char) c) does not match parameter types (immutable(char))

Oh, it looks like "*it" doesn't return a reference but a copy :(

Next, I thought: that's probably right. It's probably error-prone and disallowed on purpose. It may be better and closer to range-style to get subranges out of a these iterators (begin..it)/(it..end) and finish the task:

string dirName = range(begin(fullFilePath), it);
string fileName = range(it + 1, end(fullFilePath));

But that failed, too:

Error: template std.iterator.range(T) does not match any function template declaration

I tried different other combinations, but all of them failed.

I hope I missed something very simple, but that's what I experienced (being a professional C++ developer who knows, uses and loves STL). I believe others may have similar difficulties, too, so I thought it may be helpful to post my experience here. I hope it'll be constructive.




More information about the Digitalmars-d mailing list