digitalmars.D - Some nogc text conversion in Phobos?
- bearophile (55/55) May 28 2014 This is currently accepted code:
- Dicebot (23/79) May 28 2014 IMHO something like this is better:
- Dmitry Olshansky (8/30) May 29 2014 Why not just save 'size_t' right here, and do formattedWrite in the
- Dicebot (2/16) May 29 2014 Yep, you are right.
- bearophile (21/23) May 31 2014 A nothrow @nogc function like the bufferText I've suggested is
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
May 28 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, bearophileIMHO 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.
May 28 2014
29-May-2014 03:52, Dicebot пишет:On Wednesday, 28 May 2014 at 23:27:34 UTC, bearophile wrote:[....]This is currently accepted code:IMHO something like this is better: class MyException : Exception { private char[20] index_buff; // should be enough for size_t.maxWhy not just save 'size_t' right here, and do formattedWrite in the toString? Anyway I think this is what exceptions should do - save the state and only ever format message in toString.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.Yup. -- Dmitry Olshansky
May 29 2014
On Thursday, 29 May 2014 at 18:30:28 UTC, Dmitry Olshansky wrote:29-May-2014 03:52, Dicebot пишет:Yep, you are right.On Wednesday, 28 May 2014 at 23:27:34 UTC, bearophile wrote:[....]This is currently accepted code:IMHO something like this is better: class MyException : Exception { private char[20] index_buff; // should be enough for size_t.maxWhy not just save 'size_t' right here, and do formattedWrite in the toString? Anyway I think this is what exceptions should do - save the state and only ever format message in toString.
May 29 2014
Dicebot:Benefits: no arbitrary message length limit, no string construction unless toString is actually called.A nothrow nogc function like the bufferText I've suggested is also useful in situations like this (currently this can't compile): struct Foo { int[3] data; ref int opIndex(in size_t i) pure nothrow safe nogc in { import std.string: format; assert(i < data.length, format("opIndex, %d >= %d", i, data.length)); } body { return data[i]; } } void main() { Foo f; auto r = f[10]; } Bye, bearophile
May 31 2014