Some @nogc text conversion in Phobos?

Dicebot via Digitalmars-d digitalmars-d at puremagic.com
Wed May 28 16:52:58 PDT 2014


On Wednesday, 28 May 2014 at 23:27:34 UTC, bearophile wrote:
> This is currently accepted code:
>
>
> void main() {
>     import std.array: appender;
>     import std.format: formattedWrite;
>
>     auto writer = appender!string;
>     formattedWrite(writer, "%s is the ultimate %s.", 42, 
> "answer");
>     assert(writer.data == "42 is the ultimate answer.");
> }
>
>
>
> But there are problems caused by formatting for exception error 
> messages:
> https://d.puremagic.com/issues/show_bug.cgi?id=12768
>
>
> An example of the problem:
>
> class UTFException : Exception
> {
> ...
>     pure @safe
>     this(string msg, size_t index, string file = __FILE__, 
> size_t line = __LINE__, Throwable next = null) {
>         import std.string;
>         super(msg ~ format(" (at index %s)", index), file, 
> line, next);
>     }
>
>
> Because of that several Phobos functions can't be @nogc.
>
> So is it a good idea to add to Phobos a function similar to 
> this?
>
>
> void main() pure nothrow @safe @nogc {
>     import std.format: bufferText;
>
>     immutable n = 42;
>     immutable s = "answer";
>     char[100] buf;
>     const Nullable!(char[]) result =
>         buf.bufferText(n, " is the ultimate ", s);
>     assert(result.get == "42 is the ultimate answer.");
> }
>
>
>
> That should allow (in theory) code like:
>
> class UTFException : Exception
> {
> ...
>     pure @safe @nogc
>     this(in char[] msg, string file = __FILE__, size_t line = 
> __LINE__, Throwable next = null) {
>         super(msg, file, line, next);
>     }
>
> ...
>
> char[100] buf;
> const msg = buf.bufferText("Invalid UTF-8 sequence (at index ", 
> i, ')');
> if (mgs.isNull)
>     new UTFException("Invalid UTF-8 sequence")...
> else
>     new UTFException(msg.get)...
>
>
>
> A problem left is that the ctor of Exception is not yet @pure 
> @nothrow @safe @nogc.
>
> Bye,
> bearophile

IMHO something like this is better:

class MyException : Exception
{
     private char[20] index_buff; // should be enough for 
size_t.max

     this(string msg, size_t index, string file = __FILE__, size_t 
line = __LINE__, Throwable next = null)
     {
         super(msg, file, line, next);
	// in-place conversion of size_t to char[]
     }
	
     void toString(void delegate(const(char)[]) sink) const
     {
         sink(msg);
         sink(" (at index ");
         sink(index_buff);
         sink(")");
     }
}

Benefits: no arbitrary message length limit, no string 
construction unless toString is actually called.


More information about the Digitalmars-d mailing list