mirror of
https://github.com/dlang/phobos.git
synced 2025-04-28 22:21:09 +03:00
std.conv: add writeText, writeWText, writeDText (#10652)
* std.conv: factor out writeTextImpl from textImpl * std.conv: add writeText, writeWText, writeDText These are variants of text, wtext, and dtext that write their output to an output range instead of returning a string. Fixes #10550 * Add changelog entry for writeText
This commit is contained in:
parent
4ec4e54bcd
commit
b7395ea7f5
2 changed files with 117 additions and 20 deletions
20
changelog/write-text.dd
Normal file
20
changelog/write-text.dd
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
Add `writeText`, `writeWText`, and `writeDText` to `std.conv`
|
||||||
|
|
||||||
|
These functions are variants of the existing `text`, `wtext`, and `dtext`
|
||||||
|
functions. Instead of returning a string, they write their output to an output
|
||||||
|
range.
|
||||||
|
|
||||||
|
Like `text`, `writeText` can accept an
|
||||||
|
$(LINK2 $(ROOT_DIR)spec/istring.html, interpolated expression sequence) as an
|
||||||
|
argument.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
---
|
||||||
|
import std.conv : writeText;
|
||||||
|
import std.array : appender;
|
||||||
|
|
||||||
|
auto output = appender!string();
|
||||||
|
output.writeText(i"2 + 2 == $(2 + 2)");
|
||||||
|
assert(output.data == "2 + 2 == 4");
|
||||||
|
---
|
89
std/conv.d
89
std/conv.d
|
@ -19,6 +19,9 @@ $(TR $(TD Strings) $(TD
|
||||||
$(LREF text)
|
$(LREF text)
|
||||||
$(LREF wtext)
|
$(LREF wtext)
|
||||||
$(LREF dtext)
|
$(LREF dtext)
|
||||||
|
$(LREF writeText)
|
||||||
|
$(LREF writeWText)
|
||||||
|
$(LREF writeDText)
|
||||||
$(LREF hexString)
|
$(LREF hexString)
|
||||||
))
|
))
|
||||||
$(TR $(TD Numeric) $(TD
|
$(TR $(TD Numeric) $(TD
|
||||||
|
@ -5076,6 +5079,75 @@ if (T.length > 0) { return textImpl!dstring(args); }
|
||||||
assert(text(dg4) == "bool delegate(bool, int) @trusted");
|
assert(text(dg4) == "bool delegate(bool, int) @trusted");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convenience functions for writing arguments to an output range as text.
|
||||||
|
void writeText(Sink, T...)(ref Sink sink, T args)
|
||||||
|
if (isOutputRange!(Sink, char) && T.length > 0)
|
||||||
|
{
|
||||||
|
sink.writeTextImpl!string(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ditto
|
||||||
|
void writeWText(Sink, T...)(ref Sink sink, T args)
|
||||||
|
if (isOutputRange!(Sink, wchar) && T.length > 0)
|
||||||
|
{
|
||||||
|
sink.writeTextImpl!wstring(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ditto
|
||||||
|
void writeDText(Sink, T...)(ref Sink sink, T args)
|
||||||
|
if (isOutputRange!(Sink, dchar) && T.length > 0)
|
||||||
|
{
|
||||||
|
sink.writeTextImpl!dstring(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
@safe unittest
|
||||||
|
{
|
||||||
|
import std.array : appender;
|
||||||
|
|
||||||
|
auto output = appender!string();
|
||||||
|
output.writeText("The answer is ", 42);
|
||||||
|
|
||||||
|
assert(output.data == "The answer is 42");
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
@safe unittest
|
||||||
|
{
|
||||||
|
import std.array : appender;
|
||||||
|
|
||||||
|
const color = "red";
|
||||||
|
auto output = appender!string();
|
||||||
|
output.writeText(i"My favorite color is $(color)");
|
||||||
|
|
||||||
|
assert(output.data == "My favorite color is red");
|
||||||
|
}
|
||||||
|
|
||||||
|
@safe unittest
|
||||||
|
{
|
||||||
|
auto capp = appender!string();
|
||||||
|
auto wapp = appender!wstring();
|
||||||
|
auto dapp = appender!dstring();
|
||||||
|
|
||||||
|
capp.writeText(42, ' ', 1.5, ": xyz");
|
||||||
|
wapp.writeWText(42, ' ', 1.5, ": xyz");
|
||||||
|
dapp.writeDText(42, ' ', 1.5, ": xyz");
|
||||||
|
|
||||||
|
assert(capp.data == "42 1.5: xyz"c);
|
||||||
|
assert(wapp.data == "42 1.5: xyz"w);
|
||||||
|
assert(dapp.data == "42 1.5: xyz"d);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check range API compliance using OutputRange interface
|
||||||
|
@system unittest
|
||||||
|
{
|
||||||
|
import std.range.interfaces : OutputRange, outputRangeObject;
|
||||||
|
import std.range : nullSink;
|
||||||
|
|
||||||
|
OutputRange!char testOutput = outputRangeObject!char(nullSink);
|
||||||
|
testOutput.writeText(42, ' ', 1.5, ": xyz");
|
||||||
|
}
|
||||||
|
|
||||||
private S textImpl(S, U...)(U args)
|
private S textImpl(S, U...)(U args)
|
||||||
{
|
{
|
||||||
static if (U.length == 0)
|
static if (U.length == 0)
|
||||||
|
@ -5096,6 +5168,14 @@ private S textImpl(S, U...)(U args)
|
||||||
// assume that on average, parameters will have less
|
// assume that on average, parameters will have less
|
||||||
// than 20 elements
|
// than 20 elements
|
||||||
app.reserve(U.length * 20);
|
app.reserve(U.length * 20);
|
||||||
|
app.writeTextImpl!S(args);
|
||||||
|
return app.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeTextImpl(S, Sink, U...)(ref Sink sink, U args)
|
||||||
|
if (isSomeString!S && isOutputRange!(Sink, ElementEncodingType!S))
|
||||||
|
{
|
||||||
// Must be static foreach because of https://issues.dlang.org/show_bug.cgi?id=21209
|
// Must be static foreach because of https://issues.dlang.org/show_bug.cgi?id=21209
|
||||||
static foreach (arg; args)
|
static foreach (arg; args)
|
||||||
{
|
{
|
||||||
|
@ -5104,19 +5184,16 @@ private S textImpl(S, U...)(U args)
|
||||||
|| isSomeString!(typeof(arg))
|
|| isSomeString!(typeof(arg))
|
||||||
|| ( isInputRange!(typeof(arg)) && isSomeChar!(ElementType!(typeof(arg))) )
|
|| ( isInputRange!(typeof(arg)) && isSomeChar!(ElementType!(typeof(arg))) )
|
||||||
)
|
)
|
||||||
app.put(arg);
|
put(sink, arg);
|
||||||
else static if (
|
else static if (
|
||||||
|
|
||||||
is(immutable typeof(arg) == immutable uint) || is(immutable typeof(arg) == immutable ulong) ||
|
is(immutable typeof(arg) == immutable uint) || is(immutable typeof(arg) == immutable ulong) ||
|
||||||
is(immutable typeof(arg) == immutable int) || is(immutable typeof(arg) == immutable long)
|
is(immutable typeof(arg) == immutable int) || is(immutable typeof(arg) == immutable long)
|
||||||
)
|
)
|
||||||
// https://issues.dlang.org/show_bug.cgi?id=17712#c15
|
// https://issues.dlang.org/show_bug.cgi?id=17712#c15
|
||||||
app.put(textImpl!(S)(arg));
|
put(sink, textImpl!(S)(arg));
|
||||||
else
|
else
|
||||||
app.put(to!S(arg));
|
put(sink, to!S(arg));
|
||||||
}
|
|
||||||
|
|
||||||
return app.data;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue