On Wednesday, 4 December 2013 at 18:26:43 UTC, Ali Çehreli wrote:
On 12/04/2013 09:43 AM, MrSmith wrote:
I am trying to compile following code
import std.algorithm : findSplitBefore;
import std.range : retro;
import std.array : array;
// returns file path where name has suffix and prefix
string withSuffixPrefix(string filePath, string prefix, string
suffix)
{
auto splitted = filePath.retro.findSplitBefore("/");
return cast(string)splitted[1].retro.array
~ prefix
~ cast(string)splitted[0].retro.array //Fails!
~ suffix;
}
With following error:
build.d(56): Error: template std.range.retro does not match
any function
template declaration. Candidates are:
/phobos/std/range.d(1455): std.range.retro(Range)(Range r) if
(isBidirectionalRange!(Unqual!Range))
build.d(56): Error: template std.range.retro(Range)(Range r) if
(isBidirectionalRange!(Unqual!Range)) cannot deduce template
function
from argument types !()(Result)
Seems like i need to somehow convert splitted[0] to
Bidirectional range.
This function will be used like this:
assert(withSuffixPrefix("/some/random/path/to/file", "pref-",
".fl") ==
"/some/random/path/to/pref-file.fl");
The main reason is that the ranges that findSplitBefore
produces are not BidirectionalRanges. retro requires a
BidirectionalRange and for that reason splitted[0].retro fails.
The following solution inserts an .array to produce a
BidirectionalRange.
However, I don't see any reason why findSplitBefore could not
produce BidirectionalRanges when it operated on a
BidirectionalRange to begin with.
Just to stay with your algorithm, you can also use
std.conv.text (as well as std.conv.to!string, which Jesse
Phillips recomended):
import std.algorithm : findSplitBefore;
import std.range;
import std.array : array;
import std.stdio;
import std.conv;
// returns file path where name has suffix and prefix
string withSuffixPrefix(string filePath, string prefix, string
suffix)
{
auto splitted = filePath.retro.findSplitBefore("/");
static assert(!isBidirectionalRange!(typeof(splitted[0])));
return splitted[1].retro.text
~ prefix
~ splitted[0].array.retro.text
~ suffix;
}
void main()
{
writeln(withSuffixPrefix("/some/random/path/to/file",
"pref-", ".fl"));
}
Alternatively, you can use std.path:
import std.path;
import std.string;
string withSuffixPrefix(string filePath, string prefix, string
suffix)
{
return format("%s/%s%s%s",
filePath.dirName, prefix, filePath.baseName,
suffix);
}
void main()
{
assert(withSuffixPrefix("/some/random/path/to/file",
"pref-", ".fl") ==
"/some/random/path/to/pref-file.fl");
}
Ali
Thanks Ali!