www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - easy way to output a struct?

reply Hoenir <mrmocool gmx.de> writes:
Is there an easy way to output a struct's contents?
e.g. member1: value1, member2: value2, ...
I have a really big struct and formatting it all by hand would be 
time-consuming.
Jan 14 2009
next sibling parent reply "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Wed, Jan 14, 2009 at 4:57 PM, Hoenir <mrmocool gmx.de> wrote:
 Is there an easy way to output a struct's contents?
 e.g. member1: value1, member2: value2, ...
 I have a really big struct and formatting it all by hand would be
 time-consuming.
bearophile has apparently done so in his "libs" but I have no idea where you can download that.
Jan 14 2009
parent bearophile <bearophileHUGS lycos.com> writes:
Jarrett Billingsley:
 bearophile has apparently done so in his "libs" but I have no idea
 where you can download that.
If you use Phobos on D1 the d.string.put/putr to print generic structs, or use a d.templates.Record struct: http://www.fantascienza.net/leonardo/so/libs_d.zip Bye, bearophile
Jan 15 2009
prev sibling parent reply BCS <ao pathlink.com> writes:
Reply to Hoenir,

 Is there an easy way to output a struct's contents?
 e.g. member1: value1, member2: value2, ...
 I have a really big struct and formatting it all by hand would be
 time-consuming.
http://codepad.org/Eu16XqFu
Jan 14 2009
parent reply Hoenir <mrmocool gmx.de> writes:
BCS schrieb:
 http://codepad.org/Eu16XqFu
 
Thank you very much, it works like a charm. I wrote a small function to log whatever object I pass to it: void log(T)(T obj) { static if (is(T == struct) || is(T == class)) { writef("{"); foreach(i,_;obj.tupleof) writefln("%s : %s,", obj.tupleof[i].stringof[4..$], obj.tupleof[i]); writefln("}"); } else { writefln(obj); } } Are there better solutions than this or does it perhaps have any flaws?
Jan 14 2009
parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Thu, 15 Jan 2009 03:04:15 +0300, Hoenir <mrmocool gmx.de> wrote:

 BCS schrieb:
 http://codepad.org/Eu16XqFu
Thank you very much, it works like a charm. I wrote a small function to log whatever object I pass to it: void log(T)(T obj) { static if (is(T == struct) || is(T == class)) { writef("{"); foreach(i,_;obj.tupleof) writefln("%s : %s,", obj.tupleof[i].stringof[4..$], obj.tupleof[i]); writefln("}"); } else { writefln(obj); } } Are there better solutions than this or does it perhaps have any flaws?
One note is that you should probably pass the object by reference: void log(T)(ref T obj) { ... } // D1 void log(T)(ref const(T) obj) { ... } // D2
Jan 15 2009
parent reply Hoenir <mrmocool gmx.de> writes:
Denis Koroskin schrieb:
 One note is that you should probably pass the object by reference:
 
 void log(T)(ref T obj) { ... }        // D1
 void log(T)(ref const(T) obj) { ... } // D2
 
Good idea. btw ref'ing a class has no effect, has it? Actually discovered a flaw, if you e.g. pass an array of structs to it, dmd complains about the struct not having a toString() member. So it needs to be recursive somehow.
Jan 15 2009
next sibling parent reply BCS <ao pathlink.com> writes:
Reply to Hoenir,

 Denis Koroskin schrieb:
 
 One note is that you should probably pass the object by reference:
 
 void log(T)(ref T obj) { ... }        // D1
 void log(T)(ref const(T) obj) { ... } // D2
Good idea. btw ref'ing a class has no effect, has it?
ref object would allow you to alter what the passed in argument is: void Fn(ref object o) { o = null; } object o = new Bah!(); Fn(o); assert(o is null);
 Actually discovered a flaw, if you e.g. pass an array of structs to
 it, dmd complains about the struct not having a toString() member.
 
 So it needs to be recursive somehow.
 
