Isn't using find with retro awkward?

Andrej Mitrovic andrej.mitrovich at gmail.com
Mon Feb 14 20:40:02 PST 2011


On 2/15/11, Jonathan M Davis <jmdavisProg at gmx.com> wrote:
>
> retro revereses the whole range. What you want is something like
> findFromBack.
> I don't think that we have any functions like findFromBack though. It's
> probably
> worth an enhancement request.

std.string had a find and rfind, both of which are deprecated now
(although we can still use indexOf & lastIndexOf). So
std.algorithm.find will take its place, but there's no rFind. There's
retro().

So I suppose rFind or lastFind would fit as a name if there's a use
case for this.

The problem is, there's 7 find templates in std.algorithm. I think
making another 7 templates for lastFind would be too much work without
a valid use case. It's much more than just replacing popBack and back
calls to popFront and front, from what I can tell.

Anyway, I'm posting this since I don't know if a reversed range is
what most people want. It seems kind of strange to me to use retro to
find a last match and then get a reversed range back, but maybe that's
just me?

I'd like to hear from people who've used find with retro - if so did
the reversed range and its length make sense to them or not?

Using retro with a string doesn't make sense since that will reverse
the string and you won't match with your needle. It won't compile
either, but maybe that is a bug with retro or find. Here's what I
mean:

import std.string : indexOf, lastIndexOf;
import std.algorithm;
import std.range;

void main()
{
    string mystring = "foo bar doo bar yaz";
    auto leftIndex = indexOf(mystring, "bar");
    assert(mystring[leftIndex .. $] == "bar doo bar yaz");

    auto rightIndex = lastIndexOf(mystring, "bar");
    assert(mystring[rightIndex .. $] == "bar yaz");

    // now the std.algorithm.find case:
    auto firstRange = find(mystring, "bar");
    assert(firstRange == "bar doo bar yaz");

    // will never match, since retro reverses the string.
    // but it also errors out
    auto lastRange = find(retro(mystring), "bar");
    assert(firstRange == "bar yaz");
}

D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(2403): Error: variable
std.algorithm.simpleMindedFind!(pred,Retro!(string),string).simpleMindedFind.estimatedNeedleLength
cannot modify immutable
D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(2216): Error: template
instance std.algorithm.simpleMindedFind!(pred,Retro!(string),string)
error instantiating
stringFind2.d(20):        instantiated from here: find!("a ==
b",Retro!(string),string)
stringFind2.d(20): Error: template instance std.algorithm.find!("a ==
b",Retro!(string),string) error instantiating

Also, std.string.indexOf conflicts with std.algorithm.indexOf, but I
think some of these functions are getting fixed for the next release
(IIRC there was a thread about it).

Now, how would you easily get a range back so that:

find("foo bar doo bar", "bar") == "bar doo bar"
and:
lastFind("foo bar doo bar", "bar") == "bar"

without using a specialized version of find, in this case lastFind?


More information about the Digitalmars-d-learn mailing list