@@ -4792,21 +4792,34 @@ package template WideElementType(T)
47924792 alias WideElementType = E;
47934793}
47944794
4795+ private enum hasInputRanges (T... ) = anySatisfy! (isInputRange, T);
47954796
47964797/* **************************************************************
47974798 * Convenience functions for converting one or more arguments
47984799 * of any type into _text (the three character widths).
47994800 */
48004801string text (T... )(const (T) args)
4801- if (T.length > 0 ) { return textImpl! string (args); }
4802+ if (T.length > 0 && hasInputRanges! T) { return textImpl! string (args); }
4803+
4804+ // / ditto
4805+ string text (T... )(const T args)
4806+ if (T.length > 0 && ! hasInputRanges! T) { return textImpl! string (args); }
48024807
48034808// /ditto
48044809wstring wtext (T... )(const (T) args)
4805- if (T.length > 0 ) { return textImpl! wstring (args); }
4810+ if (T.length > 0 && hasInputRanges! T) { return textImpl! wstring (args); }
4811+
4812+ // /ditto
4813+ wstring wtext (T... )(const T args)
4814+ if (T.length > 0 && ! hasInputRanges! T) { return textImpl! wstring (args); }
48064815
48074816// /ditto
48084817dstring dtext (T... )(const (T) args)
4809- if (T.length > 0 ) { return textImpl! dstring (args); }
4818+ if (T.length > 0 && hasInputRanges! T) { return textImpl! dstring (args); }
4819+
4820+ // /ditto
4821+ dstring dtext (T... )(const T args)
4822+ if (T.length > 0 && ! hasInputRanges! T) { return textImpl! dstring (args); }
48104823
48114824// /
48124825@safe unittest
@@ -4871,10 +4884,14 @@ if (T.length > 0) { return textImpl!dstring(args); }
48714884}
48724885
48734886private S textImpl (S, U... )(const (U) args)
4887+ if (hasInputRanges! U)
48744888{
48754889 static if (U.length == 0 )
48764890 {
4877- return null ;
4891+ version (none )
4892+ return null ;
4893+ else
4894+ static assert (false , " How can zero-length `U` have InputRanges?" );
48784895 }
48794896 else static if (U.length == 1 )
48804897 {
@@ -4914,6 +4931,50 @@ private S textImpl(S, U...)(const(U) args)
49144931 }
49154932}
49164933
4934+ private S textImpl (S, U... )(const U args)
4935+ if (! hasInputRanges! U)
4936+ {
4937+ static if (U.length == 0 )
4938+ {
4939+ return null ;
4940+ }
4941+ else static if (U.length == 1 )
4942+ {
4943+ return to! S(args[0 ]);
4944+ }
4945+ else
4946+ {
4947+ import std.array : appender;
4948+ import std.traits : isSomeChar, isSomeString;
4949+
4950+ auto app = appender! S();
4951+
4952+ // assume that on average, parameters will have less
4953+ // than 20 elements
4954+ app.reserve (U.length * 20 );
4955+ // Must be static foreach because of https://issues.dlang.org/show_bug.cgi?id=21209
4956+ static foreach (arg; args)
4957+ {
4958+ static if (
4959+ isSomeChar! (typeof (arg))
4960+ || isSomeString! (typeof (arg))
4961+ || ( isInputRange! (typeof (arg)) && isSomeChar! (ElementType! (typeof (arg))) )
4962+ )
4963+ app.put(arg);
4964+ else static if (
4965+
4966+ is (immutable typeof (arg) == immutable uint ) || is (immutable typeof (arg) == immutable ulong ) ||
4967+ is (immutable typeof (arg) == immutable int ) || is (immutable typeof (arg) == immutable long )
4968+ )
4969+ // https://issues.dlang.org/show_bug.cgi?id=17712#c15
4970+ app.put(textImpl! (S)(arg));
4971+ else
4972+ app.put(to! S(arg));
4973+ }
4974+
4975+ return app.data;
4976+ }
4977+ }
49174978
49184979/* **************************************************************
49194980The `octal` facility provides a means to declare a number in base 8.
0 commit comments