Recently, I discovered an interesting idiom for dealing with transient ranges, esp. w.r.t. strings / char[]. Many places in D require string, but sometimes what you have is char[] which can't be converted to string except by .idup. But you don't want to .idup in generic code, because if the input's already a string, then it's wasteful duplication. The solution is to do this:
void func(S)(S input) if (isSomeString!S) { string x = to!string(input); ... // use at will } The nice thing about this is that if input is already a string, to!string does nothing, and if it's char[] or const(char)[], to!() handles calling .idup for you so you don't have to pollute generic code with it. When writing a generic function that takes a range of some string, and you're not sure if the range is transient or not, the same trick helps ensure that you don't run into transience-related problems: auto func(R)(R range) if (isSomeString!(ElementType!S)) { struct WrapperRange { ... auto front() { // This ensures we don't run into // transience related problems, and that // the range we return will *not* be // transient. return range.front.to!string(); } } return WrapperRange(...); } T -- Freedom: (n.) Man's self-given right to be enslaved by his own depravity.