From: "Robert I. Eachus" <rieachus@comcast.net>
Subject: Re: strings and multidimensional arrays
Date: Sun, 12 Oct 2003 14:16:38 GMT
Date: 2003-10-12T14:16:38+00:00 [thread overview]
Message-ID: <3F89621F.7070406@comcast.net> (raw)
In-Reply-To: 3F88E586.5060809@chartermi.net
Andrew wrote:
>
> hopefully I don't confuse the situation by adding this, but...
>
> my problem is this .. on a multi-dimensional array .. at any given point
> in that array I can only have on piece of data (ex: blue or X or 65 or
> some other value.. but only one piece of data) I need to store multiple
> pieces of data ..
>
> I'm hoping that when that point on the multi-dimensional array is called
> or looked at, that I can put a string there so in essense I will have
> multiple pieces of data running off of that point.. (if that makes sense).
It can be done, and in fact done pretty cleanly. However, it sounds
like that is not really what you want to do, but a workaround for the
solution you really want.
It sounds like what you would prefer is something like this:
type Contents_Type is (None, Integer_Data, Some_String,
Integer_and_String, Subprogram_Access, ...);
type Contents(CT: Contents_Type := None) is record
case CT is
when None => null;
when Integer_Data => I: Integer;
when Some_String => U: Ada.Strings.Unbounded.Unbounded_String;
when Integer_and_String =>
The_Integer: Integer;
The_String: Ada.Strings.Unbounded.Unbounded_String;
when Subprogram_Access => FP: Function_Pointer;
when ...
end case;
end record;
type Element is record
C: Contents := (CT => None);
end record;
type My_Array is array(Natural range <>; Natural range <>) of Element;
...
A few words of wisdom. If this really is what you want.
1) Keep the actual contents small. That is why I used Unbounded_String
above. It will result in a pointer to the actual data in the record
type, and the actual data being stored on the heap. (The Unbound_String
type will manage the heap storage for the individual values, so you
never have to write an allocator or deallocator.)
The Ada compiler is almost certainly going to "allocate the max," allow
room in every entry for the largest entry. (I believe the Alsys
compiler still supports "mutant" records. That would allow you to use
String for individual components. But it doesn't come for free. The
compiler manages the mutant type without coding effort on your part, but
it still results in extra code, and the overhead of executing it.)
2) Given the above, and that most Ada compilers (and operating systems)
allow you to have a much bigger heap than stack, you may want to store
any actual arrays of this type on the heap. That is, create an access
type that points to one of these arrays, and call new (once) to create
the array.
3) You will probably want to make the actual type an abstract data type
and put the real declarations in the private part of a package, along
with access functions, etc.
4) If you do this, one of the operations you will want for the abstract
data type is a function that displays the contents, of a cell, including
the discriminant.
5) In the variant part(s), if you take this approach, every component
list has to have unique names. But you can have multiple variant parts.
So if you have several Contents_Type for which you want say to have an
integer, you could say inside the record declaration:
case CT is
when Integer_Data | Integer_and_String =>
I: Integer;
when others => null;
end case;
case CT is
when Some_String | Integer_and_String =>
S: Ada.Strings.Unbounded.Unbounded_String;
when others => null;
end case;
case CT is...
Of course, if you do this, making the type an ADT is almost a necessity.
You don't want to deal with unwrapping things in more than one place,
and you will want "inquiry" functions like:
function Contains_Integer (E: Element) return Boolean;
5) Having the Ada Reference Manual handy while you work on this is a
good idea. An up-to-date version on-line can be found at:
http://www.adaic.org/standards/95lrm/html/RM-TOC.html
6) Another approach is to use a tagged type, and have an array of access
values of an access to classwide type. I'll let someone else describe
that approach. But the important thing to remember is that if you do
put all this in a package with Element as a private type, you can switch
between implementations just by replacing the package. (The decision on
whether or not to make the array type private is up to you. I wouldn't,
I'd just hide the details of the various parts of Element. But see
the next item.)
7) Design first! This is a useful pattern to know. The tagged type
approach is a different way to approach the problem. If the
multidimensional array is expected to be sparsely populated there are
other approaches. In fact, if what you are really trying to do is store
data where the presence or absence of each field type is independent,
you may be better off with separate arrays for each datatype. Either of
those cases argues for making the array type abstract as well, and
making the array accesses implicit. If you do a lot of thinking, and
perhaps even write the application that will use the type before
defining the type itself, you can save a lot of coding effort.
8) Good luck.
--
Robert I. Eachus
"Quality is the Buddha. Quality is scientific reality. Quality is the
goal of Art. It remains to work these concepts into a practical,
down-to-earth context, and for this there is nothing more practical or
down-to-earth than what I have been talking about all along...the repair
of an old motorcycle." -- from Zen and the Art of Motorcycle
Maintenance by Robert Pirsig
next prev parent reply other threads:[~2003-10-12 14:16 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-10-12 4:05 strings and multidimensional arrays Andrew
2003-10-12 5:24 ` Andrew
2003-10-12 6:27 ` tmoran
2003-10-12 14:16 ` Robert I. Eachus [this message]
2003-10-12 19:34 ` Jeffrey Carter
2003-10-13 0:02 ` Robert I. Eachus
2003-10-13 3:14 ` Jeffrey Carter
2003-10-13 17:05 ` Robert I. Eachus
2003-10-13 18:49 ` Martin Dowie
2003-10-13 21:47 ` Mark Lorenzen
2003-10-14 1:10 ` Jeffrey Carter
2003-10-14 15:29 ` Robert I. Eachus
2003-10-12 21:01 ` Andrew
2003-10-13 13:59 ` Rodrigo Garcia
-- strict thread matches above, loose matches on Subject: below --
2003-10-14 6:24 christoph.grein
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox