Small iterators/algorithm usage feedback
dsimcha
dsimcha at yahoo.com
Sun Apr 26 15:12:16 PDT 2009
== Quote from Denis Koroskin (2korden at gmail.com)'s article
> 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.
Yes, std.algorithm is supposed to be very generic, rather than focusing on doing
one thing well. This is good when you have some very generic needs, but since
strings are such a common thing, we have std.string.rfind to handle exactly what
you're looking for without massive template gymnastics.
More information about the Digitalmars-d
mailing list