I have a partial solution here: http://www.dsource.org/projects/scrapple/browser/trunk/log_api/LogAPI.d Feel free to steal whatever you want from it. If you are really adventures and want to, I can get you SVN access and you can dump stuff back into that.
Jan 15 2009
next sibling parent Hoenir <mrmocool gmx.de> writes:
BCS schrieb:
 Reply to Hoenir,
 
 Denis Koroskin schrieb:

 One note is that you should probably pass the object by reference:

 void log(T)(ref T obj) { ... }        // D1
 void log(T)(ref const(T) obj) { ... } // D2
Good idea. btw ref'ing a class has no effect, has it?
ref object would allow you to alter what the passed in argument is: void Fn(ref object o) { o = null; } object o = new Bah!(); Fn(o); assert(o is null);
Oh, yeah of course, forgot that. Was just thinking of structs being value and classes being reference types.
Jan 15 2009
prev sibling parent reply Hoenir <mrmocool gmx.de> writes:
BCS schrieb:
 I have a partial solution here:  
 http://www.dsource.org/projects/scrapple/browser/trunk/log_api/LogAPI.d
 
 Feel free to steal whatever you want from it. If you are really 
 adventures and want to, I can get you SVN access and you can dump stuff 
 back into that.
 
Why is that "is" used here: static if(is(a == char*)) I know is is normally used for identity comparison, but what does it do here? Also, I've never seen something like that (I mean that ":"): else static if(is(a : int))
Jan 15 2009
next sibling parent reply "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Thu, Jan 15, 2009 at 6:57 PM, Hoenir <mrmocool gmx.de> wrote:
 Why is that "is" used here:
 static if(is(a == char*))

 I know is is normally used for identity comparison, but what does it do
 here?
is(blah blah) is a completely different thing than "x is y" ;) is() is used to test, at compile time, for some type-related information. It also has some stranger forms that allows it to introduce symbols that are bound to smaller pieces of types (for example, it can be used to get the return type or parameter types of a function or delegate). is(a == char*) returns true if the type 'a' is char*, and false otherwise.
 Also, I've never seen something like that (I mean that ":"):
 else static if(is(a : int))
The : is similar to ==, but means "implicitly." While is(a == int) returns true only if the type 'a' is int, is(a : int) returns true if the type 'a' is _implicitly_ convertible to int, including things like short and dchar.
Jan 15 2009
parent reply Hoenir <mrmocool gmx.de> writes:
Thanks for your explanation.
Is there any good resource about that stuff other than 
http://www.digitalmars.com/d/1.0/template.html
Jan 15 2009
parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Fri, Jan 16, 2009 at 2:46 AM, Hoenir <mrmocool gmx.de> wrote:
 Thanks for your explanation.
 Is there any good resource about that stuff other than
 http://www.digitalmars.com/d/1.0/template.html
Yeah. http://www.digitalmars.com/d/1.0/expression.html#IsExpression
Jan 16 2009
prev sibling parent BCS <ao pathlink.com> writes:
Reply to Hoenir,

 BCS schrieb:
 
 I have a partial solution here:
 http://www.dsource.org/projects/scrapple/browser/trunk/log_api/LogAPI
 .d
 
 Feel free to steal whatever you want from it. If you are really
 adventures and want to, I can get you SVN access and you can dump
 stuff back into that.
 
Why is that "is" used here: static if(is(a == char*)) I know is is normally used for identity comparison, but what does it do here? Also, I've never seen something like that (I mean that ":"): else static if(is(a : int))
the code with some annotations. It should be pointed out that the code is only designed to deal with C types) // If the variable is a C-string, print it as such static if(is(a == char*)) writef(`, "%s"`, t[i][0..strlen(t[i])]); // if the variable is implicitly castable to int print it as such else static if(is(a : int)) writef(", %d", t[i]); // otherwise print the type name and the value (hope write can deal with it) else writef(", [%s]%s", a.stringof,t[i]);
Jan 16 2009
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Hoenir:
 So it needs to be recursive somehow.
The stuff I have linked you is recursive, of course. Bye, bearophile
Jan 15 2009
parent Hoenir <mrmocool gmx.de> writes:
bearophile schrieb:
 Hoenir:
 So it needs to be recursive somehow.
The stuff I have linked you is recursive, of course.
Thanks. That's a whole lot of stuff. Guess I really need to dig deeper into template stuff.
Jan 15 2009