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
type Element_Access is access all Element;
type Element_Array is array (Index_Type range <>) of aliased Element;
type Memory_Element_Pointer is array (First_Element .. Index_Type'Last) of aliased Element_Access;
subtype Memory_Element_Array is Element_Array (First_Element .. Index_Type'Last);
type Memory_Element_Array_Pointer is access all Memory_Element_Array with Storage_Size => 0;
type Element_Array_Access is access all Element_Array with Storage_Size => 0;
type NElement_Access is new Element_Access;
type Memory_Element_Pointer_Access is access all Memory_Element_Pointer with Storage_Size => 0;
type Sequence is record Owned : aliased Boolean := True; Contiguous_Buffer : aliased Memory_Element_Array_Pointer := null; Discontiguous_Buffer : aliased Memory_Element_Pointer_Access := null; Maximum : aliased Index_Type := 0; Length : aliased Index_Type := 0; Sequence_Init : aliased Integer := SEQUENCE_MAGIC_NUMBER; Read_Token1 : aliased System.Address := System.Null_Address; Read_Token2 : aliased System.Address := System.Null_Address; ElementPointersAllocation : aliased RTIDDS.Low_Level.dds_c.sequence_h.DDS_SeqElementTypeAllocationParams_t := (1, 1, 1); ElementDeallocParams : aliased RTIDDS.Low_Level.dds_c.sequence_h.DDS_SeqElementTypeDeallocationParams_t := (1, 1); Absolute_Maximum : aliased Index_Type := Index_Type'Last; end record with
type Sequence_Access is access all Sequence;
First_Element : Index_Type;
DEFAULT_SEQUENCE : aliased constant Sequence := (Owned => True, Contiguous_Buffer => null, Discontiguous_Buffer => null, Maximum => 0, Length => 0, Sequence_Init => SEQUENCE_MAGIC_NUMBER, Read_Token1 => System.Null_Address, Read_Token2 => System.Null_Address, ElementPointersAllocation => (1, 1, 1), ElementDeallocParams => (1, 1), Absolute_Maximum => Index_Type'Last);
with procedure Initialize
( | Self | : in out Element) is <>; |
with procedure Finalize
( | Self | : in out Element) is <>; |
function I_First_Element
( | Self | : Sequence) return Index_Type; |
function I_Next
( | Self | : Sequence; |
C | : Index_Type) return Index_Type; |
function I_Has_Element
( | Self | : Sequence; |
C | : Index_Type) return Standard.Boolean; |
function I_Get_Element
( | Self | : Sequence; |
C | : Index_Type) return Element_Access; |
procedure Initialize
( | Self | : not null access Sequence); |
Use this function to initialize new sequences to a valid emptu state. C users should initialize sequences before using them.
self: <<in>> Cannot be NULL
See also: DDS_SEQUENCE_INITIALIZER
function Get_Reference
( | Self | : not null access constant Sequence; |
Index | : Index_Type) return Element_Access; |
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
procedure Iterate
( | Self | : not null access Sequence; |
Handle | : not null access procedure (continue : in out Boolean; | |
elt | : Element_Access)); |
function Get
( | Self | : not null access constant Sequence; |
Index | : Index_Type) return Element; |
self: <<in>> Cannot be NULL
i: index of element to access, must be >= 1 and less than FooSeq::length()
Returns: the i-th element
function Get_Element_Pointers_Allocation
( | Self | : not null access constant Sequence) return Boolean; |
procedure Set_Element_Pointers_Allocation
( | Self | : not null access Sequence; |
Allocate_Pointers | : in Boolean); |
function Get_Maximum
( | Self | : not null access constant Sequence) return Index_Type; |
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()
procedure Set_Maximum
( | Self | : not null access Sequence; |
New_Max | : in Index_Type); |
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.
Returns: DDS.BOOLEAN_TRUE on success, DDS.BOOLEAN_FALSE if the preconditions are not met. In that case the sequence is not modified.
function Get_Length
( | Self | : not null access constant Sequence) return Index_Type; |
procedure Set_Length
( | Self | : not null access Sequence; |
New_Length | : in Index_Type); |
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 sucess or DDS.BOOLEAN_FALSE on failure
procedure Ensure_Length
( | Self | : not null access Sequence; |
Length | : in Index_Type; | |
Max | : in Index_Type); |
If the current maximum is greater than the desired length, then 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. 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.
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=
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
procedure From_Array
( | Self | : not null access Sequence; |
Src | : in Element_Array); |
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.
procedure To_Array
( | Self | : not null access constant Sequence; |
Target | : out Element_Array); |
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.
function To_Array
( | Self | : not null access constant Sequence) return Element_Array; |
procedure Loan_Contiguous
( | Self | : not null access Sequence; |
Buffer | : not null access Element_Array; | |
New_Length | : in Index_Type; | |
New_Max | : in Index_Type); |
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.
Returns: DDS.BOOLEAN_TRUE if buffer is successfully loaned to this sequence or DDS.BOOLEAN_FALSE otherwise. Failure only occurs due to failing to meet the pre-conditions. Upon failure the sequence remains unmodified.
See also: FooSeq.unloan , FooSeq.loan_discontiguous
procedure Loan_Discontiguous
( | Self | : access Sequence; |
Buffer | : not null access Element_Access; | |
New_Length | : in Index_Type; | |
New_Max | : in Index_Type); |
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
procedure Unloan
( | Self | : not null access Sequence); |
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
Returns: DDS.BOOLEAN_TRUE if the preconditions were met. Otherwise DDS.BOOLEAN_FALSE. The function only fails if the pre-conditions are not met, in which case it leaves the sequence unmodified.
See also: FooSeq.loan_contiguous, FooSeq.loan_discontiguous, FooSeq::maximum(DDS_Long)
function Has_Ownership
( | Self | : not null access constant Sequence) return Boolean; |
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.
procedure Finalize
( | Self | : not null access Sequence); |
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
procedure Check_InvariantsI
( | Self | : not null access constant Sequence; |
Calling_Function | : Standard.String := GNAT.Source_Info.Enclosing_Entity); |
procedure Check_InitI
( | Self | : not null access constant Sequence); |
procedure Get_Read_TokenI
( | Self | : not null access constant Sequence; |
Token1 | : not null access System.Address; | |
Token2 | : not null access System.Address); |
procedure Set_Read_TokenI
( | Self | : not null access Sequence; |
Token1 | : in System.Address; | |
Token2 | : in System.Address); |
function Get_Contiguous_BufferI
( | Self | : not null access constant Sequence) return access Memory_Element_Array; |
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.
function Get_DisContiguous_BufferI
( | Self | : not null access constant Sequence) return access Memory_Element_Pointer; |
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.