www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to get struct's members ?

reply "bioinfornatics" <bioifornatics fedoraproject.org> writes:
Dear,

I would like to get struct's members and zip them with an action

as

struct A
{
   int a;
   int b;
}

std.range.zip( __traits( allmembers, A ), [(x) => x == 0, (y) =>
y > 3] );

like this i could apply an action to each field.

I tried this:
http://dpaste.dzfl.pl/747799ffa64e

but:
   tuple get by allmembers is not an input rage then i can't to use
zip
   allmembers return both fiels and method while i would like only
fields

thanks
May 22 2014
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
allMembers yields the names of all the members. Try .tupleof on 
an object instead, that might work better.
May 22 2014
prev sibling next sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Friday, 23 May 2014 at 01:17:18 UTC, bioinfornatics wrote:
 Dear,

 I would like to get struct's members and zip them with an action

 as

 struct A
 {
   int a;
   int b;
 }

 std.range.zip( __traits( allmembers, A ), [(x) => x == 0, (y) =>
 y > 3] );

 like this i could apply an action to each field.

 I tried this:
 http://dpaste.dzfl.pl/747799ffa64e

 but:
   tuple get by allmembers is not an input rage then i can't to 
 use
 zip
   allmembers return both fiels and method while i would like 
 only
 fields

 thanks
tupleof will do what you need (mostly). However, I don't think there will be any way to (generically) run-time zip on the members, due to probably type mismatch, and memory layout. In any case, nothing trivial, AFAIK.
May 22 2014
parent reply Philippe Sigaud via Digitalmars-d-learn writes:
On Fri, May 23, 2014 at 8:44 AM, monarch_dodra via Digitalmars-d-learn
<digitalmars-d-learn puremagic.com> wrote:
 On Friday, 23 May 2014 at 01:17:18 UTC, bioinfornatics wrote:
 I would like to get struct's members and zip them with an action
 tupleof will do what you need (mostly). However, I don't think there will be
 any way to (generically) run-time zip on the members, due to probably type
 mismatch, and memory layout. In any case, nothing trivial, AFAIK.
You can define a map-like (or zip-like) template to act on tuples as if they were ranges, but the resulting type will still be a tuple: in general, the members and the delegates associated with them will all have a different type. Bioinfornatics, if you know your struct members are all of the same type, you can 'cast' the tuple as an array by wrapping it in square brackets like this: [ myStruct.tupleof ] and then use the usual range algorithms. If that's not the case, you can create another struct, holding both the original struct and the delegates... I did some generic range-like work on tuples a few years ago. See for example: https://github.com/PhilippeSigaud/dranges/blob/master/tuple.d#L620 Could you explain what you want with more details?
May 23 2014
next sibling parent "bioinfornatics" <bioifornatics fedoraproject.org> writes:
On Friday, 23 May 2014 at 08:20:05 UTC, Philippe Sigaud via
Digitalmars-d-learn wrote:
 On Fri, May 23, 2014 at 8:44 AM, monarch_dodra via 
 Digitalmars-d-learn
 <digitalmars-d-learn puremagic.com> wrote:
 On Friday, 23 May 2014 at 01:17:18 UTC, bioinfornatics wrote:
 I would like to get struct's members and zip them with an 
 action
 tupleof will do what you need (mostly). However, I don't think 
 there will be
 any way to (generically) run-time zip on the members, due to 
 probably type
 mismatch, and memory layout. In any case, nothing trivial, 
 AFAIK.
You can define a map-like (or zip-like) template to act on tuples as if they were ranges, but the resulting type will still be a tuple: in general, the members and the delegates associated with them will all have a different type. Bioinfornatics, if you know your struct members are all of the same type, you can 'cast' the tuple as an array by wrapping it in square brackets like this: [ myStruct.tupleof ] and then use the usual range algorithms. If that's not the case, you can create another struct, holding both the original struct and the delegates... I did some generic range-like work on tuples a few years ago. See for example: https://github.com/PhilippeSigaud/dranges/blob/master/tuple.d#L620 Could you explain what you want with more details?
I would like to create a generic parser for simple case. User provide a sructure to fill: struct A { string a; string b } In another way they are a struct whicg describe how to get start and end section. alias predicate = bool delegate( immutable(ubyte)[] ); struct Statement { immutable bool delegate( immutable(ubyte)[] ) start; immutable bool delegate( immutable(ubyte)[] ) end; immutable bool isOptional; safe nothrow this( in predicate start, in predicate end, isOptional = false ) { this.start = start; this.end = end; this.isOptional = isOptional; } } Like this you could say members a start by and end by a newline Statement sequenceLine = Statement( ( word ) => word[0] >= 'A' && word[0] <= 'z', ( word ) => word[0] == '\n' ); Once all section are delimited give them to eat to a parser. You have not to write a parser for each new file format
May 23 2014
prev sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Friday, 23 May 2014 at 08:20:05 UTC, Philippe Sigaud via 
Digitalmars-d-learn wrote:
 On Fri, May 23, 2014 at 8:44 AM, monarch_dodra via 
 Digitalmars-d-learn
 <digitalmars-d-learn puremagic.com> wrote:
 On Friday, 23 May 2014 at 01:17:18 UTC, bioinfornatics wrote:
 I would like to get struct's members and zip them with an 
 action
 tupleof will do what you need (mostly). However, I don't think 
 there will be
 any way to (generically) run-time zip on the members, due to 
 probably type
 mismatch, and memory layout. In any case, nothing trivial, 
 AFAIK.
You can define a map-like (or zip-like) template to act on tuples as if they were ranges, but the resulting type will still be a tuple: in general, the members and the delegates associated with them will all have a different type. Bioinfornatics, if you know your struct members are all of the same type, you can 'cast' the tuple as an array by wrapping it in square brackets like this: [ myStruct.tupleof ] and then use the usual range algorithms.
One issue with this is that it will allocate a copy of all the elements. This may be fine if the elements are meant for a "read-only" operation. But it won't solve the issue if there are any mutating operations. Just saying.
May 23 2014
prev sibling parent "bioinfornatics" <bioifornatics fedoraproject.org> writes:
On Friday, 23 May 2014 at 01:17:18 UTC, bioinfornatics wrote:
 Dear,

 I would like to get struct's members and zip them with an action

 as

 struct A
 {
   int a;
   int b;
 }

 std.range.zip( __traits( allmembers, A ), [(x) => x == 0, (y) =>
 y > 3] );

 like this i could apply an action to each field.

 I tried this:
 http://dpaste.dzfl.pl/747799ffa64e

 but:
   tuple get by allmembers is not an input rage then i can't to 
 use
 zip
   allmembers return both fiels and method while i would like 
 only
 fields

 thanks
I change a little my mind to ease the usage. Maybe using annotate/attribute on members will be better as: struct A { Parser( start = "( word ) => word[0] == '>'", end = "( word ) => word[0] == '\n'" ) string header; } but it seem we can't use curstom annotation in D and mxin in this case are not easy.
May 23 2014