www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Pretty print struct field values

reply Andrej Mitrovic <none none.none> writes:
This keeps popping up in my posts. Here's an example of printing out fields of
a struct with its names:

import std.stdio;

void main()
{
    struct ASIOChannelInfo
    {
        int channel;
        int isInput;
        int isActive;
        int channelGroup;
        int type;
        string name;
    }

    auto info = ASIOChannelInfo(1, 1, 1, 16, 32, "Analog OUT");

    auto fields = __traits(allMembers, typeof(info));
    auto values = info.tupleof;

    foreach (index, value; values)
    {
        writef("\n%-15s %s", fields[index], value);
    }
}

Prints:
channel           1
isInput            1
isActive           1
channelGroup 16
type             32
name            Analog OUT

I think we could a function in Phobos that does this with a single call. Maybe
it could also determine the longest field name and calculate the width
specifier for the formatted output so it prints out the columns nicely. It
should probably also avoid printing functions. Anyone interested in this type
of function? I could give it a shot and implement it.

Btw, is there a lockstep implementation that works with tuples?
Apr 24 2011
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-04-24 23:11, Andrej Mitrovic wrote:
 This keeps popping up in my posts. Here's an example of printing out fields of
a struct with its names:

 import std.stdio;

 void main()
 {
      struct ASIOChannelInfo
      {
          int channel;
          int isInput;
          int isActive;
          int channelGroup;
          int type;
          string name;
      }

      auto info = ASIOChannelInfo(1, 1, 1, 16, 32, "Analog OUT");

      auto fields = __traits(allMembers, typeof(info));
      auto values = info.tupleof;

      foreach (index, value; values)
      {
          writef("\n%-15s %s", fields[index], value);
      }
 }

 Prints:
 channel           1
 isInput            1
 isActive           1
 channelGroup 16
 type             32
 name            Analog OUT

 I think we could a function in Phobos that does this with a single call. Maybe
it could also determine the longest field name and calculate the width
specifier for the formatted output so it prints out the columns nicely. It
should probably also avoid printing functions. Anyone interested in this type
of function? I could give it a shot and implement it.

 Btw, is there a lockstep implementation that works with tuples?

I think it's a good idea. If __traits(allMembers) returns both method and field names then you can use Type.tupleof[0].stringof. -- /Jacob Carlborg
Apr 25 2011
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2011-04-25 18:47, Andrej Mitrovic wrote:
 Good idea. .tupleof seems to avoid collecting functions which is
 perfect. Here's a quick implementation:

 http://codepad.org/lSDTFd7E

 The only issue I have left is that the function that prints the code
 doesn't really know what the variable was named in the calling code.

I'm not sure I understand but do you want to print "properties" in this case?
 As an alternative I could pass "myvar.stringof" and it would print its
 name before all field names instead of the type name.

 Btw, it seems CTFE doesn't work with this syntax:
 foreach (index; 0..100)

 But it does work with this syntax:
 foreach (index, value; values)

-- /Jacob Carlborg
Apr 25 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 4/25/11, Jacob Carlborg <doob me.com> wrote:
 I'm not sure I understand but do you want to print "properties" in this
 case?

Yeah.
Apr 25 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Good idea. .tupleof seems to avoid collecting functions which is
perfect. Here's a quick implementation:

http://codepad.org/lSDTFd7E

The only issue I have left is that the function that prints the code
doesn't really know what the variable was named in the calling code.

As an alternative I could pass "myvar.stringof" and it would print its
name before all field names instead of the type name.

Btw, it seems CTFE doesn't work with this syntax:
foreach (index; 0..100)

But it does work with this syntax:
foreach (index, value; values)
Apr 25 2011