Index

Package: DDS_Support.Sequences_Generic

Description

generic
   type Element is limited private;
   type Element_Access is access all Element;
   type Index_Type is range <>;
   First_Element : Index_Type;
   type Element_Array is array (Index_Type range <>) of aliased Element;
   with procedure Initialize (Self  : in out Element) is <>;
   with procedure Finalize (Self  : in out Element) is <>;
   with procedure Copy (Dst : in out Element; Src : in Element) is <>;

--  FooSeq
package DDS_Support.Sequences_Generic is

Types

Element

type Element is limited private;

Element_Access

type Element_Access is access all Element;

Index_Type

type Index_Type is range <>;

Element_Array

type Element_Array is array (Index_Type range <>) of aliased Element;

Memory_Element_Pointer

type Memory_Element_Pointer  is
     array (First_Element .. Index_Type'Last) of aliased Element_Access;

Memory_Element_Array

subtype Memory_Element_Array is
     Element_Array (First_Element .. Index_Type'Last);

Memory_Element_Array_Pointer

type Memory_Element_Array_Pointer is access all Memory_Element_Array with
     Storage_Size => 0;

Element_Array_Access

type Element_Array_Access is access all Element_Array  with
     Storage_Size => 0;

NElement_Access

type NElement_Access is new Element_Access;

Memory_Element_Pointer_Access

type Memory_Element_Pointer_Access is access all Memory_Element_Pointer with
     Storage_Size => 0;

SeqElementTypeAllocationParams

type SeqElementTypeAllocationParams is record
      Allocate_Pointers         : aliased Boolean := True;
      Allocate_Optional_Members : aliased Boolean := True;
      Allocate_Memory           : aliased Boolean := True;
   end record
     with Convention => C;

SeqElementTypeDeallocationParams

type SeqElementTypeDeallocationParams is record
      Delete_Pointers         : aliased Boolean := True;
      Delete_Optional_Members : aliased Boolean := True;
   end record
     with Convention => C;

Sequence

type Sequence is record
      Contiguous_Buffer        : Memory_Element_Array_Pointer;
      Discontiguous_Buffer     : Memory_Element_Pointer_Access;
      Read_Token1              : System.Address := System.Null_Address;
      Read_Token2              : System.Address := System.Null_Address;
      Maximum                  : aliased Index_Type := 0;
      Length                   : aliased Index_Type := 0;
      Sequence_Init            : aliased Integer := SEQUENCE_MAGIC_NUMBER;
      Owned                    : aliased Boolean := True;
      ElementAllocParams       : aliased SeqElementTypeAllocationParams;
      Absolute_Maximum         : aliased Index_Type := Index_Type'Last;
      ElementDeallocParams     : aliased SeqElementTypeDeallocationParams;
   end record with

Sequence_Access

type Sequence_Access is access all Sequence;

Constants & Global variables

First_Element (Index_Type)

First_Element : Index_Type;

SEQUENCE_MAGIC_NUMBER

SEQUENCE_MAGIC_NUMBER : constant := 16#7344#;
<TBD>

SEQUENCE_UNINITIALIZED

SEQUENCE_UNINITIALIZED : exception;

SEQUENCE_ERROR

SEQUENCE_ERROR : exception;

DEFAULT_SEQUENCE (Sequence)

DEFAULT_SEQUENCE : aliased constant Sequence := (others => <>);

Subprograms & Entries

Initialize

with procedure Initialize 
(Self: in out Element) is <>;

Finalize

with procedure Finalize 
(Self: in out Element) is <>;

Copy

with procedure Copy 
(Dst: in out Element;
Src: in Element) is <>;

I_First_Element

function I_First_Element 
(Self: Sequence) return Index_Type;

I_Next

function I_Next 
(Self: Sequence;
C: Index_Type) return Index_Type;

I_Has_Element

function I_Has_Element 
(Self: Sequence;
C: Index_Type) return Standard.Boolean;

I_Get_Element

function I_Get_Element 
(Self: Sequence;
C: Index_Type) return Element_Access;

Initialize

procedure Initialize 
(Self: not null access Sequence);

Summary: Initialize sequence instances.

Use this function to initialize new sequences to a valid empty state. C users should initialize sequences before using them.

self: <<in>> Cannot be NULL


See also: DDS_SEQUENCE_INITIALIZER

Get_Reference

function Get_Reference 
(Self: not null access constant Sequence;
Index: Index_Type) return Element_Access;

Summary: Get the pointer to the i-th element of this sequence.

This operation can used to modify the elements of the sequence in place.

self: <<in>> Cannot be NULL

i: index of element to access, must be >= 1 and less than FooSeq::length()

Returns: a pointer to the i-th element

Set_Element

procedure Set_Element 
(Self: not null access Sequence;
Index: Index_Type;
Elt: Element);

Append

procedure Append 
(Self: not null access Sequence;
Elt: Element);

Iterate

procedure Iterate 
(Self: not null access Sequence;
Handle: not null access procedure (continue : in out Boolean;
elt: Element_Access));

Get

function Get 
(Self: not null access constant Sequence;
Index: Index_Type) return Element;

Summary: Get the i-th element for a const sequence.

self: <<in>> Cannot be NULL

i: index of element to access, must be >= 1 and less than FooSeq::length()

Returns: the i-th element

Get_Element_Pointers_Allocation

function Get_Element_Pointers_Allocation 
(Self: not null access constant Sequence) return Boolean;

Set_Element_Pointers_Allocation

procedure Set_Element_Pointers_Allocation 
(Self: not null access Sequence;
Allocate_Pointers: in Boolean);

Get_Maximum

function Get_Maximum 
(Self: not null access constant Sequence) return Index_Type;

Summary: Get the current maximum number of elements that can be stored in this sequence.

The maximum of the sequence represents the maximum number of elements that the underlying buffer can hold. It does not represent the current number of elements.

The maximum is a non-negative number. It is initialized when the sequence is first created.

The maximum can be changed implicitly by adding an element to the sequence with add(), or explicitly by calling FooSeq::maximum(DDS_Long).

self: <<in>> Cannot be NULL

Returns: the current maximum of the sequence.


See also: FooSeq::length()

Set_Maximum

procedure Set_Maximum 
(Self: not null access Sequence;
New_Max: in Index_Type);

Summary: Resize this sequence to a new desired maximum.

This operation does nothing if the new desired maximum matches the current maximum.

Note: If you add an element with add(), the sequence's size is increased implicitly.

Postcondition: length == MINIMUM(original length, new_max)

self: <<in>> Cannot be NULL

new_max: Must be >= 0.

Get_Length

function Get_Length 
(Self: not null access constant Sequence) return Index_Type;

Summary: Get the logical length of this sequence.

Get the length that was last set, or zero if the length has never been set.

self: <<in>> Cannot be NULL

Returns: the length of the sequence

Set_Length

procedure Set_Length 
(Self: not null access Sequence;
New_Length: in Index_Type);

Summary: Change the length of this sequence.

This procedure does not allocate/deallocate memory.

The new length must not exceed the maximum of this sequence as returned by the FooSeq::maximum() operation. (Note that, if necessary, the maximum of this sequence can be increased manually by using the FooSeq::maximum(DDS_Long) operation.)

The elements of the sequence are not modified by this operation. If the new length is larger than the original length, the new elements will be uninitialized; if the length is decreased, the old elements that are beyond the new length will physically remain in the sequence but will not be accessible.

Postcondition: length = new_length.

self: <<in>> Cannot be NULL

new_length: the new desired length. This value must be non-negative and cannot exceed maximum of the sequence. In other words 0 <= new_length <= maximum

Returns: DDS.BOOLEAN_TRUE on success or DDS.BOOLEAN_FALSE on failure

Ensure_Length

procedure Ensure_Length 
(Self: not null access Sequence;
Length: in Index_Type;
Max: in Index_Type);

Summary: Set the sequence to the desired length, and resize the sequence if necessary.

If the current maximum is greater than the new length, then the sequence is not resized.

Otherwise, if this sequence owns its buffer, the sequence is resized to the new maximum by freeing and re-allocating the buffer, and the length is set to the new length. However, if the sequence does not own its buffer, this operation will fail.

This function allows user to avoid unnecessary buffer re-allocation.

Precondition: length <= max

Precondition: max <= maximum size for IDL bounded sequences

Precondition: owned == DDS.BOOLEAN_TRUE if sequence needs to be resized

Postcondition: length == length

Postcondition: maximum == max if resized

self: <<in>> Cannot be NULL

length: <<in>> The new length that should be set. Must be >= 0.

max: <<in>> If sequence need to be resized, this is the maximum that should be set. max >= length

Returns: DDS.BOOLEAN_TRUE on success, DDS.BOOLEAN_FALSE if the preconditions are not met. In that case the sequence is not modified.

Copy_No_Alloc

procedure Copy_No_Alloc 
(Self: not null access Sequence;
Src: not null access constant Sequence);

Summary: Copy elements from another sequence, only if the destination sequence has enough capacity.

Fill the elements in this sequence by copying the corresponding elements in src_seq. The original contents in this sequence are replaced via the element assignment operation (Foo_copy() function). By default, elements are discarded; 'delete' is not invoked on the discarded elements.

Precondition: this::maximum >= src_seq::length

Precondition: this::owned == DDS.BOOLEAN_TRUE

Postcondition: this::length == src_seq::length

Postcondition: this[i] == src_seq[i] for 0 <= i < target_seq::length

Postcondition: this::owned == DDS.BOOLEAN_TRUE

self: <<in>> Cannot be NULL

src_seq: <<in>> the sequence from which to copy

Returns: DDS.BOOLEAN_TRUE if the sequence was successfully copied; DDS.BOOLEAN_FALSE otherwise.

Note: If the pre-conditions are not met, the operator will print a message to stdout and leave this sequence unchanged.


See also: FooSeq::operator=

Copy

procedure Copy 
(Self: not null access Sequence;
Src: not null access constant Sequence);

Summary: Copy elements from another sequence, resizing the sequence if necessary.

This procedure invokes FooSeq.copy_no_alloc after ensuring that the sequence has enough capacity to hold the elements to be copied.

self: <<in>> Cannot be NULL

src_seq: <<in>> the sequence from which to copy


See also: FooSeq.copy_no_alloc

From_Array

procedure From_Array 
(Self: not null access Sequence;
Src: in Element_Array);

Summary: Copy elements from an array of elements, resizing the sequence if necessary. The original contents of the sequence (if any) are replaced.

Fill the elements in this sequence by copying the corresponding elements in array. The original contents in this sequence are replaced via the element assignment operation (Foo_copy() function). By default, elements are discarded; 'delete' is not invoked on the discarded elements.

Precondition: this::owned == DDS.BOOLEAN_TRUE

Postcondition: this::length == length

Postcondition: this[i] == array[i] for 0 <= i < length

Postcondition: this::owned == DDS.BOOLEAN_TRUE

self: <<in>> Cannot be NULL

array: <<in>> The array of elements to be copy elements from

length: <<in>> The length of the array.

Returns: DDS.BOOLEAN_TRUE if the array was successfully copied; DDS.BOOLEAN_FALSE otherwise.

Note: If the pre-conditions are not met, the procedure will print a message to stdout and leave this sequence unchanged.

To_Array

procedure To_Array 
(Self: not null access constant Sequence;
Target: out Element_Array);

Summary: Copy elements to an array of elements. The original contents of the array (if any) are replaced.

Copy the elements of this sequence to the corresponding elements in the array. The original contents of the array are replaced via the element assignment operation (Foo_copy() function). By default, elements are discarded; 'delete' is not invoked on the discarded elements.

self: <<in>> Cannot be NULL

array: <<in>> The array of elements to be filled with elements from this sequence

length: <<in>> The number of elements to be copied.

Returns: DDS.BOOLEAN_TRUE if the elements of the sequence were successfully copied; DDS.BOOLEAN_FALSE otherwise.

To_Array

function To_Array 
(Self: not null access constant Sequence) return Element_Array;
Convert elements to an array of elements.

Loan_Contiguous

procedure Loan_Contiguous 
(Self: not null access Sequence;
Buffer: not null access Element_Array;
New_Length: in Index_Type;
New_Max: in Index_Type);

Summary: Loan a contiguous buffer to this sequence.

This operation changes the owned flag of the sequence to DDS.BOOLEAN_FALSE and also sets the underlying buffer used by the sequence. See the User's Manual for more information about sequences and memory ownership.

Use this procedure if you want to manage the memory used by the sequence yourself. You must provide an array of elements and integers indicating how many elements are allocated in that array (i.e. the maximum) and how many elements are valid (i.e. the length). The sequence will subsequently use the memory you provide and will not permit it to be freed by a call to FooSeq::maximum(DDS_Long).

new_length: The desired new length for the sequence.


See also: FooSeq.unloan , FooSeq.loan_discontiguous

Loan_Discontiguous

procedure Loan_Discontiguous 
(Self: access Sequence;
Buffer: not null access Element_Access;
New_Length: in Index_Type;
New_Max: in Index_Type);

Summary: Loan a discontiguous buffer to this sequence.

This procedure is exactly like FooSeq.loan_contiguous except that the buffer loaned is an array of Foo pointers, not an array of Foo.

self: <<in>> Cannot be NULL

buffer: The new buffer that the sequence will use. Must point to enough memory to hold new_max elements of type Foo*. It may be NULL if new_max == 0.

new_length: The desired new length for the sequence. It must be the case that that 0 <= new_length <= new_max.

new_max: The allocated number of elements that could fit in the loaned buffer.


See also: FooSeq.unloan, FooSeq.loan_contiguous

Unloan

procedure Unloan  
(Self: not null access Sequence);

Summary: Return the loaned buffer in the sequence and set the maximum to 0.

This procedure affects only the state of this sequence; it does not change the contents of the buffer in any way.

Only the user who originally loaned a buffer should return that loan, as the user may have dependencies on that memory known only to them. Unloaning someone else's buffer may cause unspecified problems. For example, suppose a sequence is loaning memory from a custom memory pool. A user of the sequence likely has no way to release the memory back into the pool, so unloaning the sequence buffer would result in a resource leak. If the user were to then re-loan a different buffer, the original creator of the sequence would have no way to discover, when freeing the sequence, that the loan no longer referred to its own memory and would thus not free the user's memory properly, exacerbating the situation and leading to undefined behavior.

Precondition: owned == DDS.BOOLEAN_FALSE

Postcondition: owned == DDS.BOOLEAN_TRUE

Postcondition: maximum == 0

self: <<in>> Cannot be NULL


See also: FooSeq.loan_contiguous, FooSeq.loan_discontiguous, FooSeq::maximum(DDS_Long)

Has_Ownership

function Has_Ownership 
(Self: not null access constant Sequence) return Boolean;

Summary: Return the value of the owned flag.

self: <<in>> Cannot be NULL

Returns: DDS.BOOLEAN_TRUE if sequence owns the underlying buffer, or DDS.BOOLEAN_FALSE if it has an outstanding loan.

Finalize

procedure Finalize 
(Self: not null access Sequence);

Summary: Deallocate this sequence's buffer.

Precondition: (owned == DDS.BOOLEAN_TRUE). If this precondition is not met, no memory will be freed and an error will be logged.

self: <<in>> Cannot be NULL

Postcondition: maximum == 0 and the underlying buffer is freed.


See also: FooSeq::maximum(), FooSeq.unloan

Check_InvariantsI

procedure Check_InvariantsI 
(Self: not null access constant Sequence;
Calling_Function: Standard.String := GNAT.Source_Info.Enclosing_Entity);

Check_InitI

procedure Check_InitI 
(Self: not null access constant Sequence);

Copy_No_AllocI

procedure Copy_No_AllocI 
(Self: not null access Sequence;
Src: not null access constant Sequence);

Get_Read_TokenI

procedure Get_Read_TokenI 
(Self: not null access constant Sequence;
Token1: not null access System.Address;
Token2: not null access System.Address);

Set_Read_TokenI

procedure Set_Read_TokenI 
(Self: not null access Sequence;
Token1: in System.Address;
Token2: in System.Address);

Get_Contiguous_BufferI

function Get_Contiguous_BufferI  
(Self: not null access constant Sequence) return access Memory_Element_Array;

Summary: Return the contiguous buffer of the sequence.

Get the underlying buffer where contiguous elements of the sequence are stored. The size of the buffer matches the maximum of the sequence, but only the elements up to the FooSeq::length() of the sequence are valid.

This procedure provides almost no encapsulation of the sequence's underlying implementation. Certain operations, such as FooSeq::maximum(DDS_Long), may render the buffer invalid. In light of these caveats, this operation should be used with care.

self: <<in>> Cannot be NULL

Returns: buffer that stores contiguous elements in sequence.

Get_DisContiguous_BufferI

function Get_DisContiguous_BufferI 
(Self: not null access constant Sequence) return access Memory_Element_Pointer;

Summary: Return the discontiguous buffer of the sequence.

This operation returns the underlying buffer where discontiguous elements of the sequence are stored. The size of the buffer matches the maximum of this sequence, but only the elements up to the FooSeq::length() of the sequence are valid.

The same caveats apply to this procedure as to FooSeq.get_contiguous_buffer.

The sequence will dereference pointers in the discontiguous buffer to provide access to its elements by value in C and by reference in C++. If you access the discontiguous buffer directly by means of this procedure, do not store any NULL values into it, as acessing those values will result in a segmentation fault.

self: <<in>> Cannot be NULL

Returns: buffer that stores discontiguous elements in sequence.