www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - filling an array of structures

reply Brad <brad.lanam.comp_nospam nospam_gmail.com> writes:
Given an array of structures that you need to populate.
Also assume the structure is quite large and has many
elements to fill in.

S s[];
while (something) {
  s.length += 1;
  auto sp = &s[$-1];   // method 1
  sp.a = 1;
  ...
  with (s[$-1]) {   // method 2
    a = 1;
  }
  ...
  foreach (ref sp; s[$-1..$]) {  // method 3
    sp.a = 1;
  }
}

I don't mind 'with' statements, but they have a readability and
maintenance problem if their scope is large.  The reader would have
to be aware of the context of the structure and the local variables,
whereas 'sp.a' is self documenting.

method 3 is fine, and provides me with a reference to s[$-1],
but I'd really like to have:
   auto sp = ref s[$-1];  // possible method 4
where sp is a reference, but no pointer arithmetic can be done on it.

Another alternative would be runtime aliases.
   alias s[$-1] as sp;
Or
   sp = with (s[$-1]); // I don't much like this syntax...

In the meantime, I'll go with method 1.

  -- Brad
Jan 10 2011
next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 11 Jan 2011 00:39:55 -0500, Brad  
<brad.lanam.comp_nospam nospam_gmail.com> wrote:

 Given an array of structures that you need to populate.
 Also assume the structure is quite large and has many
 elements to fill in.

 S s[];
 while (something) {
   s.length += 1;
   auto sp = &s[$-1];   // method 1
   sp.a = 1;
   ...
   with (s[$-1]) {   // method 2
     a = 1;
   }
   ...
   foreach (ref sp; s[$-1..$]) {  // method 3
     sp.a = 1;
   }
 }

 I don't mind 'with' statements, but they have a readability and
 maintenance problem if their scope is large.  The reader would have
 to be aware of the context of the structure and the local variables,
 whereas 'sp.a' is self documenting.

 method 3 is fine, and provides me with a reference to s[$-1],
 but I'd really like to have:
    auto sp = ref s[$-1];  // possible method 4
 where sp is a reference, but no pointer arithmetic can be done on it.

 Another alternative would be runtime aliases.
    alias s[$-1] as sp;
 Or
    sp = with (s[$-1]); // I don't much like this syntax...

 In the meantime, I'll go with method 1.

What about: S sp; sp.a = 1; s ~= sp; Or if you have a constructor for S, or a is the only member in it: s ~= S(1); -Steve
Jan 11 2011
prev sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
Brad wrote:
 Given an array of structures that you need to populate.
 Also assume the structure is quite large and has many
 elements to fill in.

 S s[];
 while (something) {
   s.length += 1;
   auto sp = &s[$-1];   // method 1
   sp.a = 1;
   ...
   with (s[$-1]) {   // method 2
     a = 1;
   }
   ...
   foreach (ref sp; s[$-1..$]) {  // method 3
     sp.a = 1;
   }
 }

 I don't mind 'with' statements, but they have a readability and
 maintenance problem if their scope is large.  The reader would have
 to be aware of the context of the structure and the local variables,
 whereas 'sp.a' is self documenting.

 method 3 is fine, and provides me with a reference to s[$-1],
 but I'd really like to have:
    auto sp = ref s[$-1];  // possible method 4
 where sp is a reference, but no pointer arithmetic can be done on it.

 Another alternative would be runtime aliases.
    alias s[$-1] as sp;
 Or
    sp = with (s[$-1]); // I don't much like this syntax...

 In the meantime, I'll go with method 1.

   -- Brad

I've been using a method in C++, which involves boost::shared_ptr boost::enable_from_shared boost::list_of That was useful when objects had both some required and some optional properties. Anyway... If polymorphism is not needed something similar can be achieved very simply in D: S[] esses = [ S(42), S(100).optional(3) ]; The whole code: import std.stdio; import std.string; struct S { int must_have_; int optional_; this(int must_have) { must_have_ = must_have; } ref S optional(int optional_arg) { optional_ = optional_arg; return this; } string toString() const { return format("%s.%s", must_have_, optional_); } } void main() { S[] esses = [ S(42), S(100).optional(3) ]; writeln(esses); } Ali
Jan 11 2011