Version 1.1 of acs/ac-00263.txt

Unformatted version of acs/ac-00263.txt version 1.1
Other versions for file acs/ac-00263.txt

!standard A.18.18(5/3)          14-10-09 AC95-00263/00
!class Amendment 13-10-09
!status received no action 14-10-09
!status received 14-08-11
!subject Add Element_Access function to Containers.Indefinite_Holders
!summary
!appendix

!topic Add Element_Access function to Containers.Indefinite_Holders
!reference Ada 2012 RM A.18.18(5/3)
!from Victor Porton 80-07-21
!keywords indefinite holders, container, access
!discussion

I think that we should add new function:

function Element_Access (Container : Holder) return access Element_Type;

which should return access to the element in the container (or null if there are
none).

Its need appeared in real world programming:

I want an indefinite holder which contains Interfaces.C.char_array. I need to
pass access to this char_array as an argument to
Interfaces.C.Strings.To_Chars_Ptr (in order to interface with a C library). For
this I need access to the contained element.

Due shortcoming of APIs related with this, I an forced to write my own
indefinite holder and use it instead of the indefinite holder provided by the
language. This situation is not tolerable.

Implementation note: Indefinite holders may be implemented by placing the
indefinite object in a storage pool (and I know no other way to implement them).
If this implementation is chosen, the object is aliased and the function
Element_Access is natural and easy to implement.

***************************************************************

From: Christoph Grein
Sent: Monday, August 11, 2014  4:44 AM

Why don't you use
(18/3) function Constant_Reference (Container : aliased in Holder) return Constant_Reference_Type;
(19/3) function Reference (Container : aliased in out Holder) return Reference_Type;

Your proposal has the disadvantage that the reference you want may outlive the
referenced object. This is why reference types have been invented, whose objets
can never outlive the object.

See
http://www.adacore.com/adaanswers/gems/gem-107-preventing-deallocation-for-reference-counted-types/
http://www.adacore.com/adaanswers/gems/gem-123-implicit-dereferencing-in-ada-2012/

***************************************************************

From: Randy Brukardt
Sent: Monday, August 11, 2014  1:54 PM

...
> I think that we should add new function:
>
> function Element_Access (Container : Holder) return access
> Element_Type;

As Christoph has already noted, this already exists in the form of the Reference
and Constant_Reference routines. Writing Reference(Container).Element will give
exactly the same thing as your proposed function with the added advantage that
modications of the container are prohibited so long as the reference exists
(thus the element will exist as well).

But be careful about accessibility. The above and the reference function have
(or at least are supposed to have - the accessibility rules for access
discriminants and for anomymous access function returns are supposed to be the
same, but they're so complex its hard to tell for sure) the same accessibility
rules, such that the result cannot be stored long-term. For a lot of uses of
access values, this is not going to work.

> Its need appeared in real world programming:
>
> I want an indefinite holder which contains Interfaces.C.char_array. I
> need to pass access to this char_array as an argument to
> Interfaces.C.Strings.To_Chars_Ptr (in order to interface with a C
> library). For this I need access to the contained element.

Neither the existing Reference function, nor your proposed function above will
work for this. The parameter type of To_Chars_Ptr is a library-level access
type, which is too long lived for the result of a function call. You'll get
either a compile-time or run-time error. (Note that this was an intentional
feature of the Interfaces.C.Strings library; the designers were trying to
prevent you from passing something short-lived to C. It's not clear to me that
this library-level requirement was a good idea; if there is a problem anywhere,
it's here and not in the containers.)

In order for this call to work, you'd need your container to have a function

    function Element_Access (Container : Holder) return Interfaces.C.char_array_access;

(and your container would internally have to use char_array_access or something
similar). Obviously, this isn't going to be possible in a general-purpose
generic container.

> Due shortcoming of APIs related with this,

The API has the capability you ask for, it just isn't allowed to solve your
problem (by design).

> I an forced to
> write my own indefinite holder and use it instead of the indefinite
> holder provided by the language. This situation is not tolerable.

Better get used to it if you're going to do Ada. The Ada.Containers were
designed to be as safe as the equivalent operations on an array object. This
means that they do compile-time and run-time checks to prevent risky behavior.

This level of safety and performance may not be appropriate for all
applications; in such a case, you'll need to write your own data structures
rather than using Ada.Containers.

It's certainly not possible for the Ada containers to be all things to all
people. There are a series of trade-offs, which in Ada lean toward safety (while
in many other languages, they tend to lean toward risk in a chase for the last
ounce of performance).

***************************************************************

Questions? Ask the ACAA Technical Agent