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.

Reply via email to