next!T

Andrew Edwards via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Jun 6 19:23:18 PDT 2014


On 5/25/14, 10:12 PM, Ali Çehreli wrote:
> On 05/25/2014 05:21 PM, Andrew Edwards wrote:
>> Hello All,
>>
>> I wrote the following convenience functions to aid in my studies.
>> Unfortunately, I'm using Java books (Ali I will get to yours soon
>> enough) so the need was necessitated by the frequency of use in the
>> examples. Would appreciate a sanity check. Is there something that I
>> should be thinking about am obviously not? Comments/criticisms
>> appreciated.
>>
>> ------------ io.d ------------
>> module io;
>>
>> public import std.stdio;
>>
>> private string buffer;
>>
>> auto next(T)()
>> {
>>      import std.traits;
>>      import std.conv;
>>      import std.string;
>>
>>      if(buffer.length == 0)
>>          buffer = stdin.readln;
>>
>>      static if (isSomeString!T) {
>>          scope (exit) buffer = null;
>>          return buffer.strip;
>>      }
>>      else {
>>          scope (exit) buffer = buffer.strip;
>>          return parse!T(buffer);
>>      }
>> }
>>
>> auto next(T)(string msg)
>> {
>>      if (msg != null)
>>          msg.write;
>>
>>      return next!T;
>> }
>> ------------ End ------------
>>
>> Thanks,
>> Andrew
>
> Works like a charm here! :)
>
> void main()
> {
>      auto s = next!string("What is your name? ");
>      auto i = next!uint("Your age? ");
>      auto a = next!string("Your address? ");
>      auto arr = next!(string[])("Names of your children? ");
>
>      writefln("%s year old %s lives in %s. Children: %s", i, s, a, arr);
> }
>
> Ali
>

So one of the things I really wanted to do is Unicode IO (namely 
Japanese) from the console. I tried using this and quickly realized that 
no considerations were taken. The modified version next(T)() now looks 
like this:

auto next(T)()
{
	import std.traits;
	import std.conv;
	import std.string;
	import std.range;

	if(buffer.length == 0)
		buffer = stdin.readln;

	static if (isSomeString!T) {                     // [1]
		scope (exit) buffer = null;
		return buffer.strip.to!T;
	}
	static if (isSomeChar!T) {
		scope (exit) { buffer.popFront; buffer = buffer.strip; }
		return stride(buffer, 1).array[0].to!T;
	}
	else {
		scope (exit) buffer = buffer.strip;
		return parse!T(buffer);                   // [2] Line 64
	}
}

This function now works for all types except dstring. This remains a 
problem I cannot figure out. The error code is as follows:

$ rdmd -unittest textnext
/usr/share/dmd/src/phobos/std/conv.d(3293): Error: cannot modify 
immutable expression c
/usr/share/dmd/src/phobos/std/conv.d(3297): Error: cannot modify 
immutable expression c
/usr/share/dmd/src/phobos/std/conv.d(2904): Error: template instance 
std.conv.parseElement!(immutable(dchar), string) error instantiating
io.d(64):        instantiated from here: parse!(immutable(dchar)[], string)
textnext.d(12):        instantiated from here: next!(immutable(dchar)[])
io.d(64): Error: template instance std.conv.parse!(immutable(dchar)[], 
string) error instantiating
textnext.d(12):        instantiated from here: next!(immutable(dchar)[])
textnext.d(12): Error: template instance io.next!(immutable(dchar)[]) 
error instantiating
Failed: ["dmd", "-unittest", "-v", "-o-", "textnext.d", "-I."]

This error is report failure on dstring at [2] but I fully expected them 
at [1].

I've looked at implementation of isSomeString() 
(https://github.com/D-Programming-Language/phobos/blob/master/std/traits.d#L5178) 
and clearly dstrings are addressed in the implementation there. What 
exactly am I missing in my understanding?

Any assistance/advice is appreciated.

Thanks,
Andrew


More information about the Digitalmars-d-learn mailing list