www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Using std.conv.to with std.typecons.Typedef

reply Saurabh Das <saurabh.das gmail.com> writes:
I am trying to create 2 types which contain integral values but 
should not be compatible with each other. std.typecons.Typedef 
seems perfect for this:

alias QuestionId = Typedef!(long, long.init, "QuestionId");
alias StudentId = Typedef!(long, long.init, "StudentId");

However I'm failing to use using std.conv.to:
QuestionId q = to!QuestionId("34"); <-- gives compile errors

(This is a reduced example, the actual use case is to use std.csv 
to read in a structure from file, which in turn calls to!xyz)

How can I get std.conv to understand std.typecons.Typedef? In 
general, is there a better solution to orthogonal types than 
Typedef?

Thanks,
Saurabh
Jan 11
parent reply Tobi G. <gruen_tobias web.de> writes:
On Monday, 11 January 2016 at 08:03:19 UTC, Saurabh Das wrote:
 How can I get std.conv to understand std.typecons.Typedef?
You can do something like this: QuestionId q = to!(TypedefType!QuestionId)("43");
 In general, is there a better solution to orthogonal types than 
 Typedef?
Typedef is a reasonably solution, for this in my opinion. togrue
Jan 11
parent reply Saurabh Das <saurabh.das gmail.com> writes:
On Monday, 11 January 2016 at 12:01:30 UTC, Tobi G. wrote:
 On Monday, 11 January 2016 at 08:03:19 UTC, Saurabh Das wrote:
 How can I get std.conv to understand std.typecons.Typedef?
You can do something like this: QuestionId q = to!(TypedefType!QuestionId)("43");
 In general, is there a better solution to orthogonal types 
 than Typedef?
Typedef is a reasonably solution, for this in my opinion. togrue
Oh excellent. Yes that works for a standalone conversion. Do you know how I can use this with std.csv? import std.typecons; alias QuestionId = Typedef!(long, long.init, "QuestionId"); alias StudentId = Typedef!(long, long.init, "StudentId"); struct MyStuff { QuestionId q; StudentId s; } void main() { import std.csv, std.stdio, std.algorithm, std.range; File("file.csv").byLine.joiner("\n").csvReader!(MyStuff)(null).array; } This doesn't work. But if MyStuff is defined as: struct MyStuff { int q, s; }, then it works. Any ideas?
Jan 11
parent reply Tobi G. <gruen_tobias web.de> writes:
On Monday, 11 January 2016 at 12:15:55 UTC, Saurabh Das wrote:
 Any ideas?
Yes. Because Typedef is introducing new Types, which csvReader doesn't know what they are, you'll need a little workaround and cast the values yourself. import std.csv, std.stdio, std.algorithm, std.range; enum csvTxt = "10, 20 30, 40 50, 50"; myStuff = csvTxt.csvReader!(Tuple!(long, long)) .map!(a => MyStuff(cast(QuestionId)a[0], cast(StudentId) a[1])) .array; The .map does nothing other as getting the information out of the Tuple 'a' and constructing a struct of the type MyStuff. togrue
Jan 11
parent Saurabh Das <saurabh.das gmail.com> writes:
On Monday, 11 January 2016 at 12:59:05 UTC, Tobi G. wrote:
 On Monday, 11 January 2016 at 12:15:55 UTC, Saurabh Das wrote:
 Any ideas?
Yes. Because Typedef is introducing new Types, which csvReader doesn't know what they are, you'll need a little workaround and cast the values yourself. import std.csv, std.stdio, std.algorithm, std.range; enum csvTxt = "10, 20 30, 40 50, 50"; myStuff = csvTxt.csvReader!(Tuple!(long, long)) .map!(a => MyStuff(cast(QuestionId)a[0], cast(StudentId) a[1])) .array; The .map does nothing other as getting the information out of the Tuple 'a' and constructing a struct of the type MyStuff. togrue
Yes that does make sense. I could read in a POD struct and convert it to a typed one. Though I was hoping for a more elegant solution... This'll have to do I guess. Thanks!
Jan 11