!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). ***************************************************************