Help: Dynamic-size arrays using record discriminant. 
Author Message
 Help: Dynamic-size arrays using record discriminant.

-- I have this problem:
-- There is a record with a discriminant (and a default value to the
-- discriminant). The record contains a constrained array, and the range

-- of the array depends on the discriminant. For example:

procedure PROBLEM is

        type ARRAY_TYPE  is array (INTEGER range <>) of NATURAL;
        type RECORD_TYPE (SIZE: INTEGER:= 5) is
                record
                        VECTOR: ARRAY_TYPE (1..SIZE);
                end record;

-- Now, I have a variable with the record type:
        REC: RECORD_TYPE;
        TEMP: RECORD_TYPE;  -- This variable will be explained later.

-- The question is how do I change the array size (i.e, the discriminant

-- value) WITHOUT loosing its current content.

-- For example, lets say it was filled with values:

begin
    for I in REC.VECTOR'RANGE loop
                REC.VECTOR(I):= I;
    end loop;

-- Now the array contains the values 1, 2, 3, 4 and 5. Lets say I want
to
-- enlarge the array to 6 cells. Theoretically, I can do this:

    REC:= (SIZE => 6, VECTOR => (1, 2, 3, 4, 5, 0));

-- But lets say I don't know the content of the first five cells (for
example,
-- they came from input). I must give SOME value to "VECTOR" (otherwise
it's
-- not a complete aggregate). Of course, I can do something like this:

        REC:= (SIZE => 6, VECTOR => (others => 0));

-- ...but then I loose the original content of the array!

-- The only solution I could come up with is quite a shabby one. It goes

-- like this:

        TEMP:= (SIZE => 6, VECTOR => (others => 0));          -- Copying
the original

-- array into a

-- temporary array.
        TEMP.VECTOR(REC.VECTOR'RANGE):= REC.VECTOR;  -- Enlarging the

-- original

-- array.
        REC:= (SIZE => 6, VECTOR => TEMP.VECTOR);    -- Copying the
temporary

-- array into the

-- original array.

-- It's working but it's ugly. Is there a better way?

-- If you have an idea, please help!
-- Thanks!

end PROBLEM;



Tue, 27 Mar 2001 03:00:00 GMT  
 Help: Dynamic-size arrays using record discriminant.

Quote:

> -- I have this problem:
> -- There is a record with a discriminant (and a default value to the
> -- discriminant). The record contains a constrained array, and the range
> -- of the array depends on the discriminant. For example:

> procedure PROBLEM is

>         type ARRAY_TYPE  is array (INTEGER range <>) of NATURAL;
>         type RECORD_TYPE (SIZE: INTEGER:= 5) is
>                 record
>                         VECTOR: ARRAY_TYPE (1..SIZE);
>                 end record;

> -- Now, I have a variable with the record type:
>         REC: RECORD_TYPE;
>         TEMP: RECORD_TYPE;  -- This variable will be explained later.

> -- The question is how do I change the array size (i.e, the discriminant

> -- value) WITHOUT loosing its current content.

   [text snipped]

Quote:
> Of course, I can do something like this:

>         REC:= (SIZE => 6, VECTOR => (others => 0));

You can do

    REC := (SIZE => 6, VECTOR => REC.VECTOR & (6 => 0));

However, the compiler is likely to generate a temporary and
copy VECTOR contents back and forth. If this is performance-
critical, you should perhaps consider other data structures
where existing VECTOR data remain in place. For example, the
SIZE could be an ordinary component, instead of a discriminant.
You must then constrain the VECTOR component to some assumed
maximum size.

You should anyway constrain the SIZE discriminant, since some
compilers will allocate RECORD_TYPE memory for the maximum
possible SIZE value (integer'last in your code).

- Niklas



Thu, 29 Mar 2001 03:00:00 GMT  
 Help: Dynamic-size arrays using record discriminant.

   -- I have this problem:
   -- There is a record with a discriminant (and a default value to the
   -- discriminant). The record contains a constrained array, and the range
   -- of the array depends on the discriminant. For example:

   -- The question is how do I change the array size (i.e, the discriminant
   -- value) WITHOUT loosing its current content...

   Easy, make the discriminant an element of the record.

   If you insist on being clever, do the following.  First insure that
your compiler actually allocates the maximum size necessary for the
largest possible value of the object.  Next, declare a type which
overlays exactly the discriminated record type, but where the
discriminant is replaced by a array component.  Now use address
clauses to do the aliasing and do what you want...

   Or you can just realize that some compilers will create the objects
in a way that requires hidden heap allocations and pointers, and from
the fact that your declarations:

        type ARRAY_TYPE  is array (INTEGER range <>) of NATURAL;
        type RECORD_TYPE (SIZE: INTEGER:= 5) is
                record
                        VECTOR: ARRAY_TYPE (1..SIZE);
                end record;

    don't lead to a compiler warning, that you are using such an
implementation.  So not only is it necessary to copy the old value to
the new object, but a clever compiler will (depending on how you write
the code) optimize away the "extra" copy.
--

                                        Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...



Sat, 31 Mar 2001 03:00:00 GMT  
 Help: Dynamic-size arrays using record discriminant.


Quote:
>-- I have this problem:

I believe this will work:

    procedure PROBLEM is

        type ARRAY_TYPE  is array (INTEGER range <>) of NATURAL;
        type RECORD_TYPE (SIZE: INTEGER:= 5) is
                record
                        VECTOR: ARRAY_TYPE (1..SIZE);
                end record;
        REC: RECORD_TYPE;
             -- SIZE will be 5 by default
             -- enough space will be allocated by many compilers
             --  to hold largest possible value, i.e. with
             --  SIZE=integer'last
    begin
        -- * * *
         -- REC gets initial values somehow
        -- * * *

        -- add New_Value to the end of Rec
        Rec :=
            (SIZE => SIZE + 1,
             VECTOR => (VECTOR'RANGE
                         => VECTOR (VECTOR'FIRST..VECTOR'LAST),
                        VECTOR'LAST + 1 => New_Value));

Best,
Sam Mize

--

Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam



Tue, 03 Apr 2001 03:00:00 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. Help with a constant of a discriminant record type

2. Dynamic Array Sizing

3. An array of records within an array of records (Still a problem)

4. an array of records within an array of records

5. Dynamic array size reallocation

6. Dynamic Array Sizes in CVF 5.0?

7. Dynamic array sizing

8. Dynamic Array of Record

9. dynamic arrays in a record ?

10. aliased discriminant record components

11. GNAT's internal format for Discriminant Records?

12. Packing Records Using Size Attribute Definitions Clauses

 

 
Powered by phpBB® Forum Software