Annex A (normative) Predefined Language Environment 1 This Annex contains the specifications of library units that shall be provided by every implementation. There are three root library units: Ada, Interfaces, and System; other library units are children of these: 2/3 Standard - A.1 Ada - A.2 Assertions - 11.4.2 Asynchronous_Task_Control - D.11 Calendar - 9.6 Arithmetic - 9.6.1 Formatting - 9.6.1 Time_Zones - 9.6.1 Characters - A.3.1 Conversions - A.3.4 Handling - A.3.2 Latin_1 - A.3.3 Command_Line - A.15 Complex_Text_IO - G.1.3 Containers - A.18.1 Bounded_Doubly_Linked_Lists - A.18.20 Bounded_Hashed_Maps - A.18.21 Bounded_Hashed_Sets - A.18.23 Bounded_Multiway_Trees - A.18.25 Bounded_Ordered_Maps - A.18.22 Bounded_Ordered_Sets - A.18.24 Bounded_Priority_Queues - A.18.31 Bounded_Synchronized_Queues - A.18.29 Bounded_Vectors - A.18.19 Doubly_Linked_Lists - A.18.3 Generic_Array_Sort - A.18.26 Generic_Constrained_Array_Sort - A.18.26 Generic_Sort - A.18.26 Hashed_Maps - A.18.5 Hashed_Sets - A.18.8 Indefinite_Doubly_Linked_Lists - A.18.12 Indefinite_Hashed_Maps - A.18.13 Indefinite_Hashed_Sets - A.18.15 Indefinite_Holders - A.18.18 Indefinite_Multiway_Trees - A.18.17 Indefinite_Ordered_Maps - A.18.14 Indefinite_Ordered_Sets - A.18.16 Indefinite_Vectors - A.18.11Standard (...continued) Ada (...continued) Containers (...continued) Multiway_Trees - A.18.10 Ordered_Maps - A.18.6 Ordered_Sets - A.18.9 Synchronized_Queue_Interfaces - A.18.27 Unbounded_Priority_Queues - A.18.30 Unbounded_Synchronized_Queues - A.18.28 Vectors - A.18.2 Decimal - F.2 Direct_IO - A.8.4 Directories - A.16 Hierarchical_File_Names - A.16.1 Information - A.16 Dispatching - D.2.1 EDF - D.2.6 Non_Preemptive - D.2.4 Round_Robin - D.2.5 Dynamic_Priorities - D.5.1 Environment_Variables - A.17 Exceptions - 11.4.1 Execution_Time - D.14 Group_Budgets - D.14.2 Interrupts - D.14.3 Timers - D.14.1 Finalization - 7.6 Float_Text_IO - A.10.9 Float_Wide_Text_IO - A.11 Float_Wide_Wide_Text_IO - A.11 Integer_Text_IO - A.10.8 Integer_Wide_Text_IO - A.11 Integer_Wide_Wide_Text_IO - A.11 Interrupts - C.3.2 Names - C.3.2 IO_Exceptions - A.13 Iterator_Interfaces - 5.5.1 Locales - A.19 Standard (...continued) Ada (...continued) Numerics - A.5 Complex_Arrays - G.3.2 Complex_Elementary_Functions - G.1.2 Complex_Types - G.1.1 Discrete_Random - A.5.2 Elementary_Functions - A.5.1 Float_Random - A.5.2 Generic_Complex_Arrays - G.3.2 Generic_Complex_Elementary_Functions - G.1.2 Generic_Complex_Types - G.1.1 Generic_Elementary_Functions - A.5.1 Generic_Real_Arrays - G.3.1 Real_Arrays - G.3.1 Real_Time - D.8 Timing_Events - D.15 Sequential_IO - A.8.1 Storage_IO - A.9 Streams - 13.13.1 Stream_IO - A.12.1 Strings - A.4.1 Bounded - A.4.4 Equal_Case_Insensitive - A.4.10 Hash - A.4.9 Hash_Case_Insensitive - A.4.9 Less_Case_Insensitive - A.4.10 Fixed - A.4.3 Equal_Case_Insensitive - A.4.10 Hash - A.4.9 Hash_Case_Insensitive - A.4.9 Less_Case_Insensitive - A.4.10 Equal_Case_Insensitive - A.4.10 Hash - A.4.9 Hash_Case_Insensitive - A.4.9 Less_Case_Insensitive - A.4.10 Maps - A.4.2 Constants - A.4.6 Unbounded - A.4.5 Equal_Case_Insensitive - A.4.10 Hash - A.4.9 Hash_Case_Insensitive - A.4.9 Less_Case_Insensitive - A.4.10 UTF_Encoding - A.4.11 Conversions - A.4.11 Strings - A.4.11 Wide_Strings - A.4.11 Wide_Wide_Strings - A.4.11 Standard (...continued) Ada (...continued) Strings (...continued) Wide_Bounded - A.4.7 Wide_Equal_Case_Insensitive - A.4.7 Wide_Hash - A.4.7 Wide_Hash_Case_Insensitive - A.4.7 Wide_Equal_Case_Insensitive - A.4.7 Wide_Fixed - A.4.7 Wide_Equal_Case_Insensitive - A.4.7 Wide_Hash - A.4.7 Wide_Hash_Case_Insensitive - A.4.7 Wide_Hash - A.4.7 Wide_Hash_Case_Insensitive - A.4.7 Wide_Maps - A.4.7 Wide_Constants - A.4.7 Wide_Unbounded - A.4.7 Wide_Equal_Case_Insensitive - A.4.7 Wide_Hash - A.4.7 Wide_Hash_Case_Insensitive - A.4.7 Wide_Wide_Bounded - A.4.8 Wide_Wide_Equal_Case_Insensitive - A.4.8 Wide_Wide_Hash - A.4.8 Wide_Wide_Hash_Case_Insensitive - A.4.8 Wide_Wide_Equal_Case_Insensitive - A.4.8 Wide_Wide_Fixed - A.4.8 Wide_Wide_Equal_Case_Insensitive - A.4.8 Wide_Wide_Hash - A.4.8 Wide_Wide_Hash_Case_Insensitive - A.4.8 Wide_Wide_Hash - A.4.8 Wide_Wide_Hash_Case_Insensitive - A.4.8 Wide_Wide_Maps - A.4.8 Wide_Wide_Constants - A.4.8 Wide_Wide_Unbounded - A.4.8 Wide_Wide_Equal_Case_Insensitive - A.4.8 Wide_Wide_Hash - A.4.8 Wide_Wide_Hash_Case_Insensitive - A.4.8 Synchronous_Barriers - D.10.1 Synchronous_Task_Control - D.10 EDF - D.10 Standard (...continued) Ada (...continued) Tags - 3.9 Generic_Dispatching_Constructor - 3.9 Task_Attributes - C.7.2 Task_Identification - C.7.1 Task_Termination - C.7.3 Text_IO - A.10.1 Bounded_IO - A.10.11 Complex_IO - G.1.3 Editing - F.3.3 Text_Streams - A.12.2 Unbounded_IO - A.10.12 Unchecked_Conversion - 13.9 Unchecked_Deallocate_Subpool - 13.11.5 Unchecked_Deallocation - 13.11.2 Wide_Characters - A.3.1 Handling - A.3.5 Wide_Text_IO - A.11 Complex_IO - G.1.4 Editing - F.3.4 Text_Streams - A.12.3 Wide_Bounded_IO - A.11 Wide_Unbounded_IO - A.11 Wide_Wide_Characters - A.3.1 Handling - A.3.6 Wide_Wide_Text_IO - A.11 Complex_IO - G.1.5 Editing - F.3.5 Text_Streams - A.12.4 Wide_Wide_Bounded_IO - A.11 Wide_Wide_Unbounded_IO - A.11 Interfaces - B.2 C - B.3 Pointers - B.3.2 Strings - B.3.1 COBOL - B.4 Fortran - B.5 System - 13.7 Address_To_Access_Conversions - 13.7.2 Machine_Code - 13.8 Multiprocessors - D.16 Dispatching_Domains - D.16.1 RPC - E.5 Storage_Elements - 13.7.1 Storage_Pools - 13.11 Subpools - 13.11.4 Implementation Requirements 3/4 The implementation shall ensure that each language-defined subprogram is reentrant in the sense that concurrent calls on any language-defined subprogram perform as specified, so long as all objects that are denoted by parameters that could be passed by reference or designated by parameters of an access type are nonoverlapping. 3.1/4 For the purpose of determining whether concurrent calls on text input-output subprograms are required to perform as specified above, when calling a subprogram within Text_IO or its children that implicitly operates on one of the default input-output files, the subprogram is considered to have a parameter of Current_Input or Current_Output (as appropriate). 3.2/3 If a descendant of a language-defined tagged type is declared, the implementation shall ensure that each inherited language-defined subprogram behaves as described in this International Standard. In particular, overriding a language-defined subprogram shall not alter the effect of any inherited language-defined subprogram. Implementation Permissions 4 The implementation may restrict the replacement of language-defined compilation units. The implementation may restrict children of language-defined library units (other than Standard). A.1 The Package Standard 1/3 This subclause outlines the specification of the package Standard containing all predefined identifiers in the language. The corresponding package body is not specified by the language. 2 The operators that are predefined for the types declared in the package Standard are given in comments since they are implicitly declared. Italics are used for pseudo-names of anonymous types (such as root_real) and for undefined information (such as implementation-defined). Static Semantics 3 The library package Standard has the following declaration: 4 package Standard is pragma Pure(Standard); 5 type Boolean is (False, True); 6 -- The predefined relational operators for this type are as follows: 7/1 -- function "=" (Left, Right : Boolean'Base) return Boolean; -- function "/=" (Left, Right : Boolean'Base) return Boolean; -- function "<" (Left, Right : Boolean'Base) return Boolean; -- function "<=" (Left, Right : Boolean'Base) return Boolean; -- function ">" (Left, Right : Boolean'Base) return Boolean; -- function ">=" (Left, Right : Boolean'Base) return Boolean; 8 -- The predefined logical operators and the predefined logical -- negation operator are as follows: 9/1 -- function "and" (Left, Right : Boolean'Base) return Boolean'Base; -- function "or" (Left, Right : Boolean'Base) return Boolean'Base; -- function "xor" (Left, Right : Boolean'Base) return Boolean'Base; 10/1 -- function "not" (Right : Boolean'Base) return Boolean'Base; 11/2 -- The integer type root_integer and the -- corresponding universal type universal_integer are predefined. 12 type Integer is range implementation-defined; 13 subtype Natural is Integer range 0 .. Integer'Last; subtype Positive is Integer range 1 .. Integer'Last; 14 -- The predefined operators for type Integer are as follows: 15 -- function "=" (Left, Right : Integer'Base) return Boolean; -- function "/=" (Left, Right : Integer'Base) return Boolean; -- function "<" (Left, Right : Integer'Base) return Boolean; -- function "<=" (Left, Right : Integer'Base) return Boolean; -- function ">" (Left, Right : Integer'Base) return Boolean; -- function ">=" (Left, Right : Integer'Base) return Boolean; 16 -- function "+" (Right : Integer'Base) return Integer'Base; -- function "-" (Right : Integer'Base) return Integer'Base; -- function "abs" (Right : Integer'Base) return Integer'Base; 17 -- function "+" (Left, Right : Integer'Base) return Integer'Base; -- function "-" (Left, Right : Integer'Base) return Integer'Base; -- function "*" (Left, Right : Integer'Base) return Integer'Base; -- function "/" (Left, Right : Integer'Base) return Integer'Base; -- function "rem" (Left, Right : Integer'Base) return Integer'Base; -- function "mod" (Left, Right : Integer'Base) return Integer'Base; 18 -- function "**" (Left : Integer'Base; Right : Natural) -- return Integer'Base; 19 -- The specification of each operator for the type -- root_integer, or for any additional predefined integer -- type, is obtained by replacing Integer by the name of the type -- in the specification of the corresponding operator of the type -- Integer. The right operand of the exponentiation operator -- remains as subtype Natural. 20/2 -- The floating point type root_real and the -- corresponding universal type universal_real are predefined. 21 type Float is digits implementation-defined; 22 -- The predefined operators for this type are as follows: 23 -- function "=" (Left, Right : Float) return Boolean; -- function "/=" (Left, Right : Float) return Boolean; -- function "<" (Left, Right : Float) return Boolean; -- function "<=" (Left, Right : Float) return Boolean; -- function ">" (Left, Right : Float) return Boolean; -- function ">=" (Left, Right : Float) return Boolean; 24 -- function "+" (Right : Float) return Float; -- function "-" (Right : Float) return Float; -- function "abs" (Right : Float) return Float; 25 -- function "+" (Left, Right : Float) return Float; -- function "-" (Left, Right : Float) return Float; -- function "*" (Left, Right : Float) return Float; -- function "/" (Left, Right : Float) return Float; 26 -- function "**" (Left : Float; Right : Integer'Base) return Float; 27 -- The specification of each operator for the type root_real, or for -- any additional predefined floating point type, is obtained by -- replacing Float by the name of the type in the specification of the -- corresponding operator of the type Float. 28 -- In addition, the following operators are predefined for the root -- numeric types: 29 function "*" (Left : root_integer; Right : root_real) return root_real; 30 function "*" (Left : root_real; Right : root_integer) return root_real; 31 function "/" (Left : root_real; Right : root_integer) return root_real; 32 -- The type universal_fixed is predefined. -- The only multiplying operators defined between -- fixed point types are 33 function "*" (Left : universal_fixed; Right : universal_fixed) return universal_fixed; 34 function "/" (Left : universal_fixed; Right : universal_fixed) return universal_fixed; 34.1/2 -- The type universal_access is predefined. -- The following equality operators are predefined: 34.2/2 function "=" (Left, Right: universal_access) return Boolean; function "/=" (Left, Right: universal_access) return Boolean; 35/3 -- The declaration of type Character is based on the standard ISO 8859-1 character set. -- There are no character literals corresponding to the positions for control characters. -- They are indicated in italics in this definition. See 3.5.2. type Character is (nul, soh, stx, etx, eot, enq, ack, bel, --0 (16#00#) .. 7 (16#07#) bs, ht, lf, vt, ff, cr, so, si, --8 (16#08#) .. 15 (16#0F#) dle, dc1, dc2, dc3, dc4, nak, syn, etb, --16 (16#10#) .. 23 (16#17#) can, em, sub, esc, fs, gs, rs, us, --24 (16#18#) .. 31 (16#1F#) ' ', '!', '"', '#', '$', '%', '&', ''', --32 (16#20#) .. 39 (16#27#) '(', ')', '*', '+', ',', '-', '.', '/', --40 (16#28#) .. 47 (16#2F#) '0', '1', '2', '3', '4', '5', '6', '7', --48 (16#30#) .. 55 (16#37#) '8', '9', ':', ';', '<', '=', '>', '?', --56 (16#38#) .. 63 (16#3F#) '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', --64 (16#40#) .. 71 (16#47#) 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', --72 (16#48#) .. 79 (16#4F#) 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', --80 (16#50#) .. 87 (16#57#) 'X', 'Y', 'Z', '[', '\', ']', '^', '_', --88 (16#58#) .. 95 (16#5F#) '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', --96 (16#60#) .. 103 (16#67#) 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', --104 (16#68#) .. 111 (16#6F#) 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', --112 (16#70#) .. 119 (16#77#) 'x', 'y', 'z', '{', '|', '}', '~', del, --120 (16#78#) .. 127 (16#7F#) reserved_128, reserved_129, bph, nbh, --128 (16#80#) .. 131 (16#83#) reserved_132, nel, ssa, esa, --132 (16#84#) .. 135 (16#87#) hts, htj, vts, pld, plu, ri, ss2, ss3, --136 (16#88#) .. 143 (16#8F#) dcs, pu1, pu2, sts, cch, mw, spa, epa, --144 (16#90#) .. 151 (16#97#) sos, reserved_153, sci, csi, --152 (16#98#) .. 155 (16#9B#) st, osc, pm, apc, --156 (16#9C#) .. 159 (16#9F#) ' ', '¡', '¢', '£', '¤', '¥', '¦', '§', --160 (16#A0#) .. 167 (16#A7#) '¨', '©', 'ª', '«', --168 (16#A8#) .. 171 (16#AB#) ¬', soft_hyphen, '®', '¯', --172 (16#AC#) .. 175 (16#AF#) '°', '±', '²', '³', '´', 'µ', '¶', '·', --176 (16#B0#) .. 183 (16#B7#) '¸', '¹', 'º', '»', '¼', '½', '¾', '¿', --184 (16#B8#) .. 191 (16#BF#) 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', --192 (16#C0#) .. 199 (16#C7#) 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', --200 (16#C8#) .. 207 (16#CF#) 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', '×', --208 (16#D0#) .. 215 (16#D7#) 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'Þ', 'ß', --216 (16#D8#) .. 223 (16#DF#) 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', --224 (16#E0#) .. 231 (16#E7#) 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', --232 (16#E8#) .. 239 (16#EF#) 'ð', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', '÷', --240 (16#F0#) .. 247 (16#F7#) 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'þ', 'ÿ');--248 (16#F8#) .. 255 (16#FF#) 36 -- The predefined operators for the type Character are the same as for -- any enumeration type. 36.1/3 -- The declaration of type Wide_Character is based on the standard ISO/IEC 10646:2011 BMP character -- set. The first 256 positions have the same contents as type Character. See 3.5.2 . type Wide_Character is (nul, soh ... Hex_0000FFFE, Hex_0000FFFF); 36.2/3 -- The declaration of type Wide_Wide_Character is based on the full -- ISO/IEC 10646:2011 character set. The first 65536 positions have the -- same contents as type Wide_Character. See 3.5.2. type Wide_Wide_Character is (nul, soh ... Hex_7FFFFFFE, Hex_7FFFFFFF); for Wide_Wide_Character'Size use 32; 36.3/2 package ASCII is ... end ASCII; --Obsolescent; see J.5 37/3 -- Predefined string types: type String is array(Positive range <>) of Character with Pack; 38 -- The predefined operators for this type are as follows: 39 -- function "=" (Left, Right: String) return Boolean; -- function "/=" (Left, Right: String) return Boolean; -- function "<" (Left, Right: String) return Boolean; -- function "<=" (Left, Right: String) return Boolean; -- function ">" (Left, Right: String) return Boolean; -- function ">=" (Left, Right: String) return Boolean; 40 -- function "&" (Left: String; Right: String) return String; -- function "&" (Left: Character; Right: String) return String; -- function "&" (Left: String; Right: Character) return String; -- function "&" (Left: Character; Right: Character) return String; 41/3 type Wide_String is array(Positive range <>) of Wide_Character with Pack; 42 -- The predefined operators for this type correspond to those for String. 42.1/3 type Wide_Wide_String is array (Positive range <>) of Wide_Wide_Character with Pack; 42.2/2 -- The predefined operators for this type correspond to those for String. 43 type Duration is delta implementation-defined range implementation-defined; 44 -- The predefined operators for the type Duration are the same as for -- any fixed point type. 45 -- The predefined exceptions: 46 Constraint_Error: exception; Program_Error : exception; Storage_Error : exception; Tasking_Error : exception; 47 end Standard; 48 Standard has no private part. 49/2 In each of the types Character, Wide_Character, and Wide_Wide_Character, the character literals for the space character (position 32) and the non-breaking space character (position 160) correspond to different values. Unless indicated otherwise, each occurrence of the character literal ' ' in this International Standard refers to the space character. Similarly, the character literals for hyphen (position 45) and soft hyphen (position 173) correspond to different values. Unless indicated otherwise, each occurrence of the character literal '-' in this International Standard refers to the hyphen character. Dynamic Semantics 50 Elaboration of the body of Standard has no effect. Implementation Permissions 51 An implementation may provide additional predefined integer types and additional predefined floating point types. Not all of these types need have names. Implementation Advice 52 If an implementation provides additional named predefined integer types, then the names should end with "Integer" as in "Long_Integer". If an implementation provides additional named predefined floating point types, then the names should end with "Float" as in "Long_Float". NOTES 53 1 Certain aspects of the predefined entities cannot be completely described in the language itself. For example, although the enumeration type Boolean can be written showing the two enumeration literals False and True, the short-circuit control forms cannot be expressed in the language. 54 2 As explained in 8.1, "Declarative Region" and 10.1.4, " The Compilation Process", the declarative region of the package Standard encloses every library unit and consequently the main subprogram; the declaration of every library unit is assumed to occur within this declarative region. Library_items are assumed to be ordered in such a way that there are no forward semantic dependences. However, as explained in 8.3, "Visibility", the only library units that are visible within a given compilation unit are the library units named by all with_clauses that apply to the given unit, and moreover, within the declarative region of a given library unit, that library unit itself. 55 3 If all block_statements of a program are named, then the name of each program unit can always be written as an expanded name starting with Standard (unless Standard is itself hidden). The name of a library unit cannot be a homograph of a name (such as Integer) that is already declared in Standard. 56 4 The exception Standard.Numeric_Error is defined in J.6. A.2 The Package Ada Static Semantics 1 The following language-defined library package exists: 2 package Ada is pragma Pure(Ada); end Ada; 3 Ada serves as the parent of most of the other language-defined library units; its declaration is empty (except for the pragma Pure). Legality Rules 4 In the standard mode, it is illegal to compile a child of package Ada. A.3 Character Handling 1/3 This subclause presents the packages related to character processing: an empty declared pure package Characters and child packages Characters.Handling and Characters.Latin_1. The package Characters.Handling provides classification and conversion functions for Character data, and some simple functions for dealing with Wide_Character and Wide_Wide_Character data. The child package Characters.Latin_1 declares a set of constants initialized to values of type Character. A.3.1 The Packages Characters, Wide_Characters, and Wide_Wide_Characters Static Semantics 1 The library package Characters has the following declaration: 2 package Ada.Characters is pragma Pure(Characters); end Ada.Characters; 3/2 The library package Wide_Characters has the following declaration: 4/2 package Ada.Wide_Characters is pragma Pure(Wide_Characters); end Ada.Wide_Characters; 5/2 The library package Wide_Wide_Characters has the following declaration: 6/2 package Ada.Wide_Wide_Characters is pragma Pure(Wide_Wide_Characters); end Ada.Wide_Wide_Characters; Implementation Advice 7/3 If an implementation chooses to provide implementation-defined operations on Wide_Character or Wide_String (such as collating and sorting, etc.) it should do so by providing child units of Wide_Characters. Similarly if it chooses to provide implementation-defined operations on Wide_Wide_Character or Wide_Wide_String it should do so by providing child units of Wide_Wide_Characters. A.3.2 The Package Characters.Handling Static Semantics 1 The library package Characters.Handling has the following declaration: 2/2 with Ada.Characters.Conversions; package Ada.Characters.Handling is pragma Pure(Handling); 3 --Character classification functions 4/3 function Is_Control (Item : in Character) return Boolean; function Is_Graphic (Item : in Character) return Boolean; function Is_Letter (Item : in Character) return Boolean; function Is_Lower (Item : in Character) return Boolean; function Is_Upper (Item : in Character) return Boolean; function Is_Basic (Item : in Character) return Boolean; function Is_Digit (Item : in Character) return Boolean; function Is_Decimal_Digit (Item : in Character) return Boolean renames Is_Digit; function Is_Hexadecimal_Digit (Item : in Character) return Boolean; function Is_Alphanumeric (Item : in Character) return Boolean; function Is_Special (Item : in Character) return Boolean; function Is_Line_Terminator (Item : in Character) return Boolean; function Is_Mark (Item : in Character) return Boolean; function Is_Other_Format (Item : in Character) return Boolean; function Is_Punctuation_Connector (Item : in Character) return Boolean; function Is_Space (Item : in Character) return Boolean; 5 --Conversion functions for Character and String 6 function To_Lower (Item : in Character) return Character; function To_Upper (Item : in Character) return Character; function To_Basic (Item : in Character) return Character; 7 function To_Lower (Item : in String) return String; function To_Upper (Item : in String) return String; function To_Basic (Item : in String) return String; 8 --Classifications of and conversions between Character and ISO 646 9 subtype ISO_646 is Character range Character'Val(0) .. Character'Val(127); 10 function Is_ISO_646 (Item : in Character) return Boolean; function Is_ISO_646 (Item : in String) return Boolean; 11 function To_ISO_646 (Item : in Character; Substitute : in ISO_646 := ' ') return ISO_646; 12 function To_ISO_646 (Item : in String; Substitute : in ISO_646 := ' ') return String; 13/2 -- The functions Is_Character, Is_String, To_Character, To_String, To_Wide_Character, -- and To_Wide_String are obsolescent; see J.14. Paragraphs 14 through 18 were deleted. 19 end Ada.Characters.Handling; 20 In the description below for each function that returns a Boolean result, the effect is described in terms of the conditions under which the value True is returned. If these conditions are not met, then the function returns False. 21 Each of the following classification functions has a formal Character parameter, Item, and returns a Boolean result. 22 Is_Control True if Item is a control character. A control character is a character whose position is in one of the ranges 0..31 or 127..159. 23 Is_Graphic True if Item is a graphic character. A graphic character is a character whose position is in one of the ranges 32..126 or 160..255. 24 Is_Letter True if Item is a letter. A letter is a character that is in one of the ranges 'A'..'Z' or 'a'..'z', or whose position is in one of the ranges 192..214, 216..246, or 248..255. 25 Is_Lower True if Item is a lower-case letter. A lower-case letter is a character that is in the range 'a'..'z', or whose position is in one of the ranges 223..246 or 248..255. 26 Is_Upper True if Item is an upper-case letter. An upper-case letter is a character that is in the range 'A'..'Z' or whose position is in one of the ranges 192..214 or 216.. 222. 27 Is_Basic True if Item is a basic letter. A basic letter is a character that is in one of the ranges 'A'..'Z' and 'a'..'z', or that is one of the following: 'Æ', 'æ', 'Ð', 'ð', 'Þ', 'þ', or 'ß'. 28 Is_Digit True if Item is a decimal digit. A decimal digit is a character in the range '0'..'9'. 29 Is_Decimal_Digit A renaming of Is_Digit. 30 Is_Hexadecimal_Digit True if Item is a hexadecimal digit. A hexadecimal digit is a character that is either a decimal digit or that is in one of the ranges 'A' .. 'F' or 'a' .. 'f'. 31 Is_Alphanumeric True if Item is an alphanumeric character. An alphanumeric character is a character that is either a letter or a decimal digit. 32 Is_Special True if Item is a special graphic character. A special graphic character is a graphic character that is not alphanumeric. 32.1/3 Is_Line_Terminator True if Item is a character with position 10 .. 13 (Line_Feed, Line_Tabulation, Form_Feed, Carriage_Return) or 133 (Next_Line). 32.2/3 Is_Mark Never True (no value of type Character has categories Mark, Non-Spacing or Mark, Spacing Combining). 32.3/3 Is_Other_Format True if Item is a character with position 173 (Soft_Hyphen). 32.4/3 Is_Punctuation_Connector True if Item is a character with position 95 ('_', known as Low_Line or Underscore). 32.5/3 Is_Space True if Item is a character with position 32 (' ') or 160 (No_Break_Space). 33 Each of the names To_Lower, To_Upper, and To_Basic refers to two functions: one that converts from Character to Character, and the other that converts from String to String. The result of each Character-to-Character function is described below, in terms of the conversion applied to Item, its formal Character parameter. The result of each String-to-String conversion is obtained by applying to each element of the function's String parameter the corresponding Character-to-Character conversion; the result is the null String if the value of the formal parameter is the null String. The lower bound of the result String is 1. 34 To_Lower Returns the corresponding lower-case value for Item if Is_Upper(Item), and returns Item otherwise. 35 To_Upper Returns the corresponding upper-case value for Item if Is_Lower(Item) and Item has an upper-case form, and returns Item otherwise. The lower case letters 'ß' and 'ÿ' do not have upper case forms. 36 To_Basic Returns the letter corresponding to Item but with no diacritical mark, if Item is a letter but not a basic letter; returns Item otherwise. 37 The following set of functions test for membership in the ISO 646 character range, or convert between ISO 646 and Character. 38 Is_ISO_646 The function whose formal parameter, Item, is of type Character returns True if Item is in the subtype ISO_646. 39 Is_ISO_646 The function whose formal parameter, Item, is of type String returns True if Is_ISO_646(Item(I)) is True for each I in Item'Range. 40 To_ISO_646 The function whose first formal parameter, Item, is of type Character returns Item if Is_ISO_646(Item), and returns the Substitute ISO_646 character otherwise. 41 To_ISO_646 The function whose first formal parameter, Item, is of type String returns the String whose Range is 1..Item'Length and each of whose elements is given by To_ISO_646 of the corresponding element in Item. Paragraphs 42 through 49 were deleted. NOTES 50 5 A basic letter is a letter without a diacritical mark. 51 6 Except for the hexadecimal digits, basic letters, and ISO_646 characters, the categories identified in the classification functions form a strict hierarchy: 52 - Control characters 53 - Graphic characters 54 - Alphanumeric characters 55 - Letters 56 - Upper-case letters 57 - Lower-case letters 58 - Decimal digits 59 - Special graphic characters 60/3 7 There are certain characters which are defined to be lower case letters by ISO 10646 and are therefore allowed in identifiers, but are not considered lower case letters by Ada.Characters.Handling. A.3.3 The Package Characters.Latin_1 1 The package Characters.Latin_1 declares constants for characters in ISO 8859-1. Static Semantics 2 The library package Characters.Latin_1 has the following declaration: 3 package Ada.Characters.Latin_1 is pragma Pure(Latin_1); 4 -- Control characters: 5 NUL : constant Character := Character'Val(0); SOH : constant Character := Character'Val(1); STX : constant Character := Character'Val(2); ETX : constant Character := Character'Val(3); EOT : constant Character := Character'Val(4); ENQ : constant Character := Character'Val(5); ACK : constant Character := Character'Val(6); BEL : constant Character := Character'Val(7); BS : constant Character := Character'Val(8); HT : constant Character := Character'Val(9); LF : constant Character := Character'Val(10); VT : constant Character := Character'Val(11); FF : constant Character := Character'Val(12); CR : constant Character := Character'Val(13); SO : constant Character := Character'Val(14); SI : constant Character := Character'Val(15); 6 DLE : constant Character := Character'Val(16); DC1 : constant Character := Character'Val(17); DC2 : constant Character := Character'Val(18); DC3 : constant Character := Character'Val(19); DC4 : constant Character := Character'Val(20); NAK : constant Character := Character'Val(21); SYN : constant Character := Character'Val(22); ETB : constant Character := Character'Val(23); CAN : constant Character := Character'Val(24); EM : constant Character := Character'Val(25); SUB : constant Character := Character'Val(26); ESC : constant Character := Character'Val(27); FS : constant Character := Character'Val(28); GS : constant Character := Character'Val(29); RS : constant Character := Character'Val(30); US : constant Character := Character'Val(31); 7 -- ISO 646 graphic characters: 8 Space : constant Character := ' '; -- Character'Val(32) Exclamation : constant Character := '!'; -- Character'Val(33) Quotation : constant Character := '"'; -- Character'Val(34) Number_Sign : constant Character := '#'; -- Character'Val(35) Dollar_Sign : constant Character := '$'; -- Character'Val(36) Percent_Sign : constant Character := '%'; -- Character'Val(37) Ampersand : constant Character := '&'; -- Character'Val(38) Apostrophe : constant Character := '''; -- Character'Val(39) Left_Parenthesis : constant Character := '('; -- Character'Val(40) Right_Parenthesis : constant Character := ')'; -- Character'Val(41) Asterisk : constant Character := '*'; -- Character'Val(42) Plus_Sign : constant Character := '+'; -- Character'Val(43) Comma : constant Character := ','; -- Character'Val(44) Hyphen : constant Character := '-'; -- Character'Val(45) Minus_Sign : Character renames Hyphen; Full_Stop : constant Character := '.'; -- Character'Val(46) Solidus : constant Character := '/'; -- Character'Val(47) 9 -- Decimal digits '0' though '9' are at positions 48 through 57 10 Colon : constant Character := ':'; -- Character'Val(58) Semicolon : constant Character := ';'; -- Character'Val(59) Less_Than_Sign : constant Character := '<'; -- Character'Val(60) Equals_Sign : constant Character := '='; -- Character'Val(61) Greater_Than_Sign : constant Character := '>'; -- Character'Val(62) Question : constant Character := '?'; -- Character'Val(63) Commercial_At : constant Character := '@'; -- Character'Val(64) 11 -- Letters 'A' through 'Z' are at positions 65 through 90 12 Left_Square_Bracket : constant Character := '['; -- Character'Val(91) Reverse_Solidus : constant Character := '\'; -- Character'Val(92) Right_Square_Bracket : constant Character := ']'; -- Character'Val(93) Circumflex : constant Character := '^'; -- Character'Val(94) Low_Line : constant Character := '_'; -- Character'Val(95) 13 Grave : constant Character := '`'; -- Character'Val(96) LC_A : constant Character := 'a'; -- Character'Val(97) LC_B : constant Character := 'b'; -- Character'Val(98) LC_C : constant Character := 'c'; -- Character'Val(99) LC_D : constant Character := 'd'; -- Character'Val(100) LC_E : constant Character := 'e'; -- Character'Val(101) LC_F : constant Character := 'f'; -- Character'Val(102) LC_G : constant Character := 'g'; -- Character'Val(103) LC_H : constant Character := 'h'; -- Character'Val(104) LC_I : constant Character := 'i'; -- Character'Val(105) LC_J : constant Character := 'j'; -- Character'Val(106) LC_K : constant Character := 'k'; -- Character'Val(107) LC_L : constant Character := 'l'; -- Character'Val(108) LC_M : constant Character := 'm'; -- Character'Val(109) LC_N : constant Character := 'n'; -- Character'Val(110) LC_O : constant Character := 'o'; -- Character'Val(111) 14 LC_P : constant Character := 'p'; -- Character'Val(112) LC_Q : constant Character := 'q'; -- Character'Val(113) LC_R : constant Character := 'r'; -- Character'Val(114) LC_S : constant Character := 's'; -- Character'Val(115) LC_T : constant Character := 't'; -- Character'Val(116) LC_U : constant Character := 'u'; -- Character'Val(117) LC_V : constant Character := 'v'; -- Character'Val(118) LC_W : constant Character := 'w'; -- Character'Val(119) LC_X : constant Character := 'x'; -- Character'Val(120) LC_Y : constant Character := 'y'; -- Character'Val(121) LC_Z : constant Character := 'z'; -- Character'Val(122) Left_Curly_Bracket : constant Character := '{'; -- Character'Val(123) Vertical_Line : constant Character := '|'; -- Character'Val(124) Right_Curly_Bracket : constant Character := '}'; -- Character'Val(125) Tilde : constant Character := '~'; -- Character'Val(126) DEL : constant Character := Character'Val(127); 15 -- ISO 6429 control characters: 16 IS4 : Character renames FS; IS3 : Character renames GS; IS2 : Character renames RS; IS1 : Character renames US; 17 Reserved_128 : constant Character := Character'Val(128); Reserved_129 : constant Character := Character'Val(129); BPH : constant Character := Character'Val(130); NBH : constant Character := Character'Val(131); Reserved_132 : constant Character := Character'Val(132); NEL : constant Character := Character'Val(133); SSA : constant Character := Character'Val(134); ESA : constant Character := Character'Val(135); HTS : constant Character := Character'Val(136); HTJ : constant Character := Character'Val(137); VTS : constant Character := Character'Val(138); PLD : constant Character := Character'Val(139); PLU : constant Character := Character'Val(140); RI : constant Character := Character'Val(141); SS2 : constant Character := Character'Val(142); SS3 : constant Character := Character'Val(143); 18 DCS : constant Character := Character'Val(144); PU1 : constant Character := Character'Val(145); PU2 : constant Character := Character'Val(146); STS : constant Character := Character'Val(147); CCH : constant Character := Character'Val(148); MW : constant Character := Character'Val(149); SPA : constant Character := Character'Val(150); EPA : constant Character := Character'Val(151); 19 SOS : constant Character := Character'Val(152); Reserved_153 : constant Character := Character'Val(153); SCI : constant Character := Character'Val(154); CSI : constant Character := Character'Val(155); ST : constant Character := Character'Val(156); OSC : constant Character := Character'Val(157); PM : constant Character := Character'Val(158); APC : constant Character := Character'Val(159); 20 -- Other graphic characters: 21/3 -- Character positions 160 (16#A0#) .. 175 (16#AF#): No_Break_Space : constant Character := ' '; --Character'Val(160) NBSP : Character renames No_Break_Space; Inverted_Exclamation : constant Character := '¡'; --Character'Val(161) Cent_Sign : constant Character := '¢'; --Character'Val(162) Pound_Sign : constant Character := '£'; --Character'Val(163) Currency_Sign : constant Character := '¤'; --Character'Val(164) Yen_Sign : constant Character := '¥'; --Character'Val(165) Broken_Bar : constant Character := '¦'; --Character'Val(166) Section_Sign : constant Character := '§'; --Character'Val(167) Diaeresis : constant Character := '¨'; --Character'Val(168) Copyright_Sign : constant Character := '©'; --Character'Val(169) Feminine_Ordinal_Indicator : constant Character := 'ª'; --Character'Val(170) Left_Angle_Quotation : constant Character := '«'; --Character'Val(171) Not_Sign : constant Character := '¬'; --Character'Val(172) Soft_Hyphen : constant Character := Character'Val(173); Registered_Trade_Mark_Sign : constant Character := '®'; --Character'Val(174) Macron : constant Character := '¯'; --Character'Val(175) 22 -- Character positions 176 (16#B0#) .. 191 (16#BF#): Degree_Sign : constant Character := '°'; --Character'Val(176) Ring_Above : Character renames Degree_Sign; Plus_Minus_Sign : constant Character := '±'; --Character'Val(177) Superscript_Two : constant Character := '²'; --Character'Val(178) Superscript_Three : constant Character := '³'; --Character'Val(179) Acute : constant Character := '´'; --Character'Val(180) Micro_Sign : constant Character := 'µ'; --Character'Val(181) Pilcrow_Sign : constant Character := '¶'; --Character'Val(182) Paragraph_Sign : Character renames Pilcrow_Sign; Middle_Dot : constant Character := '·'; --Character'Val(183) Cedilla : constant Character := '¸'; --Character'Val(184) Superscript_One : constant Character := '¹'; --Character'Val(185) Masculine_Ordinal_Indicator : constant Character := 'º'; --Character'Val(186) Right_Angle_Quotation : constant Character := '»'; --Character'Val(187) Fraction_One_Quarter : constant Character := '¼'; --Character'Val(188) Fraction_One_Half : constant Character := '½'; --Character'Val(189) Fraction_Three_Quarters : constant Character := '¾'; --Character'Val(190) Inverted_Question : constant Character := '¿'; --Character'Val(191) 23 -- Character positions 192 (16#C0#) .. 207 (16#CF#): UC_A_Grave : constant Character := 'À'; --Character'Val(192) UC_A_Acute : constant Character := 'Á'; --Character'Val(193) UC_A_Circumflex : constant Character := 'Â'; --Character'Val(194) UC_A_Tilde : constant Character := 'Ã'; --Character'Val(195) UC_A_Diaeresis : constant Character := 'Ä'; --Character'Val(196) UC_A_Ring : constant Character := 'Å'; --Character'Val(197) UC_AE_Diphthong : constant Character := 'Æ'; --Character'Val(198) UC_C_Cedilla : constant Character := 'Ç'; --Character'Val(199) UC_E_Grave : constant Character := 'È'; --Character'Val(200) UC_E_Acute : constant Character := 'É'; --Character'Val(201) UC_E_Circumflex : constant Character := 'Ê'; --Character'Val(202) UC_E_Diaeresis : constant Character := 'Ë'; --Character'Val(203) UC_I_Grave : constant Character := 'Ì'; --Character'Val(204) UC_I_Acute : constant Character := 'Í'; --Character'Val(205) UC_I_Circumflex : constant Character := 'Î'; --Character'Val(206) UC_I_Diaeresis : constant Character := 'Ï'; --Character'Val(207) 24 -- Character positions 208 (16#D0#) .. 223 (16#DF#): UC_Icelandic_Eth : constant Character := 'Ð'; --Character'Val(208) UC_N_Tilde : constant Character := 'Ñ'; --Character'Val(209) UC_O_Grave : constant Character := 'Ò'; --Character'Val(210) UC_O_Acute : constant Character := 'Ó'; --Character'Val(211) UC_O_Circumflex : constant Character := 'Ô'; --Character'Val(212) UC_O_Tilde : constant Character := 'Õ'; --Character'Val(213) UC_O_Diaeresis : constant Character := 'Ö'; --Character'Val(214) Multiplication_Sign : constant Character := '×'; --Character'Val(215) UC_O_Oblique_Stroke : constant Character := 'Ø'; --Character'Val(216) UC_U_Grave : constant Character := 'Ù'; --Character'Val(217) UC_U_Acute : constant Character := 'Ú'; --Character'Val(218) UC_U_Circumflex : constant Character := 'Û'; --Character'Val(219) UC_U_Diaeresis : constant Character := 'Ü'; --Character'Val(220) UC_Y_Acute : constant Character := 'Ý'; --Character'Val(221) UC_Icelandic_Thorn : constant Character := 'Þ'; --Character'Val(222) LC_German_Sharp_S : constant Character := 'ß'; --Character'Val(223) 25 -- Character positions 224 (16#E0#) .. 239 (16#EF#): LC_A_Grave : constant Character := 'à'; --Character'Val(224) LC_A_Acute : constant Character := 'á'; --Character'Val(225) LC_A_Circumflex : constant Character := 'â'; --Character'Val(226) LC_A_Tilde : constant Character := 'ã'; --Character'Val(227) LC_A_Diaeresis : constant Character := 'ä'; --Character'Val(228) LC_A_Ring : constant Character := 'å'; --Character'Val(229) LC_AE_Diphthong : constant Character := 'æ'; --Character'Val(230) LC_C_Cedilla : constant Character := 'ç'; --Character'Val(231) LC_E_Grave : constant Character := 'è'; --Character'Val(232) LC_E_Acute : constant Character := 'é'; --Character'Val(233) LC_E_Circumflex : constant Character := 'ê'; --Character'Val(234) LC_E_Diaeresis : constant Character := 'ë'; --Character'Val(235) LC_I_Grave : constant Character := 'ì'; --Character'Val(236) LC_I_Acute : constant Character := 'í'; --Character'Val(237) LC_I_Circumflex : constant Character := 'î'; --Character'Val(238) LC_I_Diaeresis : constant Character := 'ï'; --Character'Val(239) 26 -- Character positions 240 (16#F0#) .. 255 (16#FF#): LC_Icelandic_Eth : constant Character := 'ð'; --Character'Val(240) LC_N_Tilde : constant Character := 'ñ'; --Character'Val(241) LC_O_Grave : constant Character := 'ò'; --Character'Val(242) LC_O_Acute : constant Character := 'ó'; --Character'Val(243) LC_O_Circumflex : constant Character := 'ô'; --Character'Val(244) LC_O_Tilde : constant Character := 'õ'; --Character'Val(245) LC_O_Diaeresis : constant Character := 'ö'; --Character'Val(246) Division_Sign : constant Character := '÷'; --Character'Val(247) LC_O_Oblique_Stroke : constant Character := 'ø'; --Character'Val(248) LC_U_Grave : constant Character := 'ù'; --Character'Val(249) LC_U_Acute : constant Character := 'ú'; --Character'Val(250) LC_U_Circumflex : constant Character := 'û'; --Character'Val(251) LC_U_Diaeresis : constant Character := 'ü'; --Character'Val(252) LC_Y_Acute : constant Character := 'ý'; --Character'Val(253) LC_Icelandic_Thorn : constant Character := 'þ'; --Character'Val(254) LC_Y_Diaeresis : constant Character := 'ÿ'; --Character'Val(255) end Ada.Characters.Latin_1; Implementation Permissions 27 An implementation may provide additional packages as children of Ada.Characters, to declare names for the symbols of the local character set or other character sets. A.3.4 The Package Characters.Conversions Static Semantics 1/2 The library package Characters.Conversions has the following declaration: 2/2 package Ada.Characters.Conversions is pragma Pure(Conversions); 3/2 function Is_Character (Item : in Wide_Character) return Boolean; function Is_String (Item : in Wide_String) return Boolean; function Is_Character (Item : in Wide_Wide_Character) return Boolean; function Is_String (Item : in Wide_Wide_String) return Boolean; function Is_Wide_Character (Item : in Wide_Wide_Character) return Boolean; function Is_Wide_String (Item : in Wide_Wide_String) return Boolean; 4/2 function To_Wide_Character (Item : in Character) return Wide_Character; function To_Wide_String (Item : in String) return Wide_String; function To_Wide_Wide_Character (Item : in Character) return Wide_Wide_Character; function To_Wide_Wide_String (Item : in String) return Wide_Wide_String; function To_Wide_Wide_Character (Item : in Wide_Character) return Wide_Wide_Character; function To_Wide_Wide_String (Item : in Wide_String) return Wide_Wide_String; 5/2 function To_Character (Item : in Wide_Character; Substitute : in Character := ' ') return Character; function To_String (Item : in Wide_String; Substitute : in Character := ' ') return String; function To_Character (Item : in Wide_Wide_Character; Substitute : in Character := ' ') return Character; function To_String (Item : in Wide_Wide_String; Substitute : in Character := ' ') return String; function To_Wide_Character (Item : in Wide_Wide_Character; Substitute : in Wide_Character := ' ') return Wide_Character; function To_Wide_String (Item : in Wide_Wide_String; Substitute : in Wide_Character := ' ') return Wide_String; 6/2 end Ada.Characters.Conversions; 7/2 The functions in package Characters.Conversions test Wide_Wide_Character or Wide_Character values for membership in Wide_Character or Character, or convert between corresponding characters of Wide_Wide_Character, Wide_Character, and Character. 8/2 function Is_Character (Item : in Wide_Character) return Boolean; 9/2 Returns True if Wide_Character'Pos(Item) <= Character'Pos(Character'Last). 10/2 function Is_Character (Item : in Wide_Wide_Character) return Boolean; 11/2 Returns True if Wide_Wide_Character'Pos(Item) <= Character'Pos(Character'Last). 12/2 function Is_Wide_Character (Item : in Wide_Wide_Character) return Boolean; 13/2 Returns True if Wide_Wide_Character'Pos(Item) <= Wide_Character'Pos(Wide_Character'Last). 14/2 function Is_String (Item : in Wide_String) return Boolean; function Is_String (Item : in Wide_Wide_String) return Boolean; 15/2 Returns True if Is_Character(Item(I)) is True for each I in Item'Range. 16/2 function Is_Wide_String (Item : in Wide_Wide_String) return Boolean; 17/2 Returns True if Is_Wide_Character(Item(I)) is True for each I in Item'Range. 18/2 function To_Character (Item : in Wide_Character; Substitute : in Character := ' ') return Character; function To_Character (Item : in Wide_Wide_Character; Substitute : in Character := ' ') return Character; 19/2 Returns the Character corresponding to Item if Is_Character(Item), and returns the Substitute Character otherwise. 20/2 function To_Wide_Character (Item : in Character) return Wide_Character; 21/2 Returns the Wide_Character X such that Character'Pos(Item) = Wide_Character'Pos (X). 22/2 function To_Wide_Character (Item : in Wide_Wide_Character; Substitute : in Wide_Character := ' ') return Wide_Character; 23/2 Returns the Wide_Character corresponding to Item if Is_Wide_Character(Item), and returns the Substitute Wide_Character otherwise. 24/2 function To_Wide_Wide_Character (Item : in Character) return Wide_Wide_Character; 25/2 Returns the Wide_Wide_Character X such that Character'Pos(Item) = Wide_Wide_Character'Pos (X). 26/2 function To_Wide_Wide_Character (Item : in Wide_Character) return Wide_Wide_Character; 27/2 Returns the Wide_Wide_Character X such that Wide_Character'Pos(Item) = Wide_Wide_Character'Pos (X). 28/2 function To_String (Item : in Wide_String; Substitute : in Character := ' ') return String; function To_String (Item : in Wide_Wide_String; Substitute : in Character := ' ') return String; 29/2 Returns the String whose range is 1..Item'Length and each of whose elements is given by To_Character of the corresponding element in Item. 30/2 function To_Wide_String (Item : in String) return Wide_String; 31/2 Returns the Wide_String whose range is 1..Item'Length and each of whose elements is given by To_Wide_Character of the corresponding element in Item. 32/2 function To_Wide_String (Item : in Wide_Wide_String; Substitute : in Wide_Character := ' ') return Wide_String; 33/2 Returns the Wide_String whose range is 1..Item'Length and each of whose elements is given by To_Wide_Character of the corresponding element in Item with the given Substitute Wide_Character. 34/2 function To_Wide_Wide_String (Item : in String) return Wide_Wide_String; function To_Wide_Wide_String (Item : in Wide_String) return Wide_Wide_String; 35/2 Returns the Wide_Wide_String whose range is 1..Item'Length and each of whose elements is given by To_Wide_Wide_Character of the corresponding element in Item. A.3.5 The Package Wide_Characters.Handling 1/3 The package Wide_Characters.Handling provides operations for classifying Wide_Characters and case folding for Wide_Characters. Static Semantics 2/3 The library package Wide_Characters.Handling has the following declaration: 3/3 package Ada.Wide_Characters.Handling is pragma Pure(Handling); 4/3 function Character_Set_Version return String; 5/3 function Is_Control (Item : Wide_Character) return Boolean; 6/3 function Is_Letter (Item : Wide_Character) return Boolean; 7/3 function Is_Lower (Item : Wide_Character) return Boolean; 8/3 function Is_Upper (Item : Wide_Character) return Boolean; 9/3 function Is_Digit (Item : Wide_Character) return Boolean; 10/3 function Is_Decimal_Digit (Item : Wide_Character) return Boolean renames Is_Digit; 11/3 function Is_Hexadecimal_Digit (Item : Wide_Character) return Boolean; 12/3 function Is_Alphanumeric (Item : Wide_Character) return Boolean; 13/3 function Is_Special (Item : Wide_Character) return Boolean; 14/3 function Is_Line_Terminator (Item : Wide_Character) return Boolean; 15/3 function Is_Mark (Item : Wide_Character) return Boolean; 16/3 function Is_Other_Format (Item : Wide_Character) return Boolean; 17/3 function Is_Punctuation_Connector (Item : Wide_Character) return Boolean; 18/3 function Is_Space (Item : Wide_Character) return Boolean; 19/3 function Is_Graphic (Item : Wide_Character) return Boolean; 20/3 function To_Lower (Item : Wide_Character) return Wide_Character; function To_Upper (Item : Wide_Character) return Wide_Character; 21/3 function To_Lower (Item : Wide_String) return Wide_String; function To_Upper (Item : Wide_String) return Wide_String; 22/3 end Ada.Wide_Characters.Handling; 23/3 The subprograms defined in Wide_Characters.Handling are locale independent. 24/3 function Character_Set_Version return String; 25/3 Returns an implementation-defined identifier that identifies the version of the character set standard that is used for categorizing characters by the implementation. 26/3 function Is_Control (Item : Wide_Character) return Boolean; 27/3 Returns True if the Wide_Character designated by Item is categorized as other_control; otherwise returns False. 28/3 function Is_Letter (Item : Wide_Character) return Boolean; 29/3 Returns True if the Wide_Character designated by Item is categorized as letter_uppercase, letter_lowercase, letter_titlecase, letter_modifier, letter_other, or number_letter; otherwise returns False. 30/3 function Is_Lower (Item : Wide_Character) return Boolean; 31/3 Returns True if the Wide_Character designated by Item is categorized as letter_lowercase; otherwise returns False. 32/3 function Is_Upper (Item : Wide_Character) return Boolean; 33/3 Returns True if the Wide_Character designated by Item is categorized as letter_uppercase; otherwise returns False. 34/3 function Is_Digit (Item : Wide_Character) return Boolean; 35/3 Returns True if the Wide_Character designated by Item is categorized as number_decimal; otherwise returns False. 36/3 function Is_Hexadecimal_Digit (Item : Wide_Character) return Boolean; 37/3 Returns True if the Wide_Character designated by Item is categorized as number_decimal, or is in the range 'A' .. 'F' or 'a' .. 'f'; otherwise returns False. 38/3 function Is_Alphanumeric (Item : Wide_Character) return Boolean; 39/3 Returns True if the Wide_Character designated by Item is categorized as letter_uppercase, letter_lowercase, letter_titlecase, letter_modifier, letter_other, number_letter, or number_decimal; otherwise returns False. 40/3 function Is_Special (Item : Wide_Character) return Boolean; 41/3 Returns True if the Wide_Character designated by Item is categorized as graphic_character, but not categorized as letter_uppercase, letter_lowercase, letter_titlecase, letter_modifier, letter_other, number_letter, or number_decimal; otherwise returns False. 42/3 function Is_Line_Terminator (Item : Wide_Character) return Boolean; 43/3 Returns True if the Wide_Character designated by Item is categorized as separator_line or separator_paragraph, or if Item is a conventional line terminator character (Line_Feed, Line_Tabulation, Form_Feed, Carriage_Return, Next_Line); otherwise returns False. 44/3 function Is_Mark (Item : Wide_Character) return Boolean; 45/3 Returns True if the Wide_Character designated by Item is categorized as mark_non_spacing or mark_spacing_combining; otherwise returns False. 46/3 function Is_Other_Format (Item : Wide_Character) return Boolean; 47/3 Returns True if the Wide_Character designated by Item is categorized as other_format; otherwise returns False. 48/3 function Is_Punctuation_Connector (Item : Wide_Character) return Boolean; 49/3 Returns True if the Wide_Character designated by Item is categorized as punctuation_connector; otherwise returns False. 50/3 function Is_Space (Item : Wide_Character) return Boolean; 51/3 Returns True if the Wide_Character designated by Item is categorized as separator_space; otherwise returns False. 52/3 function Is_Graphic (Item : Wide_Character) return Boolean; 53/3 Returns True if the Wide_Character designated by Item is categorized as graphic_character; otherwise returns False. 54/3 function To_Lower (Item : Wide_Character) return Wide_Character; 55/3 Returns the Simple Lowercase Mapping as defined by documents referenced in the note in Clause 1 of ISO/IEC 10646:2011 of the Wide_Character designated by Item. If the Simple Lowercase Mapping does not exist for the Wide_Character designated by Item, then the value of Item is returned. 56/3 function To_Lower (Item : Wide_String) return Wide_String; 57/3 Returns the result of applying the To_Lower conversion to each Wide_Character element of the Wide_String designated by Item. The result is the null Wide_String if the value of the formal parameter is the null Wide_String. The lower bound of the result Wide_String is 1. 58/3 function To_Upper (Item : Wide_Character) return Wide_Character; 59/3 Returns the Simple Uppercase Mapping as defined by documents referenced in the note in Clause 1 of ISO/IEC 10646:2011 of the Wide_Character designated by Item. If the Simple Uppercase Mapping does not exist for the Wide_Character designated by Item, then the value of Item is returned. 60/3 function To_Upper (Item : Wide_String) return Wide_String; 61/3 Returns the result of applying the To_Upper conversion to each Wide_Character element of the Wide_String designated by Item. The result is the null Wide_String if the value of the formal parameter is the null Wide_String. The lower bound of the result Wide_String is 1. Implementation Advice 62/3 The string returned by Character_Set_Version should include either " 10646:" or "Unicode". NOTES 63/3 8 The results returned by these functions may depend on which particular version of the 10646 standard is supported by the implementation (see 2.1). 64/3 9 The case insensitive equality comparison routines provided in A.4.10, "String Comparison" are also available for wide strings (see A.4.7). A.3.6 The Package Wide_Wide_Characters.Handling 1/3 The package Wide_Wide_Characters.Handling has the same contents as Wide_Characters.Handling except that each occurrence of Wide_Character is replaced by Wide_Wide_Character, and each occurrence of Wide_String is replaced by Wide_Wide_String. A.4 String Handling 1/3 This subclause presents the specifications of the package Strings and several child packages, which provide facilities for dealing with string data. Fixed-length, bounded-length, and unbounded-length strings are supported, for String, Wide_String, and Wide_Wide_String. The string-handling subprograms include searches for pattern strings and for characters in program-specified sets, translation (via a character-to-character mapping), and transformation (replacing, inserting, overwriting, and deleting of substrings). A.4.1 The Package Strings 1 The package Strings provides declarations common to the string handling packages. Static Semantics 2 The library package Strings has the following declaration: 3 package Ada.Strings is pragma Pure(Strings); 4/2 Space : constant Character := ' '; Wide_Space : constant Wide_Character := ' '; Wide_Wide_Space : constant Wide_Wide_Character := ' '; 5 Length_Error, Pattern_Error, Index_Error, Translation_Error : exception; 6 type Alignment is (Left, Right, Center); type Truncation is (Left, Right, Error); type Membership is (Inside, Outside); type Direction is (Forward, Backward); type Trim_End is (Left, Right, Both); end Ada.Strings; A.4.2 The Package Strings.Maps 1 The package Strings.Maps defines the types, operations, and other entities needed for character sets and character-to-character mappings. Static Semantics 2 The library package Strings.Maps has the following declaration: 3/2 package Ada.Strings.Maps is pragma Pure(Maps); 4/2 -- Representation for a set of character values: type Character_Set is private; pragma Preelaborable_Initialization(Character_Set); 5 Null_Set : constant Character_Set; 6 type Character_Range is record Low : Character; High : Character; end record; -- Represents Character range Low..High 7 type Character_Ranges is array (Positive range <>) of Character_Range; 8 function To_Set (Ranges : in Character_Ranges)return Character_Set; 9 function To_Set (Span : in Character_Range)return Character_Set; 10 function To_Ranges (Set : in Character_Set) return Character_Ranges; 11 function "=" (Left, Right : in Character_Set) return Boolean; 12 function "not" (Right : in Character_Set) return Character_Set; function "and" (Left, Right : in Character_Set) return Character_Set; function "or" (Left, Right : in Character_Set) return Character_Set; function "xor" (Left, Right : in Character_Set) return Character_Set; function "-" (Left, Right : in Character_Set) return Character_Set; 13 function Is_In (Element : in Character; Set : in Character_Set) return Boolean; 14 function Is_Subset (Elements : in Character_Set; Set : in Character_Set) return Boolean; 15 function "<=" (Left : in Character_Set; Right : in Character_Set) return Boolean renames Is_Subset; 16 -- Alternative representation for a set of character values: subtype Character_Sequence is String; 17 function To_Set (Sequence : in Character_Sequence)return Character_Set; 18 function To_Set (Singleton : in Character) return Character_Set; 19 function To_Sequence (Set : in Character_Set) return Character_Sequence; 20/2 -- Representation for a character to character mapping: type Character_Mapping is private; pragma Preelaborable_Initialization(Character_Mapping); 21 function Value (Map : in Character_Mapping; Element : in Character) return Character; 22 Identity : constant Character_Mapping; 23 function To_Mapping (From, To : in Character_Sequence) return Character_Mapping; 24 function To_Domain (Map : in Character_Mapping) return Character_Sequence; function To_Range (Map : in Character_Mapping) return Character_Sequence; 25 type Character_Mapping_Function is access function (From : in Character) return Character; 26 private ... -- not specified by the language end Ada.Strings.Maps; 27 An object of type Character_Set represents a set of characters. 28 Null_Set represents the set containing no characters. 29 An object Obj of type Character_Range represents the set of characters in the range Obj.Low .. Obj.High. 30 An object Obj of type Character_Ranges represents the union of the sets corresponding to Obj(I) for I in Obj'Range. 31 function To_Set (Ranges : in Character_Ranges) return Character_Set; 32/3 If Ranges'Length=0 then Null_Set is returned; otherwise, the returned value represents the set corresponding to Ranges. 33 function To_Set (Span : in Character_Range) return Character_Set; 34 The returned value represents the set containing each character in Span. 35 function To_Ranges (Set : in Character_Set) return Character_Ranges; 36/3 If Set = Null_Set, then an empty Character_Ranges array is returned; otherwise, the shortest array of contiguous ranges of Character values in Set, in increasing order of Low, is returned. 37 function "=" (Left, Right : in Character_Set) return Boolean; 38 The function "=" returns True if Left and Right represent identical sets, and False otherwise. 39 Each of the logical operators "not", "and", "or", and "xor" returns a Character_Set value that represents the set obtained by applying the corresponding operation to the set(s) represented by the parameter(s) of the operator. "-"(Left, Right) is equivalent to "and"(Left, "not"(Right)). 40 function Is_In (Element : in Character; Set : in Character_Set); return Boolean; 41 Is_In returns True if Element is in Set, and False otherwise. 42 function Is_Subset (Elements : in Character_Set; Set : in Character_Set) return Boolean; 43 Is_Subset returns True if Elements is a subset of Set, and False otherwise. 44 subtype Character_Sequence is String; 45 The Character_Sequence subtype is used to portray a set of character values and also to identify the domain and range of a character mapping. 46 function To_Set (Sequence : in Character_Sequence) return Character_Set; function To_Set (Singleton : in Character) return Character_Set; 47 Sequence portrays the set of character values that it explicitly contains (ignoring duplicates). Singleton portrays the set comprising a single Character. Each of the To_Set functions returns a Character_Set value that represents the set portrayed by Sequence or Singleton. 48 function To_Sequence (Set : in Character_Set) return Character_Sequence; 49 The function To_Sequence returns a Character_Sequence value containing each of the characters in the set represented by Set, in ascending order with no duplicates. 50 type Character_Mapping is private; 51 An object of type Character_Mapping represents a Character-to-Character mapping. 52 function Value (Map : in Character_Mapping; Element : in Character) return Character; 53 The function Value returns the Character value to which Element maps with respect to the mapping represented by Map. 54 A character C matches a pattern character P with respect to a given Character_Mapping value Map if Value(Map, C) = P. A string S matches a pattern string P with respect to a given Character_Mapping if their lengths are the same and if each character in S matches its corresponding character in the pattern string P. 55 String handling subprograms that deal with character mappings have parameters whose type is Character_Mapping. 56 Identity : constant Character_Mapping; 57 Identity maps each Character to itself. 58 function To_Mapping (From, To : in Character_Sequence) return Character_Mapping; 59 To_Mapping produces a Character_Mapping such that each element of From maps to the corresponding element of To, and each other character maps to itself. If From'Length /= To'Length, or if some character is repeated in From, then Translation_Error is propagated. 60 function To_Domain (Map : in Character_Mapping) return Character_Sequence; 61 To_Domain returns the shortest Character_Sequence value D such that each character not in D maps to itself, and such that the characters in D are in ascending order. The lower bound of D is 1. 62 function To_Range (Map : in Character_Mapping) return Character_Sequence; 63/1 To_Range returns the Character_Sequence value R, such that if D = To_Domain(Map), then R has the same bounds as D, and D(I) maps to R(I) for each I in D'Range. 64 An object F of type Character_Mapping_Function maps a Character value C to the Character value F.all(C), which is said to match C with respect to mapping function F. NOTES 65 10 Character_Mapping and Character_Mapping_Function are used both for character equivalence mappings in the search subprograms (such as for case insensitivity) and as transformational mappings in the Translate subprograms. 66 11 To_Domain(Identity) and To_Range(Identity) each returns the null string. Examples 67 To_Mapping("ABCD", "ZZAB") returns a Character_Mapping that maps 'A' and 'B' to 'Z', 'C' to 'A', 'D' to 'B', and each other Character to itself. A.4.3 Fixed-Length String Handling 1 The language-defined package Strings.Fixed provides string-handling subprograms for fixed-length strings; that is, for values of type Standard.String. Several of these subprograms are procedures that modify the contents of a String that is passed as an out or an in out parameter; each has additional parameters to control the effect when the logical length of the result differs from the parameter's length. 2 For each function that returns a String, the lower bound of the returned value is 1. 3 The basic model embodied in the package is that a fixed-length string comprises significant characters and possibly padding (with space characters) on either or both ends. When a shorter string is copied to a longer string, padding is inserted, and when a longer string is copied to a shorter one, padding is stripped. The Move procedure in Strings.Fixed, which takes a String as an out parameter, allows the programmer to control these effects. Similar control is provided by the string transformation procedures. Static Semantics 4 The library package Strings.Fixed has the following declaration: 5 with Ada.Strings.Maps; package Ada.Strings.Fixed is pragma Preelaborate(Fixed); 6 -- "Copy" procedure for strings of possibly different lengths 7 procedure Move (Source : in String; Target : out String; Drop : in Truncation := Error; Justify : in Alignment := Left; Pad : in Character := Space); 8 -- Search subprograms 8.1/2 function Index (Source : in String; Pattern : in String; From : in Positive; Going : in Direction := Forward; Mapping : in Maps.Character_Mapping := Maps.Identity) return Natural; 8.2/2 function Index (Source : in String; Pattern : in String; From : in Positive; Going : in Direction := Forward; Mapping : in Maps.Character_Mapping_Function) return Natural; 9 function Index (Source : in String; Pattern : in String; Going : in Direction := Forward; Mapping : in Maps.Character_Mapping := Maps.Identity) return Natural; 10 function Index (Source : in String; Pattern : in String; Going : in Direction := Forward; Mapping : in Maps.Character_Mapping_Function) return Natural; 10.1/2 function Index (Source : in String; Set : in Maps.Character_Set; From : in Positive; Test : in Membership := Inside; Going : in Direction := Forward) return Natural; 11 function Index (Source : in String; Set : in Maps.Character_Set; Test : in Membership := Inside; Going : in Direction := Forward) return Natural; 11.1/2 function Index_Non_Blank (Source : in String; From : in Positive; Going : in Direction := Forward) return Natural; 12 function Index_Non_Blank (Source : in String; Going : in Direction := Forward) return Natural; 13 function Count (Source : in String; Pattern : in String; Mapping : in Maps.Character_Mapping := Maps.Identity) return Natural; 14 function Count (Source : in String; Pattern : in String; Mapping : in Maps.Character_Mapping_Function) return Natural; 15 function Count (Source : in String; Set : in Maps.Character_Set) return Natural; 15.1/3 procedure Find_Token (Source : in String; Set : in Maps.Character_Set; From : in Positive; Test : in Membership; First : out Positive; Last : out Natural); 16 procedure Find_Token (Source : in String; Set : in Maps.Character_Set; Test : in Membership; First : out Positive; Last : out Natural); 17 -- String translation subprograms 18 function Translate (Source : in String; Mapping : in Maps.Character_Mapping) return String; 19 procedure Translate (Source : in out String; Mapping : in Maps.Character_Mapping); 20 function Translate (Source : in String; Mapping : in Maps.Character_Mapping_Function) return String; 21 procedure Translate (Source : in out String; Mapping : in Maps.Character_Mapping_Function); 22 -- String transformation subprograms 23 function Replace_Slice (Source : in String; Low : in Positive; High : in Natural; By : in String) return String; 24 procedure Replace_Slice (Source : in out String; Low : in Positive; High : in Natural; By : in String; Drop : in Truncation := Error; Justify : in Alignment := Left; Pad : in Character := Space); 25 function Insert (Source : in String; Before : in Positive; New_Item : in String) return String; 26 procedure Insert (Source : in out String; Before : in Positive; New_Item : in String; Drop : in Truncation := Error); 27 function Overwrite (Source : in String; Position : in Positive; New_Item : in String) return String; 28 procedure Overwrite (Source : in out String; Position : in Positive; New_Item : in String; Drop : in Truncation := Right); 29 function Delete (Source : in String; From : in Positive; Through : in Natural) return String; 30 procedure Delete (Source : in out String; From : in Positive; Through : in Natural; Justify : in Alignment := Left; Pad : in Character := Space); 31 --String selector subprograms function Trim (Source : in String; Side : in Trim_End) return String; 32 procedure Trim (Source : in out String; Side : in Trim_End; Justify : in Alignment := Left; Pad : in Character := Space); 33 function Trim (Source : in String; Left : in Maps.Character_Set; Right : in Maps.Character_Set) return String; 34 procedure Trim (Source : in out String; Left : in Maps.Character_Set; Right : in Maps.Character_Set; Justify : in Alignment := Strings.Left; Pad : in Character := Space); 35 function Head (Source : in String; Count : in Natural; Pad : in Character := Space) return String; 36 procedure Head (Source : in out String; Count : in Natural; Justify : in Alignment := Left; Pad : in Character := Space); 37 function Tail (Source : in String; Count : in Natural; Pad : in Character := Space) return String; 38 procedure Tail (Source : in out String; Count : in Natural; Justify : in Alignment := Left; Pad : in Character := Space); 39 --String constructor functions 40 function "*" (Left : in Natural; Right : in Character) return String; 41 function "*" (Left : in Natural; Right : in String) return String; 42 end Ada.Strings.Fixed; 43 The effects of the above subprograms are as follows. 44 procedure Move (Source : in String; Target : out String; Drop : in Truncation := Error; Justify : in Alignment := Left; Pad : in Character := Space); 45/3 The Move procedure copies characters from Source to Target. If Source has the same length as Target, then the effect is to assign Source to Target. If Source is shorter than Target, then: 46 * If Justify=Left, then Source is copied into the first Source'Length characters of Target. 47 * If Justify=Right, then Source is copied into the last Source'Length characters of Target. 48 * If Justify=Center, then Source is copied into the middle Source'Length characters of Target. In this case, if the difference in length between Target and Source is odd, then the extra Pad character is on the right. 49 * Pad is copied to each Target character not otherwise assigned. 50 If Source is longer than Target, then the effect is based on Drop. 51 * If Drop=Left, then the rightmost Target'Length characters of Source are copied into Target. 52 * If Drop=Right, then the leftmost Target'Length characters of Source are copied into Target. 53 * If Drop=Error, then the effect depends on the value of the Justify parameter and also on whether any characters in Source other than Pad would fail to be copied: 54 * If Justify=Left, and if each of the rightmost Source'Length-Target'Length characters in Source is Pad, then the leftmost Target'Length characters of Source are copied to Target. 55 * If Justify=Right, and if each of the leftmost Source'Length-Target'Length characters in Source is Pad, then the rightmost Target'Length characters of Source are copied to Target. 56 * Otherwise, Length_Error is propagated. 56.1/2 function Index (Source : in String; Pattern : in String; From : in Positive; Going : in Direction := Forward; Mapping : in Maps.Character_Mapping := Maps.Identity) return Natural; function Index (Source : in String; Pattern : in String; From : in Positive; Going : in Direction := Forward; Mapping : in Maps.Character_Mapping_Function) return Natural; 56.2/3 Each Index function searches, starting from From, for a slice of Source, with length Pattern'Length, that matches Pattern with respect to Mapping; the parameter Going indicates the direction of the lookup. If Source is the null string, Index returns 0; otherwise, if From is not in Source'Range, then Index_Error is propagated. If Going = Forward, then Index returns the smallest index I which is greater than or equal to From such that the slice of Source starting at I matches Pattern. If Going = Backward, then Index returns the largest index I such that the slice of Source starting at I matches Pattern and has an upper bound less than or equal to From. If there is no such slice, then 0 is returned. If Pattern is the null string, then Pattern_Error is propagated. 57 function Index (Source : in String; Pattern : in String; Going : in Direction := Forward; Mapping : in Maps.Character_Mapping := Maps.Identity) return Natural; function Index (Source : in String; Pattern : in String; Going : in Direction := Forward; Mapping : in Maps.Character_Mapping_Function) return Natural; 58/2 If Going = Forward, returns 58.1/2 Index (Source, Pattern, Source'First, Forward, Mapping); 58.2/3 otherwise, returns 58.3/2 Index (Source, Pattern, Source'Last, Backward, Mapping); 58.4/2 function Index (Source : in String; Set : in Maps.Character_Set; From : in Positive; Test : in Membership := Inside; Going : in Direction := Forward) return Natural; 58.5/3 Index searches for the first or last occurrence of any of a set of characters (when Test=Inside), or any of the complement of a set of characters (when Test=Outside). If Source is the null string, Index returns 0; otherwise, if From is not in Source'Range, then Index_Error is propagated. Otherwise, it returns the smallest index I >= From (if Going=Forward) or the largest index I <= From (if Going=Backward) such that Source(I) satisfies the Test condition with respect to Set; it returns 0 if there is no such Character in Source. 59 function Index (Source : in String; Set : in Maps.Character_Set; Test : in Membership := Inside; Going : in Direction := Forward) return Natural; 60/2 If Going = Forward, returns 60.1/2 Index (Source, Set, Source'First, Test, Forward); 60.2/3 otherwise, returns 60.3/2 Index (Source, Set, Source'Last, Test, Backward); 60.4/2 function Index_Non_Blank (Source : in String; From : in Positive; Going : in Direction := Forward) return Natural; 60.5/2 Returns Index (Source, Maps.To_Set(Space), From, Outside, Going); 61 function Index_Non_Blank (Source : in String; Going : in Direction := Forward) return Natural; 62 Returns Index(Source, Maps.To_Set(Space), Outside, Going) 63 function Count (Source : in String; Pattern : in String; Mapping : in Maps.Character_Mapping := Maps.Identity) return Natural; function Count (Source : in String; Pattern : in String; Mapping : in Maps.Character_Mapping_Function) return Natural; 64 Returns the maximum number of nonoverlapping slices of Source that match Pattern with respect to Mapping. If Pattern is the null string then Pattern_Error is propagated. 65 function Count (Source : in String; Set : in Maps.Character_Set) return Natural; 66 Returns the number of occurrences in Source of characters that are in Set. 66.1/3 procedure Find_Token (Source : in String; Set : in Maps.Character_Set; From : in Positive; Test : in Membership; First : out Positive; Last : out Natural); 66.2/3 If Source is not the null string and From is not in Source'Range, then Index_Error is raised. Otherwise, First is set to the index of the first character in Source(From .. Source'Last) that satisfies the Test condition. Last is set to the largest index such that all characters in Source(First .. Last) satisfy the Test condition. If no characters in Source(From .. Source'Last) satisfy the Test condition, First is set to From, and Last is set to 0. 67 procedure Find_Token (Source : in String; Set : in Maps.Character_Set; Test : in Membership; First : out Positive; Last : out Natural); 68/3 Equivalent to Find_Token (Source, Set, Source'First, Test, First, Last). 69 function Translate (Source : in String; Mapping : in Maps.Character_Mapping) return String; function Translate (Source : in String; Mapping : in Maps.Character_Mapping_Function) return String; 70 Returns the string S whose length is Source'Length and such that S(I) is the character to which Mapping maps the corresponding element of Source, for I in 1..Source'Length. 71 procedure Translate (Source : in out String; Mapping : in Maps.Character_Mapping); procedure Translate (Source : in out String; Mapping : in Maps.Character_Mapping_Function); 72 Equivalent to Source := Translate(Source, Mapping). 73 function Replace_Slice (Source : in String; Low : in Positive; High : in Natural; By : in String) return String; 74/1 If Low > Source'Last+1, or High < Source'First-1, then Index_Error is propagated. Otherwise: 74.1/1 * If High >= Low, then the returned string comprises Source(Source'First..Low-1) & By & Source(High+1..Source'Last), but with lower bound 1. 74.2/1 * If High < Low, then the returned string is Insert(Source, Before=>Low, New_Item=>By). 75 procedure Replace_Slice (Source : in out String; Low : in Positive; High : in Natural; By : in String; Drop : in Truncation := Error; Justify : in Alignment := Left; Pad : in Character := Space); 76 Equivalent to Move(Replace_Slice(Source, Low, High, By), Source, Drop, Justify, Pad). 77 function Insert (Source : in String; Before : in Positive; New_Item : in String) return String; 78/3 Propagates Index_Error if Before is not in Source'First .. Source'Last+1; otherwise, returns Source(Source'First..Before-1) & New_Item & Source(Before..Source'Last), but with lower bound 1. 79 procedure Insert (Source : in out String; Before : in Positive; New_Item : in String; Drop : in Truncation := Error); 80 Equivalent to Move(Insert(Source, Before, New_Item), Source, Drop). 81 function Overwrite (Source : in String; Position : in Positive; New_Item : in String) return String; 82/3 Propagates Index_Error if Position is not in Source'First .. Source'Last+1; otherwise, returns the string obtained from Source by consecutively replacing characters starting at Position with corresponding characters from New_Item. If the end of Source is reached before the characters in New_Item are exhausted, the remaining characters from New_Item are appended to the string. 83 procedure Overwrite (Source : in out String; Position : in Positive; New_Item : in String; Drop : in Truncation := Right); 84 Equivalent to Move(Overwrite(Source, Position, New_Item), Source, Drop). 85 function Delete (Source : in String; From : in Positive; Through : in Natural) return String; 86/3 If From <= Through, the returned string is Replace_Slice(Source, From, Through, ""); otherwise, it is Source with lower bound 1. 87 procedure Delete (Source : in out String; From : in Positive; Through : in Natural; Justify : in Alignment := Left; Pad : in Character := Space); 88 Equivalent to Move(Delete(Source, From, Through), Source, Justify => Justify, Pad => Pad). 89 function Trim (Source : in String; Side : in Trim_End) return String; 90 Returns the string obtained by removing from Source all leading Space characters (if Side = Left), all trailing Space characters (if Side = Right), or all leading and trailing Space characters (if Side = Both). 91 procedure Trim (Source : in out String; Side : in Trim_End; Justify : in Alignment := Left; Pad : in Character := Space); 92 Equivalent to Move(Trim(Source, Side), Source, Justify=>Justify, Pad=>Pad). 93 function Trim (Source : in String; Left : in Maps.Character_Set; Right : in Maps.Character_Set) return String; 94 Returns the string obtained by removing from Source all leading characters in Left and all trailing characters in Right. 95 procedure Trim (Source : in out String; Left : in Maps.Character_Set; Right : in Maps.Character_Set; Justify : in Alignment := Strings.Left; Pad : in Character := Space); 96 Equivalent to Move(Trim(Source, Left, Right), Source, Justify => Justify, Pad=>Pad). 97 function Head (Source : in String; Count : in Natural; Pad : in Character := Space) return String; 98/3 Returns a string of length Count. If Count <= Source'Length, the string comprises the first Count characters of Source. Otherwise, its contents are Source concatenated with Count-Source'Length Pad characters. 99 procedure Head (Source : in out String; Count : in Natural; Justify : in Alignment := Left; Pad : in Character := Space); 100 Equivalent to Move(Head(Source, Count, Pad), Source, Drop=>Error, Justify=>Justify, Pad=>Pad). 101 function Tail (Source : in String; Count : in Natural; Pad : in Character := Space) return String; 102/3 Returns a string of length Count. If Count <= Source'Length, the string comprises the last Count characters of Source. Otherwise, its contents are Count-Source'Length Pad characters concatenated with Source. 103 procedure Tail (Source : in out String; Count : in Natural; Justify : in Alignment := Left; Pad : in Character := Space); 104 Equivalent to Move(Tail(Source, Count, Pad), Source, Drop=>Error, Justify=>Justify, Pad=>Pad). 105 function "*" (Left : in Natural; Right : in Character) return String; function "*" (Left : in Natural; Right : in String) return String; 106/1 These functions replicate a character or string a specified number of times. The first function returns a string whose length is Left and each of whose elements is Right. The second function returns a string whose length is Left*Right'Length and whose value is the null string if Left = 0 and otherwise is (Left-1)*Right & Right with lower bound 1. NOTES 107/3 12 In the Index and Count functions taking Pattern and Mapping parameters, the actual String parameter passed to Pattern should comprise characters occurring as target characters of the mapping. Otherwise, the pattern will not match. 108 13 In the Insert subprograms, inserting at the end of a string is obtained by passing Source'Last+1 as the Before parameter. 109 14 If a null Character_Mapping_Function is passed to any of the string handling subprograms, Constraint_Error is propagated. A.4.4 Bounded-Length String Handling 1 The language-defined package Strings.Bounded provides a generic package each of whose instances yields a private type Bounded_String and a set of operations. An object of a particular Bounded_String type represents a String whose low bound is 1 and whose length can vary conceptually between 0 and a maximum size established at the generic instantiation. The subprograms for fixed-length string handling are either overloaded directly for Bounded_String, or are modified as needed to reflect the variability in length. Additionally, since the Bounded_String type is private, appropriate constructor and selector operations are provided. Static Semantics 2 The library package Strings.Bounded has the following declaration: 3 with Ada.Strings.Maps; package Ada.Strings.Bounded is pragma Preelaborate(Bounded); 4 generic Max : Positive; -- Maximum length of a Bounded_String package Generic_Bounded_Length is 5 Max_Length : constant Positive := Max; 6 type Bounded_String is private; 7 Null_Bounded_String : constant Bounded_String; 8 subtype Length_Range is Natural range 0 .. Max_Length; 9 function Length (Source : in Bounded_String) return Length_Range; 10 -- Conversion, Concatenation, and Selection functions 11 function To_Bounded_String (Source : in String; Drop : in Truncation := Error) return Bounded_String; 12 function To_String (Source : in Bounded_String) return String; 12.1/2 procedure Set_Bounded_String (Target : out Bounded_String; Source : in String; Drop : in Truncation := Error); 13 function Append (Left, Right : in Bounded_String; Drop : in Truncation := Error) return Bounded_String; 14 function Append (Left : in Bounded_String; Right : in String; Drop : in Truncation := Error) return Bounded_String; 15 function Append (Left : in String; Right : in Bounded_String; Drop : in Truncation := Error) return Bounded_String; 16 function Append (Left : in Bounded_String; Right : in Character; Drop : in Truncation := Error) return Bounded_String; 17 function Append (Left : in Character; Right : in Bounded_String; Drop : in Truncation := Error) return Bounded_String; 18 procedure Append (Source : in out Bounded_String; New_Item : in Bounded_String; Drop : in Truncation := Error); 19 procedure Append (Source : in out Bounded_String; New_Item : in String; Drop : in Truncation := Error); 20 procedure Append (Source : in out Bounded_String; New_Item : in Character; Drop : in Truncation := Error); 21 function "&" (Left, Right : in Bounded_String) return Bounded_String; 22 function "&" (Left : in Bounded_String; Right : in String) return Bounded_String; 23 function "&" (Left : in String; Right : in Bounded_String) return Bounded_String; 24 function "&" (Left : in Bounded_String; Right : in Character) return Bounded_String; 25 function "&" (Left : in Character; Right : in Bounded_String) return Bounded_String; 26 function Element (Source : in Bounded_String; Index : in Positive) return Character; 27 procedure Replace_Element (Source : in out Bounded_String; Index : in Positive; By : in Character); 28 function Slice (Source : in Bounded_String; Low : in Positive; High : in Natural) return String; 28.1/2 function Bounded_Slice (Source : in Bounded_String; Low : in Positive; High : in Natural) return Bounded_String; 28.2/2 procedure Bounded_Slice (Source : in Bounded_String; Target : out Bounded_String; Low : in Positive; High : in Natural); 29 function "=" (Left, Right : in Bounded_String) return Boolean; function "=" (Left : in Bounded_String; Right : in String) return Boolean; 30 function "=" (Left : in String; Right : in Bounded_String) return Boolean; 31 function "<" (Left, Right : in Bounded_String) return Boolean; 32 function "<" (Left : in Bounded_String; Right : in String) return Boolean; 33 function "<" (Left : in String; Right : in Bounded_String) return Boolean; 34 function "<=" (Left, Right : in Bounded_String) return Boolean; 35 function "<=" (Left : in Bounded_String; Right : in String) return Boolean; 36 function "<=" (Left : in String; Right : in Bounded_String) return Boolean; 37 function ">" (Left, Right : in Bounded_String) return Boolean; 38 function ">" (Left : in Bounded_String; Right : in String) return Boolean; 39 function ">" (Left : in String; Right : in Bounded_String) return Boolean; 40 function ">=" (Left, Right : in Bounded_String) return Boolean; 41 function ">=" (Left : in Bounded_String; Right : in String) return Boolean; 42 function ">=" (Left : in String; Right : in Bounded_String) return Boolean; 43/2 -- Search subprograms 43.1/2 function Index (Source : in Bounded_String; Pattern : in String; From : in Positive; Going : in Direction := Forward; Mapping : in Maps.Character_Mapping := Maps.Identity) return Natural; 43.2/2 function Index (Source : in Bounded_String; Pattern : in String; From : in Positive; Going : in Direction := Forward; Mapping : in Maps.Character_Mapping_Function) return Natural; 44 function Index (Source : in Bounded_String; Pattern : in String; Going : in Direction := Forward; Mapping : in Maps.Character_Mapping := Maps.Identity) return Natural; 45 function Index (Source : in Bounded_String; Pattern : in String; Going : in Direction := Forward; Mapping : in Maps.Character_Mapping_Function) return Natural; 45.1/2 function Index (Source : in Bounded_String; Set : in Maps.Character_Set; From : in Positive; Test : in Membership := Inside; Going : in Direction := Forward) return Natural; 46 function Index (Source : in Bounded_String; Set : in Maps.Character_Set; Test : in Membership := Inside; Going : in Direction := Forward) return Natural; 46.1/2 function Index_Non_Blank (Source : in Bounded_String; From : in Positive; Going : in Direction := Forward) return Natural; 47 function Index_Non_Blank (Source : in Bounded_String; Going : in Direction := Forward) return Natural; 48 function Count (Source : in Bounded_String; Pattern : in String; Mapping : in Maps.Character_Mapping := Maps.Identity) return Natural; 49 function Count (Source : in Bounded_String; Pattern : in String; Mapping : in Maps.Character_Mapping_Function) return Natural; 50 function Count (Source : in Bounded_String; Set : in Maps.Character_Set) return Natural; 50.1/3 procedure Find_Token (Source : in Bounded_String; Set : in Maps.Character_Set; From : in Positive; Test : in Membership; First : out Positive; Last : out Natural); 51 procedure Find_Token (Source : in Bounded_String; Set : in Maps.Character_Set; Test : in Membership; First : out Positive; Last : out Natural); 52 -- String translation subprograms 53 function Translate (Source : in Bounded_String; Mapping : in Maps.Character_Mapping) return Bounded_String; 54 procedure Translate (Source : in out Bounded_String; Mapping : in Maps.Character_Mapping); 55 function Translate (Source : in Bounded_String; Mapping : in Maps.Character_Mapping_Function) return Bounded_String; 56 procedure Translate (Source : in out Bounded_String; Mapping : in Maps.Character_Mapping_Function); 57 -- String transformation subprograms 58 function Replace_Slice (Source : in Bounded_String; Low : in Positive; High : in Natural; By : in String; Drop : in Truncation := Error) return Bounded_String; 59 procedure Replace_Slice (Source : in out Bounded_String; Low : in Positive; High : in Natural; By : in String; Drop : in Truncation := Error); 60 function Insert (Source : in Bounded_String; Before : in Positive; New_Item : in String; Drop : in Truncation := Error) return Bounded_String; 61 procedure Insert (Source : in out Bounded_String; Before : in Positive; New_Item : in String; Drop : in Truncation := Error); 62 function Overwrite (Source : in Bounded_String; Position : in Positive; New_Item : in String; Drop : in Truncation := Error) return Bounded_String; 63 procedure Overwrite (Source : in out Bounded_String; Position : in Positive; New_Item : in String; Drop : in Truncation := Error); 64 function Delete (Source : in Bounded_String; From : in Positive; Through : in Natural) return Bounded_String; 65 procedure Delete (Source : in out Bounded_String; From : in Positive; Through : in Natural); 66 --String selector subprograms 67 function Trim (Source : in Bounded_String; Side : in Trim_End) return Bounded_String; procedure Trim (Source : in out Bounded_String; Side : in Trim_End); 68 function Trim (Source : in Bounded_String; Left : in Maps.Character_Set; Right : in Maps.Character_Set) return Bounded_String; 69 procedure Trim (Source : in out Bounded_String; Left : in Maps.Character_Set; Right : in Maps.Character_Set); 70 function Head (Source : in Bounded_String; Count : in Natural; Pad : in Character := Space; Drop : in Truncation := Error) return Bounded_String; 71 procedure Head (Source : in out Bounded_String; Count : in Natural; Pad : in Character := Space; Drop : in Truncation := Error); 72 function Tail (Source : in Bounded_String; Count : in Natural; Pad : in Character := Space; Drop : in Truncation := Error) return Bounded_String; 73 procedure Tail (Source : in out Bounded_String; Count : in Natural; Pad : in Character := Space; Drop : in Truncation := Error); 74 --String constructor subprograms 75 function "*" (Left : in Natural; Right : in Character) return Bounded_String; 76 function "*" (Left : in Natural; Right : in String) return Bounded_String; 77 function "*" (Left : in Natural; Right : in Bounded_String) return Bounded_String; 78 function Replicate (Count : in Natural; Item : in Character; Drop : in Truncation := Error) return Bounded_String; 79 function Replicate (Count : in Natural; Item : in String; Drop : in Truncation := Error) return Bounded_String; 80 function Replicate (Count : in Natural; Item : in Bounded_String; Drop : in Truncation := Error) return Bounded_String; 81 private ... -- not specified by the language end Generic_Bounded_Length; 82 end Ada.Strings.Bounded; 83 Null_Bounded_String represents the null string. If an object of type Bounded_String is not otherwise initialized, it will be initialized to the same value as Null_Bounded_String. 84 function Length (Source : in Bounded_String) return Length_Range; 85 The Length function returns the length of the string represented by Source. 86 function To_Bounded_String (Source : in String; Drop : in Truncation := Error) return Bounded_String; 87/3 If Source'Length <= Max_Length, then this function returns a Bounded_String that represents Source. Otherwise, the effect depends on the value of Drop: 88 * If Drop=Left, then the result is a Bounded_String that represents the string comprising the rightmost Max_Length characters of Source. 89 * If Drop=Right, then the result is a Bounded_String that represents the string comprising the leftmost Max_Length characters of Source. 90 * If Drop=Error, then Strings.Length_Error is propagated. 91 function To_String (Source : in Bounded_String) return String; 92 To_String returns the String value with lower bound 1 represented by Source. If B is a Bounded_String, then B = To_Bounded_String(To_String(B)). 92.1/2 procedure Set_Bounded_String (Target : out Bounded_String; Source : in String; Drop : in Truncation := Error); 92.2/2 Equivalent to Target := To_Bounded_String (Source, Drop); 93 Each of the Append functions returns a Bounded_String obtained by concatenating the string or character given or represented by one of the parameters, with the string or character given or represented by the other parameter, and applying To_Bounded_String to the concatenation result string, with Drop as provided to the Append function. 94 Each of the procedures Append(Source, New_Item, Drop) has the same effect as the corresponding assignment Source := Append(Source, New_Item, Drop). 95 Each of the "&" functions has the same effect as the corresponding Append function, with Error as the Drop parameter. 96 function Element (Source : in Bounded_String; Index : in Positive) return Character; 97 Returns the character at position Index in the string represented by Source; propagates Index_Error if Index > Length(Source). 98 procedure Replace_Element (Source : in out Bounded_String; Index : in Positive; By : in Character); 99 Updates Source such that the character at position Index in the string represented by Source is By; propagates Index_Error if Index > Length(Source). 100 function Slice (Source : in Bounded_String; Low : in Positive; High : in Natural) return String; 101/1 Returns the slice at positions Low through High in the string represented by Source; propagates Index_Error if Low > Length(Source)+1 or High > Length(Source). The bounds of the returned string are Low and High.. 101.1/2 function Bounded_Slice (Source : in Bounded_String; Low : in Positive; High : in Natural) return Bounded_String; 101.2/2 Returns the slice at positions Low through High in the string represented by Source as a bounded string; propagates Index_Error if Low > Length(Source)+1 or High > Length(Source). 101.3/2 procedure Bounded_Slice (Source : in Bounded_String; Target : out Bounded_String; Low : in Positive; High : in Natural); 101.4/2 Equivalent to Target := Bounded_Slice (Source, Low, High); 102 Each of the functions "=", "<", ">", "<=", and ">=" returns the same result as the corresponding String operation applied to the String values given or represented by the two parameters. 103 Each of the search subprograms (Index, Index_Non_Blank, Count, Find_Token) has the same effect as the corresponding subprogram in Strings.Fixed applied to the string represented by the Bounded_String parameter. 104 Each of the Translate subprograms, when applied to a Bounded_String, has an analogous effect to the corresponding subprogram in Strings.Fixed. For the Translate function, the translation is applied to the string represented by the Bounded_String parameter, and the result is converted (via To_Bounded_String) to a Bounded_String. For the Translate procedure, the string represented by the Bounded_String parameter after the translation is given by the Translate function for fixed-length strings applied to the string represented by the original value of the parameter. 105/1 Each of the transformation subprograms (Replace_Slice, Insert, Overwrite, Delete), selector subprograms (Trim, Head, Tail), and constructor functions ("*") has an effect based on its corresponding subprogram in Strings.Fixed, and Replicate is based on Fixed."*". In the case of a function, the corresponding fixed-length string subprogram is applied to the string represented by the Bounded_String parameter. To_Bounded_String is applied the result string, with Drop (or Error in the case of Generic_Bounded_Length."*") determining the effect when the string length exceeds Max_Length. In the case of a procedure, the corresponding function in Strings.Bounded.Generic_Bounded_- Length is applied, with the result assigned into the Source parameter. Implementation Advice 106 Bounded string objects should not be implemented by implicit pointers and dynamic allocation. A.4.5 Unbounded-Length String Handling 1 The language-defined package Strings.Unbounded provides a private type Unbounded_String and a set of operations. An object of type Unbounded_String represents a String whose low bound is 1 and whose length can vary conceptually between 0 and Natural'Last. The subprograms for fixed-length string handling are either overloaded directly for Unbounded_String, or are modified as needed to reflect the flexibility in length. Since the Unbounded_String type is private, relevant constructor and selector operations are provided. Static Semantics 2 The library package Strings.Unbounded has the following declaration: 3 with Ada.Strings.Maps; package Ada.Strings.Unbounded is pragma Preelaborate(Unbounded); 4/2 type Unbounded_String is private; pragma Preelaborable_Initialization(Unbounded_String); 5 Null_Unbounded_String : constant Unbounded_String; 6 function Length (Source : in Unbounded_String) return Natural; 7 type String_Access is access all String; procedure Free (X : in out String_Access); 8 -- Conversion, Concatenation, and Selection functions 9 function To_Unbounded_String (Source : in String) return Unbounded_String; 10 function To_Unbounded_String (Length : in Natural) return Unbounded_String; 11 function To_String (Source : in Unbounded_String) return String; 11.1/2 procedure Set_Unbounded_String (Target : out Unbounded_String; Source : in String); 12 procedure Append (Source : in out Unbounded_String; New_Item : in Unbounded_String); 13 procedure Append (Source : in out Unbounded_String; New_Item : in String); 14 procedure Append (Source : in out Unbounded_String; New_Item : in Character); 15 function "&" (Left, Right : in Unbounded_String) return Unbounded_String; 16 function "&" (Left : in Unbounded_String; Right : in String) return Unbounded_String; 17 function "&" (Left : in String; Right : in Unbounded_String) return Unbounded_String; 18 function "&" (Left : in Unbounded_String; Right : in Character) return Unbounded_String; 19 function "&" (Left : in Character; Right : in Unbounded_String) return Unbounded_String; 20 function Element (Source : in Unbounded_String; Index : in Positive) return Character; 21 procedure Replace_Element (Source : in out Unbounded_String; Index : in Positive; By : in Character); 22 function Slice (Source : in Unbounded_String; Low : in Positive; High : in Natural) return String; 22.1/2 function Unbounded_Slice (Source : in Unbounded_String; Low : in Positive; High : in Natural) return Unbounded_String; 22.2/2 procedure Unbounded_Slice (Source : in Unbounded_String; Target : out Unbounded_String; Low : in Positive; High : in Natural); 23 function "=" (Left, Right : in Unbounded_String) return Boolean; 24 function "=" (Left : in Unbounded_String; Right : in String) return Boolean; 25 function "=" (Left : in String; Right : in Unbounded_String) return Boolean; 26 function "<" (Left, Right : in Unbounded_String) return Boolean; 27 function "<" (Left : in Unbounded_String; Right : in String) return Boolean; 28 function "<" (Left : in String; Right : in Unbounded_String) return Boolean; 29 function "<=" (Left, Right : in Unbounded_String) return Boolean; 30 function "<=" (Left : in Unbounded_String; Right : in String) return Boolean; 31 function "<=" (Left : in String; Right : in Unbounded_String) return Boolean; 32 function ">" (Left, Right : in Unbounded_String) return Boolean; 33 function ">" (Left : in Unbounded_String; Right : in String) return Boolean; 34 function ">" (Left : in String; Right : in Unbounded_String) return Boolean; 35 function ">=" (Left, Right : in Unbounded_String) return Boolean; 36 function ">=" (Left : in Unbounded_String; Right : in String) return Boolean; 37 function ">=" (Left : in String; Right : in Unbounded_String) return Boolean; 38 -- Search subprograms 38.1/2 function Index (Source : in Unbounded_String; Pattern : in String; From : in Positive; Going : in Direction := Forward; Mapping : in Maps.Character_Mapping := Maps.Identity) return Natural; 38.2/2 function Index (Source : in Unbounded_String; Pattern : in String; From : in Positive; Going : in Direction := Forward; Mapping : in Maps.Character_Mapping_Function) return Natural; 39 function Index (Source : in Unbounded_String; Pattern : in String; Going : in Direction := Forward; Mapping : in Maps.Character_Mapping := Maps.Identity) return Natural; 40 function Index (Source : in Unbounded_String; Pattern : in String; Going : in Direction := Forward; Mapping : in Maps.Character_Mapping_Function) return Natural; 40.1/2 function Index (Source : in Unbounded_String; Set : in Maps.Character_Set; From : in Positive; Test : in Membership := Inside; Going : in Direction := Forward) return Natural; 41 function Index (Source : in Unbounded_String; Set : in Maps.Character_Set; Test : in Membership := Inside; Going : in Direction := Forward) return Natural; 41.1/2 function Index_Non_Blank (Source : in Unbounded_String; From : in Positive; Going : in Direction := Forward) return Natural; 42 function Index_Non_Blank (Source : in Unbounded_String; Going : in Direction := Forward) return Natural; 43 function Count (Source : in Unbounded_String; Pattern : in String; Mapping : in Maps.Character_Mapping := Maps.Identity) return Natural; 44 function Count (Source : in Unbounded_String; Pattern : in String; Mapping : in Maps.Character_Mapping_Function) return Natural; 45 function Count (Source : in Unbounded_String; Set : in Maps.Character_Set) return Natural; 45.1/3 procedure Find_Token (Source : in Unbounded_String; Set : in Maps.Character_Set; From : in Positive; Test : in Membership; First : out Positive; Last : out Natural); 46 procedure Find_Token (Source : in Unbounded_String; Set : in Maps.Character_Set; Test : in Membership; First : out Positive; Last : out Natural); 47 -- String translation subprograms 48 function Translate (Source : in Unbounded_String; Mapping : in Maps.Character_Mapping) return Unbounded_String; 49 procedure Translate (Source : in out Unbounded_String; Mapping : in Maps.Character_Mapping); 50 function Translate (Source : in Unbounded_String; Mapping : in Maps.Character_Mapping_Function) return Unbounded_String; 51 procedure Translate (Source : in out Unbounded_String; Mapping : in Maps.Character_Mapping_Function); 52 -- String transformation subprograms 53 function Replace_Slice (Source : in Unbounded_String; Low : in Positive; High : in Natural; By : in String) return Unbounded_String; 54 procedure Replace_Slice (Source : in out Unbounded_String; Low : in Positive; High : in Natural; By : in String); 55 function Insert (Source : in Unbounded_String; Before : in Positive; New_Item : in String) return Unbounded_String; 56 procedure Insert (Source : in out Unbounded_String; Before : in Positive; New_Item : in String); 57 function Overwrite (Source : in Unbounded_String; Position : in Positive; New_Item : in String) return Unbounded_String; 58 procedure Overwrite (Source : in out Unbounded_String; Position : in Positive; New_Item : in String); 59 function Delete (Source : in Unbounded_String; From : in Positive; Through : in Natural) return Unbounded_String; 60 procedure Delete (Source : in out Unbounded_String; From : in Positive; Through : in Natural); 61 function Trim (Source : in Unbounded_String; Side : in Trim_End) return Unbounded_String; 62 procedure Trim (Source : in out Unbounded_String; Side : in Trim_End); 63 function Trim (Source : in Unbounded_String; Left : in Maps.Character_Set; Right : in Maps.Character_Set) return Unbounded_String; 64 procedure Trim (Source : in out Unbounded_String; Left : in Maps.Character_Set; Right : in Maps.Character_Set); 65 function Head (Source : in Unbounded_String; Count : in Natural; Pad : in Character := Space) return Unbounded_String; 66 procedure Head (Source : in out Unbounded_String; Count : in Natural; Pad : in Character := Space); 67 function Tail (Source : in Unbounded_String; Count : in Natural; Pad : in Character := Space) return Unbounded_String; 68 procedure Tail (Source : in out Unbounded_String; Count : in Natural; Pad : in Character := Space); 69 function "*" (Left : in Natural; Right : in Character) return Unbounded_String; 70 function "*" (Left : in Natural; Right : in String) return Unbounded_String; 71 function "*" (Left : in Natural; Right : in Unbounded_String) return Unbounded_String; 72 private ... -- not specified by the language end Ada.Strings.Unbounded; 72.1/2 The type Unbounded_String needs finalization (see 7.6). 73 Null_Unbounded_String represents the null String. If an object of type Unbounded_String is not otherwise initialized, it will be initialized to the same value as Null_Unbounded_String. 74 The function Length returns the length of the String represented by Source. 75 The type String_Access provides a (nonprivate) access type for explicit processing of unbounded-length strings. The procedure Free performs an unchecked deallocation of an object of type String_Access. 76 The function To_Unbounded_String(Source : in String) returns an Unbounded_String that represents Source. The function To_Unbounded_String(Length : in Natural) returns an Unbounded_String that represents an uninitialized String whose length is Length. 77 The function To_String returns the String with lower bound 1 represented by Source. To_String and To_Unbounded_String are related as follows: 78 * If S is a String, then To_String(To_Unbounded_String(S)) = S. 79 * If U is an Unbounded_String, then To_Unbounded_String(To_String(U)) = U. 79.1/2 The procedure Set_Unbounded_String sets Target to an Unbounded_String that represents Source. 80 For each of the Append procedures, the resulting string represented by the Source parameter is given by the concatenation of the original value of Source and the value of New_Item. 81 Each of the "&" functions returns an Unbounded_String obtained by concatenating the string or character given or represented by one of the parameters, with the string or character given or represented by the other parameter, and applying To_Unbounded_String to the concatenation result string. 82 The Element, Replace_Element, and Slice subprograms have the same effect as the corresponding bounded-length string subprograms. 82.1/3 The function Unbounded_Slice returns the slice at positions Low through High in the string represented by Source as an Unbounded_String. The procedure Unbounded_Slice sets Target to the Unbounded_String representing the slice at positions Low through High in the string represented by Source. Both subprograms propagate Index_Error if Low > Length(Source)+1 or High > Length(Source). 83 Each of the functions "=", "<", ">", "<=", and ">=" returns the same result as the corresponding String operation applied to the String values given or represented by Left and Right. 84 Each of the search subprograms (Index, Index_Non_Blank, Count, Find_Token) has the same effect as the corresponding subprogram in Strings.Fixed applied to the string represented by the Unbounded_String parameter. 85 The Translate function has an analogous effect to the corresponding subprogram in Strings.Fixed. The translation is applied to the string represented by the Unbounded_String parameter, and the result is converted (via To_Unbounded_String) to an Unbounded_String. 86 Each of the transformation functions (Replace_Slice, Insert, Overwrite, Delete), selector functions (Trim, Head, Tail), and constructor functions ("*") is likewise analogous to its corresponding subprogram in Strings.Fixed. For each of the subprograms, the corresponding fixed-length string subprogram is applied to the string represented by the Unbounded_String parameter, and To_Unbounded_String is applied the result string. 87 For each of the procedures Translate, Replace_Slice, Insert, Overwrite, Delete, Trim, Head, and Tail, the resulting string represented by the Source parameter is given by the corresponding function for fixed-length strings applied to the string represented by Source's original value. Implementation Requirements 88 No storage associated with an Unbounded_String object shall be lost upon assignment or scope exit. A.4.6 String-Handling Sets and Mappings 1 The language-defined package Strings.Maps.Constants declares Character_Set and Character_Mapping constants corresponding to classification and conversion functions in package Characters.Handling. Static Semantics 2 The library package Strings.Maps.Constants has the following declaration: 3/2 package Ada.Strings.Maps.Constants is pragma Pure(Constants); 4 Control_Set : constant Character_Set; Graphic_Set : constant Character_Set; Letter_Set : constant Character_Set; Lower_Set : constant Character_Set; Upper_Set : constant Character_Set; Basic_Set : constant Character_Set; Decimal_Digit_Set : constant Character_Set; Hexadecimal_Digit_Set : constant Character_Set; Alphanumeric_Set : constant Character_Set; Special_Set : constant Character_Set; ISO_646_Set : constant Character_Set; 5 Lower_Case_Map : constant Character_Mapping; --Maps to lower case for letters, else identity Upper_Case_Map : constant Character_Mapping; --Maps to upper case for letters, else identity Basic_Map : constant Character_Mapping; --Maps to basic letter for letters, else identity 6 private ... -- not specified by the language end Ada.Strings.Maps.Constants; 7 Each of these constants represents a correspondingly named set of characters or character mapping in Characters.Handling (see A.3.2). NOTES 8/3 15 There are certain characters which are defined to be lower case letters by ISO 10646 and are therefore allowed in identifiers, but are not considered lower case letters by Ada.Strings.Maps.Constants. A.4.7 Wide_String Handling 1/3 Facilities for handling strings of Wide_Character elements are found in the packages Strings.Wide_Maps, Strings.Wide_Fixed, Strings.Wide_Bounded, Strings.Wide_Unbounded, and Strings.Wide_Maps.Wide_Constants, and in the library functions Strings.Wide_Hash, Strings.Wide_Fixed.Wide_Hash, Strings.- Wide_Bounded.Wide_Hash, Strings.Wide_Unbounded.Wide_Hash, Strings.Wide_- Hash_Case_Insensitive, Strings.Wide_Fixed.Wide_Hash_Case_Insensitive, Strings.- Wide_Bounded.Wide_Hash_Case_Insensitive, Strings.Wide_Unbounded.Wide_Hash_- Case_Insensitive, Strings.Wide_Equal_Case_Insensitive, Strings.Wide_Fixed.Wide_- Equal_Case_Insensitive, Strings.Wide_Bounded.Wide_Equal_Case_Insensitive, and Strings.Wide_Unbounded.Wide_Equal_Case_Insensitive. They provide the same string-handling operations as the corresponding packages and functions for strings of Character elements. Static Semantics 2 The package Strings.Wide_Maps has the following declaration. 3 package Ada.Strings.Wide_Maps is pragma Preelaborate(Wide_Maps); 4/2 -- Representation for a set of Wide_Character values: type Wide_Character_Set is private; pragma Preelaborable_Initialization(Wide_Character_Set); 5 Null_Set : constant Wide_Character_Set; 6 type Wide_Character_Range is record Low : Wide_Character; High : Wide_Character; end record; -- Represents Wide_Character range Low..High 7 type Wide_Character_Ranges is array (Positive range <>) of Wide_Character_Range; 8 function To_Set (Ranges : in Wide_Character_Ranges) return Wide_Character_Set; 9 function To_Set (Span : in Wide_Character_Range) return Wide_Character_Set; 10 function To_Ranges (Set : in Wide_Character_Set) return Wide_Character_Ranges; 11 function "=" (Left, Right : in Wide_Character_Set) return Boolean; 12 function "not" (Right : in Wide_Character_Set) return Wide_Character_Set; function "and" (Left, Right : in Wide_Character_Set) return Wide_Character_Set; function "or" (Left, Right : in Wide_Character_Set) return Wide_Character_Set; function "xor" (Left, Right : in Wide_Character_Set) return Wide_Character_Set; function "-" (Left, Right : in Wide_Character_Set) return Wide_Character_Set; 13 function Is_In (Element : in Wide_Character; Set : in Wide_Character_Set) return Boolean; 14 function Is_Subset (Elements : in Wide_Character_Set; Set : in Wide_Character_Set) return Boolean; 15 function "<=" (Left : in Wide_Character_Set; Right : in Wide_Character_Set) return Boolean renames Is_Subset; 16 -- Alternative representation for a set of Wide_Character values: subtype Wide_Character_Sequence is Wide_String; 17 function To_Set (Sequence : in Wide_Character_Sequence) return Wide_Character_Set; 18 function To_Set (Singleton : in Wide_Character) return Wide_Character_Set; 19 function To_Sequence (Set : in Wide_Character_Set) return Wide_Character_Sequence; 20/2 -- Representation for a Wide_Character to Wide_Character mapping: type Wide_Character_Mapping is private; pragma Preelaborable_Initialization(Wide_Character_Mapping); 21 function Value (Map : in Wide_Character_Mapping; Element : in Wide_Character) return Wide_Character; 22 Identity : constant Wide_Character_Mapping; 23 function To_Mapping (From, To : in Wide_Character_Sequence) return Wide_Character_Mapping; 24 function To_Domain (Map : in Wide_Character_Mapping) return Wide_Character_Sequence; 25 function To_Range (Map : in Wide_Character_Mapping) return Wide_Character_Sequence; 26 type Wide_Character_Mapping_Function is access function (From : in Wide_Character) return Wide_Character; 27 private ... -- not specified by the language end Ada.Strings.Wide_Maps; 28 The context clause for each of the packages Strings.Wide_Fixed, Strings.Wide_Bounded, and Strings.Wide_Unbounded identifies Strings.Wide_Maps instead of Strings.Maps. 28.1/3 Types Wide_Character_Set and Wide_Character_Mapping need finalization. 29/3 For each of the packages Strings.Fixed, Strings.Bounded, Strings.Unbounded, and Strings.Maps.Constants, and for library functions Strings.Hash, Strings.Fixed.Hash, Strings.Bounded.Hash, Strings.Unbounded.Hash, Strings.Hash_Case_Insensitive, Strings.Fixed.Hash_- Case_Insensitive, Strings.Bounded.Hash_Case_Insensitive, Strings.Unbounded.Hash_Case_Insensitive, Strings.Equal_Case_Insensitive, Strings.Fixed.Equal_Case_Insensitive, Strings.Bounded.Equal_Case_Insensitive, and Strings.Unbounded.Equal_Case_Insensitive, the corresponding wide string package or function has the same contents except that 30 * Wide_Space replaces Space 31 * Wide_Character replaces Character 32 * Wide_String replaces String 33 * Wide_Character_Set replaces Character_Set 34 * Wide_Character_Mapping replaces Character_Mapping 35 * Wide_Character_Mapping_Function replaces Character_Mapping_Function 36 * Wide_Maps replaces Maps 37 * Bounded_Wide_String replaces Bounded_String 38 * Null_Bounded_Wide_String replaces Null_Bounded_String 39 * To_Bounded_Wide_String replaces To_Bounded_String 40 * To_Wide_String replaces To_String 40.1/2 * Set_Bounded_Wide_String replaces Set_Bounded_String 41 * Unbounded_Wide_String replaces Unbounded_String 42 * Null_Unbounded_Wide_String replaces Null_Unbounded_String 43 * Wide_String_Access replaces String_Access 44 * To_Unbounded_Wide_String replaces To_Unbounded_String 44.1/2 * Set_Unbounded_Wide_String replaces Set_Unbounded_String 45 The following additional declaration is present in Strings.Wide_Maps.Wide_Constants: 46/2 Character_Set : constant Wide_Maps.Wide_Character_Set; --Contains each Wide_Character value WC such that --Characters.Conversions.Is_Character(WC) is True 46.1/2 Each Wide_Character_Set constant in the package Strings.Wide_Maps.Wide_Constants contains no values outside the Character portion of Wide_Character. Similarly, each Wide_Character_Mapping constant in this package is the identity mapping when applied to any element outside the Character portion of Wide_Character. 46.2/2 Pragma Pure is replaced by pragma Preelaborate in Strings.Wide_Maps.Wide_Constants. NOTES 47 16 If a null Wide_Character_Mapping_Function is passed to any of the Wide_String handling subprograms, Constraint_Error is propagated. A.4.8 Wide_Wide_String Handling 1/3 Facilities for handling strings of Wide_Wide_Character elements are found in the packages Strings.Wide_Wide_Maps, Strings.Wide_Wide_Fixed, Strings.- Wide_Wide_Bounded, Strings.Wide_Wide_Unbounded, and Strings.Wide_Wide_Maps.- Wide_Wide_Constants, and in the library functions Strings.Wide_Wide_Hash, Strings.Wide_Wide_Fixed.Wide_Wide_Hash, Strings.Wide_Wide_Bounded.Wide_- Wide_Hash, Strings.Wide_Wide_Unbounded.Wide_Wide_Hash, Strings.Wide_Wide_- Hash_Case_Insensitive, Strings.Wide_Wide_Fixed.Wide_Wide_Hash_Case_Insensitive, Strings.Wide_Wide_Bounded.Wide_Wide_Hash_Case_Insensitive, Strings.Wide_Wide_- Unbounded.Wide_Wide_Hash_Case_Insensitive, Strings.Wide_Wide_Equal_Case_- Insensitive, Strings.Wide_Wide_Fixed.Wide_Wide_Equal_Case_Insensitive, Strings.- Wide_Wide_Bounded.Wide_Wide_Equal_Case_Insensitive, and Strings.Wide_Wide_- Unbounded.Wide_Wide_Equal_Case_Insensitive. They provide the same string-handling operations as the corresponding packages and functions for strings of Character elements. Static Semantics 2/2 The library package Strings.Wide_Wide_Maps has the following declaration. 3/2 package Ada.Strings.Wide_Wide_Maps is pragma Preelaborate(Wide_Wide_Maps); 4/2 -- Representation for a set of Wide_Wide_Character values: type Wide_Wide_Character_Set is private; pragma Preelaborable_Initialization(Wide_Wide_Character_Set); 5/2 Null_Set : constant Wide_Wide_Character_Set; 6/2 type Wide_Wide_Character_Range is record Low : Wide_Wide_Character; High : Wide_Wide_Character; end record; -- Represents Wide_Wide_Character range Low..High 7/2 type Wide_Wide_Character_Ranges is array (Positive range <>) of Wide_Wide_Character_Range; 8/2 function To_Set (Ranges : in Wide_Wide_Character_Ranges) return Wide_Wide_Character_Set; 9/2 function To_Set (Span : in Wide_Wide_Character_Range) return Wide_Wide_Character_Set; 10/2 function To_Ranges (Set : in Wide_Wide_Character_Set) return Wide_Wide_Character_Ranges; 11/2 function "=" (Left, Right : in Wide_Wide_Character_Set) return Boolean; 12/2 function "not" (Right : in Wide_Wide_Character_Set) return Wide_Wide_Character_Set; function "and" (Left, Right : in Wide_Wide_Character_Set) return Wide_Wide_Character_Set; function "or" (Left, Right : in Wide_Wide_Character_Set) return Wide_Wide_Character_Set; function "xor" (Left, Right : in Wide_Wide_Character_Set) return Wide_Wide_Character_Set; function "-" (Left, Right : in Wide_Wide_Character_Set) return Wide_Wide_Character_Set; 13/2 function Is_In (Element : in Wide_Wide_Character; Set : in Wide_Wide_Character_Set) return Boolean; 14/2 function Is_Subset (Elements : in Wide_Wide_Character_Set; Set : in Wide_Wide_Character_Set) return Boolean; 15/2 function "<=" (Left : in Wide_Wide_Character_Set; Right : in Wide_Wide_Character_Set) return Boolean renames Is_Subset; 16/2 -- Alternative representation for a set of Wide_Wide_Character values: subtype Wide_Wide_Character_Sequence is Wide_Wide_String; 17/2 function To_Set (Sequence : in Wide_Wide_Character_Sequence) return Wide_Wide_Character_Set; 18/2 function To_Set (Singleton : in Wide_Wide_Character) return Wide_Wide_Character_Set; 19/2 function To_Sequence (Set : in Wide_Wide_Character_Set) return Wide_Wide_Character_Sequence; 20/2 -- Representation for a Wide_Wide_Character to Wide_Wide_Character -- mapping: type Wide_Wide_Character_Mapping is private; pragma Preelaborable_Initialization(Wide_Wide_Character_Mapping); 21/2 function Value (Map : in Wide_Wide_Character_Mapping; Element : in Wide_Wide_Character) return Wide_Wide_Character; 22/2 Identity : constant Wide_Wide_Character_Mapping; 23/2 function To_Mapping (From, To : in Wide_Wide_Character_Sequence) return Wide_Wide_Character_Mapping; 24/2 function To_Domain (Map : in Wide_Wide_Character_Mapping) return Wide_Wide_Character_Sequence; 25/2 function To_Range (Map : in Wide_Wide_Character_Mapping) return Wide_Wide_Character_Sequence; 26/2 type Wide_Wide_Character_Mapping_Function is access function (From : in Wide_Wide_Character) return Wide_Wide_Character; 27/2 private ... -- not specified by the language end Ada.Strings.Wide_Wide_Maps; 28/2 The context clause for each of the packages Strings.Wide_Wide_Fixed, Strings.Wide_Wide_Bounded, and Strings.Wide_Wide_Unbounded identifies Strings.Wide_Wide_Maps instead of Strings.Maps. 28.1/3 Types Wide_Wide_Character_Set and Wide_Wide_Character_Mapping need finalization. 29/3 For each of the packages Strings.Fixed, Strings.Bounded, Strings.Unbounded, and Strings.Maps.Constants, and for library functions Strings.Hash, Strings.Fixed.Hash, Strings.Bounded.Hash, Strings.Unbounded.Hash, Strings.Hash_Case_Insensitive, Strings.Fixed.Hash_- Case_Insensitive, Strings.Bounded.Hash_Case_Insensitive, Strings.Unbounded.Hash_Case_Insensitive, Strings.Equal_Case_Insensitive, Strings.Fixed.Equal_Case_Insensitive, Strings.Bounded.Equal_Case_Insensitive, and Strings.Unbounded.Equal_Case_Insensitive, the corresponding wide wide string package or function has the same contents except that 30/2 * Wide_Wide_Space replaces Space 31/2 * Wide_Wide_Character replaces Character 32/2 * Wide_Wide_String replaces String 33/2 * Wide_Wide_Character_Set replaces Character_Set 34/2 * Wide_Wide_Character_Mapping replaces Character_Mapping 35/2 * Wide_Wide_Character_Mapping_Function replaces Character_Mapping_Function 36/2 * Wide_Wide_Maps replaces Maps 37/2 * Bounded_Wide_Wide_String replaces Bounded_String 38/2 * Null_Bounded_Wide_Wide_String replaces Null_Bounded_String 39/2 * To_Bounded_Wide_Wide_String replaces To_Bounded_String 40/2 * To_Wide_Wide_String replaces To_String 41/2 * Set_Bounded_Wide_Wide_String replaces Set_Bounded_String 42/2 * Unbounded_Wide_Wide_String replaces Unbounded_String 43/2 * Null_Unbounded_Wide_Wide_String replaces Null_Unbounded_String 44/2 * Wide_Wide_String_Access replaces String_Access 45/2 * To_Unbounded_Wide_Wide_String replaces To_Unbounded_String 46/2 * Set_Unbounded_Wide_Wide_String replaces Set_Unbounded_String 47/2 The following additional declarations are present in Strings.Wide_Wide_Maps.Wide_Wide_Constants: 48/2 Character_Set : constant Wide_Wide_Maps.Wide_Wide_Character_Set; -- Contains each Wide_Wide_Character value WWC such that -- Characters.Conversions.Is_Character(WWC) is True Wide_Character_Set : constant Wide_Wide_Maps.Wide_Wide_Character_Set; -- Contains each Wide_Wide_Character value WWC such that -- Characters.Conversions.Is_Wide_Character(WWC) is True 49/2 Each Wide_Wide_Character_Set constant in the package Strings.Wide_Wide_- Maps.Wide_Wide_Constants contains no values outside the Character portion of Wide_Wide_Character. Similarly, each Wide_Wide_Character_Mapping constant in this package is the identity mapping when applied to any element outside the Character portion of Wide_Wide_Character. 50/2 Pragma Pure is replaced by pragma Preelaborate in Strings.Wide_Wide_Maps.Wide_Wide_Constants. NOTES 51/2 17 If a null Wide_Wide_Character_Mapping_Function is passed to any of the Wide_Wide_String handling subprograms, Constraint_Error is propagated. A.4.9 String Hashing Static Semantics 1/2 The library function Strings.Hash has the following declaration: 2/3 with Ada.Containers; function Ada.Strings.Hash (Key : String) return Containers.Hash_Type; pragma Pure(Ada.Strings.Hash); 3/2 Returns an implementation-defined value which is a function of the value of Key. If A and B are strings such that A equals B, Hash(A) equals Hash(B). 4/2 The library function Strings.Fixed.Hash has the following declaration: 5/3 with Ada.Containers, Ada.Strings.Hash; function Ada.Strings.Fixed.Hash (Key : String) return Containers.Hash_Type renames Ada.Strings.Hash; 6/2 The generic library function Strings.Bounded.Hash has the following declaration: 7/3 with Ada.Containers; generic with package Bounded is new Ada.Strings.Bounded.Generic_Bounded_Length (<>); function Ada.Strings.Bounded.Hash (Key : Bounded.Bounded_String) return Containers.Hash_Type; pragma Preelaborate(Ada.Strings.Bounded.Hash); 8/3 Equivalent to Strings.Hash (Bounded.To_String (Key)); 9/2 The library function Strings.Unbounded.Hash has the following declaration: 10/3 with Ada.Containers; function Ada.Strings.Unbounded.Hash (Key : Unbounded_String) return Containers.Hash_Type; pragma Preelaborate(Ada.Strings.Unbounded.Hash); 11/3 Equivalent to Strings.Hash (To_String (Key)); 11.1/3 The library function Strings.Hash_Case_Insensitive has the following declaration: 11.2/3 with Ada.Containers; function Ada.Strings.Hash_Case_Insensitive (Key : String) return Containers.Hash_Type; pragma Pure(Ada.Strings.Hash_Case_Insensitive); 11.3/3 Returns an implementation-defined value which is a function of the value of Key, converted to lower case. If A and B are strings such that Strings.Equal_Case_Insensitive (A, B) (see A.4.10) is True, then Hash_Case_Insensitive(A) equals Hash_Case_Insensitive(B). 11.4/3 The library function Strings.Fixed.Hash_Case_Insensitive has the following declaration: 11.5/3 with Ada.Containers, Ada.Strings.Hash_Case_Insensitive; function Ada.Strings.Fixed.Hash_Case_Insensitive (Key : String) return Containers.Hash_Type renames Ada.Strings.Hash_Case_Insensitive; 11.6/3 The generic library function Strings.Bounded.Hash_Case_Insensitive has the following declaration: 11.7/3 with Ada.Containers; generic with package Bounded is new Ada.Strings.Bounded.Generic_Bounded_Length (<>); function Ada.Strings.Bounded.Hash_Case_Insensitive (Key : Bounded.Bounded_String) return Containers.Hash_Type; pragma Preelaborate(Ada.Strings.Bounded.Hash_Case_Insensitive); 11.8/3 Equivalent to Strings.Hash_Case_Insensitive (Bounded.To_String (Key)); 11.9/3 The library function Strings.Unbounded.Hash_Case_Insensitive has the following declaration: 11.10/3 with Ada.Containers; function Ada.Strings.Unbounded.Hash_Case_Insensitive (Key : Unbounded_String) return Containers.Hash_Type; pragma Preelaborate(Ada.Strings.Unbounded.Hash_Case_Insensitive); 11.11/3 Equivalent to Strings.Hash_Case_Insensitive (To_String (Key)); Implementation Advice 12/2 The Hash functions should be good hash functions, returning a wide spread of values for different string values. It should be unlikely for similar strings to return the same value. A.4.10 String Comparison Static Semantics 1/3 The library function Strings.Equal_Case_Insensitive has the following declaration: 2/3 function Ada.Strings.Equal_Case_Insensitive (Left, Right : String) return Boolean; pragma Pure(Ada.Strings.Equal_Case_Insensitive); 3/3 Returns True if the strings consist of the same sequence of characters after applying locale-independent simple case folding, as defined by documents referenced in the note in Clause 1 of ISO/IEC 10646:2011. Otherwise, returns False. This function uses the same method as is used to determine whether two identifiers are the same. 4/3 The library function Strings.Fixed.Equal_Case_Insensitive has the following declaration: 5/3 with Ada.Strings.Equal_Case_Insensitive; function Ada.Strings.Fixed.Equal_Case_Insensitive (Left, Right : String) return Boolean renames Ada.Strings.Equal_Case_Insensitive; 6/3 The generic library function Strings.Bounded.Equal_Case_Insensitive has the following declaration: 7/3 generic with package Bounded is new Ada.Strings.Bounded.Generic_Bounded_Length (<>); function Ada.Strings.Bounded.Equal_Case_Insensitive (Left, Right : Bounded.Bounded_String) return Boolean; pragma Preelaborate(Ada.Strings.Bounded.Equal_Case_Insensitive); 8/3 Equivalent to Strings.Equal_Case_Insensitive (Bounded.To_String (Left), Bounded.To_String (Right)); 9/3 The library function Strings.Unbounded.Equal_Case_Insensitive has the following declaration: 10/3 function Ada.Strings.Unbounded.Equal_Case_Insensitive (Left, Right : Unbounded_String) return Boolean; pragma Preelaborate(Ada.Strings.Unbounded.Equal_Case_Insensitive); 11/3 Equivalent to Strings.Equal_Case_Insensitive (To_String (Left), To_String (Right)); 12/3 The library function Strings.Less_Case_Insensitive has the following declaration: 13/3 function Ada.Strings.Less_Case_Insensitive (Left, Right : String) return Boolean; pragma Pure(Ada.Strings.Less_Case_Insensitive); 14/3 Performs a lexicographic comparison of strings Left and Right, converted to lower case. 15/3 The library function Strings.Fixed.Less_Case_Insensitive has the following declaration: 16/3 with Ada.Strings.Less_Case_Insensitive; function Ada.Strings.Fixed.Less_Case_Insensitive (Left, Right : String) return Boolean renames Ada.Strings.Less_Case_Insensitive; 17/3 The generic library function Strings.Bounded.Less_Case_Insensitive has the following declaration: 18/3 generic with package Bounded is new Ada.Strings.Bounded.Generic_Bounded_Length (<>); function Ada.Strings.Bounded.Less_Case_Insensitive (Left, Right : Bounded.Bounded_String) return Boolean; pragma Preelaborate(Ada.Strings.Bounded.Less_Case_Insensitive); 19/3 Equivalent to Strings.Less_Case_Insensitive (Bounded.To_String (Left), Bounded.To_String (Right)); 20/3 The library function Strings.Unbounded.Less_Case_Insensitive has the following declaration: 21/3 function Ada.Strings.Unbounded.Less_Case_Insensitive (Left, Right : Unbounded_String) return Boolean; pragma Preelaborate(Ada.Strings.Unbounded.Less_Case_Insensitive); 22/3 Equivalent to Strings.Less_Case_Insensitive (To_String (Left), To_String (Right)); A.4.11 String Encoding 1/3 Facilities for encoding, decoding, and converting strings in various character encoding schemes are provided by packages Strings.UTF_Encoding, Strings.UTF_Encoding.Conversions, Strings.UTF_Encoding.Strings, Strings.- UTF_Encoding.Wide_Strings, and Strings.UTF_Encoding.Wide_Wide_Strings. Static Semantics 2/3 The encoding library packages have the following declarations: 3/3 package Ada.Strings.UTF_Encoding is pragma Pure (UTF_Encoding); 4/3 -- Declarations common to the string encoding packages type Encoding_Scheme is (UTF_8, UTF_16BE, UTF_16LE); 5/3 subtype UTF_String is String; 6/3 subtype UTF_8_String is String; 7/3 subtype UTF_16_Wide_String is Wide_String; 8/3 Encoding_Error : exception; 9/3 BOM_8 : constant UTF_8_String := Character'Val(16#EF#) & Character'Val(16#BB#) & Character'Val(16#BF#); 10/3 BOM_16BE : constant UTF_String := Character'Val(16#FE#) & Character'Val(16#FF#); 11/3 BOM_16LE : constant UTF_String := Character'Val(16#FF#) & Character'Val(16#FE#); 12/3 BOM_16 : constant UTF_16_Wide_String := (1 => Wide_Character'Val(16#FEFF#)); 13/3 function Encoding (Item : UTF_String; Default : Encoding_Scheme := UTF_8) return Encoding_Scheme; 14/3 end Ada.Strings.UTF_Encoding; 15/3 package Ada.Strings.UTF_Encoding.Conversions is pragma Pure (Conversions); 16/3 -- Conversions between various encoding schemes function Convert (Item : UTF_String; Input_Scheme : Encoding_Scheme; Output_Scheme : Encoding_Scheme; Output_BOM : Boolean := False) return UTF_String; 17/3 function Convert (Item : UTF_String; Input_Scheme : Encoding_Scheme; Output_BOM : Boolean := False) return UTF_16_Wide_String; 18/3 function Convert (Item : UTF_8_String; Output_BOM : Boolean := False) return UTF_16_Wide_String; 19/3 function Convert (Item : UTF_16_Wide_String; Output_Scheme : Encoding_Scheme; Output_BOM : Boolean := False) return UTF_String; 20/3 function Convert (Item : UTF_16_Wide_String; Output_BOM : Boolean := False) return UTF_8_String; 21/3 end Ada.Strings.UTF_Encoding.Conversions; 22/3 package Ada.Strings.UTF_Encoding.Strings is pragma Pure (Strings); 23/3 -- Encoding / decoding between String and various encoding schemes function Encode (Item : String; Output_Scheme : Encoding_Scheme; Output_BOM : Boolean := False) return UTF_String; 24/3 function Encode (Item : String; Output_BOM : Boolean := False) return UTF_8_String; 25/3 function Encode (Item : String; Output_BOM : Boolean := False) return UTF_16_Wide_String; 26/3 function Decode (Item : UTF_String; Input_Scheme : Encoding_Scheme) return String; 27/3 function Decode (Item : UTF_8_String) return String; 28/3 function Decode (Item : UTF_16_Wide_String) return String; 29/3 end Ada.Strings.UTF_Encoding.Strings; 30/3 package Ada.Strings.UTF_Encoding.Wide_Strings is pragma Pure (Wide_Strings); 31/3 -- Encoding / decoding between Wide_String and various encoding schemes function Encode (Item : Wide_String; Output_Scheme : Encoding_Scheme; Output_BOM : Boolean := False) return UTF_String; 32/3 function Encode (Item : Wide_String; Output_BOM : Boolean := False) return UTF_8_String; 33/3 function Encode (Item : Wide_String; Output_BOM : Boolean := False) return UTF_16_Wide_String; 34/3 function Decode (Item : UTF_String; Input_Scheme : Encoding_Scheme) return Wide_String; 35/3 function Decode (Item : UTF_8_String) return Wide_String; 36/3 function Decode (Item : UTF_16_Wide_String) return Wide_String; 37/3 end Ada.Strings.UTF_Encoding.Wide_Strings; 38/3 package Ada.Strings.UTF_Encoding.Wide_Wide_Strings is pragma Pure (Wide_Wide_Strings); 39/3 -- Encoding / decoding between Wide_Wide_String and various encoding schemes function Encode (Item : Wide_Wide_String; Output_Scheme : Encoding_Scheme; Output_BOM : Boolean := False) return UTF_String; 40/3 function Encode (Item : Wide_Wide_String; Output_BOM : Boolean := False) return UTF_8_String; 41/3 function Encode (Item : Wide_Wide_String; Output_BOM : Boolean := False) return UTF_16_Wide_String; 42/3 function Decode (Item : UTF_String; Input_Scheme : Encoding_Scheme) return Wide_Wide_String; 43/3 function Decode (Item : UTF_8_String) return Wide_Wide_String; 44/3 function Decode (Item : UTF_16_Wide_String) return Wide_Wide_String; 45/3 end Ada.Strings.UTF_Encoding.Wide_Wide_Strings; 46/3 The type Encoding_Scheme defines encoding schemes. UTF_8 corresponds to the UTF-8 encoding scheme defined by Annex D of ISO/IEC 10646. UTF_16BE corresponds to the UTF-16 encoding scheme defined by Annex C of ISO/IEC 10646 in 8 bit, big-endian order; and UTF_16LE corresponds to the UTF-16 encoding scheme in 8 bit, little-endian order. 47/3 The subtype UTF_String is used to represent a String of 8-bit values containing a sequence of values encoded in one of three ways (UTF-8, UTF-16BE, or UTF-16LE). The subtype UTF_8_String is used to represent a String of 8-bit values containing a sequence of values encoded in UTF-8. The subtype UTF_16_Wide_String is used to represent a Wide_String of 16-bit values containing a sequence of values encoded in UTF-16. 48/3 The BOM_8, BOM_16BE, BOM_16LE, and BOM_16 constants correspond to values used at the start of a string to indicate the encoding. 49/3 Each of the Encode functions takes a String, Wide_String, or Wide_Wide_String Item parameter that is assumed to be an array of unencoded characters. Each of the Convert functions takes a UTF_String, UTF_8_String, or UTF_16_String Item parameter that is assumed to contain characters whose position values correspond to a valid encoding sequence according to the encoding scheme required by the function or specified by its Input_Scheme parameter. 50/3 Each of the Convert and Encode functions returns a UTF_String, UTF_8_String, or UTF_16_String value whose characters have position values that correspond to the encoding of the Item parameter according to the encoding scheme required by the function or specified by its Output_Scheme parameter. For UTF_8, no overlong encoding is returned. A BOM is included at the start of the returned string if the Output_BOM parameter is set to True. The lower bound of the returned string is 1. 51/3 Each of the Decode functions takes a UTF_String, UTF_8_String, or UTF_16_String Item parameter which is assumed to contain characters whose position values correspond to a valid encoding sequence according to the encoding scheme required by the function or specified by its Input_Scheme parameter, and returns the corresponding String, Wide_String, or Wide_Wide_String value. The lower bound of the returned string is 1. 52/3 For each of the Convert and Decode functions, an initial BOM in the input that matches the expected encoding scheme is ignored, and a different initial BOM causes Encoding_Error to be propagated. 53/3 The exception Encoding_Error is also propagated in the following situations: 54/4 * By a Convert or Decode function when a UTF encoded string contains an invalid encoding sequence. 55/4 * By a Convert or Decode function when the expected encoding is UTF-16BE or UTF-16LE and the input string has an odd length. 56/3 * By a Decode function yielding a String when the decoding of a sequence results in a code point whose value exceeds 16#FF#. 57/3 * By a Decode function yielding a Wide_String when the decoding of a sequence results in a code point whose value exceeds 16#FFFF#. 58/3 * By an Encode function taking a Wide_String as input when an invalid character appears in the input. In particular, the characters whose position is in the range 16#D800# .. 16#DFFF# are invalid because they conflict with UTF-16 surrogate encodings, and the characters whose position is 16#FFFE# or 16#FFFF# are also invalid because they conflict with BOM codes. 59/3 function Encoding (Item : UTF_String; Default : Encoding_Scheme := UTF_8) return Encoding_Scheme; 60/3 Inspects a UTF_String value to determine whether it starts with a BOM for UTF-8, UTF-16BE, or UTF_16LE. If so, returns the scheme corresponding to the BOM; otherwise, returns the value of Default. 61/3 function Convert (Item : UTF_String; Input_Scheme : Encoding_Scheme; Output_Scheme : Encoding_Scheme; Output_BOM : Boolean := False) return UTF_String; 62/3 Returns the value of Item (originally encoded in UTF-8, UTF-16LE, or UTF-16BE as specified by Input_Scheme) encoded in one of these three schemes as specified by Output_Scheme. 63/3 function Convert (Item : UTF_String; Input_Scheme : Encoding_Scheme; Output_BOM : Boolean := False) return UTF_16_Wide_String; 64/3 Returns the value of Item (originally encoded in UTF-8, UTF-16LE, or UTF-16BE as specified by Input_Scheme) encoded in UTF-16. 65/3 function Convert (Item : UTF_8_String; Output_BOM : Boolean := False) return UTF_16_Wide_String; 66/3 Returns the value of Item (originally encoded in UTF-8) encoded in UTF-16. 67/3 function Convert (Item : UTF_16_Wide_String; Output_Scheme : Encoding_Scheme; Output_BOM : Boolean := False) return UTF_String; 68/3 Returns the value of Item (originally encoded in UTF-16) encoded in UTF-8, UTF-16LE, or UTF-16BE as specified by Output_Scheme. 69/3 function Convert (Item : UTF_16_Wide_String; Output_BOM : Boolean := False) return UTF_8_String; 70/3 Returns the value of Item (originally encoded in UTF-16) encoded in UTF-8. 71/3 function Encode (Item : String; Output_Scheme : Encoding_Scheme; Output_BOM : Boolean := False) return UTF_String; 72/3 Returns the value of Item encoded in UTF-8, UTF-16LE, or UTF-16BE as specified by Output_Scheme. 73/3 function Encode (Item : String; Output_BOM : Boolean := False) return UTF_8_String; 74/3 Returns the value of Item encoded in UTF-8. 75/3 function Encode (Item : String; Output_BOM : Boolean := False) return UTF_16_Wide_String; 76/3 Returns the value of Item encoded in UTF_16. 77/3 function Decode (Item : UTF_String; Input_Scheme : Encoding_Scheme) return String; 78/3 Returns the result of decoding Item, which is encoded in UTF-8, UTF-16LE, or UTF-16BE as specified by Input_Scheme. 79/3 function Decode (Item : UTF_8_String) return String; 80/3 Returns the result of decoding Item, which is encoded in UTF-8. 81/3 function Decode (Item : UTF_16_Wide_String) return String; 82/3 Returns the result of decoding Item, which is encoded in UTF-16. 83/3 function Encode (Item : Wide_String; Output_Scheme : Encoding_Scheme; Output_BOM : Boolean := False) return UTF_String; 84/3 Returns the value of Item encoded in UTF-8, UTF-16LE, or UTF-16BE as specified by Output_Scheme. 85/3 function Encode (Item : Wide_String; Output_BOM : Boolean := False) return UTF_8_String; 86/3 Returns the value of Item encoded in UTF-8. 87/3 function Encode (Item : Wide_String; Output_BOM : Boolean := False) return UTF_16_Wide_String; 88/3 Returns the value of Item encoded in UTF_16. 89/3 function Decode (Item : UTF_String; Input_Scheme : Encoding_Scheme) return Wide_String; 90/3 Returns the result of decoding Item, which is encoded in UTF-8, UTF-16LE, or UTF-16BE as specified by Input_Scheme. 91/3 function Decode (Item : UTF_8_String) return Wide_String; 92/3 Returns the result of decoding Item, which is encoded in UTF-8. 93/3 function Decode (Item : UTF_16_Wide_String) return Wide_String; 94/3 Returns the result of decoding Item, which is encoded in UTF-16. 95/3 function Encode (Item : Wide_Wide_String; Output_Scheme : Encoding_Scheme; Output_BOM : Boolean := False) return UTF_String; 96/3 Returns the value of Item encoded in UTF-8, UTF-16LE, or UTF-16BE as specified by Output_Scheme. 97/3 function Encode (Item : Wide_Wide_String; Output_BOM : Boolean := False) return UTF_8_String; 98/3 Returns the value of Item encoded in UTF-8. 99/3 function Encode (Item : Wide_Wide_String; Output_BOM : Boolean := False) return UTF_16_Wide_String; 100/3 Returns the value of Item encoded in UTF_16. 101/3 function Decode (Item : UTF_String; Input_Scheme : Encoding_Scheme) return Wide_Wide_String; 102/3 Returns the result of decoding Item, which is encoded in UTF-8, UTF-16LE, or UTF-16BE as specified by Input_Scheme. 103/3 function Decode (Item : UTF_8_String) return Wide_Wide_String; 104/3 Returns the result of decoding Item, which is encoded in UTF-8. 105/3 function Decode (Item : UTF_16_Wide_String) return Wide_Wide_String; 106/3 Returns the result of decoding Item, which is encoded in UTF-16. Implementation Advice 107/3 If an implementation supports other encoding schemes, another similar child of Ada.Strings should be defined. NOTES 108/3 18 A BOM (Byte-Order Mark, code position 16#FEFF#) can be included in a file or other entity to indicate the encoding; it is skipped when decoding. Typically, only the first line of a file or other entity contains a BOM. When decoding, the Encoding function can be called on the first line to determine the encoding; this encoding will then be used in subsequent calls to Decode to convert all of the lines to an internal format. A.5 The Numerics Packages 1 The library package Numerics is the parent of several child units that provide facilities for mathematical computation. One child, the generic package Generic_Elementary_Functions, is defined in A.5.1, together with nongeneric equivalents; two others, the package Float_Random and the generic package Discrete_Random, are defined in A.5.2. Additional (optional) children are defined in Annex G, "Numerics". Static Semantics 2/1 This paragraph was deleted. 3/2 package Ada.Numerics is pragma Pure(Numerics); Argument_Error : exception; Pi : constant := 3.14159_26535_89793_23846_26433_83279_50288_41971_69399_37511; PI : constant := Pi; e : constant := 2.71828_18284_59045_23536_02874_71352_66249_77572_47093_69996; end Ada.Numerics; 4 The Argument_Error exception is raised by a subprogram in a child unit of Numerics to signal that one or more of the actual subprogram parameters are outside the domain of the corresponding mathematical function. Implementation Permissions 5 The implementation may specify the values of Pi and e to a larger number of significant digits. A.5.1 Elementary Functions 1 Implementation-defined approximations to the mathematical functions known as the "elementary functions" are provided by the subprograms in Numerics.- Generic_Elementary_Functions. Nongeneric equivalents of this generic package for each of the predefined floating point types are also provided as children of Numerics. Static Semantics 2 The generic library package Numerics.Generic_Elementary_Functions has the following declaration: 3 generic type Float_Type is digits <>; package Ada.Numerics.Generic_Elementary_Functions is pragma Pure(Generic_Elementary_Functions); 4 function Sqrt (X : Float_Type'Base) return Float_Type'Base; function Log (X : Float_Type'Base) return Float_Type'Base; function Log (X, Base : Float_Type'Base) return Float_Type'Base; function Exp (X : Float_Type'Base) return Float_Type'Base; function "**" (Left, Right : Float_Type'Base) return Float_Type'Base; 5 function Sin (X : Float_Type'Base) return Float_Type'Base; function Sin (X, Cycle : Float_Type'Base) return Float_Type'Base; function Cos (X : Float_Type'Base) return Float_Type'Base; function Cos (X, Cycle : Float_Type'Base) return Float_Type'Base; function Tan (X : Float_Type'Base) return Float_Type'Base; function Tan (X, Cycle : Float_Type'Base) return Float_Type'Base; function Cot (X : Float_Type'Base) return Float_Type'Base; function Cot (X, Cycle : Float_Type'Base) return Float_Type'Base; 6 function Arcsin (X : Float_Type'Base) return Float_Type'Base; function Arcsin (X, Cycle : Float_Type'Base) return Float_Type'Base; function Arccos (X : Float_Type'Base) return Float_Type'Base; function Arccos (X, Cycle : Float_Type'Base) return Float_Type'Base; function Arctan (Y : Float_Type'Base; X : Float_Type'Base := 1.0) return Float_Type'Base; function Arctan (Y : Float_Type'Base; X : Float_Type'Base := 1.0; Cycle : Float_Type'Base) return Float_Type'Base; function Arccot (X : Float_Type'Base; Y : Float_Type'Base := 1.0) return Float_Type'Base; function Arccot (X : Float_Type'Base; Y : Float_Type'Base := 1.0; Cycle : Float_Type'Base) return Float_Type'Base; 7 function Sinh (X : Float_Type'Base) return Float_Type'Base; function Cosh (X : Float_Type'Base) return Float_Type'Base; function Tanh (X : Float_Type'Base) return Float_Type'Base; function Coth (X : Float_Type'Base) return Float_Type'Base; function Arcsinh (X : Float_Type'Base) return Float_Type'Base; function Arccosh (X : Float_Type'Base) return Float_Type'Base; function Arctanh (X : Float_Type'Base) return Float_Type'Base; function Arccoth (X : Float_Type'Base) return Float_Type'Base; 8 end Ada.Numerics.Generic_Elementary_Functions; 9/1 The library package Numerics.Elementary_Functions is declared pure and defines the same subprograms as Numerics.Generic_Elementary_Functions, except that the predefined type Float is systematically substituted for Float_Type'Base throughout. Nongeneric equivalents of Numerics.Generic_- Elementary_Functions for each of the other predefined floating point types are defined similarly, with the names Numerics.Short_Elementary_Functions, Numerics.Long_Elementary_Functions, etc. 10 The functions have their usual mathematical meanings. When the Base parameter is specified, the Log function computes the logarithm to the given base; otherwise, it computes the natural logarithm. When the Cycle parameter is specified, the parameter X of the forward trigonometric functions (Sin, Cos, Tan, and Cot) and the results of the inverse trigonometric functions (Arcsin, Arccos, Arctan, and Arccot) are measured in units such that a full cycle of revolution has the given value; otherwise, they are measured in radians. 11 The computed results of the mathematically multivalued functions are rendered single-valued by the following conventions, which are meant to imply the principal branch: 12 * The results of the Sqrt and Arccosh functions and that of the exponentiation operator are nonnegative. 13 * The result of the Arcsin function is in the quadrant containing the point (1.0, x), where x is the value of the parameter X. This quadrant is I or IV; thus, the range of the Arcsin function is approximately -PI/2.0 to PI/2.0 (-Cycle/4.0 to Cycle/4.0, if the parameter Cycle is specified). 14 * The result of the Arccos function is in the quadrant containing the point (x, 1.0), where x is the value of the parameter X. This quadrant is I or II; thus, the Arccos function ranges from 0.0 to approximately PI (Cycle/2.0, if the parameter Cycle is specified). 15 * The results of the Arctan and Arccot functions are in the quadrant containing the point (x, y), where x and y are the values of the parameters X and Y, respectively. This may be any quadrant (I through IV) when the parameter X (resp., Y) of Arctan (resp., Arccot) is specified, but it is restricted to quadrants I and IV (resp., I and II) when that parameter is omitted. Thus, the range when that parameter is specified is approximately -PI to PI (-Cycle/2.0 to Cycle/2.0, if the parameter Cycle is specified); when omitted, the range of Arctan (resp., Arccot) is that of Arcsin (resp., Arccos), as given above. When the point (x, y) lies on the negative x-axis, the result approximates 16 * PI (resp., -PI) when the sign of the parameter Y is positive (resp., negative), if Float_Type'Signed_Zeros is True; 17 * PI, if Float_Type'Signed_Zeros is False. 18 (In the case of the inverse trigonometric functions, in which a result lying on or near one of the axes may not be exactly representable, the approximation inherent in computing the result may place it in an adjacent quadrant, close to but on the wrong side of the axis.) Dynamic Semantics 19 The exception Numerics.Argument_Error is raised, signaling a parameter value outside the domain of the corresponding mathematical function, in the following cases: 20 * by any forward or inverse trigonometric function with specified cycle, when the value of the parameter Cycle is zero or negative; 21 * by the Log function with specified base, when the value of the parameter Base is zero, one, or negative; 22 * by the Sqrt and Log functions, when the value of the parameter X is negative; 23 * by the exponentiation operator, when the value of the left operand is negative or when both operands have the value zero; 24 * by the Arcsin, Arccos, and Arctanh functions, when the absolute value of the parameter X exceeds one; 25 * by the Arctan and Arccot functions, when the parameters X and Y both have the value zero; 26 * by the Arccosh function, when the value of the parameter X is less than one; and 27 * by the Arccoth function, when the absolute value of the parameter X is less than one. 28 The exception Constraint_Error is raised, signaling a pole of the mathematical function (analogous to dividing by zero), in the following cases, provided that Float_Type'Machine_Overflows is True: 29 * by the Log, Cot, and Coth functions, when the value of the parameter X is zero; 30 * by the exponentiation operator, when the value of the left operand is zero and the value of the exponent is negative; 31 * by the Tan function with specified cycle, when the value of the parameter X is an odd multiple of the quarter cycle; 32 * by the Cot function with specified cycle, when the value of the parameter X is zero or a multiple of the half cycle; and 33 * by the Arctanh and Arccoth functions, when the absolute value of the parameter X is one. 34 Constraint_Error can also be raised when a finite result overflows (see G.2.4); this may occur for parameter values sufficiently near poles, and, in the case of some of the functions, for parameter values with sufficiently large magnitudes. When Float_Type'Machine_Overflows is False, the result at poles is unspecified. 35 When one parameter of a function with multiple parameters represents a pole and another is outside the function's domain, the latter takes precedence (i.e., Numerics.Argument_Error is raised). Implementation Requirements 36 In the implementation of Numerics.Generic_Elementary_Functions, the range of intermediate values allowed during the calculation of a final result shall not be affected by any range constraint of the subtype Float_Type. 37 In the following cases, evaluation of an elementary function shall yield the prescribed result, provided that the preceding rules do not call for an exception to be raised: 38 * When the parameter X has the value zero, the Sqrt, Sin, Arcsin, Tan, Sinh, Arcsinh, Tanh, and Arctanh functions yield a result of zero, and the Exp, Cos, and Cosh functions yield a result of one. 39 * When the parameter X has the value one, the Sqrt function yields a result of one, and the Log, Arccos, and Arccosh functions yield a result of zero. 40 * When the parameter Y has the value zero and the parameter X has a positive value, the Arctan and Arccot functions yield a result of zero. 41 * The results of the Sin, Cos, Tan, and Cot functions with specified cycle are exact when the mathematical result is zero; those of the first two are also exact when the mathematical result is ± 1.0. 42 * Exponentiation by a zero exponent yields the value one. Exponentiation by a unit exponent yields the value of the left operand. Exponentiation of the value one yields the value one. Exponentiation of the value zero yields the value zero. 43 Other accuracy requirements for the elementary functions, which apply only in implementations conforming to the Numerics Annex, and then only in the " strict" mode defined there (see G.2), are given in G.2.4. 44 When Float_Type'Signed_Zeros is True, the sign of a zero result shall be as follows: 45 * A prescribed zero result delivered at the origin by one of the odd functions (Sin, Arcsin, Sinh, Arcsinh, Tan, Arctan or Arccot as a function of Y when X is fixed and positive, Tanh, and Arctanh) has the sign of the parameter X (Y, in the case of Arctan or Arccot). 46 * A prescribed zero result delivered by one of the odd functions away from the origin, or by some other elementary function, has an implementation-defined sign. 47 * A zero result that is not a prescribed result (i.e., one that results from rounding or underflow) has the correct mathematical sign. Implementation Permissions 48 The nongeneric equivalent packages may, but need not, be actual instantiations of the generic package for the appropriate predefined type. A.5.2 Random Number Generation 1 Facilities for the generation of pseudo-random floating point numbers are provided in the package Numerics.Float_Random; the generic package Numerics.Discrete_Random provides similar facilities for the generation of pseudo-random integers and pseudo-random values of enumeration types. For brevity, pseudo-random values of any of these types are called random numbers. 2 Some of the facilities provided are basic to all applications of random numbers. These include a limited private type each of whose objects serves as the generator of a (possibly distinct) sequence of random numbers; a function to obtain the "next" random number from a given sequence of random numbers (that is, from its generator); and subprograms to initialize or reinitialize a given generator to a time-dependent state or a state denoted by a single integer. 3 Other facilities are provided specifically for advanced applications. These include subprograms to save and restore the state of a given generator; a private type whose objects can be used to hold the saved state of a generator; and subprograms to obtain a string representation of a given generator state, or, given such a string representation, the corresponding state. Static Semantics 4 The library package Numerics.Float_Random has the following declaration: 5 package Ada.Numerics.Float_Random is 6 -- Basic facilities 7 type Generator is limited private; 8 subtype Uniformly_Distributed is Float range 0.0 .. 1.0; function Random (Gen : Generator) return Uniformly_Distributed; 9 procedure Reset (Gen : in Generator; Initiator : in Integer); procedure Reset (Gen : in Generator); 10 -- Advanced facilities 11 type State is private; 12 procedure Save (Gen : in Generator; To_State : out State); procedure Reset (Gen : in Generator; From_State : in State); 13 Max_Image_Width : constant := implementation-defined integer value; 14 function Image (Of_State : State) return String; function Value (Coded_State : String) return State; 15 private ... -- not specified by the language end Ada.Numerics.Float_Random; 15.1/2 The type Generator needs finalization (see 7.6). 16 The generic library package Numerics.Discrete_Random has the following declaration: 17 generic type Result_Subtype is (<>); package Ada.Numerics.Discrete_Random is 18 -- Basic facilities 19 type Generator is limited private; 20 function Random (Gen : Generator) return Result_Subtype; 21 procedure Reset (Gen : in Generator; Initiator : in Integer); procedure Reset (Gen : in Generator); 22 -- Advanced facilities 23 type State is private; 24 procedure Save (Gen : in Generator; To_State : out State); procedure Reset (Gen : in Generator; From_State : in State); 25 Max_Image_Width : constant := implementation-defined integer value; 26 function Image (Of_State : State) return String; function Value (Coded_State : String) return State; 27 private ... -- not specified by the language end Ada.Numerics.Discrete_Random; 27.1/2 The type Generator needs finalization (see 7.6) in every instantiation of Numerics.Discrete_Random. 28 An object of the limited private type Generator is associated with a sequence of random numbers. Each generator has a hidden (internal) state, which the operations on generators use to determine the position in the associated sequence. All generators are implicitly initialized to an unspecified state that does not vary from one program execution to another; they may also be explicitly initialized, or reinitialized, to a time-dependent state, to a previously saved state, or to a state uniquely denoted by an integer value. 29/3 An object of the private type State can be used to hold the internal state of a generator. Such objects are only needed if the application is designed to save and restore generator states or to examine or manufacture them. The implicit initial value of type State corresponds to the implicit initial value of all generators. 30 The operations on generators affect the state and therefore the future values of the associated sequence. The semantics of the operations on generators and states are defined below. 31 function Random (Gen : Generator) return Uniformly_Distributed; function Random (Gen : Generator) return Result_Subtype; 32 Obtains the "next" random number from the given generator, relative to its current state, according to an implementation-defined algorithm. The result of the function in Numerics.Float_Random is delivered as a value of the subtype Uniformly_Distributed, which is a subtype of the predefined type Float having a range of 0.0 .. 1.0. The result of the function in an instantiation of Numerics.Discrete_Random is delivered as a value of the generic formal subtype Result_Subtype. 33 procedure Reset (Gen : in Generator; Initiator : in Integer); procedure Reset (Gen : in Generator); 34 Sets the state of the specified generator to one that is an unspecified function of the value of the parameter Initiator (or to a time-dependent state, if only a generator parameter is specified). The latter form of the procedure is known as the time-dependent Reset procedure. 35 procedure Save (Gen : in Generator; To_State : out State); procedure Reset (Gen : in Generator; From_State : in State); 36 Save obtains the current state of a generator. Reset gives a generator the specified state. A generator that is reset to a state previously obtained by invoking Save is restored to the state it had when Save was invoked. 37 function Image (Of_State : State) return String; function Value (Coded_State : String) return State; 38 Image provides a representation of a state coded (in an implementation-defined way) as a string whose length is bounded by the value of Max_Image_Width. Value is the inverse of Image: Value(Image(S)) = S for each state S that can be obtained from a generator by invoking Save. Dynamic Semantics 39 Instantiation of Numerics.Discrete_Random with a subtype having a null range raises Constraint_Error. 40/1 This paragraph was deleted. Bounded (Run-Time) Errors 40.1/1 It is a bounded error to invoke Value with a string that is not the image of any generator state. If the error is detected, Constraint_Error or Program_Error is raised. Otherwise, a call to Reset with the resulting state will produce a generator such that calls to Random with this generator will produce a sequence of values of the appropriate subtype, but which might not be random in character. That is, the sequence of values might not fulfill the implementation requirements of this subclause. Implementation Requirements 41 A sufficiently long sequence of random numbers obtained by successive calls to Random is approximately uniformly distributed over the range of the result subtype. 42 The Random function in an instantiation of Numerics.Discrete_Random is guaranteed to yield each value in its result subtype in a finite number of calls, provided that the number of such values does not exceed 2 (15). 43 Other performance requirements for the random number generator, which apply only in implementations conforming to the Numerics Annex, and then only in the "strict" mode defined there (see G.2), are given in G.2.5. Documentation Requirements 44 No one algorithm for random number generation is best for all applications. To enable the user to determine the suitability of the random number generators for the intended application, the implementation shall describe the algorithm used and shall give its period, if known exactly, or a lower bound on the period, if the exact period is unknown. Periods that are so long that the periodicity is unobservable in practice can be described in such terms, without giving a numerical bound. 45 The implementation also shall document the minimum time interval between calls to the time-dependent Reset procedure that are guaranteed to initiate different sequences, and it shall document the nature of the strings that Value will accept without raising Constraint_Error. Implementation Advice 46 Any storage associated with an object of type Generator should be reclaimed on exit from the scope of the object. 47 If the generator period is sufficiently long in relation to the number of distinct initiator values, then each possible value of Initiator passed to Reset should initiate a sequence of random numbers that does not, in a practical sense, overlap the sequence initiated by any other value. If this is not possible, then the mapping between initiator values and generator states should be a rapidly varying function of the initiator value. NOTES 48 19 If two or more tasks are to share the same generator, then the tasks have to synchronize their access to the generator as for any shared variable (see 9.10). 49 20 Within a given implementation, a repeatable random number sequence can be obtained by relying on the implicit initialization of generators or by explicitly initializing a generator with a repeatable initiator value. Different sequences of random numbers can be obtained from a given generator in different program executions by explicitly initializing the generator to a time-dependent state. 50 21 A given implementation of the Random function in Numerics.Float_Random may or may not be capable of delivering the values 0.0 or 1.0. Portable applications should assume that these values, or values sufficiently close to them to behave indistinguishably from them, can occur. If a sequence of random integers from some fixed range is needed, the application should use the Random function in an appropriate instantiation of Numerics.Discrete_Random, rather than transforming the result of the Random function in Numerics.Float_Random. However, some applications with unusual requirements, such as for a sequence of random integers each drawn from a different range, will find it more convenient to transform the result of the floating point Random function. For M >= 1, the expression 51 Integer(Float(M) * Random(G)) mod M 52 transforms the result of Random(G) to an integer uniformly distributed over the range 0 .. M-1; it is valid even if Random delivers 0.0 or 1.0. Each value of the result range is possible, provided that M is not too large. Exponentially distributed (floating point) random numbers with mean and standard deviation 1.0 can be obtained by the transformation 53/2 -Log(Random(G) + Float'Model_Small) 54 where Log comes from Numerics.Elementary_Functions (see A.5.1); in this expression, the addition of Float'Model_Small avoids the exception that would be raised were Log to be given the value zero, without affecting the result (in most implementations) when Random returns a nonzero value. Examples 55 Example of a program that plays a simulated dice game: 56 with Ada.Numerics.Discrete_Random; procedure Dice_Game is subtype Die is Integer range 1 .. 6; subtype Dice is Integer range 2*Die'First .. 2*Die'Last; package Random_Die is new Ada.Numerics.Discrete_Random (Die); use Random_Die; G : Generator; D : Dice; begin Reset (G); -- Start the generator in a unique state in each run loop -- Roll a pair of dice; sum and process the results D := Random(G) + Random(G); ... end loop; end Dice_Game; 57 Example of a program that simulates coin tosses: 58 with Ada.Numerics.Discrete_Random; procedure Flip_A_Coin is type Coin is (Heads, Tails); package Random_Coin is new Ada.Numerics.Discrete_Random (Coin); use Random_Coin; G : Generator; begin Reset (G); -- Start the generator in a unique state in each run loop -- Toss a coin and process the result case Random(G) is when Heads => ... when Tails => ... end case; ... end loop; end Flip_A_Coin; 59 Example of a parallel simulation of a physical system, with a separate generator of event probabilities in each task: 60 with Ada.Numerics.Float_Random; procedure Parallel_Simulation is use Ada.Numerics.Float_Random; task type Worker is entry Initialize_Generator (Initiator : in Integer); ... end Worker; W : array (1 .. 10) of Worker; task body Worker is G : Generator; Probability_Of_Event : Uniformly_Distributed; begin accept Initialize_Generator (Initiator : in Integer) do Reset (G, Initiator); end Initialize_Generator; loop ... Probability_Of_Event := Random(G); ... end loop; end Worker; begin -- Initialize the generators in the Worker tasks to different states for I in W'Range loop W(I).Initialize_Generator (I); end loop; ... -- Wait for the Worker tasks to terminate end Parallel_Simulation; NOTES 61 22 Notes on the last example: Although each Worker task initializes its generator to a different state, those states will be the same in every execution of the program. The generator states can be initialized uniquely in each program execution by instantiating Ada.Numerics.Discrete_Random for the type Integer in the main procedure, resetting the generator obtained from that instance to a time-dependent state, and then using random integers obtained from that generator to initialize the generators in each Worker task. A.5.3 Attributes of Floating Point Types Static Semantics 1 The following representation-oriented attributes are defined for every subtype S of a floating point type T. 2 S'Machine_Radix Yields the radix of the hardware representation of the type T. The value of this attribute is of the type universal_integer. 3 The values of other representation-oriented attributes of a floating point subtype, and of the "primitive function" attributes of a floating point subtype described later, are defined in terms of a particular representation of nonzero values called the canonical form. The canonical form (for the type T) is the form ± mantissa · T'Machine_Radix(exponent) where 4 * mantissa is a fraction in the number base T'Machine_Radix, the first digit of which is nonzero, and 5 * exponent is an integer. 6 S'Machine_Mantissa Yields the largest value of p such that every value expressible in the canonical form (for the type T), having a p-digit mantissa and an exponent between T'Machine_Emin and T'Machine_Emax, is a machine number (see 3.5.7) of the type T. This attribute yields a value of the type universal_integer. 7 S'Machine_Emin Yields the smallest (most negative) value of exponent such that every value expressible in the canonical form (for the type T), having a mantissa of T'Machine_Mantissa digits, is a machine number (see 3.5.7) of the type T. This attribute yields a value of the type universal_integer. 8 S'Machine_Emax Yields the largest (most positive) value of exponent such that every value expressible in the canonical form (for the type T), having a mantissa of T'Machine_Mantissa digits, is a machine number (see 3.5.7) of the type T. This attribute yields a value of the type universal_integer. 9 S'Denorm Yields the value True if every value expressible in the form ± mantissa · T'Machine_Radix(T'Machine_Emin) where mantissa is a nonzero T'Machine_Mantissa-digit fraction in the number base T'Machine_Radix, the first digit of which is zero, is a machine number (see 3.5.7) of the type T; yields the value False otherwise. The value of this attribute is of the predefined type Boolean. 10 The values described by the formula in the definition of S'Denorm are called denormalized numbers. A nonzero machine number that is not a denormalized number is a normalized number. A normalized number x of a given type T is said to be represented in canonical form when it is expressed in the canonical form (for the type T) with a mantissa having T'Machine_Mantissa digits; the resulting form is the canonical-form representation of x. 11 S'Machine_Rounds Yields the value True if rounding is performed on inexact results of every predefined operation that yields a result of the type T; yields the value False otherwise. The value of this attribute is of the predefined type Boolean. 12 S'Machine_Overflows Yields the value True if overflow and divide-by-zero are detected and reported by raising Constraint_Error for every predefined operation that yields a result of the type T; yields the value False otherwise. The value of this attribute is of the predefined type Boolean. 13 S'Signed_Zeros Yields the value True if the hardware representation for the type T has the capability of representing both positively and negatively signed zeros, these being generated and used by the predefined operations of the type T as specified in IEC 559:1989; yields the value False otherwise. The value of this attribute is of the predefined type Boolean. 14 For every value x of a floating point type T, the normalized exponent of x is defined as follows: 15 * the normalized exponent of zero is (by convention) zero; 16 * for nonzero x, the normalized exponent of x is the unique integer k such that T'Machine_Radix(k-1) <= |x| < T'Machine_Radix(k). 17 The following primitive function attributes are defined for any subtype S of a floating point type T. 18 S'Exponent S'Exponent denotes a function with the following specification: 19 function S'Exponent (X : T) return universal_integer 20 The function yields the normalized exponent of X. 21 S'Fraction S'Fraction denotes a function with the following specification: 22 function S'Fraction (X : T) return T 23 The function yields the value X · T'Machine_Radix(-k), where k is the normalized exponent of X. A zero result, which can only occur when X is zero, has the sign of X. 24 S'Compose S'Compose denotes a function with the following specification: 25 function S'Compose (Fraction : T; Exponent : universal_integer) return T 26 Let v be the value Fraction · T'Machine_Radix(Exponent-k), where k is the normalized exponent of Fraction. If v is a machine number of the type T, or if |v| >= T'Model_Small, the function yields v; otherwise, it yields either one of the machine numbers of the type T adjacent to v. Constraint_Error is optionally raised if v is outside the base range of S. A zero result has the sign of Fraction when S'Signed_Zeros is True. 27 S'Scaling S'Scaling denotes a function with the following specification: 28 function S'Scaling (X : T; Adjustment : universal_integer) return T 29 Let v be the value X · T'Machine_Radix(Adjustment). If v is a machine number of the type T, or if |v| >= T'Model_Small, the function yields v; otherwise, it yields either one of the machine numbers of the type T adjacent to v. Constraint_Error is optionally raised if v is outside the base range of S. A zero result has the sign of X when S'Signed_Zeros is True. 30 S'Floor S'Floor denotes a function with the following specification: 31 function S'Floor (X : T) return T 32 The function yields the value Floor(X), i.e., the largest (most positive) integral value less than or equal to X. When X is zero, the result has the sign of X; a zero result otherwise has a positive sign. 33 S'Ceiling S'Ceiling denotes a function with the following specification: 34 function S'Ceiling (X : T) return T 35 The function yields the value Ceiling(X), i.e., the smallest (most negative) integral value greater than or equal to X. When X is zero, the result has the sign of X; a zero result otherwise has a negative sign when S'Signed_Zeros is True. 36 S'Rounding S'Rounding denotes a function with the following specification: 37 function S'Rounding (X : T) return T 38 The function yields the integral value nearest to X, rounding away from zero if X lies exactly halfway between two integers. A zero result has the sign of X when S'Signed_Zeros is True. 39 S'Unbiased_Rounding S'Unbiased_Rounding denotes a function with the following specification: 40 function S'Unbiased_Rounding (X : T) return T 41 The function yields the integral value nearest to X, rounding toward the even integer if X lies exactly halfway between two integers. A zero result has the sign of X when S'Signed_Zeros is True. 41.1/2 S'Machine_Rounding S'Machine_Rounding denotes a function with the following specification: 41.2/2 function S'Machine_Rounding (X : T) return T 41.3/2 The function yields the integral value nearest to X. If X lies exactly halfway between two integers, one of those integers is returned, but which of them is returned is unspecified. A zero result has the sign of X when S'Signed_Zeros is True. This function provides access to the rounding behavior which is most efficient on the target processor. 42 S'Truncation S'Truncation denotes a function with the following specification: 43 function S'Truncation (X : T) return T 44 The function yields the value Ceiling(X) when X is negative, and Floor(X) otherwise. A zero result has the sign of X when S'Signed_Zeros is True. 45 S'Remainder S'Remainder denotes a function with the following specification: 46 function S'Remainder (X, Y : T) return T 47 For nonzero Y, let v be the value X - n · Y, where n is the integer nearest to the exact value of X/Y; if |n - X/Y| = 1/2, then n is chosen to be even. If v is a machine number of the type T, the function yields v; otherwise, it yields zero. Constraint_Error is raised if Y is zero. A zero result has the sign of X when S'Signed_Zeros is True. 48 S'Adjacent S'Adjacent denotes a function with the following specification: 49 function S'Adjacent (X, Towards : T) return T 50 If Towards = X, the function yields X; otherwise, it yields the machine number of the type T adjacent to X in the direction of Towards, if that machine number exists. If the result would be outside the base range of S, Constraint_Error is raised. When T'Signed_Zeros is True, a zero result has the sign of X. When Towards is zero, its sign has no bearing on the result. 51 S'Copy_Sign S'Copy_Sign denotes a function with the following specification: 52 function S'Copy_Sign (Value, Sign : T) return T 53 If the value of Value is nonzero, the function yields a result whose magnitude is that of Value and whose sign is that of Sign; otherwise, it yields the value zero. Constraint_Error is optionally raised if the result is outside the base range of S. A zero result has the sign of Sign when S'Signed_Zeros is True. 54 S'Leading_Part S'Leading_Part denotes a function with the following specification: 55 function S'Leading_Part (X : T; Radix_Digits : universal_integer) return T 56 Let v be the value T'Machine_Radix(k-Radix_Digits), where k is the normalized exponent of X. The function yields the value 57 * Floor(X/v) · v, when X is nonnegative and Radix_Digits is positive; 58 * Ceiling(X/v) · v, when X is negative and Radix_Digits is positive. 59 Constraint_Error is raised when Radix_Digits is zero or negative. A zero result, which can only occur when X is zero, has the sign of X. 60 S'Machine S'Machine denotes a function with the following specification: 61 function S'Machine (X : T) return T 62 If X is a machine number of the type T, the function yields X; otherwise, it yields the value obtained by rounding or truncating X to either one of the adjacent machine numbers of the type T. Constraint_Error is raised if rounding or truncating X to the precision of the machine numbers results in a value outside the base range of S. A zero result has the sign of X when S'Signed_Zeros is True. 63 The following model-oriented attributes are defined for any subtype S of a floating point type T. 64 S'Model_Mantissa If the Numerics Annex is not supported, this attribute yields an implementation defined value that is greater than or equal to Ceiling(d · log(10) / log(T'Machine_Radix)) + 1, where d is the requested decimal precision of T, and less than or equal to the value of T'Machine_Mantissa. See G.2.2 for further requirements that apply to implementations supporting the Numerics Annex. The value of this attribute is of the type universal_integer. 65 S'Model_Emin If the Numerics Annex is not supported, this attribute yields an implementation defined value that is greater than or equal to the value of T'Machine_Emin. See G.2.2 for further requirements that apply to implementations supporting the Numerics Annex. The value of this attribute is of the type universal_integer. 66 S'Model_Epsilon Yields the value T'Machine_Radix(1 - T'Model_Mantissa). The value of this attribute is of the type universal_real. 67 S'Model_Small Yields the value T'Machine_Radix(T'Model_Emin - 1). The value of this attribute is of the type universal_real. 68 S'Model S'Model denotes a function with the following specification: 69 function S'Model (X : T) return T 70 If the Numerics Annex is not supported, the meaning of this attribute is implementation defined; see G.2.2 for the definition that applies to implementations supporting the Numerics Annex. 71 S'Safe_First Yields the lower bound of the safe range (see 3.5.7) of the type T. If the Numerics Annex is not supported, the value of this attribute is implementation defined; see G.2.2 for the definition that applies to implementations supporting the Numerics Annex. The value of this attribute is of the type universal_real. 72 S'Safe_Last Yields the upper bound of the safe range (see 3.5.7) of the type T. If the Numerics Annex is not supported, the value of this attribute is implementation defined; see G.2.2 for the definition that applies to implementations supporting the Numerics Annex. The value of this attribute is of the type universal_real. A.5.4 Attributes of Fixed Point Types Static Semantics 1 The following representation-oriented attributes are defined for every subtype S of a fixed point type T. 2 S'Machine_Radix Yields the radix of the hardware representation of the type T. The value of this attribute is of the type universal_integer. 3 S'Machine_Rounds Yields the value True if rounding is performed on inexact results of every predefined operation that yields a result of the type T; yields the value False otherwise. The value of this attribute is of the predefined type Boolean. 4 S'Machine_Overflows Yields the value True if overflow and divide-by-zero are detected and reported by raising Constraint_Error for every predefined operation that yields a result of the type T; yields the value False otherwise. The value of this attribute is of the predefined type Boolean. A.6 Input-Output 1/2 Input-output is provided through language-defined packages, each of which is a child of the root package Ada. The generic packages Sequential_IO and Direct_IO define input-output operations applicable to files containing elements of a given type. The generic package Storage_IO supports reading from and writing to an in-memory buffer. Additional operations for text input-output are supplied in the packages Text_IO, Wide_Text_IO, and Wide_Wide_Text_IO. Heterogeneous input-output is provided through the child packages Streams.Stream_IO and Text_IO.Text_Streams (see also 13.13). The package IO_Exceptions defines the exceptions needed by the predefined input-output packages. A.7 External Files and File Objects Static Semantics 1 Values input from the external environment of the program, or output to the external environment, are considered to occupy external files. An external file can be anything external to the program that can produce a value to be read or receive a value to be written. An external file is identified by a string (the name). A second string (the form) gives further system-dependent characteristics that may be associated with the file, such as the physical organization or access rights. The conventions governing the interpretation of such strings shall be documented. 2/3 Input and output operations are expressed as operations on objects of some file type, rather than directly in terms of the external files. In the remainder of this clause, the term file is always used to refer to a file object; the term external file is used otherwise. 3 Input-output for sequential files of values of a single element type is defined by means of the generic package Sequential_IO. In order to define sequential input-output for a given element type, an instantiation of this generic unit, with the given type as actual parameter, has to be declared. The resulting package contains the declaration of a file type (called File_Type) for files of such elements, as well as the operations applicable to these files, such as the Open, Read, and Write procedures. 4/2 Input-output for direct access files is likewise defined by a generic package called Direct_IO. Input-output in human-readable form is defined by the (nongeneric) packages Text_IO for Character and String data, Wide_Text_IO for Wide_Character and Wide_String data, and Wide_Wide_Text_IO for Wide_Wide_Character and Wide_Wide_String data. Input-output for files containing streams of elements representing values of possibly different types is defined by means of the (nongeneric) package Streams.Stream_IO. 5 Before input or output operations can be performed on a file, the file first has to be associated with an external file. While such an association is in effect, the file is said to be open, and otherwise the file is said to be closed. 6 The language does not define what happens to external files after the completion of the main program and all the library tasks (in particular, if corresponding files have not been closed). The effect of input-output for access types is unspecified. 7 An open file has a current mode, which is a value of one of the following enumeration types: 8 type File_Mode is (In_File, Inout_File, Out_File); -- for Direct_IO 9 These values correspond respectively to the cases where only reading, both reading and writing, or only writing are to be performed. 10/2 type File_Mode is (In_File, Out_File, Append_File); -- for Sequential_IO, Text_IO, Wide_Text_IO, Wide_Wide_Text_IO, and Stream_IO 11 These values correspond respectively to the cases where only reading, only writing, or only appending are to be performed. 12 The mode of a file can be changed. 13/2 Several file management operations are common to Sequential_IO, Direct_IO, Text_IO, Wide_Text_IO, and Wide_Wide_Text_IO. These operations are described in subclause A.8.2 for sequential and direct files. Any additional effects concerning text input-output are described in subclause A.10.2. 14/3 The exceptions that can be propagated by the execution of an input-output subprogram are defined in the package IO_Exceptions; the situations in which they can be propagated are described following the description of the subprogram (and in subclause A.13). The exceptions Storage_Error and Program_Error may be propagated. (Program_Error can only be propagated due to errors made by the caller of the subprogram.) Finally, exceptions can be propagated in certain implementation-defined situations. NOTES 15/2 23 Each instantiation of the generic packages Sequential_IO and Direct_IO declares a different type File_Type. In the case of Text_IO, Wide_Text_IO, Wide_Wide_Text_IO, and Streams.Stream_IO, the corresponding type File_Type is unique. 16 24 A bidirectional device can often be modeled as two sequential files associated with the device, one of mode In_File, and one of mode Out_File. An implementation may restrict the number of files that may be associated with a given external file. A.8 Sequential and Direct Files Static Semantics 1/2 Two kinds of access to external files are defined in this subclause: sequential access and direct access. The corresponding file types and the associated operations are provided by the generic packages Sequential_IO and Direct_IO. A file object to be used for sequential access is called a sequential file, and one to be used for direct access is called a direct file. Access to stream files is described in A.12.1. 2 For sequential access, the file is viewed as a sequence of values that are transferred in the order of their appearance (as produced by the program or by the external environment). When the file is opened with mode In_File or Out_File, transfer starts respectively from or to the beginning of the file. When the file is opened with mode Append_File, transfer to the file starts after the last element of the file. 3 For direct access, the file is viewed as a set of elements occupying consecutive positions in linear order; a value can be transferred to or from an element of the file at any selected position. The position of an element is specified by its index, which is a number, greater than zero, of the implementation-defined integer type Count. The first element, if any, has index one; the index of the last element, if any, is called the current size; the current size is zero if there are no elements. The current size is a property of the external file. 4 An open direct file has a current index, which is the index that will be used by the next read or write operation. When a direct file is opened, the current index is set to one. The current index of a direct file is a property of a file object, not of an external file. A.8.1 The Generic Package Sequential_IO Static Semantics 1 The generic library package Sequential_IO has the following declaration: 2 with Ada.IO_Exceptions; generic type Element_Type(<>) is private; package Ada.Sequential_IO is 3 type File_Type is limited private; 4 type File_Mode is (In_File, Out_File, Append_File); 5 -- File management 6 procedure Create(File : in out File_Type; Mode : in File_Mode := Out_File; Name : in String := ""; Form : in String := ""); 7 procedure Open (File : in out File_Type; Mode : in File_Mode; Name : in String; Form : in String := ""); 8 procedure Close (File : in out File_Type); procedure Delete(File : in out File_Type); procedure Reset (File : in out File_Type; Mode : in File_Mode); procedure Reset (File : in out File_Type); 9 function Mode (File : in File_Type) return File_Mode; function Name (File : in File_Type) return String; function Form (File : in File_Type) return String; 10 function Is_Open(File : in File_Type) return Boolean; 10.1/4 procedure Flush (File : in File_Type); 11 -- Input and output operations 12 procedure Read (File : in File_Type; Item : out Element_Type); procedure Write (File : in File_Type; Item : in Element_Type); 13 function End_Of_File(File : in File_Type) return Boolean; 14 -- Exceptions 15 Status_Error : exception renames IO_Exceptions.Status_Error; Mode_Error : exception renames IO_Exceptions.Mode_Error; Name_Error : exception renames IO_Exceptions.Name_Error; Use_Error : exception renames IO_Exceptions.Use_Error; Device_Error : exception renames IO_Exceptions.Device_Error; End_Error : exception renames IO_Exceptions.End_Error; Data_Error : exception renames IO_Exceptions.Data_Error; 16 private ... -- not specified by the language end Ada.Sequential_IO; 17/2 The type File_Type needs finalization (see 7.6) in every instantiation of Sequential_IO. A.8.2 File Management Static Semantics 1 The procedures and functions described in this subclause provide for the control of external files; their declarations are repeated in each of the packages for sequential, direct, text, and stream input-output. For text input-output, the procedures Create, Open, and Reset have additional effects described in subclause A.10.2. 2 procedure Create(File : in out File_Type; Mode : in File_Mode := default_mode; Name : in String := ""; Form : in String := ""); 3/2 Establishes a new external file, with the given name and form, and associates this external file with the given file. The given file is left open. The current mode of the given file is set to the given access mode. The default access mode is the mode Out_File for sequential, stream, and text input-output; it is the mode Inout_File for direct input-output. For direct access, the size of the created file is implementation defined. 4 A null string for Name specifies an external file that is not accessible after the completion of the main program (a temporary file). A null string for Form specifies the use of the default options of the implementation for the external file. 5 The exception Status_Error is propagated if the given file is already open. The exception Name_Error is propagated if the string given as Name does not allow the identification of an external file. The exception Use_Error is propagated if, for the specified mode, the external environment does not support creation of an external file with the given name (in the absence of Name_Error) and form. 6 procedure Open(File : in out File_Type; Mode : in File_Mode; Name : in String; Form : in String := ""); 7 Associates the given file with an existing external file having the given name and form, and sets the current mode of the given file to the given mode. The given file is left open. 8 The exception Status_Error is propagated if the given file is already open. The exception Name_Error is propagated if the string given as Name does not allow the identification of an external file; in particular, this exception is propagated if no external file with the given name exists. The exception Use_Error is propagated if, for the specified mode, the external environment does not support opening for an external file with the given name (in the absence of Name_Error) and form. 9 procedure Close(File : in out File_Type); 10 Severs the association between the given file and its associated external file. The given file is left closed. In addition, for sequential files, if the file being closed has mode Out_File or Append_File, then the last element written since the most recent open or reset is the last element that can be read from the file. If no elements have been written and the file mode is Out_File, then the closed file is empty. If no elements have been written and the file mode is Append_File, then the closed file is unchanged. 11 The exception Status_Error is propagated if the given file is not open. 12 procedure Delete(File : in out File_Type); 13 Deletes the external file associated with the given file. The given file is closed, and the external file ceases to exist. 14 The exception Status_Error is propagated if the given file is not open. The exception Use_Error is propagated if deletion of the external file is not supported by the external environment. 15 procedure Reset(File : in out File_Type; Mode : in File_Mode); procedure Reset(File : in out File_Type); 16/2 Resets the given file so that reading from its elements can be restarted from the beginning of the external file (for modes In_File and Inout_File), and so that writing to its elements can be restarted at the beginning of the external file (for modes Out_File and Inout_File) or after the last element of the external file (for mode Append_File). In particular, for direct access this means that the current index is set to one. If a Mode parameter is supplied, the current mode of the given file is set to the given mode. In addition, for sequential files, if the given file has mode Out_File or Append_File when Reset is called, the last element written since the most recent open or reset is the last element that can be read from the external file. If no elements have been written and the file mode is Out_File, the reset file is empty. If no elements have been written and the file mode is Append_File, then the reset file is unchanged. 17 The exception Status_Error is propagated if the file is not open. The exception Use_Error is propagated if the external environment does not support resetting for the external file and, also, if the external environment does not support resetting to the specified mode for the external file. 18 function Mode(File : in File_Type) return File_Mode; 19 Returns the current mode of the given file. 20 The exception Status_Error is propagated if the file is not open. 21 function Name(File : in File_Type) return String; 22/2 Returns a string which uniquely identifies the external file currently associated with the given file (and may thus be used in an Open operation). 23 The exception Status_Error is propagated if the given file is not open. The exception Use_Error is propagated if the associated external file is a temporary file that cannot be opened by any name. 24 function Form(File : in File_Type) return String; 25 Returns the form string for the external file currently associated with the given file. If an external environment allows alternative specifications of the form (for example, abbreviations using default options), the string returned by the function should correspond to a full specification (that is, it should indicate explicitly all options selected, including default options). 26 The exception Status_Error is propagated if the given file is not open. 27 function Is_Open(File : in File_Type) return Boolean; 28/3 Returns True if the file is open (that is, if it is associated with an external file); otherwise, returns False. 28.1/4 procedure Flush(File : in File_Type); 28.2/4 The Flush procedure synchronizes the external file with the internal file (by flushing any internal buffers) without closing the file. For a direct file, the current index is unchanged; for a stream file (see A.12.1), the current position is unchanged. 28.3/4 The exception Status_Error is propagated if the file is not open. The exception Mode_Error is propagated if the mode of the file is In_File. Implementation Permissions 29 An implementation may propagate Name_Error or Use_Error if an attempt is made to use an I/O feature that cannot be supported by the implementation due to limitations in the external environment. Any such restriction should be documented. A.8.3 Sequential Input-Output Operations Static Semantics 1 The operations available for sequential input and output are described in this subclause. The exception Status_Error is propagated if any of these operations is attempted for a file that is not open. 2 procedure Read(File : in File_Type; Item : out Element_Type); 3 Operates on a file of mode In_File. Reads an element from the given file, and returns the value of this element in the Item parameter. 4 The exception Mode_Error is propagated if the mode is not In_File. The exception End_Error is propagated if no more elements can be read from the given file. The exception Data_Error can be propagated if the element read cannot be interpreted as a value of the subtype Element_Type (see A.13, "Exceptions in Input-Output "). 5 procedure Write(File : in File_Type; Item : in Element_Type); 6 Operates on a file of mode Out_File or Append_File. Writes the value of Item to the given file. 7 The exception Mode_Error is propagated if the mode is not Out_File or Append_File. The exception Use_Error is propagated if the capacity of the external file is exceeded. 8 function End_Of_File(File : in File_Type) return Boolean; 9/3 Operates on a file of mode In_File. Returns True if no more elements can be read from the given file; otherwise, returns False. 10 The exception Mode_Error is propagated if the mode is not In_File. A.8.4 The Generic Package Direct_IO Static Semantics 1 The generic library package Direct_IO has the following declaration: 2 with Ada.IO_Exceptions; generic type Element_Type is private; package Ada.Direct_IO is 3 type File_Type is limited private; 4 type File_Mode is (In_File, Inout_File, Out_File); type Count is range 0 .. implementation-defined; subtype Positive_Count is Count range 1 .. Count'Last; 5 -- File management 6 procedure Create(File : in out File_Type; Mode : in File_Mode := Inout_File; Name : in String := ""; Form : in String := ""); 7 procedure Open (File : in out File_Type; Mode : in File_Mode; Name : in String; Form : in String := ""); 8 procedure Close (File : in out File_Type); procedure Delete(File : in out File_Type); procedure Reset (File : in out File_Type; Mode : in File_Mode); procedure Reset (File : in out File_Type); 9 function Mode (File : in File_Type) return File_Mode; function Name (File : in File_Type) return String; function Form (File : in File_Type) return String; 10 function Is_Open(File : in File_Type) return Boolean; 10.1/4 procedure Flush (File : in File_Type); 11 -- Input and output operations 12 procedure Read (File : in File_Type; Item : out Element_Type; From : in Positive_Count); procedure Read (File : in File_Type; Item : out Element_Type); 13 procedure Write(File : in File_Type; Item : in Element_Type; To : in Positive_Count); procedure Write(File : in File_Type; Item : in Element_Type); 14 procedure Set_Index(File : in File_Type; To : in Positive_Count); 15 function Index(File : in File_Type) return Positive_Count; function Size (File : in File_Type) return Count; 16 function End_Of_File(File : in File_Type) return Boolean; 17 -- Exceptions 18 Status_Error : exception renames IO_Exceptions.Status_Error; Mode_Error : exception renames IO_Exceptions.Mode_Error; Name_Error : exception renames IO_Exceptions.Name_Error; Use_Error : exception renames IO_Exceptions.Use_Error; Device_Error : exception renames IO_Exceptions.Device_Error; End_Error : exception renames IO_Exceptions.End_Error; Data_Error : exception renames IO_Exceptions.Data_Error; 19 private ... -- not specified by the language end Ada.Direct_IO; 20/2 The type File_Type needs finalization (see 7.6) in every instantiation of Direct_IO. A.8.5 Direct Input-Output Operations Static Semantics 1 The operations available for direct input and output are described in this subclause. The exception Status_Error is propagated if any of these operations is attempted for a file that is not open. 2 procedure Read(File : in File_Type; Item : out Element_Type; From : in Positive_Count); procedure Read(File : in File_Type; Item : out Element_Type); 3 Operates on a file of mode In_File or Inout_File. In the case of the first form, sets the current index of the given file to the index value given by the parameter From. Then (for both forms) returns, in the parameter Item, the value of the element whose position in the given file is specified by the current index of the file; finally, increases the current index by one. 4 The exception Mode_Error is propagated if the mode of the given file is Out_File. The exception End_Error is propagated if the index to be used exceeds the size of the external file. The exception Data_Error can be propagated if the element read cannot be interpreted as a value of the subtype Element_Type (see A.13). 5 procedure Write(File : in File_Type; Item : in Element_Type; To : in Positive_Count); procedure Write(File : in File_Type; Item : in Element_Type); 6 Operates on a file of mode Inout_File or Out_File. In the case of the first form, sets the index of the given file to the index value given by the parameter To. Then (for both forms) gives the value of the parameter Item to the element whose position in the given file is specified by the current index of the file; finally, increases the current index by one. 7 The exception Mode_Error is propagated if the mode of the given file is In_File. The exception Use_Error is propagated if the capacity of the external file is exceeded. 8 procedure Set_Index(File : in File_Type; To : in Positive_Count); 9 Operates on a file of any mode. Sets the current index of the given file to the given index value (which may exceed the current size of the file). 10 function Index(File : in File_Type) return Positive_Count; 11 Operates on a file of any mode. Returns the current index of the given file. 12 function Size(File : in File_Type) return Count; 13 Operates on a file of any mode. Returns the current size of the external file that is associated with the given file. 14 function End_Of_File(File : in File_Type) return Boolean; 15/3 Operates on a file of mode In_File or Inout_File. Returns True if the current index exceeds the size of the external file; otherwise, returns False. 16 The exception Mode_Error is propagated if the mode of the given file is Out_File. NOTES 17 25 Append_File mode is not supported for the generic package Direct_IO. A.9 The Generic Package Storage_IO 1 The generic package Storage_IO provides for reading from and writing to an in-memory buffer. This generic package supports the construction of user-defined input-output packages. Static Semantics 2 The generic library package Storage_IO has the following declaration: 3 with Ada.IO_Exceptions; with System.Storage_Elements; generic type Element_Type is private; package Ada.Storage_IO is pragma Preelaborate(Storage_IO); 4 Buffer_Size : constant System.Storage_Elements.Storage_Count := implementation-defined; subtype Buffer_Type is System.Storage_Elements.Storage_Array(1..Buffer_Size); 5 -- Input and output operations 6 procedure Read (Buffer : in Buffer_Type; Item : out Element_Type); 7 procedure Write(Buffer : out Buffer_Type; Item : in Element_Type); 8 -- Exceptions 9 Data_Error : exception renames IO_Exceptions.Data_Error; end Ada.Storage_IO; 10 In each instance, the constant Buffer_Size has a value that is the size (in storage elements) of the buffer required to represent the content of an object of subtype Element_Type, including any implicit levels of indirection used by the implementation. The Read and Write procedures of Storage_IO correspond to the Read and Write procedures of Direct_IO (see A.8.4), but with the content of the Item parameter being read from or written into the specified Buffer, rather than an external file. NOTES 11 26 A buffer used for Storage_IO holds only one element at a time; an external file used for Direct_IO holds a sequence of elements. A.10 Text Input-Output Static Semantics 1/3 This subclause describes the package Text_IO, which provides facilities for input and output in human-readable form. Each file is read or written sequentially, as a sequence of characters grouped into lines, and as a sequence of lines grouped into pages. The specification of the package is given below in subclause A.10.1. 2/3 The facilities for file management given above, in subclauses A.8.2 and A.8.3, are available for text input-output. In place of Read and Write, however, there are procedures Get and Put that input values of suitable types from text files, and output values to them. These values are provided to the Put procedures, and returned by the Get procedures, in a parameter Item. Several overloaded procedures of these names exist, for different types of Item. These Get procedures analyze the input sequences of characters based on lexical elements (see Clause 2) and return the corresponding values; the Put procedures output the given values as appropriate lexical elements. Procedures Get and Put are also available that input and output individual characters treated as character values rather than as lexical elements. Related to character input are procedures to look ahead at the next character without reading it, and to read a character "immediately" without waiting for an end-of-line to signal availability. 3 In addition to the procedures Get and Put for numeric and enumeration types of Item that operate on text files, analogous procedures are provided that read from and write to a parameter of type String. These procedures perform the same analysis and composition of character sequences as their counterparts which have a file parameter. 4 For all Get and Put procedures that operate on text files, and for many other subprograms, there are forms with and without a file parameter. Each such Get procedure operates on an input file, and each such Put procedure operates on an output file. If no file is specified, a default input file or a default output file is used. 5 At the beginning of program execution the default input and output files are the so-called standard input file and standard output file. These files are open, have respectively the current modes In_File and Out_File, and are associated with two implementation-defined external files. Procedures are provided to change the current default input file and the current default output file. 6 At the beginning of program execution a default file for program-dependent error-related text output is the so-called standard error file. This file is open, has the current mode Out_File, and is associated with an implementation-defined external file. A procedure is provided to change the current default error file. 7 From a logical point of view, a text file is a sequence of pages, a page is a sequence of lines, and a line is a sequence of characters; the end of a line is marked by a line terminator; the end of a page is marked by the combination of a line terminator immediately followed by a page terminator; and the end of a file is marked by the combination of a line terminator immediately followed by a page terminator and then a file terminator. Terminators are generated during output; either by calls of procedures provided expressly for that purpose; or implicitly as part of other operations, for example, when a bounded line length, a bounded page length, or both, have been specified for a file. 8 The actual nature of terminators is not defined by the language and hence depends on the implementation. Although terminators are recognized or generated by certain of the procedures that follow, they are not necessarily implemented as characters or as sequences of characters. Whether they are characters (and if so which ones) in any particular implementation need not concern a user who neither explicitly outputs nor explicitly inputs control characters. The effect of input (Get) or output (Put) of control characters (other than horizontal tabulation) is not specified by the language. 9 The characters of a line are numbered, starting from one; the number of a character is called its column number. For a line terminator, a column number is also defined: it is one more than the number of characters in the line. The lines of a page, and the pages of a file, are similarly numbered. The current column number is the column number of the next character or line terminator to be transferred. The current line number is the number of the current line. The current page number is the number of the current page. These numbers are values of the subtype Positive_Count of the type Count (by convention, the value zero of the type Count is used to indicate special conditions). 10 type Count is range 0 .. implementation-defined; subtype Positive_Count is Count range 1 .. Count'Last; 11 For an output file or an append file, a maximum line length can be specified and a maximum page length can be specified. If a value to be output cannot fit on the current line, for a specified maximum line length, then a new line is automatically started before the value is output; if, further, this new line cannot fit on the current page, for a specified maximum page length, then a new page is automatically started before the value is output. Functions are provided to determine the maximum line length and the maximum page length. When a file is opened with mode Out_File or Append_File, both values are zero: by convention, this means that the line lengths and page lengths are unbounded. (Consequently, output consists of a single line if the subprograms for explicit control of line and page structure are not used.) The constant Unbounded is provided for this purpose. A.10.1 The Package Text_IO Static Semantics 1 The library package Text_IO has the following declaration: 2 with Ada.IO_Exceptions; package Ada.Text_IO is 3 type File_Type is limited private; 4 type File_Mode is (In_File, Out_File, Append_File); 5 type Count is range 0 .. implementation-defined; subtype Positive_Count is Count range 1 .. Count'Last; Unbounded : constant Count := 0; -- line and page length 6 subtype Field is Integer range 0 .. implementation-defined; subtype Number_Base is Integer range 2 .. 16; 7 type Type_Set is (Lower_Case, Upper_Case); 8 -- File Management 9 procedure Create (File : in out File_Type; Mode : in File_Mode := Out_File; Name : in String := ""; Form : in String := ""); 10 procedure Open (File : in out File_Type; Mode : in File_Mode; Name : in String; Form : in String := ""); 11 procedure Close (File : in out File_Type); procedure Delete (File : in out File_Type); procedure Reset (File : in out File_Type; Mode : in File_Mode); procedure Reset (File : in out File_Type); 12 function Mode (File : in File_Type) return File_Mode; function Name (File : in File_Type) return String; function Form (File : in File_Type) return String; 13 function Is_Open(File : in File_Type) return Boolean; 14 -- Control of default input and output files 15 procedure Set_Input (File : in File_Type); procedure Set_Output(File : in File_Type); procedure Set_Error (File : in File_Type); 16 function Standard_Input return File_Type; function Standard_Output return File_Type; function Standard_Error return File_Type; 17 function Current_Input return File_Type; function Current_Output return File_Type; function Current_Error return File_Type; 18 type File_Access is access constant File_Type; 19 function Standard_Input return File_Access; function Standard_Output return File_Access; function Standard_Error return File_Access; 20 function Current_Input return File_Access; function Current_Output return File_Access; function Current_Error return File_Access; 21/1 --Buffer control procedure Flush (File : in File_Type); procedure Flush; 22 -- Specification of line and page lengths 23 procedure Set_Line_Length(File : in File_Type; To : in Count); procedure Set_Line_Length(To : in Count); 24 procedure Set_Page_Length(File : in File_Type; To : in Count); procedure Set_Page_Length(To : in Count); 25 function Line_Length(File : in File_Type) return Count; function Line_Length return Count; 26 function Page_Length(File : in File_Type) return Count; function Page_Length return Count; 27 -- Column, Line, and Page Control 28 procedure New_Line (File : in File_Type; Spacing : in Positive_Count := 1); procedure New_Line (Spacing : in Positive_Count := 1); 29 procedure Skip_Line (File : in File_Type; Spacing : in Positive_Count := 1); procedure Skip_Line (Spacing : in Positive_Count := 1); 30 function End_Of_Line(File : in File_Type) return Boolean; function End_Of_Line return Boolean; 31 procedure New_Page (File : in File_Type); procedure New_Page; 32 procedure Skip_Page (File : in File_Type); procedure Skip_Page; 33 function End_Of_Page(File : in File_Type) return Boolean; function End_Of_Page return Boolean; 34 function End_Of_File(File : in File_Type) return Boolean; function End_Of_File return Boolean; 35 procedure Set_Col (File : in File_Type; To : in Positive_Count); procedure Set_Col (To : in Positive_Count); 36 procedure Set_Line(File : in File_Type; To : in Positive_Count); procedure Set_Line(To : in Positive_Count); 37 function Col (File : in File_Type) return Positive_Count; function Col return Positive_Count; 38 function Line(File : in File_Type) return Positive_Count; function Line return Positive_Count; 39 function Page(File : in File_Type) return Positive_Count; function Page return Positive_Count; 40 -- Character Input-Output 41 procedure Get(File : in File_Type; Item : out Character); procedure Get(Item : out Character); 42 procedure Put(File : in File_Type; Item : in Character); procedure Put(Item : in Character); 43 procedure Look_Ahead (File : in File_Type; Item : out Character; End_Of_Line : out Boolean); procedure Look_Ahead (Item : out Character; End_Of_Line : out Boolean); 44 procedure Get_Immediate(File : in File_Type; Item : out Character); procedure Get_Immediate(Item : out Character); 45 procedure Get_Immediate(File : in File_Type; Item : out Character; Available : out Boolean); procedure Get_Immediate(Item : out Character; Available : out Boolean); 46 -- String Input-Output 47 procedure Get(File : in File_Type; Item : out String); procedure Get(Item : out String); 48 procedure Put(File : in File_Type; Item : in String); procedure Put(Item : in String); 49 procedure Get_Line(File : in File_Type; Item : out String; Last : out Natural); procedure Get_Line(Item : out String; Last : out Natural); 49.1/2 function Get_Line(File : in File_Type) return String; function Get_Line return String; 50 procedure Put_Line(File : in File_Type; Item : in String); procedure Put_Line(Item : in String); 51 -- Generic packages for Input-Output of Integer Types 52 generic type Num is range <>; package Integer_IO is 53 Default_Width : Field := Num'Width; Default_Base : Number_Base := 10; 54 procedure Get(File : in File_Type; Item : out Num; Width : in Field := 0); procedure Get(Item : out Num; Width : in Field := 0); 55 procedure Put(File : in File_Type; Item : in Num; Width : in Field := Default_Width; Base : in Number_Base := Default_Base); procedure Put(Item : in Num; Width : in Field := Default_Width; Base : in Number_Base := Default_Base); procedure Get(From : in String; Item : out Num; Last : out Positive); procedure Put(To : out String; Item : in Num; Base : in Number_Base := Default_Base); 56 end Integer_IO; 57 generic type Num is mod <>; package Modular_IO is 58 Default_Width : Field := Num'Width; Default_Base : Number_Base := 10; 59 procedure Get(File : in File_Type; Item : out Num; Width : in Field := 0); procedure Get(Item : out Num; Width : in Field := 0); 60 procedure Put(File : in File_Type; Item : in Num; Width : in Field := Default_Width; Base : in Number_Base := Default_Base); procedure Put(Item : in Num; Width : in Field := Default_Width; Base : in Number_Base := Default_Base); procedure Get(From : in String; Item : out Num; Last : out Positive); procedure Put(To : out String; Item : in Num; Base : in Number_Base := Default_Base); 61 end Modular_IO; 62 -- Generic packages for Input-Output of Real Types 63 generic type Num is digits <>; package Float_IO is 64 Default_Fore : Field := 2; Default_Aft : Field := Num'Digits-1; Default_Exp : Field := 3; 65 procedure Get(File : in File_Type; Item : out Num; Width : in Field := 0); procedure Get(Item : out Num; Width : in Field := 0); 66 procedure Put(File : in File_Type; Item : in Num; Fore : in Field := Default_Fore; Aft : in Field := Default_Aft; Exp : in Field := Default_Exp); procedure Put(Item : in Num; Fore : in Field := Default_Fore; Aft : in Field := Default_Aft; Exp : in Field := Default_Exp); 67 procedure Get(From : in String; Item : out Num; Last : out Positive); procedure Put(To : out String; Item : in Num; Aft : in Field := Default_Aft; Exp : in Field := Default_Exp); end Float_IO; 68 generic type Num is delta <>; package Fixed_IO is 69 Default_Fore : Field := Num'Fore; Default_Aft : Field := Num'Aft; Default_Exp : Field := 0; 70 procedure Get(File : in File_Type; Item : out Num; Width : in Field := 0); procedure Get(Item : out Num; Width : in Field := 0); 71 procedure Put(File : in File_Type; Item : in Num; Fore : in Field := Default_Fore; Aft : in Field := Default_Aft; Exp : in Field := Default_Exp); procedure Put(Item : in Num; Fore : in Field := Default_Fore; Aft : in Field := Default_Aft; Exp : in Field := Default_Exp); 72 procedure Get(From : in String; Item : out Num; Last : out Positive); procedure Put(To : out String; Item : in Num; Aft : in Field := Default_Aft; Exp : in Field := Default_Exp); end Fixed_IO; 73 generic type Num is delta <> digits <>; package Decimal_IO is 74 Default_Fore : Field := Num'Fore; Default_Aft : Field := Num'Aft; Default_Exp : Field := 0; 75 procedure Get(File : in File_Type; Item : out Num; Width : in Field := 0); procedure Get(Item : out Num; Width : in Field := 0); 76 procedure Put(File : in File_Type; Item : in Num; Fore : in Field := Default_Fore; Aft : in Field := Default_Aft; Exp : in Field := Default_Exp); procedure Put(Item : in Num; Fore : in Field := Default_Fore; Aft : in Field := Default_Aft; Exp : in Field := Default_Exp); 77 procedure Get(From : in String; Item : out Num; Last : out Positive); procedure Put(To : out String; Item : in Num; Aft : in Field := Default_Aft; Exp : in Field := Default_Exp); end Decimal_IO; 78 -- Generic package for Input-Output of Enumeration Types 79 generic type Enum is (<>); package Enumeration_IO is 80 Default_Width : Field := 0; Default_Setting : Type_Set := Upper_Case; 81 procedure Get(File : in File_Type; Item : out Enum); procedure Get(Item : out Enum); 82 procedure Put(File : in File_Type; Item : in Enum; Width : in Field := Default_Width; Set : in Type_Set := Default_Setting); procedure Put(Item : in Enum; Width : in Field := Default_Width; Set : in Type_Set := Default_Setting); 83 procedure Get(From : in String; Item : out Enum; Last : out Positive); procedure Put(To : out String; Item : in Enum; Set : in Type_Set := Default_Setting); end Enumeration_IO; 84 -- Exceptions 85 Status_Error : exception renames IO_Exceptions.Status_Error; Mode_Error : exception renames IO_Exceptions.Mode_Error; Name_Error : exception renames IO_Exceptions.Name_Error; Use_Error : exception renames IO_Exceptions.Use_Error; Device_Error : exception renames IO_Exceptions.Device_Error; End_Error : exception renames IO_Exceptions.End_Error; Data_Error : exception renames IO_Exceptions.Data_Error; Layout_Error : exception renames IO_Exceptions.Layout_Error; private ... -- not specified by the language end Ada.Text_IO; 86/2 The type File_Type needs finalization (see 7.6). A.10.2 Text File Management Static Semantics 1 The only allowed file modes for text files are the modes In_File, Out_File, and Append_File. The subprograms given in subclause A.8.2 for the control of external files, and the function End_Of_File given in subclause A.8.3 for sequential input-output, are also available for text files. There is also a version of End_Of_File that refers to the current default input file. For text files, the procedures have the following additional effects: 2 * For the procedures Create and Open: After a file with mode Out_File or Append_File is opened, the page length and line length are unbounded (both have the conventional value zero). After a file (of any mode) is opened, the current column, current line, and current page numbers are set to one. If the mode is Append_File, it is implementation defined whether a page terminator will separate preexisting text in the file from the new text to be written. 3 * For the procedure Close: If the file has the current mode Out_File or Append_File, has the effect of calling New_Page, unless the current page is already terminated; then outputs a file terminator. 4 * For the procedure Reset: If the file has the current mode Out_File or Append_File, has the effect of calling New_Page, unless the current page is already terminated; then outputs a file terminator. The current column, line, and page numbers are set to one, and the line and page lengths to Unbounded. If the new mode is Append_File, it is implementation defined whether a page terminator will separate preexisting text in the file from the new text to be written. 5 The exception Mode_Error is propagated by the procedure Reset upon an attempt to change the mode of a file that is the current default input file, the current default output file, or the current default error file. NOTES 6 27 An implementation can define the Form parameter of Create and Open to control effects including the following: 7 * the interpretation of line and column numbers for an interactive file, and 8 * the interpretation of text formats in a file created by a foreign program. A.10.3 Default Input, Output, and Error Files Static Semantics 1 The following subprograms provide for the control of the particular default files that are used when a file parameter is omitted from a Get, Put, or other operation of text input-output described below, or when application-dependent error-related text is to be output. 2 procedure Set_Input(File : in File_Type); 3 Operates on a file of mode In_File. Sets the current default input file to File. 4 The exception Status_Error is propagated if the given file is not open. The exception Mode_Error is propagated if the mode of the given file is not In_File. 5 procedure Set_Output(File : in File_Type); procedure Set_Error (File : in File_Type); 6 Each operates on a file of mode Out_File or Append_File. Set_Output sets the current default output file to File. Set_Error sets the current default error file to File. The exception Status_Error is propagated if the given file is not open. The exception Mode_Error is propagated if the mode of the given file is not Out_File or Append_File. 7 function Standard_Input return File_Type; function Standard_Input return File_Access; 8 Returns the standard input file (see A.10), or an access value designating the standard input file, respectively. 9 function Standard_Output return File_Type; function Standard_Output return File_Access; 10 Returns the standard output file (see A.10) or an access value designating the standard output file, respectively. 11 function Standard_Error return File_Type; function Standard_Error return File_Access; 12/1 Returns the standard error file (see A.10), or an access value designating the standard error file, respectively. 13 The Form strings implicitly associated with the opening of Standard_Input, Standard_Output, and Standard_Error at the start of program execution are implementation defined. 14 function Current_Input return File_Type; function Current_Input return File_Access; 15 Returns the current default input file, or an access value designating the current default input file, respectively. 16 function Current_Output return File_Type; function Current_Output return File_Access; 17 Returns the current default output file, or an access value designating the current default output file, respectively. 18 function Current_Error return File_Type; function Current_Error return File_Access; 19 Returns the current default error file, or an access value designating the current default error file, respectively. 20/1 procedure Flush (File : in File_Type); procedure Flush; 21/4 The effect of Flush is the same as the corresponding subprogram in Sequential_IO (see A.8.2). If File is not explicitly specified, Current_Output is used. Erroneous Execution 22/1 The execution of a program is erroneous if it invokes an operation on a current default input, default output, or default error file, and if the corresponding file object is closed or no longer exists. 23/1 This paragraph was deleted. NOTES 24 28 The standard input, standard output, and standard error files cannot be opened, closed, reset, or deleted, because the parameter File of the corresponding procedures has the mode in out. 25 29 The standard input, standard output, and standard error files are different file objects, but not necessarily different external files. A.10.4 Specification of Line and Page Lengths Static Semantics 1 The subprograms described in this subclause are concerned with the line and page structure of a file of mode Out_File or Append_File. They operate either on the file given as the first parameter, or, in the absence of such a file parameter, on the current default output file. They provide for output of text with a specified maximum line length or page length. In these cases, line and page terminators are output implicitly and automatically when needed. When line and page lengths are unbounded (that is, when they have the conventional value zero), as in the case of a newly opened file, new lines and new pages are only started when explicitly called for. 2 In all cases, the exception Status_Error is propagated if the file to be used is not open; the exception Mode_Error is propagated if the mode of the file is not Out_File or Append_File. 3 procedure Set_Line_Length(File : in File_Type; To : in Count); procedure Set_Line_Length(To : in Count); 4 Sets the maximum line length of the specified output or append file to the number of characters specified by To. The value zero for To specifies an unbounded line length. 5 The exception Use_Error is propagated if the specified line length is inappropriate for the associated external file. 6 procedure Set_Page_Length(File : in File_Type; To : in Count); procedure Set_Page_Length(To : in Count); 7 Sets the maximum page length of the specified output or append file to the number of lines specified by To. The value zero for To specifies an unbounded page length. 8 The exception Use_Error is propagated if the specified page length is inappropriate for the associated external file. 9 function Line_Length(File : in File_Type) return Count; function Line_Length return Count; 10 Returns the maximum line length currently set for the specified output or append file, or zero if the line length is unbounded. 11 function Page_Length(File : in File_Type) return Count; function Page_Length return Count; 12 Returns the maximum page length currently set for the specified output or append file, or zero if the page length is unbounded. A.10.5 Operations on Columns, Lines, and Pages Static Semantics 1 The subprograms described in this subclause provide for explicit control of line and page structure; they operate either on the file given as the first parameter, or, in the absence of such a file parameter, on the appropriate (input or output) current default file. The exception Status_Error is propagated by any of these subprograms if the file to be used is not open. 2 procedure New_Line(File : in File_Type; Spacing : in Positive_Count := 1); procedure New_Line(Spacing : in Positive_Count := 1); 3 Operates on a file of mode Out_File or Append_File. 4 For a Spacing of one: Outputs a line terminator and sets the current column number to one. Then increments the current line number by one, except in the case that the current line number is already greater than or equal to the maximum page length, for a bounded page length; in that case a page terminator is output, the current page number is incremented by one, and the current line number is set to one. 5 For a Spacing greater than one, the above actions are performed Spacing times. 6 The exception Mode_Error is propagated if the mode is not Out_File or Append_File. 7 procedure Skip_Line(File : in File_Type; Spacing : in Positive_Count := 1); procedure Skip_Line(Spacing : in Positive_Count := 1); 8 Operates on a file of mode In_File. 9 For a Spacing of one: Reads and discards all characters until a line terminator has been read, and then sets the current column number to one. If the line terminator is not immediately followed by a page terminator, the current line number is incremented by one. Otherwise, if the line terminator is immediately followed by a page terminator, then the page terminator is skipped, the current page number is incremented by one, and the current line number is set to one. 10 For a Spacing greater than one, the above actions are performed Spacing times. 11 The exception Mode_Error is propagated if the mode is not In_File. The exception End_Error is propagated if an attempt is made to read a file terminator. 12 function End_Of_Line(File : in File_Type) return Boolean; function End_Of_Line return Boolean; 13/3 Operates on a file of mode In_File. Returns True if a line terminator or a file terminator is next; otherwise, returns False. 14 The exception Mode_Error is propagated if the mode is not In_File. 15 procedure New_Page(File : in File_Type); procedure New_Page; 16 Operates on a file of mode Out_File or Append_File. Outputs a line terminator if the current line is not terminated, or if the current page is empty (that is, if the current column and line numbers are both equal to one). Then outputs a page terminator, which terminates the current page. Adds one to the current page number and sets the current column and line numbers to one. 17 The exception Mode_Error is propagated if the mode is not Out_File or Append_File. 18 procedure Skip_Page(File : in File_Type); procedure Skip_Page; 19 Operates on a file of mode In_File. Reads and discards all characters and line terminators until a page terminator has been read. Then adds one to the current page number, and sets the current column and line numbers to one. 20 The exception Mode_Error is propagated if the mode is not In_File. The exception End_Error is propagated if an attempt is made to read a file terminator. 21 function End_Of_Page(File : in File_Type) return Boolean; function End_Of_Page return Boolean; 22/3 Operates on a file of mode In_File. Returns True if the combination of a line terminator and a page terminator is next, or if a file terminator is next; otherwise, returns False. 23 The exception Mode_Error is propagated if the mode is not In_File. 24 function End_Of_File(File : in File_Type) return Boolean; function End_Of_File return Boolean; 25/3 Operates on a file of mode In_File. Returns True if a file terminator is next, or if the combination of a line, a page, and a file terminator is next; otherwise, returns False. 26 The exception Mode_Error is propagated if the mode is not In_File. 27 The following subprograms provide for the control of the current position of reading or writing in a file. In all cases, the default file is the current output file. 28 procedure Set_Col(File : in File_Type; To : in Positive_Count); procedure Set_Col(To : in Positive_Count); 29 If the file mode is Out_File or Append_File: 30 * If the value specified by To is greater than the current column number, outputs spaces, adding one to the current column number after each space, until the current column number equals the specified value. If the value specified by To is equal to the current column number, there is no effect. If the value specified by To is less than the current column number, has the effect of calling New_Line (with a spacing of one), then outputs (To - 1) spaces, and sets the current column number to the specified value. 31 * The exception Layout_Error is propagated if the value specified by To exceeds Line_Length when the line length is bounded (that is, when it does not have the conventional value zero). 32 If the file mode is In_File: 33 * Reads (and discards) individual characters, line terminators, and page terminators, until the next character to be read has a column number that equals the value specified by To; there is no effect if the current column number already equals this value. Each transfer of a character or terminator maintains the current column, line, and page numbers in the same way as a Get procedure (see A.10.6). (Short lines will be skipped until a line is reached that has a character at the specified column position.) 34 * The exception End_Error is propagated if an attempt is made to read a file terminator. 35 procedure Set_Line(File : in File_Type; To : in Positive_Count); procedure Set_Line(To : in Positive_Count); 36 If the file mode is Out_File or Append_File: 37/3 * If the value specified by To is greater than the current line number, has the effect of repeatedly calling New_Line (with a spacing of one), until the current line number equals the specified value. If the value specified by To is equal to the current line number, there is no effect. If the value specified by To is less than the current line number, has the effect of calling New_Page followed, if To is greater than 1, by a call of New_Line with a spacing equal to (To - 1). 38 * The exception Layout_Error is propagated if the value specified by To exceeds Page_Length when the page length is bounded (that is, when it does not have the conventional value zero). 39 If the mode is In_File: 40 * Has the effect of repeatedly calling Skip_Line (with a spacing of one), until the current line number equals the value specified by To; there is no effect if the current line number already equals this value. (Short pages will be skipped until a page is reached that has a line at the specified line position.) 41 * The exception End_Error is propagated if an attempt is made to read a file terminator. 42 function Col(File : in File_Type) return Positive_Count; function Col return Positive_Count; 43 Returns the current column number. 44 The exception Layout_Error is propagated if this number exceeds Count'Last. 45 function Line(File : in File_Type) return Positive_Count; function Line return Positive_Count; 46 Returns the current line number. 47 The exception Layout_Error is propagated if this number exceeds Count'Last. 48 function Page(File : in File_Type) return Positive_Count; function Page return Positive_Count; 49 Returns the current page number. 50 The exception Layout_Error is propagated if this number exceeds Count'Last. 51 The column number, line number, or page number are allowed to exceed Count'Last (as a consequence of the input or output of sufficiently many characters, lines, or pages). These events do not cause any exception to be propagated. However, a call of Col, Line, or Page propagates the exception Layout_Error if the corresponding number exceeds Count'Last. NOTES 52 30 A page terminator is always skipped whenever the preceding line terminator is skipped. An implementation may represent the combination of these terminators by a single character, provided that it is properly recognized on input. A.10.6 Get and Put Procedures Static Semantics 1 The procedures Get and Put for items of the type Character, String, numeric types, and enumeration types are described in subsequent subclauses. Features of these procedures that are common to most of these types are described in this subclause. The Get and Put procedures for items of type Character and String deal with individual character values; the Get and Put procedures for numeric and enumeration types treat the items as lexical elements. 2 All procedures Get and Put have forms with a file parameter, written first. Where this parameter is omitted, the appropriate (input or output) current default file is understood to be specified. Each procedure Get operates on a file of mode In_File. Each procedure Put operates on a file of mode Out_File or Append_File. 3 All procedures Get and Put maintain the current column, line, and page numbers of the specified file: the effect of each of these procedures upon these numbers is the result of the effects of individual transfers of characters and of individual output or skipping of terminators. Each transfer of a character adds one to the current column number. Each output of a line terminator sets the current column number to one and adds one to the current line number. Each output of a page terminator sets the current column and line numbers to one and adds one to the current page number. For input, each skipping of a line terminator sets the current column number to one and adds one to the current line number; each skipping of a page terminator sets the current column and line numbers to one and adds one to the current page number. Similar considerations apply to the procedures Get_Line, Put_Line, and Set_Col. 4 Several Get and Put procedures, for numeric and enumeration types, have format parameters which specify field lengths; these parameters are of the nonnegative subtype Field of the type Integer. 5/2 Input-output of enumeration values uses the syntax of the corresponding lexical elements. Any Get procedure for an enumeration type begins by skipping any leading blanks, or line or page terminators. A blank is defined as a space or a horizontal tabulation character. Next, characters are input only so long as the sequence input is an initial sequence of an identifier or of a character literal (in particular, input ceases when a line terminator is encountered). The character or line terminator that causes input to cease remains available for subsequent input. 6 For a numeric type, the Get procedures have a format parameter called Width. If the value given for this parameter is zero, the Get procedure proceeds in the same manner as for enumeration types, but using the syntax of numeric literals instead of that of enumeration literals. If a nonzero value is given, then exactly Width characters are input, or the characters up to a line terminator, whichever comes first; any skipped leading blanks are included in the count. The syntax used for numeric literals is an extended syntax that allows a leading sign (but no intervening blanks, or line or page terminators) and that also allows (for real types) an integer literal as well as forms that have digits only before the point or only after the point. 7 Any Put procedure, for an item of a numeric or an enumeration type, outputs the value of the item as a numeric literal, identifier, or character literal, as appropriate. This is preceded by leading spaces if required by the format parameters Width or Fore (as described in later subclauses), and then a minus sign for a negative value; for an enumeration type, the spaces follow instead of leading. The format given for a Put procedure is overridden if it is insufficiently wide, by using the minimum needed width. 8 Two further cases arise for Put procedures for numeric and enumeration types, if the line length of the specified output file is bounded (that is, if it does not have the conventional value zero). If the number of characters to be output does not exceed the maximum line length, but is such that they cannot fit on the current line, starting from the current column, then (in effect) New_Line is called (with a spacing of one) before output of the item. Otherwise, if the number of characters exceeds the maximum line length, then the exception Layout_Error is propagated and nothing is output. 9 The exception Status_Error is propagated by any of the procedures Get, Get_Line, Put, and Put_Line if the file to be used is not open. The exception Mode_Error is propagated by the procedures Get and Get_Line if the mode of the file to be used is not In_File; and by the procedures Put and Put_Line, if the mode is not Out_File or Append_File. 10 The exception End_Error is propagated by a Get procedure if an attempt is made to skip a file terminator. The exception Data_Error is propagated by a Get procedure if the sequence finally input is not a lexical element corresponding to the type, in particular if no characters were input; for this test, leading blanks are ignored; for an item of a numeric type, when a sign is input, this rule applies to the succeeding numeric literal. The exception Layout_Error is propagated by a Put procedure that outputs to a parameter of type String, if the length of the actual string is insufficient for the output of the item. Examples 11 In the examples, here and in subclauses A.10.8 and A.10.9, the string quotes and the lower case letter b are not transferred: they are shown only to reveal the layout and spaces. 12 N : Integer; ... Get(N); 13 -- Characters at input Sequence input Value of N -- bb-12535b -12535 -12535 -- bb12_535e1b 12_535e1 125350 -- bb12_535e; 12_535e (none) Data_Error raised 14 Example of overridden width parameter: 15 Put(Item => -23, Width => 2); -- "-23" A.10.7 Input-Output of Characters and Strings Static Semantics 1 For an item of type Character the following procedures are provided: 2 procedure Get(File : in File_Type; Item : out Character); procedure Get(Item : out Character); 3 After skipping any line terminators and any page terminators, reads the next character from the specified input file and returns the value of this character in the out parameter Item. 4 The exception End_Error is propagated if an attempt is made to skip a file terminator. 5 procedure Put(File : in File_Type; Item : in Character); procedure Put(Item : in Character); 6 If the line length of the specified output file is bounded (that is, does not have the conventional value zero), and the current column number exceeds it, has the effect of calling New_Line with a spacing of one. Then, or otherwise, outputs the given character to the file. 7 procedure Look_Ahead (File : in File_Type; Item : out Character; End_Of_Line : out Boolean); procedure Look_Ahead (Item : out Character; End_Of_Line : out Boolean); 8/3 Status_Error is propagated if the file is not open. Mode_Error is propagated if the mode of the file is not In_File. Sets End_Of_Line to True if at end of line, including if at end of page or at end of file; in each of these cases the value of Item is not specified. Otherwise, End_Of_Line is set to False and Item is set to the next character (without consuming it) from the file. 9 procedure Get_Immediate(File : in File_Type; Item : out Character); procedure Get_Immediate(Item : out Character); 10/3 Reads the next character, either control or graphic, from the specified File or the default input file. Status_Error is propagated if the file is not open. Mode_Error is propagated if the mode of the file is not In_File. End_Error is propagated if at the end of the file. The current column, line and page numbers for the file are not affected. 11 procedure Get_Immediate(File : in File_Type; Item : out Character; Available : out Boolean); procedure Get_Immediate(Item : out Character; Available : out Boolean); 12/3 If a character, either control or graphic, is available from the specified File or the default input file, then the character is read; Available is True and Item contains the value of this character. If a character is not available, then Available is False and the value of Item is not specified. Status_Error is propagated if the file is not open. Mode_Error is propagated if the mode of the file is not In_File. End_Error is propagated if at the end of the file. The current column, line and page numbers for the file are not affected. 13/2 For an item of type String the following subprograms are provided: 14 procedure Get(File : in File_Type; Item : out String); procedure Get(Item : out String); 15 Determines the length of the given string and attempts that number of Get operations for successive characters of the string (in particular, no operation is performed if the string is null). 16 procedure Put(File : in File_Type; Item : in String); procedure Put(Item : in String); 17 Determines the length of the given string and attempts that number of Put operations for successive characters of the string (in particular, no operation is performed if the string is null). 17.1/2 function Get_Line(File : in File_Type) return String; function Get_Line return String; 17.2/2 Returns a result string constructed by reading successive characters from the specified input file, and assigning them to successive characters of the result string. The result string has a lower bound of 1 and an upper bound of the number of characters read. Reading stops when the end of the line is met; Skip_Line is then (in effect) called with a spacing of 1. 17.3/2 Constraint_Error is raised if the length of the line exceeds Positive'Last; in this case, the line number and page number are unchanged, and the column number is unspecified but no less than it was before the call. The exception End_Error is propagated if an attempt is made to skip a file terminator. 18 procedure Get_Line(File : in File_Type; Item : out String; Last : out Natural); procedure Get_Line(Item : out String; Last : out Natural); 19 Reads successive characters from the specified input file and assigns them to successive characters of the specified string. Reading stops if the end of the string is met. Reading also stops if the end of the line is met before meeting the end of the string; in this case Skip_Line is (in effect) called with a spacing of 1. The values of characters not assigned are not specified. 20 If characters are read, returns in Last the index value such that Item(Last) is the last character assigned (the index of the first character assigned is Item'First). If no characters are read, returns in Last an index value that is one less than Item'First. The exception End_Error is propagated if an attempt is made to skip a file terminator. 21 procedure Put_Line(File : in File_Type; Item : in String); procedure Put_Line(Item : in String); 22 Calls the procedure Put for the given string, and then the procedure New_Line with a spacing of one. Implementation Advice 23 The Get_Immediate procedures should be implemented with unbuffered input. For a device such as a keyboard, input should be "available" if a key has already been typed, whereas for a disk file, input should always be available except at end of file. For a file associated with a keyboard-like device, any line-editing features of the underlying operating system should be disabled during the execution of Get_Immediate. NOTES 24 31 Get_Immediate can be used to read a single key from the keyboard "immediately"; that is, without waiting for an end of line. In a call of Get_Immediate without the parameter Available, the caller will wait until a character is available. 25 32 In a literal string parameter of Put, the enclosing string bracket characters are not output. Each doubled string bracket character in the enclosed string is output as a single string bracket character, as a consequence of the rule for string literals (see 2.6). 26 33 A string read by Get or written by Put can extend over several lines. An implementation is allowed to assume that certain external files do not contain page terminators, in which case Get_Line and Skip_Line can return as soon as a line terminator is read. A.10.8 Input-Output for Integer Types Static Semantics 1 The following procedures are defined in the generic packages Integer_IO and Modular_IO, which have to be instantiated for the appropriate signed integer or modular type respectively (indicated by Num in the specifications). 2 Values are output as decimal or based literals, without low line characters or exponent, and, for Integer_IO, preceded by a minus sign if negative. The format (which includes any leading spaces and minus sign) can be specified by an optional field width parameter. Values of widths of fields in output formats are of the nonnegative integer subtype Field. Values of bases are of the integer subtype Number_Base. 3 subtype Number_Base is Integer range 2 .. 16; 4 The default field width and base to be used by output procedures are defined by the following variables that are declared in the generic packages Integer_IO and Modular_IO: 5 Default_Width : Field := Num'Width; Default_Base : Number_Base := 10; 6 The following procedures are provided: 7 procedure Get(File : in File_Type; Item : out Num; Width : in Field := 0); procedure Get(Item : out Num; Width : in Field := 0); 8 If the value of the parameter Width is zero, skips any leading blanks, line terminators, or page terminators, then reads a plus sign if present or (for a signed type only) a minus sign if present, then reads the longest possible sequence of characters matching the syntax of a numeric literal without a point. If a nonzero value of Width is supplied, then exactly Width characters are input, or the characters (possibly none) up to a line terminator, whichever comes first; any skipped leading blanks are included in the count. 9 Returns, in the parameter Item, the value of type Num that corresponds to the sequence input. 10/3 The exception Data_Error is propagated if the sequence of characters read does not form a legal integer literal or if the value obtained is not of the subtype Num. 11 procedure Put(File : in File_Type; Item : in Num; Width : in Field := Default_Width; Base : in Number_Base := Default_Base); procedure Put(Item : in Num; Width : in Field := Default_Width; Base : in Number_Base := Default_Base); 12 Outputs the value of the parameter Item as an integer literal, with no low lines, no exponent, and no leading zeros (but a single zero for the value zero), and a preceding minus sign for a negative value. 13 If the resulting sequence of characters to be output has fewer than Width characters, then leading spaces are first output to make up the difference. 14 Uses the syntax for decimal literal if the parameter Base has the value ten (either explicitly or through Default_Base); otherwise, uses the syntax for based literal, with any letters in upper case. 15 procedure Get(From : in String; Item : out Num; Last : out Positive); 16 Reads an integer value from the beginning of the given string, following the same rules as the Get procedure that reads an integer value from a file, but treating the end of the string as a file terminator. Returns, in the parameter Item, the value of type Num that corresponds to the sequence input. Returns in Last the index value such that From(Last) is the last character read. 17 The exception Data_Error is propagated if the sequence input does not have the required syntax or if the value obtained is not of the subtype Num. 18 procedure Put(To : out String; Item : in Num; Base : in Number_Base := Default_Base); 19 Outputs the value of the parameter Item to the given string, following the same rule as for output to a file, using the length of the given string as the value for Width. 20 Integer_Text_IO is a library package that is a nongeneric equivalent to Text_IO.Integer_IO for the predefined type Integer: 21 with Ada.Text_IO; package Ada.Integer_Text_IO is new Ada.Text_IO.Integer_IO(Integer); 22 For each predefined signed integer type, a nongeneric equivalent to Text_IO.Integer_IO is provided, with names such as Ada.Long_Integer_Text_IO. Implementation Permissions 23 The nongeneric equivalent packages may, but need not, be actual instantiations of the generic package for the appropriate predefined type. Paragraphs 24 and 25 were deleted. Examples 26/3 subtype Byte_Int is Integer range -127 .. 127; package Int_IO is new Integer_IO(Byte_Int); use Int_IO; -- default format used at instantiation, -- Default_Width = 4, Default_Base = 10 27 Put(126); -- "b126" Put(-126, 7); -- "bbb-126" Put(126, Width => 13, Base => 2); -- "bbb2#1111110#" A.10.9 Input-Output for Real Types Static Semantics 1 The following procedures are defined in the generic packages Float_IO, Fixed_IO, and Decimal_IO, which have to be instantiated for the appropriate floating point, ordinary fixed point, or decimal fixed point type respectively (indicated by Num in the specifications). 2 Values are output as decimal literals without low line characters. The format of each value output consists of a Fore field, a decimal point, an Aft field, and (if a nonzero Exp parameter is supplied) the letter E and an Exp field. The two possible formats thus correspond to: 3 Fore . Aft 4 and to: 5 Fore . Aft E Exp 6 without any spaces between these fields. The Fore field may include leading spaces, and a minus sign for negative values. The Aft field includes only decimal digits (possibly with trailing zeros). The Exp field includes the sign (plus or minus) and the exponent (possibly with leading zeros). 7 For floating point types, the default lengths of these fields are defined by the following variables that are declared in the generic package Float_IO: 8 Default_Fore : Field := 2; Default_Aft : Field := Num'Digits-1; Default_Exp : Field := 3; 9 For ordinary or decimal fixed point types, the default lengths of these fields are defined by the following variables that are declared in the generic packages Fixed_IO and Decimal_IO, respectively: 10 Default_Fore : Field := Num'Fore; Default_Aft : Field := Num'Aft; Default_Exp : Field := 0; 11 The following procedures are provided: 12 procedure Get(File : in File_Type; Item : out Num; Width : in Field := 0); procedure Get(Item : out Num; Width : in Field := 0); 13 If the value of the parameter Width is zero, skips any leading blanks, line terminators, or page terminators, then reads the longest possible sequence of characters matching the syntax of any of the following (see 2.4): 14 * [+|-]numeric_literal 15 * [+|-]numeral.[exponent] 16 * [+|-].numeral[exponent] 17 * [+|-]base#based_numeral.#[exponent] 18 * [+|-]base#.based_numeral#[exponent] 19 If a nonzero value of Width is supplied, then exactly Width characters are input, or the characters (possibly none) up to a line terminator, whichever comes first; any skipped leading blanks are included in the count. 20 Returns in the parameter Item the value of type Num that corresponds to the sequence input, preserving the sign (positive if none has been specified) of a zero value if Num is a floating point type and Num'Signed_Zeros is True. 21 The exception Data_Error is propagated if the sequence input does not have the required syntax or if the value obtained is not of the subtype Num. 22 procedure Put(File : in File_Type; Item : in Num; Fore : in Field := Default_Fore; Aft : in Field := Default_Aft; Exp : in Field := Default_Exp); procedure Put(Item : in Num; Fore : in Field := Default_Fore; Aft : in Field := Default_Aft; Exp : in Field := Default_Exp); 23 Outputs the value of the parameter Item as a decimal literal with the format defined by Fore, Aft and Exp. If the value is negative, or if Num is a floating point type where Num'Signed_Zeros is True and the value is a negatively signed zero, then a minus sign is included in the integer part. If Exp has the value zero, then the integer part to be output has as many digits as are needed to represent the integer part of the value of Item, overriding Fore if necessary, or consists of the digit zero if the value of Item has no integer part. 24 If Exp has a value greater than zero, then the integer part to be output has a single digit, which is nonzero except for the value 0.0 of Item. 25 In both cases, however, if the integer part to be output has fewer than Fore characters, including any minus sign, then leading spaces are first output to make up the difference. The number of digits of the fractional part is given by Aft, or is one if Aft equals zero. The value is rounded; a value of exactly one half in the last place is rounded away from zero. 26 If Exp has the value zero, there is no exponent part. If Exp has a value greater than zero, then the exponent part to be output has as many digits as are needed to represent the exponent part of the value of Item (for which a single digit integer part is used), and includes an initial sign (plus or minus). If the exponent part to be output has fewer than Exp characters, including the sign, then leading zeros precede the digits, to make up the difference. For the value 0.0 of Item, the exponent has the value zero. 27 procedure Get(From : in String; Item : out Num; Last : out Positive); 28 Reads a real value from the beginning of the given string, following the same rule as the Get procedure that reads a real value from a file, but treating the end of the string as a file terminator. Returns, in the parameter Item, the value of type Num that corresponds to the sequence input. Returns in Last the index value such that From(Last) is the last character read. 29 The exception Data_Error is propagated if the sequence input does not have the required syntax, or if the value obtained is not of the subtype Num. 30 procedure Put(To : out String; Item : in Num; Aft : in Field := Default_Aft; Exp : in Field := Default_Exp); 31 Outputs the value of the parameter Item to the given string, following the same rule as for output to a file, using a value for Fore such that the sequence of characters output exactly fills the string, including any leading spaces. 32 Float_Text_IO is a library package that is a nongeneric equivalent to Text_IO.Float_IO for the predefined type Float: 33 with Ada.Text_IO; package Ada.Float_Text_IO is new Ada.Text_IO.Float_IO(Float); 34 For each predefined floating point type, a nongeneric equivalent to Text_IO.Float_IO is provided, with names such as Ada.Long_Float_Text_IO. Implementation Permissions 35 An implementation may extend Get and Put for floating point types to support special values such as infinities and NaNs. 36 The implementation of Put need not produce an output value with greater accuracy than is supported for the base subtype. The additional accuracy, if any, of the value produced by Put when the number of requested digits in the integer and fractional parts exceeds the required accuracy is implementation defined. 37 The nongeneric equivalent packages may, but need not, be actual instantiations of the generic package for the appropriate predefined type. NOTES 38 34 For an item with a positive value, if output to a string exactly fills the string without leading spaces, then output of the corresponding negative value will propagate Layout_Error. 39 35 The rules for the Value attribute (see 3.5) and the rules for Get are based on the same set of formats. Examples 40/1 This paragraph was deleted. 41 package Real_IO is new Float_IO(Real); use Real_IO; -- default format used at instantiation, Default_Exp = 3 42 X : Real := -123.4567; -- digits 8 (see 3.5.7) 43 Put(X); -- default format "- 1.2345670E+02" Put(X, Fore => 5, Aft => 3, Exp => 2); -- "bbb- 1.235E+2" Put(X, 5, 3, 0); -- "b- 123.457" A.10.10 Input-Output for Enumeration Types Static Semantics 1 The following procedures are defined in the generic package Enumeration_IO, which has to be instantiated for the appropriate enumeration type (indicated by Enum in the specification). 2 Values are output using either upper or lower case letters for identifiers. This is specified by the parameter Set, which is of the enumeration type Type_Set. 3 type Type_Set is (Lower_Case, Upper_Case); 4 The format (which includes any trailing spaces) can be specified by an optional field width parameter. The default field width and letter case are defined by the following variables that are declared in the generic package Enumeration_IO: 5 Default_Width : Field := 0; Default_Setting : Type_Set := Upper_Case; 6 The following procedures are provided: 7 procedure Get(File : in File_Type; Item : out Enum); procedure Get(Item : out Enum); 8 After skipping any leading blanks, line terminators, or page terminators, reads an identifier according to the syntax of this lexical element (lower and upper case being considered equivalent), or a character literal according to the syntax of this lexical element (including the apostrophes). Returns, in the parameter Item, the value of type Enum that corresponds to the sequence input. 9 The exception Data_Error is propagated if the sequence input does not have the required syntax, or if the identifier or character literal does not correspond to a value of the subtype Enum. 10 procedure Put(File : in File_Type; Item : in Enum; Width : in Field := Default_Width; Set : in Type_Set := Default_Setting); procedure Put(Item : in Enum; Width : in Field := Default_Width; Set : in Type_Set := Default_Setting); 11 Outputs the value of the parameter Item as an enumeration literal (either an identifier or a character literal). The optional parameter Set indicates whether lower case or upper case is used for identifiers; it has no effect for character literals. If the sequence of characters produced has fewer than Width characters, then trailing spaces are finally output to make up the difference. If Enum is a character type, the sequence of characters produced is as for Enum'Image(Item), as modified by the Width and Set parameters. 12 procedure Get(From : in String; Item : out Enum; Last : out Positive); 13 Reads an enumeration value from the beginning of the given string, following the same rule as the Get procedure that reads an enumeration value from a file, but treating the end of the string as a file terminator. Returns, in the parameter Item, the value of type Enum that corresponds to the sequence input. Returns in Last the index value such that From(Last) is the last character read. 14 The exception Data_Error is propagated if the sequence input does not have the required syntax, or if the identifier or character literal does not correspond to a value of the subtype Enum. 15 procedure Put(To : out String; Item : in Enum; Set : in Type_Set := Default_Setting); 16 Outputs the value of the parameter Item to the given string, following the same rule as for output to a file, using the length of the given string as the value for Width. 17/1 Although the specification of the generic package Enumeration_IO would allow instantiation for an integer type, this is not the intended purpose of this generic package, and the effect of such instantiations is not defined by the language. NOTES 18 36 There is a difference between Put defined for characters, and for enumeration values. Thus 19 Ada.Text_IO.Put('A'); -- outputs the character A 20 package Char_IO is new Ada.Text_IO.Enumeration_IO(Character); Char_IO.Put('A'); -- outputs the character 'A', between apostrophes 21 37 The type Boolean is an enumeration type, hence Enumeration_IO can be instantiated for this type. A.10.11 Input-Output for Bounded Strings 1/2 The package Text_IO.Bounded_IO provides input-output in human-readable form for Bounded_Strings. Static Semantics 2/2 The generic library package Text_IO.Bounded_IO has the following declaration: 3/2 with Ada.Strings.Bounded; generic with package Bounded is new Ada.Strings.Bounded.Generic_Bounded_Length (<>); package Ada.Text_IO.Bounded_IO is 4/2 procedure Put (File : in File_Type; Item : in Bounded.Bounded_String); 5/2 procedure Put (Item : in Bounded.Bounded_String); 6/2 procedure Put_Line (File : in File_Type; Item : in Bounded.Bounded_String); 7/2 procedure Put_Line (Item : in Bounded.Bounded_String); 8/2 function Get_Line (File : in File_Type) return Bounded.Bounded_String; 9/2 function Get_Line return Bounded.Bounded_String; 10/2 procedure Get_Line (File : in File_Type; Item : out Bounded.Bounded_String); 11/2 procedure Get_Line (Item : out Bounded.Bounded_String); 12/2 end Ada.Text_IO.Bounded_IO; 13/2 For an item of type Bounded_String, the following subprograms are provided: 14/2 procedure Put (File : in File_Type; Item : in Bounded.Bounded_String); 15/2 Equivalent to Text_IO.Put (File, Bounded.To_String(Item)); 16/2 procedure Put (Item : in Bounded.Bounded_String); 17/2 Equivalent to Text_IO.Put (Bounded.To_String(Item)); 18/2 procedure Put_Line (File : in File_Type; Item : in Bounded.Bounded_String); 19/2 Equivalent to Text_IO.Put_Line (File, Bounded.To_String(Item)); 20/2 procedure Put_Line (Item : in Bounded.Bounded_String); 21/2 Equivalent to Text_IO.Put_Line (Bounded.To_String(Item)); 22/2 function Get_Line (File : in File_Type) return Bounded.Bounded_String; 23/2 Returns Bounded.To_Bounded_String(Text_IO.Get_Line(File)); 24/2 function Get_Line return Bounded.Bounded_String; 25/2 Returns Bounded.To_Bounded_String(Text_IO.Get_Line); 26/2 procedure Get_Line (File : in File_Type; Item : out Bounded.Bounded_String); 27/2 Equivalent to Item := Get_Line (File); 28/2 procedure Get_Line (Item : out Bounded.Bounded_String); 29/2 Equivalent to Item := Get_Line; A.10.12 Input-Output for Unbounded Strings 1/2 The package Text_IO.Unbounded_IO provides input-output in human-readable form for Unbounded_Strings. Static Semantics 2/2 The library package Text_IO.Unbounded_IO has the following declaration: 3/2 with Ada.Strings.Unbounded; package Ada.Text_IO.Unbounded_IO is 4/2 procedure Put (File : in File_Type; Item : in Strings.Unbounded.Unbounded_String); 5/2 procedure Put (Item : in Strings.Unbounded.Unbounded_String); 6/2 procedure Put_Line (File : in File_Type; Item : in Strings.Unbounded.Unbounded_String); 7/2 procedure Put_Line (Item : in Strings.Unbounded.Unbounded_String); 8/2 function Get_Line (File : in File_Type) return Strings.Unbounded.Unbounded_String; 9/2 function Get_Line return Strings.Unbounded.Unbounded_String; 10/2 procedure Get_Line (File : in File_Type; Item : out Strings.Unbounded.Unbounded_String); 11/2 procedure Get_Line (Item : out Strings.Unbounded.Unbounded_String); 12/2 end Ada.Text_IO.Unbounded_IO; 13/2 For an item of type Unbounded_String, the following subprograms are provided: 14/2 procedure Put (File : in File_Type; Item : in Strings.Unbounded.Unbounded_String); 15/2 Equivalent to Text_IO.Put (File, Strings.Unbounded.To_String(Item)); 16/2 procedure Put (Item : in Strings.Unbounded.Unbounded_String); 17/2 Equivalent to Text_IO.Put (Strings.Unbounded.To_String(Item)); 18/2 procedure Put_Line (File : in File_Type; Item : in Strings.Unbounded.Unbounded_String); 19/2 Equivalent to Text_IO.Put_Line (File, Strings.Unbounded.To_String(Item)); 20/2 procedure Put_Line (Item : in Strings.Unbounded.Unbounded_String); 21/2 Equivalent to Text_IO.Put_Line (Strings.Unbounded.To_String(Item)); 22/2 function Get_Line (File : in File_Type) return Strings.Unbounded.Unbounded_String; 23/2 Returns Strings.Unbounded.To_Unbounded_String(Text_IO.Get_Line(File)); 24/2 function Get_Line return Strings.Unbounded.Unbounded_String; 25/2 Returns Strings.Unbounded.To_Unbounded_String(Text_IO.Get_Line); 26/2 procedure Get_Line (File : in File_Type; Item : out Strings.Unbounded.Unbounded_String); 27/2 Equivalent to Item := Get_Line (File); 28/2 procedure Get_Line (Item : out Strings.Unbounded.Unbounded_String); 29/2 Equivalent to Item := Get_Line; A.11 Wide Text Input-Output and Wide Wide Text Input-Output 1/2 The packages Wide_Text_IO and Wide_Wide_Text_IO provide facilities for input and output in human-readable form. Each file is read or written sequentially, as a sequence of wide characters (or wide wide characters) grouped into lines, and as a sequence of lines grouped into pages. Static Semantics 2/2 The specification of package Wide_Text_IO is the same as that for Text_IO, except that in each Get, Look_Ahead, Get_Immediate, Get_Line, Put, and Put_Line subprogram, any occurrence of Character is replaced by Wide_Character, and any occurrence of String is replaced by Wide_String. Nongeneric equivalents of Wide_Text_IO.Integer_IO and Wide_Text_IO.Float_IO are provided (as for Text_IO) for each predefined numeric type, with names such as Ada.Integer_Wide_Text_IO, Ada.Long_Integer_Wide_Text_IO, Ada.Float_- Wide_Text_IO, Ada.Long_Float_Wide_Text_IO. 3/2 The specification of package Wide_Wide_Text_IO is the same as that for Text_IO, except that in each Get, Look_Ahead, Get_Immediate, Get_Line, Put, and Put_Line subprogram, any occurrence of Character is replaced by Wide_Wide_Character, and any occurrence of String is replaced by Wide_Wide_String. Nongeneric equivalents of Wide_Wide_Text_IO.Integer_IO and Wide_Wide_Text_IO.Float_IO are provided (as for Text_IO) for each predefined numeric type, with names such as Ada.Integer_Wide_Wide_Text_IO, Ada.Long_- Integer_Wide_Wide_Text_IO, Ada.Float_Wide_Wide_Text_IO, Ada.Long_Float_- Wide_Wide_Text_IO. 4/3 The specification of package Wide_Text_IO.Wide_Bounded_IO is the same as that for Text_IO.Bounded_IO, except that any occurrence of Bounded_String is replaced by Bounded_Wide_String, and any occurrence of package Bounded is replaced by Wide_Bounded. The specification of package Wide_Wide_Text_IO.Wide_Wide_Bounded_IO is the same as that for Text_IO.- Bounded_IO, except that any occurrence of Bounded_String is replaced by Bounded_Wide_Wide_String, and any occurrence of package Bounded is replaced by Wide_Wide_Bounded. 5/3 The specification of package Wide_Text_IO.Wide_Unbounded_IO is the same as that for Text_IO.Unbounded_IO, except that any occurrence of Unbounded_- String is replaced by Unbounded_Wide_String, and any occurrence of package Unbounded is replaced by Wide_Unbounded. The specification of package Wide_Wide_Text_IO.Wide_Wide_Unbounded_IO is the same as that for Text_IO.Unbounded_IO, except that any occurrence of Unbounded_String is replaced by Unbounded_Wide_Wide_String, and any occurrence of package Unbounded is replaced by Wide_Wide_Unbounded. A.12 Stream Input-Output 1/2 The packages Streams.Stream_IO, Text_IO.Text_Streams, Wide_Text_IO.Text_Streams, and Wide_Wide_Text_IO.Text_Streams provide stream-oriented operations on files. A.12.1 The Package Streams.Stream_IO 1 The subprograms in the child package Streams.Stream_IO provide control over stream files. Access to a stream file is either sequential, via a call on Read or Write to transfer an array of stream elements, or positional (if supported by the implementation for the given file), by specifying a relative index for an element. Since a stream file can be converted to a Stream_Access value, calling stream-oriented attribute subprograms of different element types with the same Stream_Access value provides heterogeneous input-output. See 13.13 for a general discussion of streams. Static Semantics 1.1/1 The elements of a stream file are stream elements. If positioning is supported for the specified external file, a current index and current size are maintained for the file as described in A.8. If positioning is not supported, a current index is not maintained, and the current size is implementation defined. 2 The library package Streams.Stream_IO has the following declaration: 3/3 with Ada.IO_Exceptions; package Ada.Streams.Stream_IO is pragma Preelaborate(Stream_IO); 4 type Stream_Access is access all Root_Stream_Type'Class; 5/4 type File_Type is limited private; pragma Preelaborable_Initialization(File_Type); 6 type File_Mode is (In_File, Out_File, Append_File); 7 type Count is range 0 .. implementation-defined; subtype Positive_Count is Count range 1 .. Count'Last; -- Index into file, in stream elements. 8 procedure Create (File : in out File_Type; Mode : in File_Mode := Out_File; Name : in String := ""; Form : in String := ""); 9 procedure Open (File : in out File_Type; Mode : in File_Mode; Name : in String; Form : in String := ""); 10 procedure Close (File : in out File_Type); procedure Delete (File : in out File_Type); procedure Reset (File : in out File_Type; Mode : in File_Mode); procedure Reset (File : in out File_Type); 11 function Mode (File : in File_Type) return File_Mode; function Name (File : in File_Type) return String; function Form (File : in File_Type) return String; 12 function Is_Open (File : in File_Type) return Boolean; function End_Of_File (File : in File_Type) return Boolean; 13 function Stream (File : in File_Type) return Stream_Access; -- Return stream access for use with T'Input and T'Output 14/1 This paragraph was deleted. 15 -- Read array of stream elements from file procedure Read (File : in File_Type; Item : out Stream_Element_Array; Last : out Stream_Element_Offset; From : in Positive_Count); 16 procedure Read (File : in File_Type; Item : out Stream_Element_Array; Last : out Stream_Element_Offset); 17/1 This paragraph was deleted. 18 -- Write array of stream elements into file procedure Write (File : in File_Type; Item : in Stream_Element_Array; To : in Positive_Count); 19 procedure Write (File : in File_Type; Item : in Stream_Element_Array); 20/1 This paragraph was deleted. 21 -- Operations on position within file 22 procedure Set_Index(File : in File_Type; To : in Positive_Count); 23 function Index(File : in File_Type) return Positive_Count; function Size (File : in File_Type) return Count; 24 procedure Set_Mode(File : in out File_Type; Mode : in File_Mode); 25/1 procedure Flush(File : in File_Type); 26 -- exceptions Status_Error : exception renames IO_Exceptions.Status_Error; Mode_Error : exception renames IO_Exceptions.Mode_Error; Name_Error : exception renames IO_Exceptions.Name_Error; Use_Error : exception renames IO_Exceptions.Use_Error; Device_Error : exception renames IO_Exceptions.Device_Error; End_Error : exception renames IO_Exceptions.End_Error; Data_Error : exception renames IO_Exceptions.Data_Error; 27 private ... -- not specified by the language end Ada.Streams.Stream_IO; 27.1/2 The type File_Type needs finalization (see 7.6). 28/4 The subprograms given in subclause A.8.2 for the control of external files (Create, Open, Close, Delete, Reset, Mode, Name, Form, Is_Open, and Flush) are available for stream files. 28.1/2 The End_Of_File function: 28.2/2 * Propagates Mode_Error if the mode of the file is not In_File; 28.3/3 * If positioning is supported for the given external file, the function returns True if the current index exceeds the size of the external file; otherwise, it returns False; 28.4/3 * If positioning is not supported for the given external file, the function returns True if no more elements can be read from the given file; otherwise, it returns False. 28.5/2 The Set_Mode procedure sets the mode of the file. If the new mode is Append_File, the file is positioned to its end; otherwise, the position in the file is unchanged. 28.6/4 This paragraph was deleted. 29/1 The Stream function returns a Stream_Access result from a File_Type object, thus allowing the stream-oriented attributes Read, Write, Input, and Output to be used on the same file for multiple types. Stream propagates Status_Error if File is not open. 30/2 The procedures Read and Write are equivalent to the corresponding operations in the package Streams. Read propagates Mode_Error if the mode of File is not In_File. Write propagates Mode_Error if the mode of File is not Out_File or Append_File. The Read procedure with a Positive_Count parameter starts reading at the specified index. The Write procedure with a Positive_Count parameter starts writing at the specified index. For a file that supports positioning, Read without a Positive_Count parameter starts reading at the current index, and Write without a Positive_Count parameter starts writing at the current index. 30.1/1 The Size function returns the current size of the file. 31/1 The Index function returns the current index. 32 The Set_Index procedure sets the current index to the specified value. 32.1/1 If positioning is supported for the external file, the current index is maintained as follows: 32.2/1 * For Open and Create, if the Mode parameter is Append_File, the current index is set to the current size of the file plus one; otherwise, the current index is set to one. 32.3/1 * For Reset, if the Mode parameter is Append_File, or no Mode parameter is given and the current mode is Append_File, the current index is set to the current size of the file plus one; otherwise, the current index is set to one. 32.4/1 * For Set_Mode, if the new mode is Append_File, the current index is set to current size plus one; otherwise, the current index is unchanged. 32.5/1 * For Read and Write without a Positive_Count parameter, the current index is incremented by the number of stream elements read or written. 32.6/1 * For Read and Write with a Positive_Count parameter, the value of the current index is set to the value of the Positive_Count parameter plus the number of stream elements read or written. 33 If positioning is not supported for the given file, then a call of Index or Set_Index propagates Use_Error. Similarly, a call of Read or Write with a Positive_Count parameter propagates Use_Error. Paragraphs 34 through 36 were deleted. Erroneous Execution 36.1/1 If the File_Type object passed to the Stream function is later closed or finalized, and the stream-oriented attributes are subsequently called (explicitly or implicitly) on the Stream_Access value returned by Stream, execution is erroneous. This rule applies even if the File_Type object was opened again after it had been closed. A.12.2 The Package Text_IO.Text_Streams 1 The package Text_IO.Text_Streams provides a function for treating a text file as a stream. Static Semantics 2 The library package Text_IO.Text_Streams has the following declaration: 3 with Ada.Streams; package Ada.Text_IO.Text_Streams is type Stream_Access is access all Streams.Root_Stream_Type'Class; 4 function Stream (File : in File_Type) return Stream_Access; end Ada.Text_IO.Text_Streams; 5 The Stream function has the same effect as the corresponding function in Streams.Stream_IO. NOTES 6 38 The ability to obtain a stream for a text file allows Current_Input, Current_Output, and Current_Error to be processed with the functionality of streams, including the mixing of text and binary input-output, and the mixing of binary input-output for different types. 7 39 Performing operations on the stream associated with a text file does not affect the column, line, or page counts. A.12.3 The Package Wide_Text_IO.Text_Streams 1 The package Wide_Text_IO.Text_Streams provides a function for treating a wide text file as a stream. Static Semantics 2 The library package Wide_Text_IO.Text_Streams has the following declaration: 3 with Ada.Streams; package Ada.Wide_Text_IO.Text_Streams is type Stream_Access is access all Streams.Root_Stream_Type'Class; 4 function Stream (File : in File_Type) return Stream_Access; end Ada.Wide_Text_IO.Text_Streams; 5 The Stream function has the same effect as the corresponding function in Streams.Stream_IO. A.12.4 The Package Wide_Wide_Text_IO.Text_Streams 1/2 The package Wide_Wide_Text_IO.Text_Streams provides a function for treating a wide wide text file as a stream. Static Semantics 2/2 The library package Wide_Wide_Text_IO.Text_Streams has the following declaration: 3/2 with Ada.Streams; package Ada.Wide_Wide_Text_IO.Text_Streams is type Stream_Access is access all Streams.Root_Stream_Type'Class; 4/2 function Stream (File : in File_Type) return Stream_Access; end Ada.Wide_Wide_Text_IO.Text_Streams; 5/2 The Stream function has the same effect as the corresponding function in Streams.Stream_IO. A.13 Exceptions in Input-Output 1 The package IO_Exceptions defines the exceptions needed by the predefined input-output packages. Static Semantics 2 The library package IO_Exceptions has the following declaration: 3 package Ada.IO_Exceptions is pragma Pure(IO_Exceptions); 4 Status_Error : exception; Mode_Error : exception; Name_Error : exception; Use_Error : exception; Device_Error : exception; End_Error : exception; Data_Error : exception; Layout_Error : exception; 5 end Ada.IO_Exceptions; 6 If more than one error condition exists, the corresponding exception that appears earliest in the following list is the one that is propagated. 7 The exception Status_Error is propagated by an attempt to operate upon a file that is not open, and by an attempt to open a file that is already open. 8 The exception Mode_Error is propagated by an attempt to read from, or test for the end of, a file whose current mode is Out_File or Append_File, and also by an attempt to write to a file whose current mode is In_File. In the case of Text_IO, the exception Mode_Error is also propagated by specifying a file whose current mode is Out_File or Append_File in a call of Set_Input, Skip_Line, End_Of_Line, Skip_Page, or End_Of_Page; and by specifying a file whose current mode is In_File in a call of Set_Output, Set_Line_Length, Set_Page_Length, Line_Length, Page_Length, New_Line, or New_Page. 9 The exception Name_Error is propagated by a call of Create or Open if the string given for the parameter Name does not allow the identification of an external file. For example, this exception is propagated if the string is improper, or, alternatively, if either none or more than one external file corresponds to the string. 10 The exception Use_Error is propagated if an operation is attempted that is not possible for reasons that depend on characteristics of the external file. For example, this exception is propagated by the procedure Create, among other circumstances, if the given mode is Out_File but the form specifies an input only device, if the parameter Form specifies invalid access rights, or if an external file with the given name already exists and overwriting is not allowed. 11 The exception Device_Error is propagated if an input-output operation cannot be completed because of a malfunction of the underlying system. 12 The exception End_Error is propagated by an attempt to skip (read past) the end of a file. 13 The exception Data_Error can be propagated by the procedure Read (or by the Read attribute) if the element read cannot be interpreted as a value of the required subtype. This exception is also propagated by a procedure Get (defined in the package Text_IO) if the input character sequence fails to satisfy the required syntax, or if the value input does not belong to the range of the required subtype. 14 The exception Layout_Error is propagated (in text input-output) by Col, Line, or Page if the value returned exceeds Count'Last. The exception Layout_Error is also propagated on output by an attempt to set column or line numbers in excess of specified maximum line or page lengths, respectively (excluding the unbounded cases). It is also propagated by an attempt to Put too many characters to a string. 14.1/3 These exceptions are also propagated by various other language-defined packages and operations, see the definition of those entities for other reasons that these exceptions are propagated. Documentation Requirements 15 The implementation shall document the conditions under which Name_Error, Use_Error and Device_Error are propagated. Implementation Permissions 16 If the associated check is too complex, an implementation need not propagate Data_Error as part of a procedure Read (or the Read attribute) if the value read cannot be interpreted as a value of the required subtype. Erroneous Execution 17 If the element read by the procedure Read (or by the Read attribute) cannot be interpreted as a value of the required subtype, but this is not detected and Data_Error is not propagated, then the resulting value can be abnormal, and subsequent references to the value can lead to erroneous execution, as explained in 13.9.1. A.14 File Sharing Dynamic Semantics 1 It is not specified by the language whether the same external file can be associated with more than one file object. If such sharing is supported by the implementation, the following effects are defined: 2 * Operations on one text file object do not affect the column, line, and page numbers of any other file object. 3/1 * This paragraph was deleted. 4 * For direct and stream files, the current index is a property of each file object; an operation on one file object does not affect the current index of any other file object. 5 * For direct and stream files, the current size of the file is a property of the external file. 6 All other effects are identical. A.15 The Package Command_Line 1 The package Command_Line allows a program to obtain the values of its arguments and to set the exit status code to be returned on normal termination. Static Semantics 2 The library package Ada.Command_Line has the following declaration: 3 package Ada.Command_Line is pragma Preelaborate(Command_Line); 4 function Argument_Count return Natural; 5 function Argument (Number : in Positive) return String; 6 function Command_Name return String; 7 type Exit_Status is implementation-defined integer type; 8 Success : constant Exit_Status; Failure : constant Exit_Status; 9 procedure Set_Exit_Status (Code : in Exit_Status); 10 private ... -- not specified by the language end Ada.Command_Line; 11 function Argument_Count return Natural; 12/3 If the external execution environment supports passing arguments to a program, then Argument_Count returns the number of arguments passed to the program invoking the function. Otherwise, it returns 0. The meaning of "number of arguments" is implementation defined. 13 function Argument (Number : in Positive) return String; 14 If the external execution environment supports passing arguments to a program, then Argument returns an implementation-defined value corresponding to the argument at relative position Number. If Number is outside the range 1..Argument_Count, then Constraint_Error is propagated. 15 function Command_Name return String; 16/3 If the external execution environment supports passing arguments to a program, then Command_Name returns an implementation-defined value corresponding to the name of the command invoking the program; otherwise, Command_Name returns the null string. 16.1/1 type Exit_Status is implementation-defined integer type; 17 The type Exit_Status represents the range of exit status values supported by the external execution environment. The constants Success and Failure correspond to success and failure, respectively. 18 procedure Set_Exit_Status (Code : in Exit_Status); 19 If the external execution environment supports returning an exit status from a program, then Set_Exit_Status sets Code as the status. Normal termination of a program returns as the exit status the value most recently set by Set_Exit_Status, or, if no such value has been set, then the value Success. If a program terminates abnormally, the status set by Set_Exit_Status is ignored, and an implementation-defined exit status value is set. 20 If the external execution environment does not support returning an exit value from a program, then Set_Exit_Status does nothing. Implementation Permissions 21 An alternative declaration is allowed for package Command_Line if different functionality is appropriate for the external execution environment. NOTES 22 40 Argument_Count, Argument, and Command_Name correspond to the C language's argc, argv[n] (for n>0) and argv[0], respectively. A.16 The Package Directories 1/2 The package Directories provides operations for manipulating files and directories, and their names. Static Semantics 2/2 The library package Directories has the following declaration: 3/2 with Ada.IO_Exceptions; with Ada.Calendar; package Ada.Directories is 4/2 -- Directory and file operations: 5/2 function Current_Directory return String; 6/2 procedure Set_Directory (Directory : in String); 7/2 procedure Create_Directory (New_Directory : in String; Form : in String := ""); 8/2 procedure Delete_Directory (Directory : in String); 9/2 procedure Create_Path (New_Directory : in String; Form : in String := ""); 10/2 procedure Delete_Tree (Directory : in String); 11/2 procedure Delete_File (Name : in String); 12/2 procedure Rename (Old_Name, New_Name : in String); 13/2 procedure Copy_File (Source_Name, Target_Name : in String; Form : in String := ""); 14/2 -- File and directory name operations: 15/2 function Full_Name (Name : in String) return String; 16/2 function Simple_Name (Name : in String) return String; 17/2 function Containing_Directory (Name : in String) return String; 18/2 function Extension (Name : in String) return String; 19/2 function Base_Name (Name : in String) return String; 20/2 function Compose (Containing_Directory : in String := ""; Name : in String; Extension : in String := "") return String; 20.1/3 type Name_Case_Kind is (Unknown, Case_Sensitive, Case_Insensitive, Case_Preserving); 20.2/3 function Name_Case_Equivalence (Name : in String) return Name_Case_Kind; 21/2 -- File and directory queries: 22/2 type File_Kind is (Directory, Ordinary_File, Special_File); 23/2 type File_Size is range 0 .. implementation-defined; 24/2 function Exists (Name : in String) return Boolean; 25/2 function Kind (Name : in String) return File_Kind; 26/2 function Size (Name : in String) return File_Size; 27/2 function Modification_Time (Name : in String) return Ada.Calendar.Time; 28/2 -- Directory searching: 29/2 type Directory_Entry_Type is limited private; 30/2 type Filter_Type is array (File_Kind) of Boolean; 31/2 type Search_Type is limited private; 32/2 procedure Start_Search (Search : in out Search_Type; Directory : in String; Pattern : in String; Filter : in Filter_Type := (others => True)); 33/2 procedure End_Search (Search : in out Search_Type); 34/2 function More_Entries (Search : in Search_Type) return Boolean; 35/2 procedure Get_Next_Entry (Search : in out Search_Type; Directory_Entry : out Directory_Entry_Type); 36/2 procedure Search ( Directory : in String; Pattern : in String; Filter : in Filter_Type := (others => True); Process : not null access procedure ( Directory_Entry : in Directory_Entry_Type)); 37/2 -- Operations on Directory Entries: 38/2 function Simple_Name (Directory_Entry : in Directory_Entry_Type) return String; 39/2 function Full_Name (Directory_Entry : in Directory_Entry_Type) return String; 40/2 function Kind (Directory_Entry : in Directory_Entry_Type) return File_Kind; 41/2 function Size (Directory_Entry : in Directory_Entry_Type) return File_Size; 42/2 function Modification_Time (Directory_Entry : in Directory_Entry_Type) return Ada.Calendar.Time; 43/2 Status_Error : exception renames Ada.IO_Exceptions.Status_Error; Name_Error : exception renames Ada.IO_Exceptions.Name_Error; Use_Error : exception renames Ada.IO_Exceptions.Use_Error; Device_Error : exception renames Ada.IO_Exceptions.Device_Error; 44/3 private ... -- not specified by the language end Ada.Directories; 45/2 External files may be classified as directories, special files, or ordinary files. A directory is an external file that is a container for files on the target system. A special file is an external file that cannot be created or read by a predefined Ada input-output package. External files that are not special files or directories are called ordinary files. 46/2 A file name is a string identifying an external file. Similarly, a directory name is a string identifying a directory. The interpretation of file names and directory names is implementation-defined. 47/2 The full name of an external file is a full specification of the name of the file. If the external environment allows alternative specifications of the name (for example, abbreviations), the full name should not use such alternatives. A full name typically will include the names of all of the directories that contain the item. The simple name of an external file is the name of the item, not including any containing directory names. Unless otherwise specified, a file name or directory name parameter in a call to a predefined Ada input-output subprogram can be a full name, a simple name, or any other form of name supported by the implementation. 48/2 The default directory is the directory that is used if a directory or file name is not a full name (that is, when the name does not fully identify all of the containing directories). 49/2 A directory entry is a single item in a directory, identifying a single external file (including directories and special files). 50/2 For each function that returns a string, the lower bound of the returned value is 1. 51/2 The following file and directory operations are provided: 52/2 function Current_Directory return String; 53/2 Returns the full directory name for the current default directory. The name returned shall be suitable for a future call to Set_Directory. The exception Use_Error is propagated if a default directory is not supported by the external environment. 54/2 procedure Set_Directory (Directory : in String); 55/2 Sets the current default directory. The exception Name_Error is propagated if the string given as Directory does not identify an existing directory. The exception Use_Error is propagated if the external environment does not support making Directory (in the absence of Name_Error) a default directory. 56/2 procedure Create_Directory (New_Directory : in String; Form : in String := ""); 57/2 Creates a directory with name New_Directory. The Form parameter can be used to give system-dependent characteristics of the directory; the interpretation of the Form parameter is implementation-defined. A null string for Form specifies the use of the default options of the implementation of the new directory. The exception Name_Error is propagated if the string given as New_Directory does not allow the identification of a directory. The exception Use_Error is propagated if the external environment does not support the creation of a directory with the given name (in the absence of Name_Error) and form. 58/2 procedure Delete_Directory (Directory : in String); 59/3 Deletes an existing empty directory with name Directory. The exception Name_Error is propagated if the string given as Directory does not identify an existing directory. The exception Use_Error is propagated if the directory is not empty or the external environment does not support the deletion of the directory with the given name (in the absence of Name_Error). 60/2 procedure Create_Path (New_Directory : in String; Form : in String := ""); 61/3 Creates zero or more directories with name New_Directory. Each nonexistent directory named by New_Directory is created. For example, on a typical Unix system, Create_Path ("/usr/me/my"); would create directory "me" in directory "usr", then create directory "my" in directory "me". The Form parameter can be used to give system-dependent characteristics of the directory; the interpretation of the Form parameter is implementation-defined. A null string for Form specifies the use of the default options of the implementation of the new directory. The exception Name_Error is propagated if the string given as New_Directory does not allow the identification of any directory. The exception Use_Error is propagated if the external environment does not support the creation of any directories with the given name (in the absence of Name_Error) and form. If Use_Error is propagated, it is unspecified whether a portion of the directory path is created. 62/2 procedure Delete_Tree (Directory : in String); 63/2 Deletes an existing directory with name Directory. The directory and all of its contents (possibly including other directories) are deleted. The exception Name_Error is propagated if the string given as Directory does not identify an existing directory. The exception Use_Error is propagated if the external environment does not support the deletion of the directory or some portion of its contents with the given name (in the absence of Name_Error). If Use_Error is propagated, it is unspecified whether a portion of the contents of the directory is deleted. 64/2 procedure Delete_File (Name : in String); 65/2 Deletes an existing ordinary or special file with name Name. The exception Name_Error is propagated if the string given as Name does not identify an existing ordinary or special external file. The exception Use_Error is propagated if the external environment does not support the deletion of the file with the given name (in the absence of Name_Error). 66/2 procedure Rename (Old_Name, New_Name : in String); 67/3 Renames an existing external file (including directories) with name Old_Name to New_Name. The exception Name_Error is propagated if the string given as Old_Name does not identify an existing external file or if the string given as New_Name does not allow the identification of an external file. The exception Use_Error is propagated if the external environment does not support the renaming of the file with the given name (in the absence of Name_Error). In particular, Use_Error is propagated if a file or directory already exists with name New_Name. 68/3 procedure Copy_File (Source_Name, Target_Name : in String; Form : in String := ""); 69/3 Copies the contents of the existing external file with name Source_Name to an external file with name Target_Name. The resulting external file is a duplicate of the source external file. The Form parameter can be used to give system-dependent characteristics of the resulting external file; the interpretation of the Form parameter is implementation-defined. Exception Name_Error is propagated if the string given as Source_Name does not identify an existing external ordinary or special file, or if the string given as Target_Name does not allow the identification of an external file. The exception Use_Error is propagated if the external environment does not support creating the file with the name given by Target_Name and form given by Form, or copying of the file with the name given by Source_Name (in the absence of Name_Error). If Use_Error is propagated, it is unspecified whether a portion of the file is copied. 70/2 The following file and directory name operations are provided: 71/2 function Full_Name (Name : in String) return String; 72/2 Returns the full name corresponding to the file name specified by Name. The exception Name_Error is propagated if the string given as Name does not allow the identification of an external file (including directories and special files). 73/2 function Simple_Name (Name : in String) return String; 74/2 Returns the simple name portion of the file name specified by Name. The exception Name_Error is propagated if the string given as Name does not allow the identification of an external file (including directories and special files). 75/2 function Containing_Directory (Name : in String) return String; 76/2 Returns the name of the containing directory of the external file (including directories) identified by Name. (If more than one directory can contain Name, the directory name returned is implementation-defined.) The exception Name_Error is propagated if the string given as Name does not allow the identification of an external file. The exception Use_Error is propagated if the external file does not have a containing directory. 77/2 function Extension (Name : in String) return String; 78/2 Returns the extension name corresponding to Name. The extension name is a portion of a simple name (not including any separator characters), typically used to identify the file class. If the external environment does not have extension names, then the null string is returned. The exception Name_Error is propagated if the string given as Name does not allow the identification of an external file. 79/2 function Base_Name (Name : in String) return String; 80/2 Returns the base name corresponding to Name. The base name is the remainder of a simple name after removing any extension and extension separators. The exception Name_Error is propagated if the string given as Name does not allow the identification of an external file (including directories and special files). 81/2 function Compose (Containing_Directory : in String := ""; Name : in String; Extension : in String := "") return String; 82/3 Returns the name of the external file with the specified Containing_Directory, Name, and Extension. If Extension is the null string, then Name is interpreted as a simple name; otherwise, Name is interpreted as a base name. The exception Name_Error is propagated if the string given as Containing_Directory is not null and does not allow the identification of a directory, or if the string given as Extension is not null and is not a possible extension, or if the string given as Name is not a possible simple name (if Extension is null) or base name (if Extension is nonnull). 82.1/3 function Name_Case_Equivalence (Name : in String) return Name_Case_Kind; 82.2/3 Returns the file name equivalence rule for the directory containing Name. Raises Name_Error if Name is not a full name. Returns Case_Sensitive if file names that differ only in the case of letters are considered different names. If file names that differ only in the case of letters are considered the same name, then Case_Preserving is returned if names have the case of the file name used when a file is created; and Case_Insensitive is returned otherwise. Returns Unknown if the file name equivalence is not known. 83/2 The following file and directory queries and types are provided: 84/2 type File_Kind is (Directory, Ordinary_File, Special_File); 85/2 The type File_Kind represents the kind of file represented by an external file or directory. 86/2 type File_Size is range 0 .. implementation-defined; 87/2 The type File_Size represents the size of an external file. 88/2 function Exists (Name : in String) return Boolean; 89/2 Returns True if an external file represented by Name exists, and False otherwise. The exception Name_Error is propagated if the string given as Name does not allow the identification of an external file (including directories and special files). 90/2 function Kind (Name : in String) return File_Kind; 91/2 Returns the kind of external file represented by Name. The exception Name_Error is propagated if the string given as Name does not allow the identification of an existing external file. 92/2 function Size (Name : in String) return File_Size; 93/2 Returns the size of the external file represented by Name. The size of an external file is the number of stream elements contained in the file. If the external file is not an ordinary file, the result is implementation-defined. The exception Name_Error is propagated if the string given as Name does not allow the identification of an existing external file. The exception Constraint_Error is propagated if the file size is not a value of type File_Size. 94/2 function Modification_Time (Name : in String) return Ada.Calendar.Time; 95/2 Returns the time that the external file represented by Name was most recently modified. If the external file is not an ordinary file, the result is implementation-defined. The exception Name_Error is propagated if the string given as Name does not allow the identification of an existing external file. The exception Use_Error is propagated if the external environment does not support reading the modification time of the file with the name given by Name (in the absence of Name_Error). 96/2 The following directory searching operations and types are provided: 97/2 type Directory_Entry_Type is limited private; 98/2 The type Directory_Entry_Type represents a single item in a directory. These items can only be created by the Get_Next_Entry procedure in this package. Information about the item can be obtained from the functions declared in this package. A default-initialized object of this type is invalid; objects returned from Get_Next_Entry are valid. 99/2 type Filter_Type is array (File_Kind) of Boolean; 100/2 The type Filter_Type specifies which directory entries are provided from a search operation. If the Directory component is True, directory entries representing directories are provided. If the Ordinary_File component is True, directory entries representing ordinary files are provided. If the Special_File component is True, directory entries representing special files are provided. 101/2 type Search_Type is limited private; 102/2 The type Search_Type contains the state of a directory search. A default-initialized Search_Type object has no entries available (function More_Entries returns False). Type Search_Type needs finalization (see 7.6). 103/2 procedure Start_Search (Search : in out Search_Type; Directory : in String; Pattern : in String; Filter : in Filter_Type := (others => True)); 104/3 Starts a search in the directory named by Directory for entries matching Pattern and Filter. Pattern represents a pattern for matching file names. If Pattern is the null string, all items in the directory are matched; otherwise, the interpretation of Pattern is implementation-defined. Only items that match Filter will be returned. After a successful call on Start_Search, the object Search may have entries available, but it may have no entries available if no files or directories match Pattern and Filter. The exception Name_Error is propagated if the string given by Directory does not identify an existing directory, or if Pattern does not allow the identification of any possible external file or directory. The exception Use_Error is propagated if the external environment does not support the searching of the directory with the given name (in the absence of Name_Error). When Start_Search propagates Name_Error or Use_Error, the object Search will have no entries available. 105/2 procedure End_Search (Search : in out Search_Type); 106/2 Ends the search represented by Search. After a successful call on End_Search, the object Search will have no entries available. 107/2 function More_Entries (Search : in Search_Type) return Boolean; 108/2 Returns True if more entries are available to be returned by a call to Get_Next_Entry for the specified search object, and False otherwise. 109/2 procedure Get_Next_Entry (Search : in out Search_Type; Directory_Entry : out Directory_Entry_Type); 110/3 Returns the next Directory_Entry for the search described by Search that matches the pattern and filter. If no further matches are available, Status_Error is raised. It is implementation-defined as to whether the results returned by this subprogram are altered if the contents of the directory are altered while the Search object is valid (for example, by another program). The exception Use_Error is propagated if the external environment does not support continued searching of the directory represented by Search. 111/2 procedure Search ( Directory : in String; Pattern : in String; Filter : in Filter_Type := (others => True); Process : not null access procedure ( Directory_Entry : in Directory_Entry_Type)); 112/3 Searches in the directory named by Directory for entries matching Pattern and Filter. The subprogram designated by Process is called with each matching entry in turn. Pattern represents a pattern for matching file names. If Pattern is the null string, all items in the directory are matched; otherwise, the interpretation of Pattern is implementation-defined. Only items that match Filter will be returned. The exception Name_Error is propagated if the string given by Directory does not identify an existing directory, or if Pattern does not allow the identification of any possible external file or directory. The exception Use_Error is propagated if the external environment does not support the searching of the directory with the given name (in the absence of Name_Error). 113/2 function Simple_Name (Directory_Entry : in Directory_Entry_Type) return String; 114/2 Returns the simple external name of the external file (including directories) represented by Directory_Entry. The format of the name returned is implementation-defined. The exception Status_Error is propagated if Directory_Entry is invalid. 115/2 function Full_Name (Directory_Entry : in Directory_Entry_Type) return String; 116/2 Returns the full external name of the external file (including directories) represented by Directory_Entry. The format of the name returned is implementation-defined. The exception Status_Error is propagated if Directory_Entry is invalid. 117/2 function Kind (Directory_Entry : in Directory_Entry_Type) return File_Kind; 118/2 Returns the kind of external file represented by Directory_Entry. The exception Status_Error is propagated if Directory_Entry is invalid. 119/2 function Size (Directory_Entry : in Directory_Entry_Type) return File_Size; 120/2 Returns the size of the external file represented by Directory_Entry. The size of an external file is the number of stream elements contained in the file. If the external file represented by Directory_Entry is not an ordinary file, the result is implementation-defined. The exception Status_Error is propagated if Directory_Entry is invalid. The exception Constraint_Error is propagated if the file size is not a value of type File_Size. 121/2 function Modification_Time (Directory_Entry : in Directory_Entry_Type) return Ada.Calendar.Time; 122/2 Returns the time that the external file represented by Directory_Entry was most recently modified. If the external file represented by Directory_Entry is not an ordinary file, the result is implementation-defined. The exception Status_Error is propagated if Directory_Entry is invalid. The exception Use_Error is propagated if the external environment does not support reading the modification time of the file represented by Directory_Entry. Implementation Requirements 123/2 For Copy_File, if Source_Name identifies an existing external ordinary file created by a predefined Ada input-output package, and Target_Name and Form can be used in the Create operation of that input-output package with mode Out_File without raising an exception, then Copy_File shall not propagate Use_Error. Implementation Advice 124/2 If other information about a file (such as the owner or creation date) is available in a directory entry, the implementation should provide functions in a child package Directories.Information to retrieve it. 125/3 Start_Search and Search should raise Name_Error if Pattern is malformed, but not if it could represent a file in the directory but does not actually do so. 126/2 Rename should be supported at least when both New_Name and Old_Name are simple names and New_Name does not identify an existing external file. NOTES 127/2 41 The operations Containing_Directory, Full_Name, Simple_Name, Base_Name, Extension, and Compose operate on file names, not external files. The files identified by these operations do not need to exist. Name_Error is raised only if the file name is malformed and cannot possibly identify a file. Of these operations, only the result of Full_Name depends on the current default directory; the result of the others depends only on their parameters. 128/2 42 Using access types, values of Search_Type and Directory_Entry_Type can be saved and queried later. However, another task or application can modify or delete the file represented by a Directory_Entry_Type value or the directory represented by a Search_Type value; such a value can only give the information valid at the time it is created. Therefore, long-term storage of these values is not recommended. 129/2 43 If the target system does not support directories inside of directories, then Kind will never return Directory and Containing_Directory will always raise Use_Error. 130/2 44 If the target system does not support creation or deletion of directories, then Create_Directory, Create_Path, Delete_Directory, and Delete_Tree will always propagate Use_Error. 131/2 45 To move a file or directory to a different location, use Rename. Most target systems will allow renaming of files from one directory to another. If the target file or directory might already exist, it should be deleted first. A.16.1 The Package Directories.Hierarchical_File_Names 1/3 The library package Directories.Hierarchical_File_Names is an optional package providing operations for file name construction and decomposition for targets with hierarchical file naming. Static Semantics 2/3 If provided, the library package Directories.Hierarchical_File_Names has the following declaration: 3/3 package Ada.Directories.Hierarchical_File_Names is 4/3 function Is_Simple_Name (Name : in String) return Boolean; 5/3 function Is_Root_Directory_Name (Name : in String) return Boolean; 6/3 function Is_Parent_Directory_Name (Name : in String) return Boolean; 7/3 function Is_Current_Directory_Name (Name : in String) return Boolean; 8/3 function Is_Full_Name (Name : in String) return Boolean; 9/3 function Is_Relative_Name (Name : in String) return Boolean; 10/3 function Simple_Name (Name : in String) return String renames Ada.Directories.Simple_Name; 11/3 function Containing_Directory (Name : in String) return String renames Ada.Directories.Containing_Directory; 12/3 function Initial_Directory (Name : in String) return String; 13/3 function Relative_Name (Name : in String) return String; 14/3 function Compose (Directory : in String := ""; Relative_Name : in String; Extension : in String := "") return String; 15/3 end Ada.Directories.Hierarchical_File_Names; 16/3 In addition to the operations provided in package Directories.Hierarchical_File_Names, the operations in package Directories can be used with hierarchical file names. In particular, functions Full_Name, Base_Name, and Extension provide additional capabilities for hierarchical file names. 17/3 function Is_Simple_Name (Name : in String) return Boolean; 18/3 Returns True if Name is a simple name, and returns False otherwise. 19/3 function Is_Root_Directory_Name (Name : in String) return Boolean; 20/3 Returns True if Name is syntactically a root (a directory that cannot be decomposed further), and returns False otherwise. 21/3 function Is_Parent_Directory_Name (Name : in String) return Boolean; 22/3 Returns True if Name can be used to indicate symbolically the parent directory of any directory, and returns False otherwise. 23/3 function Is_Current_Directory_Name (Name : in String) return Boolean; 24/3 Returns True if Name can be used to indicate symbolically the directory itself for any directory, and returns False otherwise. 25/3 function Is_Full_Name (Name : in String) return Boolean; 26/3 Returns True if the leftmost directory part of Name is a root, and returns False otherwise. 27/3 function Is_Relative_Name (Name : in String) return Boolean; 28/3 Returns True if Name allows the identification of an external file (including directories and special files) but is not a full name, and returns False otherwise. 29/3 function Initial_Directory (Name : in String) return String; 30/3 Returns the leftmost directory part in Name. That is, it returns a root directory name (for a full name), or one of a parent directory name, a current directory name, or a simple name (for a relative name). The exception Name_Error is propagated if the string given as Name does not allow the identification of an external file (including directories and special files). 31/3 function Relative_Name (Name : in String) return String; 32/3 Returns the entire file name except the Initial_Directory portion. The exception Name_Error is propagated if the string given as Name does not allow the identification of an external file (including directories and special files), or if Name has a single part (this includes if any of Is_Simple_Name, Is_Root_Directory_Name, Is_Parent_Directory_Name, or Is_Current_Directory_Name are True). 33/3 function Compose (Directory : in String := ""; Relative_Name : in String; Extension : in String := "") return String; 34/3 Returns the name of the external file with the specified Directory, Relative_Name, and Extension. The exception Name_Error is propagated if the string given as Directory is not the null string and does not allow the identification of a directory, or if Is_Relative_Name (Relative_Name) is False, or if the string given as Extension is not the null string and is not a possible extension, or if Extension is not the null string and Simple_Name (Relative_Name) is not a base name. 35/3 The result of Compose is a full name if Is_Full_Name (Directory) is True; result is a relative name otherwise. Implementation Advice 36/3 Directories.Hierarchical_File_Names should be provided for systems with hierarchical file naming, and should not be provided on other systems. NOTES 37/3 46 These operations operate on file names, not external files. The files identified by these operations do not need to exist. Name_Error is raised only as specified or if the file name is malformed and cannot possibly identify a file. The result of these operations depends only on their parameters. 38/3 47 Containing_Directory raises Use_Error if Name does not have a containing directory, including when any of Is_Simple_Name, Is_Root_Directory_Name, Is_Parent_Directory_Name, or Is_Current_Directory_Name are True. A.17 The Package Environment_Variables 1/2 The package Environment_Variables allows a program to read or modify environment variables. Environment variables are name-value pairs, where both the name and value are strings. The definition of what constitutes an environment variable, and the meaning of the name and value, are implementation defined. Static Semantics 2/2 The library package Environment_Variables has the following declaration: 3/2 package Ada.Environment_Variables is pragma Preelaborate(Environment_Variables); 4/2 function Value (Name : in String) return String; 4.1/3 function Value (Name : in String; Default : in String) return String; 5/2 function Exists (Name : in String) return Boolean; 6/2 procedure Set (Name : in String; Value : in String); 7/2 procedure Clear (Name : in String); procedure Clear; 8/3 procedure Iterate (Process : not null access procedure (Name, Value : in String)); 9/2 end Ada.Environment_Variables; 10/2 function Value (Name : in String) return String; 11/2 If the external execution environment supports environment variables, then Value returns the value of the environment variable with the given name. If no environment variable with the given name exists, then Constraint_Error is propagated. If the execution environment does not support environment variables, then Program_Error is propagated. 11.1/3 function Value (Name : in String; Default : in String) return String; 11.2/3 If the external execution environment supports environment variables and an environment variable with the given name currently exists, then Value returns its value; otherwise, it returns Default. 12/2 function Exists (Name : in String) return Boolean; 13/3 If the external execution environment supports environment variables and an environment variable with the given name currently exists, then Exists returns True; otherwise, it returns False. 14/2 procedure Set (Name : in String; Value : in String); 15/3 If the external execution environment supports environment variables, then Set first clears any existing environment variable with the given name, and then defines a single new environment variable with the given name and value. Otherwise, Program_Error is propagated. 16/2 If implementation-defined circumstances prohibit the definition of an environment variable with the given name and value, then Constraint_Error is propagated. 17/2 It is implementation defined whether there exist values for which the call Set(Name, Value) has the same effect as Clear (Name). 18/2 procedure Clear (Name : in String); 19/3 If the external execution environment supports environment variables, then Clear deletes all existing environment variables with the given name. Otherwise, Program_Error is propagated. 20/2 procedure Clear; 21/3 If the external execution environment supports environment variables, then Clear deletes all existing environment variables. Otherwise, Program_Error is propagated. 22/3 procedure Iterate (Process : not null access procedure (Name, Value : in String)); 23/3 If the external execution environment supports environment variables, then Iterate calls the subprogram designated by Process for each existing environment variable, passing the name and value of that environment variable. Otherwise, Program_Error is propagated. 24/2 If several environment variables exist that have the same name, Process is called once for each such variable. Bounded (Run-Time) Errors 25/2 It is a bounded error to call Value if more than one environment variable exists with the given name; the possible outcomes are that: 26/2 * one of the values is returned, and that same value is returned in subsequent calls in the absence of changes to the environment; or 27/2 * Program_Error is propagated. Erroneous Execution 28/2 Making calls to the procedures Set or Clear concurrently with calls to any subprogram of package Environment_Variables, or to any instantiation of Iterate, results in erroneous execution. 29/2 Making calls to the procedures Set or Clear in the actual subprogram corresponding to the Process parameter of Iterate results in erroneous execution. Documentation Requirements 30/2 An implementation shall document how the operations of this package behave if environment variables are changed by external mechanisms (for instance, calling operating system services). Implementation Permissions 31/2 An implementation running on a system that does not support environment variables is permitted to define the operations of package Environment_Variables with the semantics corresponding to the case where the external execution environment does support environment variables. In this case, it shall provide a mechanism to initialize a nonempty set of environment variables prior to the execution of a partition. Implementation Advice 32/2 If the execution environment supports subprocesses, the currently defined environment variables should be used to initialize the environment variables of a subprocess. 33/2 Changes to the environment variables made outside the control of this package should be reflected immediately in the effect of the operations of this package. Changes to the environment variables made using this package should be reflected immediately in the external execution environment. This package should not perform any buffering of the environment variables. A.18 Containers 1/2 This clause presents the specifications of the package Containers and several child packages, which provide facilities for storing collections of elements. 2/2 A variety of sequence and associative containers are provided. Each container includes a cursor type. A cursor is a reference to an element within a container. Many operations on cursors are common to all of the containers. A cursor referencing an element in a container is considered to be overlapping with the container object itself. 3/2 Within this clause we provide Implementation Advice for the desired average or worst case time complexity of certain operations on a container. This advice is expressed using the Landau symbol O(X). Presuming f is some function of a length parameter N and t(N) is the time the operation takes (on average or worst case, as specified) for the length N, a complexity of O(f(N)) means that there exists a finite A such that for any N, t(N)/f(N) < A. 4/2 If the advice suggests that the complexity should be less than O(f(N)), then for any arbitrarily small positive real D, there should exist a positive integer M such that for all N > M, t(N)/f(N) < D. 5/3 When a formal function is used to provide an ordering for a container, it is generally required to define a strict weak ordering. A function "<" defines a strict weak ordering if it is irreflexive, asymmetric, transitive, and in addition, if x < y for any values x and y, then for all other values z, (x < z) or (z < y). Static Semantics 6/4 Certain subprograms declared within instances of some of the generic packages presented in this clause are said to perform indefinite insertion. These subprograms are those corresponding (in the sense of the copying described in subclause 12.3) to subprograms that have formal parameters of a generic formal indefinite type and that are identified as performing indefinite insertion in the subclause defining the generic package. 7/4 If a subprogram performs indefinite insertion, then certain run-time checks are performed as part of a call to the subprogram; if any of these checks fail, then the resulting exception is propagated to the caller and the container is not modified by the call. These checks are performed for each parameter corresponding (in the sense of the copying described in 12.3) to a parameter in the corresponding generic whose type is a generic formal indefinite type. The checks performed for a given parameter are those checks explicitly specified in subclause 4.8 that would be performed as part of the evaluation of an initialized allocator whose access type is declared immediately within the instance, where: 8/4 * the value of the qualified_expression is that of the parameter; and 9/4 * the designated subtype of the access type is the subtype of the parameter; and 10/4 * finalization of the collection of the access type has started if and only if the finalization of the instance has started. A.18.1 The Package Containers 1/2 The package Containers is the root of the containers subsystem. Static Semantics 2/2 The library package Containers has the following declaration: 3/2 package Ada.Containers is pragma Pure(Containers); 4/2 type Hash_Type is mod implementation-defined; 5/2 type Count_Type is range 0 .. implementation-defined; 5.1/3 Capacity_Error : exception; 6/2 end Ada.Containers; 7/2 Hash_Type represents the range of the result of a hash function. Count_Type represents the (potential or actual) number of elements of a container. 7.1/3 Capacity_Error is raised when the capacity of a container is exceeded. Implementation Advice 8/2 Hash_Type'Modulus should be at least 2**32. Count_Type'Last should be at least 2**31-1. A.18.2 The Generic Package Containers.Vectors 1/2 The language-defined generic package Containers.Vectors provides private types Vector and Cursor, and a set of operations for each type. A vector container allows insertion and deletion at any position, but it is specifically optimized for insertion and deletion at the high end (the end with the higher index) of the container. A vector container also provides random access to its elements. 2/2 A vector container behaves conceptually as an array that expands as necessary as items are inserted. The length of a vector is the number of elements that the vector contains. The capacity of a vector is the maximum number of elements that can be inserted into the vector prior to it being automatically expanded. 3/2 Elements in a vector container can be referred to by an index value of a generic formal type. The first element of a vector always has its index value equal to the lower bound of the formal type. 4/2 A vector container may contain empty elements. Empty elements do not have a specified value. Static Semantics 5/2 The generic library package Containers.Vectors has the following declaration: 6/3 with Ada.Iterator_Interfaces; generic type Index_Type is range <>; type Element_Type is private; with function "=" (Left, Right : Element_Type) return Boolean is <>; package Ada.Containers.Vectors is pragma Preelaborate(Vectors); pragma Remote_Types(Vectors); 7/2 subtype Extended_Index is Index_Type'Base range Index_Type'First-1 .. Index_Type'Min (Index_Type'Base'Last - 1, Index_Type'Last) + 1; No_Index : constant Extended_Index := Extended_Index'First; 8/3 type Vector is tagged private with Constant_Indexing => Constant_Reference, Variable_Indexing => Reference, Default_Iterator => Iterate, Iterator_Element => Element_Type; pragma Preelaborable_Initialization(Vector); 9/2 type Cursor is private; pragma Preelaborable_Initialization(Cursor); 10/2 Empty_Vector : constant Vector; 11/2 No_Element : constant Cursor; 11.1/3 function Has_Element (Position : Cursor) return Boolean; 11.2/3 package Vector_Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, Has_Element); 12/2 function "=" (Left, Right : Vector) return Boolean; 13/2 function To_Vector (Length : Count_Type) return Vector; 14/2 function To_Vector (New_Item : Element_Type; Length : Count_Type) return Vector; 15/2 function "&" (Left, Right : Vector) return Vector; 16/2 function "&" (Left : Vector; Right : Element_Type) return Vector; 17/2 function "&" (Left : Element_Type; Right : Vector) return Vector; 18/2 function "&" (Left, Right : Element_Type) return Vector; 19/2 function Capacity (Container : Vector) return Count_Type; 20/2 procedure Reserve_Capacity (Container : in out Vector; Capacity : in Count_Type); 21/2 function Length (Container : Vector) return Count_Type; 22/2 procedure Set_Length (Container : in out Vector; Length : in Count_Type); 23/2 function Is_Empty (Container : Vector) return Boolean; 24/2 procedure Clear (Container : in out Vector); 25/2 function To_Cursor (Container : Vector; Index : Extended_Index) return Cursor; 26/2 function To_Index (Position : Cursor) return Extended_Index; 27/2 function Element (Container : Vector; Index : Index_Type) return Element_Type; 28/2 function Element (Position : Cursor) return Element_Type; 29/2 procedure Replace_Element (Container : in out Vector; Index : in Index_Type; New_Item : in Element_Type); 30/2 procedure Replace_Element (Container : in out Vector; Position : in Cursor; New_item : in Element_Type); 31/2 procedure Query_Element (Container : in Vector; Index : in Index_Type; Process : not null access procedure (Element : in Element_Type)); 32/2 procedure Query_Element (Position : in Cursor; Process : not null access procedure (Element : in Element_Type)); 33/2 procedure Update_Element (Container : in out Vector; Index : in Index_Type; Process : not null access procedure (Element : in out Element_Type)); 34/2 procedure Update_Element (Container : in out Vector; Position : in Cursor; Process : not null access procedure (Element : in out Element_Type)); 34.1/3 type Constant_Reference_Type (Element : not null access constant Element_Type) is private with Implicit_Dereference => Element; 34.2/3 type Reference_Type (Element : not null access Element_Type) is private with Implicit_Dereference => Element; 34.3/3 function Constant_Reference (Container : aliased in Vector; Index : in Index_Type) return Constant_Reference_Type; 34.4/3 function Reference (Container : aliased in out Vector; Index : in Index_Type) return Reference_Type; 34.5/3 function Constant_Reference (Container : aliased in Vector; Position : in Cursor) return Constant_Reference_Type; 34.6/3 function Reference (Container : aliased in out Vector; Position : in Cursor) return Reference_Type; 34.7/3 procedure Assign (Target : in out Vector; Source : in Vector); 34.8/3 function Copy (Source : Vector; Capacity : Count_Type := 0) return Vector; 35/2 procedure Move (Target : in out Vector; Source : in out Vector); 36/2 procedure Insert (Container : in out Vector; Before : in Extended_Index; New_Item : in Vector); 37/2 procedure Insert (Container : in out Vector; Before : in Cursor; New_Item : in Vector); 38/2 procedure Insert (Container : in out Vector; Before : in Cursor; New_Item : in Vector; Position : out Cursor); 39/2 procedure Insert (Container : in out Vector; Before : in Extended_Index; New_Item : in Element_Type; Count : in Count_Type := 1); 40/2 procedure Insert (Container : in out Vector; Before : in Cursor; New_Item : in Element_Type; Count : in Count_Type := 1); 41/2 procedure Insert (Container : in out Vector; Before : in Cursor; New_Item : in Element_Type; Position : out Cursor; Count : in Count_Type := 1); 42/2 procedure Insert (Container : in out Vector; Before : in Extended_Index; Count : in Count_Type := 1); 43/2 procedure Insert (Container : in out Vector; Before : in Cursor; Position : out Cursor; Count : in Count_Type := 1); 44/2 procedure Prepend (Container : in out Vector; New_Item : in Vector); 45/2 procedure Prepend (Container : in out Vector; New_Item : in Element_Type; Count : in Count_Type := 1); 46/2 procedure Append (Container : in out Vector; New_Item : in Vector); 47/2 procedure Append (Container : in out Vector; New_Item : in Element_Type; Count : in Count_Type := 1); 48/2 procedure Insert_Space (Container : in out Vector; Before : in Extended_Index; Count : in Count_Type := 1); 49/2 procedure Insert_Space (Container : in out Vector; Before : in Cursor; Position : out Cursor; Count : in Count_Type := 1); 50/2 procedure Delete (Container : in out Vector; Index : in Extended_Index; Count : in Count_Type := 1); 51/2 procedure Delete (Container : in out Vector; Position : in out Cursor; Count : in Count_Type := 1); 52/2 procedure Delete_First (Container : in out Vector; Count : in Count_Type := 1); 53/2 procedure Delete_Last (Container : in out Vector; Count : in Count_Type := 1); 54/2 procedure Reverse_Elements (Container : in out Vector); 55/2 procedure Swap (Container : in out Vector; I, J : in Index_Type); 56/2 procedure Swap (Container : in out Vector; I, J : in Cursor); 57/2 function First_Index (Container : Vector) return Index_Type; 58/2 function First (Container : Vector) return Cursor; 59/2 function First_Element (Container : Vector) return Element_Type; 60/2 function Last_Index (Container : Vector) return Extended_Index; 61/2 function Last (Container : Vector) return Cursor; 62/2 function Last_Element (Container : Vector) return Element_Type; 63/2 function Next (Position : Cursor) return Cursor; 64/2 procedure Next (Position : in out Cursor); 65/2 function Previous (Position : Cursor) return Cursor; 66/2 procedure Previous (Position : in out Cursor); 67/2 function Find_Index (Container : Vector; Item : Element_Type; Index : Index_Type := Index_Type'First) return Extended_Index; 68/2 function Find (Container : Vector; Item : Element_Type; Position : Cursor := No_Element) return Cursor; 69/2 function Reverse_Find_Index (Container : Vector; Item : Element_Type; Index : Index_Type := Index_Type'Last) return Extended_Index; 70/2 function Reverse_Find (Container : Vector; Item : Element_Type; Position : Cursor := No_Element) return Cursor; 71/2 function Contains (Container : Vector; Item : Element_Type) return Boolean; 72/3 This paragraph was deleted. 73/2 procedure Iterate (Container : in Vector; Process : not null access procedure (Position : in Cursor)); 74/2 procedure Reverse_Iterate (Container : in Vector; Process : not null access procedure (Position : in Cursor)); 74.1/3 function Iterate (Container : in Vector) return Vector_Iterator_Interfaces.Reversible_Iterator'Class; 74.2/3 function Iterate (Container : in Vector; Start : in Cursor) return Vector_Iterator_Interfaces.Reversible_Iterator'Class; 75/2 generic with function "<" (Left, Right : Element_Type) return Boolean is <>; package Generic_Sorting is 76/2 function Is_Sorted (Container : Vector) return Boolean; 77/2 procedure Sort (Container : in out Vector); 78/2 procedure Merge (Target : in out Vector; Source : in out Vector); 79/2 end Generic_Sorting; 80/2 private 81/2 ... -- not specified by the language 82/2 end Ada.Containers.Vectors; 83/2 The actual function for the generic formal function "=" on Element_Type values is expected to define a reflexive and symmetric relationship and return the same result value each time it is called with a particular pair of values. If it behaves in some other manner, the functions defined to use it return an unspecified value. The exact arguments and number of calls of this generic formal function by the functions defined to use it are unspecified. 84/2 The type Vector is used to represent vectors. The type Vector needs finalization (see 7.6). 85/2 Empty_Vector represents the empty vector object. It has a length of 0. If an object of type Vector is not otherwise initialized, it is initialized to the same value as Empty_Vector. 86/2 No_Element represents a cursor that designates no element. If an object of type Cursor is not otherwise initialized, it is initialized to the same value as No_Element. 87/2 The predefined "=" operator for type Cursor returns True if both cursors are No_Element, or designate the same element in the same container. 88/2 Execution of the default implementation of the Input, Output, Read, or Write attribute of type Cursor raises Program_Error. 88.1/3 Vector'Write for a Vector object V writes Length(V) elements of the vector to the stream. It also may write additional information about the vector. 88.2/3 Vector'Read reads the representation of a vector from the stream, and assigns to Item a vector with the same length and elements as was written by Vector'Write. 89/2 No_Index represents a position that does not correspond to any element. The subtype Extended_Index includes the indices covered by Index_Type plus the value No_Index and, if it exists, the successor to the Index_Type'Last. 89.1/3 If an operation attempts to modify the vector such that the position of the last element would be greater than Index_Type'Last, then the operation propagates Constraint_Error. 90/2 Some operations of this generic package have access-to-subprogram parameters. To ensure such operations are well-defined, they guard against certain actions by the designated subprogram. In particular, some operations check for "tampering with cursors" of a container because they depend on the set of elements of the container remaining constant, and others check for " tampering with elements" of a container because they depend on elements of the container not being replaced. 91/2 A subprogram is said to tamper with cursors of a vector object V if: 92/2 * it inserts or deletes elements of V, that is, it calls the Insert, Insert_Space, Clear, Delete, or Set_Length procedures with V as a parameter; or 93/2 * it finalizes V; or 93.1/3 * it calls the Assign procedure with V as the Target parameter; or 94/2 * it calls the Move procedure with V as a parameter. 95/2 A subprogram is said to tamper with elements of a vector object V if: 96/2 * it tampers with cursors of V; or 97/2 * it replaces one or more elements of V, that is, it calls the Replace_Element, Reverse_Elements, or Swap procedures or the Sort or Merge procedures of an instance of Generic_Sorting with V as a parameter. 97.1/4 When tampering with cursors is prohibited for a particular vector object V, Program_Error is propagated by a call of any language-defined subprogram that is defined to tamper with the cursors of V, leaving V unmodified. Similarly, when tampering with elements is prohibited for a particular vector object V, Program_Error is propagated by a call of any language-defined subprogram that is defined to tamper with the elements of V (or tamper with the cursors of V), leaving V unmodified. These checks are made before any other defined behavior of the body of the language-defined subprogram. 97.2/3 function Has_Element (Position : Cursor) return Boolean; 97.3/3 Returns True if Position designates an element, and returns False otherwise. 98/2 function "=" (Left, Right : Vector) return Boolean; 99/3 If Left and Right denote the same vector object, then the function returns True. If Left and Right have different lengths, then the function returns False. Otherwise, it compares each element in Left to the corresponding element in Right using the generic formal equality operator. If any such comparison returns False, the function returns False; otherwise, it returns True. Any exception raised during evaluation of element equality is propagated. 100/2 function To_Vector (Length : Count_Type) return Vector; 101/2 Returns a vector with a length of Length, filled with empty elements. 102/2 function To_Vector (New_Item : Element_Type; Length : Count_Type) return Vector; 103/2 Returns a vector with a length of Length, filled with elements initialized to the value New_Item. 104/2 function "&" (Left, Right : Vector) return Vector; 105/2 Returns a vector comprising the elements of Left followed by the elements of Right. 106/2 function "&" (Left : Vector; Right : Element_Type) return Vector; 107/2 Returns a vector comprising the elements of Left followed by the element Right. 108/2 function "&" (Left : Element_Type; Right : Vector) return Vector; 109/2 Returns a vector comprising the element Left followed by the elements of Right. 110/2 function "&" (Left, Right : Element_Type) return Vector; 111/2 Returns a vector comprising the element Left followed by the element Right. 112/2 function Capacity (Container : Vector) return Count_Type; 113/2 Returns the capacity of Container. 114/2 procedure Reserve_Capacity (Container : in out Vector; Capacity : in Count_Type); 115/3 If the capacity of Container is already greater than or equal to Capacity, then Reserve_Capacity has no effect. Otherwise, Reserve_Capacity allocates additional storage as necessary to ensure that the length of the resulting vector can become at least the value Capacity without requiring an additional call to Reserve_Capacity, and is large enough to hold the current length of Container. Reserve_Capacity then, as necessary, moves elements into the new storage and deallocates any storage no longer needed. Any exception raised during allocation is propagated and Container is not modified. 116/2 function Length (Container : Vector) return Count_Type; 117/2 Returns the number of elements in Container. 118/2 procedure Set_Length (Container : in out Vector; Length : in Count_Type); 119/3 If Length is larger than the capacity of Container, Set_Length calls Reserve_Capacity (Container, Length), then sets the length of the Container to Length. If Length is greater than the original length of Container, empty elements are added to Container; otherwise, elements are removed from Container. 120/2 function Is_Empty (Container : Vector) return Boolean; 121/2 Equivalent to Length (Container) = 0. 122/2 procedure Clear (Container : in out Vector); 123/2 Removes all the elements from Container. The capacity of Container does not change. 124/2 function To_Cursor (Container : Vector; Index : Extended_Index) return Cursor; 125/2 If Index is not in the range First_Index (Container) .. Last_Index (Container), then No_Element is returned. Otherwise, a cursor designating the element at position Index in Container is returned. 126/2 function To_Index (Position : Cursor) return Extended_Index; 127/2 If Position is No_Element, No_Index is returned. Otherwise, the index (within its containing vector) of the element designated by Position is returned. 128/2 function Element (Container : Vector; Index : Index_Type) return Element_Type; 129/2 If Index is not in the range First_Index (Container) .. Last_Index (Container), then Constraint_Error is propagated. Otherwise, Element returns the element at position Index. 130/2 function Element (Position : Cursor) return Element_Type; 131/2 If Position equals No_Element, then Constraint_Error is propagated. Otherwise, Element returns the element designated by Position. 132/2 procedure Replace_Element (Container : in out Vector; Index : in Index_Type; New_Item : in Element_Type); 133/3 If Index is not in the range First_Index (Container) .. Last_Index (Container), then Constraint_Error is propagated. Otherwise, Replace_Element assigns the value New_Item to the element at position Index. Any exception raised during the assignment is propagated. The element at position Index is not an empty element after successful call to Replace_Element. 134/2 procedure Replace_Element (Container : in out Vector; Position : in Cursor; New_Item : in Element_Type); 135/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Replace_Element assigns New_Item to the element designated by Position. Any exception raised during the assignment is propagated. The element at Position is not an empty element after successful call to Replace_Element. 136/2 procedure Query_Element (Container : in Vector; Index : in Index_Type; Process : not null access procedure (Element : in Element_Type)); 137/3 If Index is not in the range First_Index (Container) .. Last_Index (Container), then Constraint_Error is propagated. Otherwise, Query_Element calls Process.all with the element at position Index as the argument. Tampering with the elements of Container is prohibited during the execution of the call on Process.all. Any exception raised by Process.all is propagated. 138/2 procedure Query_Element (Position : in Cursor; Process : not null access procedure (Element : in Element_Type)); 139/3 If Position equals No_Element, then Constraint_Error is propagated. Otherwise, Query_Element calls Process.all with the element designated by Position as the argument. Tampering with the elements of the vector that contains the element designated by Position is prohibited during the execution of the call on Process.all. Any exception raised by Process.all is propagated. 140/2 procedure Update_Element (Container : in out Vector; Index : in Index_Type; Process : not null access procedure (Element : in out Element_Type)); 141/3 If Index is not in the range First_Index (Container) .. Last_Index (Container), then Constraint_Error is propagated. Otherwise, Update_Element calls Process.all with the element at position Index as the argument. Tampering with the elements of Container is prohibited during the execution of the call on Process.all. Any exception raised by Process.all is propagated. 142/2 If Element_Type is unconstrained and definite, then the actual Element parameter of Process.all shall be unconstrained. 143/2 The element at position Index is not an empty element after successful completion of this operation. 144/2 procedure Update_Element (Container : in out Vector; Position : in Cursor; Process : not null access procedure (Element : in out Element_Type)); 145/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Update_Element calls Process.all with the element designated by Position as the argument. Tampering with the elements of Container is prohibited during the execution of the call on Process.all. Any exception raised by Process.all is propagated. 146/2 If Element_Type is unconstrained and definite, then the actual Element parameter of Process.all shall be unconstrained. 147/2 The element designated by Position is not an empty element after successful completion of this operation. 147.1/3 type Constant_Reference_Type (Element : not null access constant Element_Type) is private with Implicit_Dereference => Element; 147.2/3 type Reference_Type (Element : not null access Element_Type) is private with Implicit_Dereference => Element; 147.3/3 The types Constant_Reference_Type and Reference_Type need finalization. 147.4/3 The default initialization of an object of type Constant_Reference_Type or Reference_Type propagates Program_Error. 147.5/3 function Constant_Reference (Container : aliased in Vector; Index : in Index_Type) return Constant_Reference_Type; 147.6/3 This function (combined with the Constant_Indexing and Implicit_Dereference aspects) provides a convenient way to gain read access to an individual element of a vector given an index value. 147.7/3 If Index is not in the range First_Index (Container) .. Last_Index (Container), then Constraint_Error is propagated. Otherwise, Constant_Reference returns an object whose discriminant is an access value that designates the element at position Index. Tampering with the elements of Container is prohibited while the object returned by Constant_Reference exists and has not been finalized. 147.8/3 function Reference (Container : aliased in out Vector; Index : in Index_Type) return Reference_Type; 147.9/3 This function (combined with the Variable_Indexing and Implicit_Dereference aspects) provides a convenient way to gain read and write access to an individual element of a vector given an index value. 147.10/3 If Index is not in the range First_Index (Container) .. Last_Index (Container), then Constraint_Error is propagated. Otherwise, Reference returns an object whose discriminant is an access value that designates the element at position Index. Tampering with the elements of Container is prohibited while the object returned by Reference exists and has not been finalized. 147.11/3 The element at position Index is not an empty element after successful completion of this operation. 147.12/3 function Constant_Reference (Container : aliased in Vector; Position : in Cursor) return Constant_Reference_Type; 147.13/3 This function (combined with the Constant_Indexing and Implicit_Dereference aspects) provides a convenient way to gain read access to an individual element of a vector given a cursor. 147.14/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Constant_Reference returns an object whose discriminant is an access value that designates the element designated by Position. Tampering with the elements of Container is prohibited while the object returned by Constant_Reference exists and has not been finalized. 147.15/3 function Reference (Container : aliased in out Vector; Position : in Cursor) return Reference_Type; 147.16/3 This function (combined with the Variable_Indexing and Implicit_Dereference aspects) provides a convenient way to gain read and write access to an individual element of a vector given a cursor. 147.17/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Reference returns an object whose discriminant is an access value that designates the element designated by Position. Tampering with the elements of Container is prohibited while the object returned by Reference exists and has not been finalized. 147.18/3 The element designated by Position is not an empty element after successful completion of this operation. 147.19/3 procedure Assign (Target : in out Vector; Source : in Vector); 147.20/3 If Target denotes the same object as Source, the operation has no effect. If the length of Source is greater than the capacity of Target, Reserve_Capacity (Target, Length (Source)) is called. The elements of Source are then copied to Target as for an assignment_statement assigning Source to Target (this includes setting the length of Target to be that of Source). 147.21/3 function Copy (Source : Vector; Capacity : Count_Type := 0) return Vector; 147.22/3 Returns a vector whose elements are initialized from the corresponding elements of Source. If Capacity is 0, then the vector capacity is the length of Source; if Capacity is equal to or greater than the length of Source, the vector capacity is at least the specified value. Otherwise, the operation propagates Capacity_Error. 148/2 procedure Move (Target : in out Vector; Source : in out Vector); 149/3 If Target denotes the same object as Source, then the operation has no effect. Otherwise, Move first calls Reserve_Capacity (Target, Length (Source)) and then Clear (Target); then, each element from Source is removed from Source and inserted into Target in the original order. The length of Source is 0 after a successful call to Move. 150/2 procedure Insert (Container : in out Vector; Before : in Extended_Index; New_Item : in Vector); 151/3 If Before is not in the range First_Index (Container) .. Last_Index (Container) + 1, then Constraint_Error is propagated. If Length(New_Item) is 0, then Insert does nothing. Otherwise, it computes the new length NL as the sum of the current length and Length (New_Item); if the value of Last appropriate for length NL would be greater than Index_Type'Last, then Constraint_Error is propagated. 152/2 If the current vector capacity is less than NL, Reserve_Capacity (Container, NL) is called to increase the vector capacity. Then Insert slides the elements in the range Before .. Last_Index (Container) up by Length(New_Item) positions, and then copies the elements of New_Item to the positions starting at Before. Any exception raised during the copying is propagated. 153/2 procedure Insert (Container : in out Vector; Before : in Cursor; New_Item : in Vector); 154/3 If Before is not No_Element, and does not designate an element in Container, then Program_Error is propagated. Otherwise, if Length(New_Item) is 0, then Insert does nothing. If Before is No_Element, then the call is equivalent to Insert (Container, Last_Index (Container) + 1, New_Item); otherwise, the call is equivalent to Insert (Container, To_Index (Before), New_Item); 155/2 procedure Insert (Container : in out Vector; Before : in Cursor; New_Item : in Vector; Position : out Cursor); 156/2 If Before is not No_Element, and does not designate an element in Container, then Program_Error is propagated. If Before equals No_Element, then let T be Last_Index (Container) + 1; otherwise, let T be To_Index (Before). Insert (Container, T, New_Item) is called, and then Position is set to To_Cursor (Container, T). 157/2 procedure Insert (Container : in out Vector; Before : in Extended_Index; New_Item : in Element_Type; Count : in Count_Type := 1); 158/2 Equivalent to Insert (Container, Before, To_Vector (New_Item, Count)); 159/2 procedure Insert (Container : in out Vector; Before : in Cursor; New_Item : in Element_Type; Count : in Count_Type := 1); 160/2 Equivalent to Insert (Container, Before, To_Vector (New_Item, Count)); 161/2 procedure Insert (Container : in out Vector; Before : in Cursor; New_Item : in Element_Type; Position : out Cursor; Count : in Count_Type := 1); 162/2 Equivalent to Insert (Container, Before, To_Vector (New_Item, Count), Position); 163/2 procedure Insert (Container : in out Vector; Before : in Extended_Index; Count : in Count_Type := 1); 164/3 If Before is not in the range First_Index (Container) .. Last_Index (Container) + 1, then Constraint_Error is propagated. If Count is 0, then Insert does nothing. Otherwise, it computes the new length NL as the sum of the current length and Count; if the value of Last appropriate for length NL would be greater than Index_Type'Last, then Constraint_Error is propagated. 165/2 If the current vector capacity is less than NL, Reserve_Capacity (Container, NL) is called to increase the vector capacity. Then Insert slides the elements in the range Before .. Last_Index (Container) up by Count positions, and then inserts elements that are initialized by default (see 3.3.1) in the positions starting at Before. 166/2 procedure Insert (Container : in out Vector; Before : in Cursor; Position : out Cursor; Count : in Count_Type := 1); 167/2 If Before is not No_Element, and does not designate an element in Container, then Program_Error is propagated. If Before equals No_Element, then let T be Last_Index (Container) + 1; otherwise, let T be To_Index (Before). Insert (Container, T, Count) is called, and then Position is set to To_Cursor (Container, T). 168/4 procedure Prepend (Container : in out Vector; New_Item : in Vector); 169/2 Equivalent to Insert (Container, First_Index (Container), New_Item). 170/2 procedure Prepend (Container : in out Vector; New_Item : in Element_Type; Count : in Count_Type := 1); 171/2 Equivalent to Insert (Container, First_Index (Container), New_Item, Count). 172/2 procedure Append (Container : in out Vector; New_Item : in Vector); 173/2 Equivalent to Insert (Container, Last_Index (Container) + 1, New_Item). 174/2 procedure Append (Container : in out Vector; New_Item : in Element_Type; Count : in Count_Type := 1); 175/2 Equivalent to Insert (Container, Last_Index (Container) + 1, New_Item, Count). 176/2 procedure Insert_Space (Container : in out Vector; Before : in Extended_Index; Count : in Count_Type := 1); 177/3 If Before is not in the range First_Index (Container) .. Last_Index (Container) + 1, then Constraint_Error is propagated. If Count is 0, then Insert_Space does nothing. Otherwise, it computes the new length NL as the sum of the current length and Count; if the value of Last appropriate for length NL would be greater than Index_Type'Last, then Constraint_Error is propagated. 178/2 If the current vector capacity is less than NL, Reserve_Capacity (Container, NL) is called to increase the vector capacity. Then Insert_Space slides the elements in the range Before .. Last_Index (Container) up by Count positions, and then inserts empty elements in the positions starting at Before. 179/2 procedure Insert_Space (Container : in out Vector; Before : in Cursor; Position : out Cursor; Count : in Count_Type := 1); 180/2 If Before is not No_Element, and does not designate an element in Container, then Program_Error is propagated. If Before equals No_Element, then let T be Last_Index (Container) + 1; otherwise, let T be To_Index (Before). Insert_Space (Container, T, Count) is called, and then Position is set to To_Cursor (Container, T). 181/2 procedure Delete (Container : in out Vector; Index : in Extended_Index; Count : in Count_Type := 1); 182/3 If Index is not in the range First_Index (Container) .. Last_Index (Container) + 1, then Constraint_Error is propagated. If Count is 0, Delete has no effect. Otherwise, Delete slides the elements (if any) starting at position Index + Count down to Index. Any exception raised during element assignment is propagated. 183/2 procedure Delete (Container : in out Vector; Position : in out Cursor; Count : in Count_Type := 1); 184/2 If Position equals No_Element, then Constraint_Error is propagated. If Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Delete (Container, To_Index (Position), Count) is called, and then Position is set to No_Element. 185/2 procedure Delete_First (Container : in out Vector; Count : in Count_Type := 1); 186/2 Equivalent to Delete (Container, First_Index (Container), Count). 187/2 procedure Delete_Last (Container : in out Vector; Count : in Count_Type := 1); 188/3 If Length (Container) <= Count, then Delete_Last is equivalent to Clear (Container). Otherwise, it is equivalent to Delete (Container, Index_Type'Val(Index_Type'Pos(Last_Index (Container)) - Count + 1), Count). 189/2 procedure Reverse_Elements (Container : in out Vector); 190/2 Reorders the elements of Container in reverse order. 191/2 procedure Swap (Container : in out Vector; I, J : in Index_Type); 192/2 If either I or J is not in the range First_Index (Container) .. Last_Index (Container), then Constraint_Error is propagated. Otherwise, Swap exchanges the values of the elements at positions I and J. 193/2 procedure Swap (Container : in out Vector; I, J : in Cursor); 194/2 If either I or J is No_Element, then Constraint_Error is propagated. If either I or J do not designate an element in Container, then Program_Error is propagated. Otherwise, Swap exchanges the values of the elements designated by I and J. 195/2 function First_Index (Container : Vector) return Index_Type; 196/2 Returns the value Index_Type'First. 197/2 function First (Container : Vector) return Cursor; 198/2 If Container is empty, First returns No_Element. Otherwise, it returns a cursor that designates the first element in Container. 199/2 function First_Element (Container : Vector) return Element_Type; 200/2 Equivalent to Element (Container, First_Index (Container)). 201/2 function Last_Index (Container : Vector) return Extended_Index; 202/2 If Container is empty, Last_Index returns No_Index. Otherwise, it returns the position of the last element in Container. 203/2 function Last (Container : Vector) return Cursor; 204/2 If Container is empty, Last returns No_Element. Otherwise, it returns a cursor that designates the last element in Container. 205/2 function Last_Element (Container : Vector) return Element_Type; 206/2 Equivalent to Element (Container, Last_Index (Container)). 207/2 function Next (Position : Cursor) return Cursor; 208/2 If Position equals No_Element or designates the last element of the container, then Next returns the value No_Element. Otherwise, it returns a cursor that designates the element with index To_Index (Position) + 1 in the same vector as Position. 209/2 procedure Next (Position : in out Cursor); 210/2 Equivalent to Position := Next (Position). 211/2 function Previous (Position : Cursor) return Cursor; 212/2 If Position equals No_Element or designates the first element of the container, then Previous returns the value No_Element. Otherwise, it returns a cursor that designates the element with index To_Index (Position) - 1 in the same vector as Position. 213/2 procedure Previous (Position : in out Cursor); 214/2 Equivalent to Position := Previous (Position). 215/2 function Find_Index (Container : Vector; Item : Element_Type; Index : Index_Type := Index_Type'First) return Extended_Index; 216/2 Searches the elements of Container for an element equal to Item (using the generic formal equality operator). The search starts at position Index and proceeds towards Last_Index (Container). If no equal element is found, then Find_Index returns No_Index. Otherwise, it returns the index of the first equal element encountered. 217/2 function Find (Container : Vector; Item : Element_Type; Position : Cursor := No_Element) return Cursor; 218/3 If Position is not No_Element, and does not designate an element in Container, then Program_Error is propagated. Otherwise, Find searches the elements of Container for an element equal to Item (using the generic formal equality operator). The search starts at the first element if Position equals No_Element, and at the element designated by Position otherwise. It proceeds towards the last element of Container. If no equal element is found, then Find returns No_Element. Otherwise, it returns a cursor designating the first equal element encountered. 219/2 function Reverse_Find_Index (Container : Vector; Item : Element_Type; Index : Index_Type := Index_Type'Last) return Extended_Index; 220/2 Searches the elements of Container for an element equal to Item (using the generic formal equality operator). The search starts at position Index or, if Index is greater than Last_Index (Container), at position Last_Index (Container). It proceeds towards First_Index (Container). If no equal element is found, then Reverse_Find_Index returns No_Index. Otherwise, it returns the index of the first equal element encountered. 221/2 function Reverse_Find (Container : Vector; Item : Element_Type; Position : Cursor := No_Element) return Cursor; 222/3 If Position is not No_Element, and does not designate an element in Container, then Program_Error is propagated. Otherwise, Reverse_Find searches the elements of Container for an element equal to Item (using the generic formal equality operator). The search starts at the last element if Position equals No_Element, and at the element designated by Position otherwise. It proceeds towards the first element of Container. If no equal element is found, then Reverse_Find returns No_Element. Otherwise, it returns a cursor designating the first equal element encountered. 223/2 function Contains (Container : Vector; Item : Element_Type) return Boolean; 224/2 Equivalent to Has_Element (Find (Container, Item)). Paragraphs 225 and 226 were moved above. 227/2 procedure Iterate (Container : in Vector; Process : not null access procedure (Position : in Cursor)); 228/3 Invokes Process.all with a cursor that designates each element in Container, in index order. Tampering with the cursors of Container is prohibited during the execution of a call on Process.all. Any exception raised by Process.all is propagated. 229/2 procedure Reverse_Iterate (Container : in Vector; Process : not null access procedure (Position : in Cursor)); 230/3 Iterates over the elements in Container as per procedure Iterate, except that elements are traversed in reverse index order. 230.1/3 function Iterate (Container : in Vector) return Vector_Iterator_Interfaces.Reversible_Iterator'Class; 230.2/3 Iterate returns a reversible iterator object (see 5.5.1) that will generate a value for a loop parameter (see 5.5.2) designating each node in Container, starting with the first node and moving the cursor as per the Next function when used as a forward iterator, and starting with the last node and moving the cursor as per the Previous function when used as a reverse iterator. Tampering with the cursors of Container is prohibited while the iterator object exists (in particular, in the sequence_of_statements of the loop_statement whose iterator_specification denotes this object). The iterator object needs finalization. 230.3/3 function Iterate (Container : in Vector; Start : in Cursor) return Vector_Iterator_Interfaces.Reversible_Iterator'Class; 230.4/3 If Start is not No_Element and does not designate an item in Container, then Program_Error is propagated. If Start is No_Element, then Constraint_Error is propagated. Otherwise, Iterate returns a reversible iterator object (see 5.5.1) that will generate a value for a loop parameter (see 5.5.2) designating each node in Container, starting with the node designated by Start and moving the cursor as per the Next function when used as a forward iterator, or moving the cursor as per the Previous function when used as a reverse iterator. Tampering with the cursors of Container is prohibited while the iterator object exists (in particular, in the sequence_of_statements of the loop_statement whose iterator_specification denotes this object). The iterator object needs finalization. 231/3 The actual function for the generic formal function "<" of Generic_Sorting is expected to return the same value each time it is called with a particular pair of element values. It should define a strict weak ordering relationship (see A.18); it should not modify Container. If the actual for "<" behaves in some other manner, the behavior of the subprograms of Generic_Sorting are unspecified. The number of times the subprograms of Generic_Sorting call "<" is unspecified. 232/2 function Is_Sorted (Container : Vector) return Boolean; 233/2 Returns True if the elements are sorted smallest first as determined by the generic formal "<" operator; otherwise, Is_Sorted returns False. Any exception raised during evaluation of "<" is propagated. 234/2 procedure Sort (Container : in out Vector); 235/2 Reorders the elements of Container such that the elements are sorted smallest first as determined by the generic formal "<" operator provided. Any exception raised during evaluation of "<" is propagated. 236/2 procedure Merge (Target : in out Vector; Source : in out Vector); 237/3 If Source is empty, then Merge does nothing. If Source and Target are the same nonempty container object, then Program_Error is propagated. Otherwise, Merge removes elements from Source and inserts them into Target; afterwards, Target contains the union of the elements that were initially in Source and Target; Source is left empty. If Target and Source are initially sorted smallest first, then Target is ordered smallest first as determined by the generic formal "<" operator; otherwise, the order of elements in Target is unspecified. Any exception raised during evaluation of "<" is propagated. Bounded (Run-Time) Errors 238/3 Reading the value of an empty element by calling Element, Query_Element, Update_Element, Constant_Reference, Reference, Swap, Is_Sorted, Sort, Merge, "=", Find, or Reverse_Find is a bounded error. The implementation may treat the element as having any normal value (see 13.9.1) of the element type, or raise Constraint_Error or Program_Error before modifying the vector. 239/2 Calling Merge in an instance of Generic_Sorting with either Source or Target not ordered smallest first using the provided generic formal "<" operator is a bounded error. Either Program_Error is raised after Target is updated as described for Merge, or the operation works as defined. 239.1/3 It is a bounded error for the actual function associated with a generic formal subprogram, when called as part of an operation of this package, to tamper with elements of any Vector parameter of the operation. Either Program_Error is raised, or the operation works as defined on the value of the Vector either prior to, or subsequent to, some or all of the modifications to the Vector. 239.2/3 It is a bounded error to call any subprogram declared in the visible part of Containers.Vectors when the associated container has been finalized. If the operation takes Container as an in out parameter, then it raises Constraint_Error or Program_Error. Otherwise, the operation either proceeds as it would for an empty container, or it raises Constraint_Error or Program_Error. 240/2 A Cursor value is ambiguous if any of the following have occurred since it was created: 241/2 * Insert, Insert_Space, or Delete has been called on the vector that contains the element the cursor designates with an index value (or a cursor designating an element at such an index value) less than or equal to the index value of the element designated by the cursor; or 242/2 * The vector that contains the element it designates has been passed to the Sort or Merge procedures of an instance of Generic_Sorting, or to the Reverse_Elements procedure. 243/2 It is a bounded error to call any subprogram other than "=" or Has_Element declared in Containers.Vectors with an ambiguous (but not invalid, see below) cursor parameter. Possible results are: 244/2 * The cursor may be treated as if it were No_Element; 245/2 * The cursor may designate some element in the vector (but not necessarily the element that it originally designated); 246/2 * Constraint_Error may be raised; or 247/2 * Program_Error may be raised. Erroneous Execution 248/2 A Cursor value is invalid if any of the following have occurred since it was created: 249/2 * The vector that contains the element it designates has been finalized; 249.1/3 * The vector that contains the element it designates has been used as the Target of a call to Assign, or as the target of an assignment_statement; 250/2 * The vector that contains the element it designates has been used as the Source or Target of a call to Move; or 251/3 * The element it designates has been deleted or removed from the vector that previously contained the element. 252/2 The result of "=" or Has_Element is unspecified if it is called with an invalid cursor parameter. Execution is erroneous if any other subprogram declared in Containers.Vectors is called with an invalid cursor parameter. 252.1/3 Execution is erroneous if the vector associated with the result of a call to Reference or Constant_Reference is finalized before the result object returned by the call to Reference or Constant_Reference is finalized. Implementation Requirements 253/2 No storage associated with a vector object shall be lost upon assignment or scope exit. 254/3 The execution of an assignment_statement for a vector shall have the effect of copying the elements from the source vector object to the target vector object and changing the length of the target object to that of the source object. Implementation Advice 255/2 Containers.Vectors should be implemented similarly to an array. In particular, if the length of a vector is N, then 256/2 * the worst-case time complexity of Element should be O(log N); 257/2 * the worst-case time complexity of Append with Count=1 when N is less than the capacity of the vector should be O(log N); and 258/2 * the worst-case time complexity of Prepend with Count=1 and Delete_First with Count=1 should be O(N log N). 259/2 The worst-case time complexity of a call on procedure Sort of an instance of Containers.Vectors.Generic_Sorting should be O(N**2), and the average time complexity should be better than O(N**2). 260/2 Containers.Vectors.Generic_Sorting.Sort and Containers.Vectors.Generic_Sorting.Merge should minimize copying of elements. 261/2 Move should not copy elements, and should minimize copying of internal data structures. 262/2 If an exception is propagated from a vector operation, no storage should be lost, nor any elements removed from a vector unless specified by the operation. NOTES 263/2 48 All elements of a vector occupy locations in the internal array. If a sparse container is required, a Hashed_Map should be used rather than a vector. 264/2 49 If Index_Type'Base'First = Index_Type'First an instance of Ada.Containers.Vectors will raise Constraint_Error. A value below Index_Type'First is required so that an empty vector has a meaningful value of Last_Index. A.18.3 The Generic Package Containers.Doubly_Linked_Lists 1/2 The language-defined generic package Containers.Doubly_Linked_Lists provides private types List and Cursor, and a set of operations for each type. A list container is optimized for insertion and deletion at any position. 2/2 A doubly-linked list container object manages a linked list of internal nodes, each of which contains an element and pointers to the next (successor) and previous (predecessor) internal nodes. A cursor designates a particular node within a list (and by extension the element contained in that node). A cursor keeps designating the same node (and element) as long as the node is part of the container, even if the node is moved in the container. 3/2 The length of a list is the number of elements it contains. Static Semantics 4/2 The generic library package Containers.Doubly_Linked_Lists has the following declaration: 5/3 with Ada.Iterator_Interfaces; generic type Element_Type is private; with function "=" (Left, Right : Element_Type) return Boolean is <>; package Ada.Containers.Doubly_Linked_Lists is pragma Preelaborate(Doubly_Linked_Lists); pragma Remote_Types(Doubly_Linked_Lists); 6/3 type List is tagged private with Constant_Indexing => Constant_Reference, Variable_Indexing => Reference, Default_Iterator => Iterate, Iterator_Element => Element_Type; pragma Preelaborable_Initialization(List); 7/2 type Cursor is private; pragma Preelaborable_Initialization(Cursor); 8/2 Empty_List : constant List; 9/2 No_Element : constant Cursor; 9.1/3 function Has_Element (Position : Cursor) return Boolean; 9.2/3 package List_Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, Has_Element); 10/2 function "=" (Left, Right : List) return Boolean; 11/2 function Length (Container : List) return Count_Type; 12/2 function Is_Empty (Container : List) return Boolean; 13/2 procedure Clear (Container : in out List); 14/2 function Element (Position : Cursor) return Element_Type; 15/2 procedure Replace_Element (Container : in out List; Position : in Cursor; New_Item : in Element_Type); 16/2 procedure Query_Element (Position : in Cursor; Process : not null access procedure (Element : in Element_Type)); 17/2 procedure Update_Element (Container : in out List; Position : in Cursor; Process : not null access procedure (Element : in out Element_Type)); 17.1/3 type Constant_Reference_Type (Element : not null access constant Element_Type) is private with Implicit_Dereference => Element; 17.2/3 type Reference_Type (Element : not null access Element_Type) is private with Implicit_Dereference => Element; 17.3/3 function Constant_Reference (Container : aliased in List; Position : in Cursor) return Constant_Reference_Type; 17.4/3 function Reference (Container : aliased in out List; Position : in Cursor) return Reference_Type; 17.5/3 procedure Assign (Target : in out List; Source : in List); 17.6/3 function Copy (Source : List) return List; 18/2 procedure Move (Target : in out List; Source : in out List); 19/2 procedure Insert (Container : in out List; Before : in Cursor; New_Item : in Element_Type; Count : in Count_Type := 1); 20/2 procedure Insert (Container : in out List; Before : in Cursor; New_Item : in Element_Type; Position : out Cursor; Count : in Count_Type := 1); 21/2 procedure Insert (Container : in out List; Before : in Cursor; Position : out Cursor; Count : in Count_Type := 1); 22/2 procedure Prepend (Container : in out List; New_Item : in Element_Type; Count : in Count_Type := 1); 23/2 procedure Append (Container : in out List; New_Item : in Element_Type; Count : in Count_Type := 1); 24/2 procedure Delete (Container : in out List; Position : in out Cursor; Count : in Count_Type := 1); 25/2 procedure Delete_First (Container : in out List; Count : in Count_Type := 1); 26/2 procedure Delete_Last (Container : in out List; Count : in Count_Type := 1); 27/2 procedure Reverse_Elements (Container : in out List); 28/2 procedure Swap (Container : in out List; I, J : in Cursor); 29/2 procedure Swap_Links (Container : in out List; I, J : in Cursor); 30/2 procedure Splice (Target : in out List; Before : in Cursor; Source : in out List); 31/2 procedure Splice (Target : in out List; Before : in Cursor; Source : in out List; Position : in out Cursor); 32/2 procedure Splice (Container: in out List; Before : in Cursor; Position : in Cursor); 33/2 function First (Container : List) return Cursor; 34/2 function First_Element (Container : List) return Element_Type; 35/2 function Last (Container : List) return Cursor; 36/2 function Last_Element (Container : List) return Element_Type; 37/2 function Next (Position : Cursor) return Cursor; 38/2 function Previous (Position : Cursor) return Cursor; 39/2 procedure Next (Position : in out Cursor); 40/2 procedure Previous (Position : in out Cursor); 41/2 function Find (Container : List; Item : Element_Type; Position : Cursor := No_Element) return Cursor; 42/2 function Reverse_Find (Container : List; Item : Element_Type; Position : Cursor := No_Element) return Cursor; 43/2 function Contains (Container : List; Item : Element_Type) return Boolean; 44/3 This paragraph was deleted. 45/2 procedure Iterate (Container : in List; Process : not null access procedure (Position : in Cursor)); 46/2 procedure Reverse_Iterate (Container : in List; Process : not null access procedure (Position : in Cursor)); 46.1/3 function Iterate (Container : in List) return List_Iterator_Interfaces.Reversible_Iterator'Class; 46.2/3 function Iterate (Container : in List; Start : in Cursor) return List_Iterator_Interfaces.Reversible_Iterator'Class; 47/2 generic with function "<" (Left, Right : Element_Type) return Boolean is <>; package Generic_Sorting is 48/2 function Is_Sorted (Container : List) return Boolean; 49/2 procedure Sort (Container : in out List); 50/2 procedure Merge (Target : in out List; Source : in out List); 51/2 end Generic_Sorting; 52/2 private 53/2 ... -- not specified by the language 54/2 end Ada.Containers.Doubly_Linked_Lists; 55/2 The actual function for the generic formal function "=" on Element_Type values is expected to define a reflexive and symmetric relationship and return the same result value each time it is called with a particular pair of values. If it behaves in some other manner, the functions Find, Reverse_Find, and "=" on list values return an unspecified value. The exact arguments and number of calls of this generic formal function by the functions Find, Reverse_Find, and "=" on list values are unspecified. 56/2 The type List is used to represent lists. The type List needs finalization (see 7.6). 57/2 Empty_List represents the empty List object. It has a length of 0. If an object of type List is not otherwise initialized, it is initialized to the same value as Empty_List. 58/2 No_Element represents a cursor that designates no element. If an object of type Cursor is not otherwise initialized, it is initialized to the same value as No_Element. 59/2 The predefined "=" operator for type Cursor returns True if both cursors are No_Element, or designate the same element in the same container. 60/2 Execution of the default implementation of the Input, Output, Read, or Write attribute of type Cursor raises Program_Error. 60.1/3 List'Write for a List object L writes Length(L) elements of the list to the stream. It also may write additional information about the list. 60.2/3 List'Read reads the representation of a list from the stream, and assigns to Item a list with the same length and elements as was written by List'Write. 61/2 Some operations of this generic package have access-to-subprogram parameters. To ensure such operations are well-defined, they guard against certain actions by the designated subprogram. In particular, some operations check for "tampering with cursors" of a container because they depend on the set of elements of the container remaining constant, and others check for " tampering with elements" of a container because they depend on elements of the container not being replaced. 62/2 A subprogram is said to tamper with cursors of a list object L if: 63/2 * it inserts or deletes elements of L, that is, it calls the Insert, Clear, Delete, or Delete_Last procedures with L as a parameter; or 64/2 * it reorders the elements of L, that is, it calls the Splice, Swap_Links, or Reverse_Elements procedures or the Sort or Merge procedures of an instance of Generic_Sorting with L as a parameter; or 65/2 * it finalizes L; or 65.1/3 * it calls the Assign procedure with L as the Target parameter; or 66/2 * it calls the Move procedure with L as a parameter. 67/2 A subprogram is said to tamper with elements of a list object L if: 68/2 * it tampers with cursors of L; or 69/2 * it replaces one or more elements of L, that is, it calls the Replace_Element or Swap procedures with L as a parameter. 69.1/4 When tampering with cursors is prohibited for a particular list object L, Program_Error is propagated by a call of any language-defined subprogram that is defined to tamper with the cursors of L, leaving L unmodified. Similarly, when tampering with elements is prohibited for a particular list object L, Program_Error is propagated by a call of any language-defined subprogram that is defined to tamper with the elements of L (or tamper with the cursors of L), leaving L unmodified. These checks are made before any other defined behavior of the body of the language-defined subprogram. 69.2/3 function Has_Element (Position : Cursor) return Boolean; 69.3/3 Returns True if Position designates an element, and returns False otherwise. 70/2 function "=" (Left, Right : List) return Boolean; 71/3 If Left and Right denote the same list object, then the function returns True. If Left and Right have different lengths, then the function returns False. Otherwise, it compares each element in Left to the corresponding element in Right using the generic formal equality operator. If any such comparison returns False, the function returns False; otherwise, it returns True. Any exception raised during evaluation of element equality is propagated. 72/2 function Length (Container : List) return Count_Type; 73/2 Returns the number of elements in Container. 74/2 function Is_Empty (Container : List) return Boolean; 75/2 Equivalent to Length (Container) = 0. 76/2 procedure Clear (Container : in out List); 77/2 Removes all the elements from Container. 78/2 function Element (Position : Cursor) return Element_Type; 79/2 If Position equals No_Element, then Constraint_Error is propagated. Otherwise, Element returns the element designated by Position. 80/2 procedure Replace_Element (Container : in out List; Position : in Cursor; New_Item : in Element_Type); 81/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Replace_Element assigns the value New_Item to the element designated by Position. 82/2 procedure Query_Element (Position : in Cursor; Process : not null access procedure (Element : in Element_Type)); 83/3 If Position equals No_Element, then Constraint_Error is propagated. Otherwise, Query_Element calls Process.all with the element designated by Position as the argument. Tampering with the elements of the list that contains the element designated by Position is prohibited during the execution of the call on Process.all. Any exception raised by Process.all is propagated. 84/2 procedure Update_Element (Container : in out List; Position : in Cursor; Process : not null access procedure (Element : in out Element_Type)); 85/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Update_Element calls Process.all with the element designated by Position as the argument. Tampering with the elements of Container is prohibited during the execution of the call on Process.all. Any exception raised by Process.all is propagated. 86/2 If Element_Type is unconstrained and definite, then the actual Element parameter of Process.all shall be unconstrained. 86.1/3 type Constant_Reference_Type (Element : not null access constant Element_Type) is private with Implicit_Dereference => Element; 86.2/3 type Reference_Type (Element : not null access Element_Type) is private with Implicit_Dereference => Element; 86.3/3 The types Constant_Reference_Type and Reference_Type need finalization. 86.4/3 The default initialization of an object of type Constant_Reference_Type or Reference_Type propagates Program_Error. 86.5/3 function Constant_Reference (Container : aliased in List; Position : in Cursor) return Constant_Reference_Type; 86.6/3 This function (combined with the Constant_Indexing and Implicit_Dereference aspects) provides a convenient way to gain read access to an individual element of a list given a cursor. 86.7/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Constant_Reference returns an object whose discriminant is an access value that designates the element designated by Position. Tampering with the elements of Container is prohibited while the object returned by Constant_Reference exists and has not been finalized. 86.8/3 function Reference (Container : aliased in out List; Position : in Cursor) return Reference_Type; 86.9/3 This function (combined with the Variable_Indexing and Implicit_Dereference aspects) provides a convenient way to gain read and write access to an individual element of a list given a cursor. 86.10/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Reference returns an object whose discriminant is an access value that designates the element designated by Position. Tampering with the elements of Container is prohibited while the object returned by Reference exists and has not been finalized. 86.11/3 procedure Assign (Target : in out List; Source : in List); 86.12/3 If Target denotes the same object as Source, the operation has no effect. Otherwise, the elements of Source are copied to Target as for an assignment_statement assigning Source to Target. 86.13/3 function Copy (Source : List) return List; 86.14/3 Returns a list whose elements match the elements of Source. 87/2 procedure Move (Target : in out List; Source : in out List); 88/3 If Target denotes the same object as Source, then the operation has no effect. Otherwise, the operation is equivalent to Assign (Target, Source) followed by Clear (Source). 89/2 procedure Insert (Container : in out List; Before : in Cursor; New_Item : in Element_Type; Count : in Count_Type := 1); 90/2 If Before is not No_Element, and does not designate an element in Container, then Program_Error is propagated. Otherwise, Insert inserts Count copies of New_Item prior to the element designated by Before. If Before equals No_Element, the new elements are inserted after the last node (if any). Any exception raised during allocation of internal storage is propagated, and Container is not modified. 91/2 procedure Insert (Container : in out List; Before : in Cursor; New_Item : in Element_Type; Position : out Cursor; Count : in Count_Type := 1); 92/3 If Before is not No_Element, and does not designate an element in Container, then Program_Error is propagated. Otherwise, Insert allocates Count copies of New_Item, and inserts them prior to the element designated by Before. If Before equals No_Element, the new elements are inserted after the last element (if any). Position designates the first newly-inserted element, or if Count equals 0, then Position is assigned the value of Before. Any exception raised during allocation of internal storage is propagated, and Container is not modified. 93/2 procedure Insert (Container : in out List; Before : in Cursor; Position : out Cursor; Count : in Count_Type := 1); 94/3 If Before is not No_Element, and does not designate an element in Container, then Program_Error is propagated. Otherwise, Insert inserts Count new elements prior to the element designated by Before. If Before equals No_Element, the new elements are inserted after the last node (if any). The new elements are initialized by default (see 3.3.1). Position designates the first newly-inserted element, or if Count equals 0, then Position is assigned the value of Before. Any exception raised during allocation of internal storage is propagated, and Container is not modified. 95/2 procedure Prepend (Container : in out List; New_Item : in Element_Type; Count : in Count_Type := 1); 96/2 Equivalent to Insert (Container, First (Container), New_Item, Count). 97/2 procedure Append (Container : in out List; New_Item : in Element_Type; Count : in Count_Type := 1); 98/2 Equivalent to Insert (Container, No_Element, New_Item, Count). 99/2 procedure Delete (Container : in out List; Position : in out Cursor; Count : in Count_Type := 1); 100/3 If Position equals No_Element, then Constraint_Error is propagated. If Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Delete removes (from Container) Count elements starting at the element designated by Position (or all of the elements starting at Position if there are fewer than Count elements starting at Position). Finally, Position is set to No_Element. 101/2 procedure Delete_First (Container : in out List; Count : in Count_Type := 1); 102/3 If Length (Container) <= Count, then Delete_First is equivalent to Clear (Container). Otherwise, it removes the first Count nodes from Container. 103/2 procedure Delete_Last (Container : in out List; Count : in Count_Type := 1); 104/3 If Length (Container) <= Count, then Delete_Last is equivalent to Clear (Container). Otherwise, it removes the last Count nodes from Container. 105/2 procedure Reverse_Elements (Container : in out List); 106/2 Reorders the elements of Container in reverse order. 107/2 procedure Swap (Container : in out List; I, J : in Cursor); 108/2 If either I or J is No_Element, then Constraint_Error is propagated. If either I or J do not designate an element in Container, then Program_Error is propagated. Otherwise, Swap exchanges the values of the elements designated by I and J. 109/2 procedure Swap_Links (Container : in out List; I, J : in Cursor); 110/2 If either I or J is No_Element, then Constraint_Error is propagated. If either I or J do not designate an element in Container, then Program_Error is propagated. Otherwise, Swap_Links exchanges the nodes designated by I and J. 111/2 procedure Splice (Target : in out List; Before : in Cursor; Source : in out List); 112/2 If Before is not No_Element, and does not designate an element in Target, then Program_Error is propagated. Otherwise, if Source denotes the same object as Target, the operation has no effect. Otherwise, Splice reorders elements such that they are removed from Source and moved to Target, immediately prior to Before. If Before equals No_Element, the nodes of Source are spliced after the last node of Target. The length of Target is incremented by the number of nodes in Source, and the length of Source is set to 0. 113/2 procedure Splice (Target : in out List; Before : in Cursor; Source : in out List; Position : in out Cursor); 114/3 If Position is No_Element, then Constraint_Error is propagated. If Before does not equal No_Element, and does not designate an element in Target, then Program_Error is propagated. If Position does not equal No_Element, and does not designate a node in Source, then Program_Error is propagated. If Source denotes the same object as Target, then there is no effect if Position equals Before, else the element designated by Position is moved immediately prior to Before, or, if Before equals No_Element, after the last element. In both cases, Position and the length of Target are unchanged. Otherwise, the element designated by Position is removed from Source and moved to Target, immediately prior to Before, or, if Before equals No_Element, after the last element of Target. The length of Target is incremented, the length of Source is decremented, and Position is updated to represent an element in Target. 115/2 procedure Splice (Container: in out List; Before : in Cursor; Position : in Cursor); 116/3 If Position is No_Element, then Constraint_Error is propagated. If Before does not equal No_Element, and does not designate an element in Container, then Program_Error is propagated. If Position does not equal No_Element, and does not designate a node in Container, then Program_Error is propagated. If Position equals Before there is no effect. Otherwise, the element designated by Position is moved immediately prior to Before, or, if Before equals No_Element, after the last element. The length of Container is unchanged. 117/2 function First (Container : List) return Cursor; 118/3 If Container is empty, First returns the value No_Element. Otherwise, it returns a cursor that designates the first node in Container. 119/2 function First_Element (Container : List) return Element_Type; 120/2 Equivalent to Element (First (Container)). 121/2 function Last (Container : List) return Cursor; 122/3 If Container is empty, Last returns the value No_Element. Otherwise, it returns a cursor that designates the last node in Container. 123/2 function Last_Element (Container : List) return Element_Type; 124/2 Equivalent to Element (Last (Container)). 125/2 function Next (Position : Cursor) return Cursor; 126/2 If Position equals No_Element or designates the last element of the container, then Next returns the value No_Element. Otherwise, it returns a cursor that designates the successor of the element designated by Position. 127/2 function Previous (Position : Cursor) return Cursor; 128/2 If Position equals No_Element or designates the first element of the container, then Previous returns the value No_Element. Otherwise, it returns a cursor that designates the predecessor of the element designated by Position. 129/2 procedure Next (Position : in out Cursor); 130/2 Equivalent to Position := Next (Position). 131/2 procedure Previous (Position : in out Cursor); 132/2 Equivalent to Position := Previous (Position). 133/2 function Find (Container : List; Item : Element_Type; Position : Cursor := No_Element) return Cursor; 134/2 If Position is not No_Element, and does not designate an element in Container, then Program_Error is propagated. Find searches the elements of Container for an element equal to Item (using the generic formal equality operator). The search starts at the element designated by Position, or at the first element if Position equals No_Element. It proceeds towards Last (Container). If no equal element is found, then Find returns No_Element. Otherwise, it returns a cursor designating the first equal element encountered. 135/2 function Reverse_Find (Container : List; Item : Element_Type; Position : Cursor := No_Element) return Cursor; 136/2 If Position is not No_Element, and does not designate an element in Container, then Program_Error is propagated. Find searches the elements of Container for an element equal to Item (using the generic formal equality operator). The search starts at the element designated by Position, or at the last element if Position equals No_Element. It proceeds towards First (Container). If no equal element is found, then Reverse_Find returns No_Element. Otherwise, it returns a cursor designating the first equal element encountered. 137/2 function Contains (Container : List; Item : Element_Type) return Boolean; 138/2 Equivalent to Find (Container, Item) /= No_Element. Paragraphs 139 and 140 were moved above. 141/2 procedure Iterate (Container : in List; Process : not null access procedure (Position : in Cursor)); 142/3 Iterate calls Process.all with a cursor that designates each node in Container, starting with the first node and moving the cursor as per the Next function. Tampering with the cursors of Container is prohibited during the execution of a call on Process.all. Any exception raised by Process.all is propagated. 143/2 procedure Reverse_Iterate (Container : in List; Process : not null access procedure (Position : in Cursor)); 144/3 Iterates over the nodes in Container as per procedure Iterate, except that elements are traversed in reverse order, starting with the last node and moving the cursor as per the Previous function. 144.1/3 function Iterate (Container : in List) return List_Iterator_Interfaces.Reversible_Iterator'Class; 144.2/3 Iterate returns a reversible iterator object (see 5.5.1) that will generate a value for a loop parameter (see 5.5.2) designating each node in Container, starting with the first node and moving the cursor as per the Next function when used as a forward iterator, and starting with the last node and moving the cursor as per the Previous function when used as a reverse iterator. Tampering with the cursors of Container is prohibited while the iterator object exists (in particular, in the sequence_of_statements of the loop_statement whose iterator_specification denotes this object). The iterator object needs finalization. 144.3/3 function Iterate (Container : in List; Start : in Cursor) return List_Iterator_Interfaces.Reversible_Iterator'Class; 144.4/3 If Start is not No_Element and does not designate an item in Container, then Program_Error is propagated. If Start is No_Element, then Constraint_Error is propagated. Otherwise, Iterate returns a reversible iterator object (see 5.5.1) that will generate a value for a loop parameter (see 5.5.2) designating each node in Container, starting with the node designated by Start and moving the cursor as per the Next function when used as a forward iterator, or moving the cursor as per the Previous function when used as a reverse iterator. Tampering with the cursors of Container is prohibited while the iterator object exists (in particular, in the sequence_of_statements of the loop_statement whose iterator_specification denotes this object). The iterator object needs finalization. 145/3 The actual function for the generic formal function "<" of Generic_Sorting is expected to return the same value each time it is called with a particular pair of element values. It should define a strict weak ordering relationship (see A.18); it should not modify Container. If the actual for "<" behaves in some other manner, the behavior of the subprograms of Generic_Sorting are unspecified. The number of times the subprograms of Generic_Sorting call "<" is unspecified. 146/2 function Is_Sorted (Container : List) return Boolean; 147/2 Returns True if the elements are sorted smallest first as determined by the generic formal "<" operator; otherwise, Is_Sorted returns False. Any exception raised during evaluation of "<" is propagated. 148/2 procedure Sort (Container : in out List); 149/2 Reorders the nodes of Container such that the elements are sorted smallest first as determined by the generic formal "<" operator provided. The sort is stable. Any exception raised during evaluation of "<" is propagated. 150/2 procedure Merge (Target : in out List; Source : in out List); 151/3 If Source is empty, then Merge does nothing. If Source and Target are the same nonempty container object, then Program_Error is propagated. Otherwise, Merge removes elements from Source and inserts them into Target; afterwards, Target contains the union of the elements that were initially in Source and Target; Source is left empty. If Target and Source are initially sorted smallest first, then Target is ordered smallest first as determined by the generic formal "<" operator; otherwise, the order of elements in Target is unspecified. Any exception raised during evaluation of "<" is propagated. Bounded (Run-Time) Errors 152/2 Calling Merge in an instance of Generic_Sorting with either Source or Target not ordered smallest first using the provided generic formal "<" operator is a bounded error. Either Program_Error is raised after Target is updated as described for Merge, or the operation works as defined. 152.1/3 It is a bounded error for the actual function associated with a generic formal subprogram, when called as part of an operation of this package, to tamper with elements of any List parameter of the operation. Either Program_Error is raised, or the operation works as defined on the value of the List either prior to, or subsequent to, some or all of the modifications to the List. 152.2/3 It is a bounded error to call any subprogram declared in the visible part of Containers.Doubly_Linked_Lists when the associated container has been finalized. If the operation takes Container as an in out parameter, then it raises Constraint_Error or Program_Error. Otherwise, the operation either proceeds as it would for an empty container, or it raises Constraint_Error or Program_Error. Erroneous Execution 153/2 A Cursor value is invalid if any of the following have occurred since it was created: 154/2 * The list that contains the element it designates has been finalized; 154.1/3 * The list that contains the element it designates has been used as the Target of a call to Assign, or as the target of an assignment_statement; 155/2 * The list that contains the element it designates has been used as the Source or Target of a call to Move; or 156/3 * The element it designates has been removed from the list that previously contained the element. 157/2 The result of "=" or Has_Element is unspecified if it is called with an invalid cursor parameter. Execution is erroneous if any other subprogram declared in Containers.Doubly_Linked_Lists is called with an invalid cursor parameter. 157.1/3 Execution is erroneous if the list associated with the result of a call to Reference or Constant_Reference is finalized before the result object returned by the call to Reference or Constant_Reference is finalized. Implementation Requirements 158/2 No storage associated with a doubly-linked List object shall be lost upon assignment or scope exit. 159/3 The execution of an assignment_statement for a list shall have the effect of copying the elements from the source list object to the target list object and changing the length of the target object to that of the source object. Implementation Advice 160/2 Containers.Doubly_Linked_Lists should be implemented similarly to a linked list. In particular, if N is the length of a list, then the worst-case time complexity of Element, Insert with Count=1, and Delete with Count=1 should be O(log N). 161/2 The worst-case time complexity of a call on procedure Sort of an instance of Containers.Doubly_Linked_Lists.Generic_Sorting should be O(N**2), and the average time complexity should be better than O(N**2). 162/2 Move should not copy elements, and should minimize copying of internal data structures. 163/2 If an exception is propagated from a list operation, no storage should be lost, nor any elements removed from a list unless specified by the operation. NOTES 164/2 50 Sorting a list never copies elements, and is a stable sort (equal elements remain in the original order). This is different than sorting an array or vector, which may need to copy elements, and is probably not a stable sort. A.18.4 Maps 1/2 The language-defined generic packages Containers.Hashed_Maps and Containers.Ordered_Maps provide private types Map and Cursor, and a set of operations for each type. A map container allows an arbitrary type to be used as a key to find the element associated with that key. A hashed map uses a hash function to organize the keys, while an ordered map orders the keys per a specified relation. 2/3 This subclause describes the declarations that are common to both kinds of maps. See A.18.5 for a description of the semantics specific to Containers.Hashed_Maps and A.18.6 for a description of the semantics specific to Containers.Ordered_Maps. Static Semantics 3/2 The actual function for the generic formal function "=" on Element_Type values is expected to define a reflexive and symmetric relationship and return the same result value each time it is called with a particular pair of values. If it behaves in some other manner, the function "=" on map values returns an unspecified value. The exact arguments and number of calls of this generic formal function by the function "=" on map values are unspecified. 4/2 The type Map is used to represent maps. The type Map needs finalization (see 7.6). 5/2 A map contains pairs of keys and elements, called nodes. Map cursors designate nodes, but also can be thought of as designating an element (the element contained in the node) for consistency with the other containers. There exists an equivalence relation on keys, whose definition is different for hashed maps and ordered maps. A map never contains two or more nodes with equivalent keys. The length of a map is the number of nodes it contains. 6/2 Each nonempty map has two particular nodes called the first node and the last node (which may be the same). Each node except for the last node has a successor node. If there are no other intervening operations, starting with the first node and repeatedly going to the successor node will visit each node in the map exactly once until the last node is reached. The exact definition of these terms is different for hashed maps and ordered maps. 7/2 Some operations of these generic packages have access-to-subprogram parameters. To ensure such operations are well-defined, they guard against certain actions by the designated subprogram. In particular, some operations check for "tampering with cursors" of a container because they depend on the set of elements of the container remaining constant, and others check for " tampering with elements" of a container because they depend on elements of the container not being replaced. 8/2 A subprogram is said to tamper with cursors of a map object M if: 9/2 * it inserts or deletes elements of M, that is, it calls the Insert, Include, Clear, Delete, or Exclude procedures with M as a parameter; or 10/2 * it finalizes M; or 10.1/3 * it calls the Assign procedure with M as the Target parameter; or 11/2 * it calls the Move procedure with M as a parameter; or 12/2 * it calls one of the operations defined to tamper with the cursors of M. 13/2 A subprogram is said to tamper with elements of a map object M if: 14/2 * it tampers with cursors of M; or 15/2 * it replaces one or more elements of M, that is, it calls the Replace or Replace_Element procedures with M as a parameter. 15.1/4 When tampering with cursors is prohibited for a particular map object M, Program_Error is propagated by a call of any language-defined subprogram that is defined to tamper with the cursors of M, leaving M unmodified. Similarly, when tampering with elements is prohibited for a particular map object M, Program_Error is propagated by a call of any language-defined subprogram that is defined to tamper with the elements of M (or tamper with the cursors of M), leaving M unmodified. These checks are made before any other defined behavior of the body of the language-defined subprogram. 16/2 Empty_Map represents the empty Map object. It has a length of 0. If an object of type Map is not otherwise initialized, it is initialized to the same value as Empty_Map. 17/2 No_Element represents a cursor that designates no node. If an object of type Cursor is not otherwise initialized, it is initialized to the same value as No_Element. 18/2 The predefined "=" operator for type Cursor returns True if both cursors are No_Element, or designate the same element in the same container. 19/2 Execution of the default implementation of the Input, Output, Read, or Write attribute of type Cursor raises Program_Error. 19.1/3 Map'Write for a Map object M writes Length(M) elements of the map to the stream. It also may write additional information about the map. 19.2/3 Map'Read reads the representation of a map from the stream, and assigns to Item a map with the same length and elements as was written by Map'Write. 19.3/3 function Has_Element (Position : Cursor) return Boolean; 19.4/3 Returns True if Position designates an element, and returns False otherwise. 20/2 function "=" (Left, Right : Map) return Boolean; 21/2 If Left and Right denote the same map object, then the function returns True. If Left and Right have different lengths, then the function returns False. Otherwise, for each key K in Left, the function returns False if: 22/2 * a key equivalent to K is not present in Right; or 23/2 * the element associated with K in Left is not equal to the element associated with K in Right (using the generic formal equality operator for elements). 24/2 If the function has not returned a result after checking all of the keys, it returns True. Any exception raised during evaluation of key equivalence or element equality is propagated. 25/2 function Length (Container : Map) return Count_Type; 26/2 Returns the number of nodes in Container. 27/2 function Is_Empty (Container : Map) return Boolean; 28/2 Equivalent to Length (Container) = 0. 29/2 procedure Clear (Container : in out Map); 30/2 Removes all the nodes from Container. 31/2 function Key (Position : Cursor) return Key_Type; 32/2 If Position equals No_Element, then Constraint_Error is propagated. Otherwise, Key returns the key component of the node designated by Position. 33/2 function Element (Position : Cursor) return Element_Type; 34/2 If Position equals No_Element, then Constraint_Error is propagated. Otherwise, Element returns the element component of the node designated by Position. 35/2 procedure Replace_Element (Container : in out Map; Position : in Cursor; New_Item : in Element_Type); 36/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Replace_Element assigns New_Item to the element of the node designated by Position. 37/2 procedure Query_Element (Position : in Cursor; Process : not null access procedure (Key : in Key_Type; Element : in Element_Type)); 38/3 If Position equals No_Element, then Constraint_Error is propagated. Otherwise, Query_Element calls Process.all with the key and element from the node designated by Position as the arguments. Tampering with the elements of the map that contains the element designated by Position is prohibited during the execution of the call on Process.all. Any exception raised by Process.all is propagated. 39/2 procedure Update_Element (Container : in out Map; Position : in Cursor; Process : not null access procedure (Key : in Key_Type; Element : in out Element_Type)); 40/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Update_Element calls Process.all with the key and element from the node designated by Position as the arguments. Tampering with the elements of Container is prohibited during the execution of the call on Process.all. Any exception raised by Process.all is propagated. 41/2 If Element_Type is unconstrained and definite, then the actual Element parameter of Process.all shall be unconstrained. 41.1/3 type Constant_Reference_Type (Element : not null access constant Element_Type) is private with Implicit_Dereference => Element; 41.2/3 type Reference_Type (Element : not null access Element_Type) is private with Implicit_Dereference => Element; 41.3/3 The types Constant_Reference_Type and Reference_Type need finalization. 41.4/3 The default initialization of an object of type Constant_Reference_Type or Reference_Type propagates Program_Error. 41.5/3 function Constant_Reference (Container : aliased in Map; Position : in Cursor) return Constant_Reference_Type; 41.6/3 This function (combined with the Constant_Indexing and Implicit_Dereference aspects) provides a convenient way to gain read access to an individual element of a map given a cursor. 41.7/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Constant_Reference returns an object whose discriminant is an access value that designates the element designated by Position. Tampering with the elements of Container is prohibited while the object returned by Constant_Reference exists and has not been finalized. 41.8/3 function Reference (Container : aliased in out Map; Position : in Cursor) return Reference_Type; 41.9/3 This function (combined with the Variable_Indexing and Implicit_Dereference aspects) provides a convenient way to gain read and write access to an individual element of a map given a cursor. 41.10/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Reference returns an object whose discriminant is an access value that designates the element designated by Position. Tampering with the elements of Container is prohibited while the object returned by Reference exists and has not been finalized. 41.11/3 function Constant_Reference (Container : aliased in Map; Key : in Key_Type) return Constant_Reference_Type; 41.12/3 This function (combined with the Constant_Indexing and Implicit_Dereference aspects) provides a convenient way to gain read access to an individual element of a map given a key value. 41.13/3 Equivalent to Constant_Reference (Container, Find (Container, Key)). 41.14/3 function Reference (Container : aliased in out Map; Key : in Key_Type) return Reference_Type; 41.15/3 This function (combined with the Variable_Indexing and Implicit_Dereference aspects) provides a convenient way to gain read and write access to an individual element of a map given a key value. 41.16/3 Equivalent to Reference (Container, Find (Container, Key)). 41.17/3 procedure Assign (Target : in out Map; Source : in Map); 41.18/3 If Target denotes the same object as Source, the operation has no effect. Otherwise, the key/element pairs of Source are copied to Target as for an assignment_statement assigning Source to Target. 42/2 procedure Move (Target : in out Map; Source : in out Map); 43/3 If Target denotes the same object as Source, then the operation has no effect. Otherwise, the operation is equivalent to Assign (Target, Source) followed by Clear (Source). 44/2 procedure Insert (Container : in out Map; Key : in Key_Type; New_Item : in Element_Type; Position : out Cursor; Inserted : out Boolean); 45/2 Insert checks if a node with a key equivalent to Key is already present in Container. If a match is found, Inserted is set to False and Position designates the element with the matching key. Otherwise, Insert allocates a new node, initializes it to Key and New_Item, and adds it to Container; Inserted is set to True and Position designates the newly-inserted node. Any exception raised during allocation is propagated and Container is not modified. 46/2 procedure Insert (Container : in out Map; Key : in Key_Type; Position : out Cursor; Inserted : out Boolean); 47/2 Insert inserts Key into Container as per the five-parameter Insert, with the difference that an element initialized by default (see 3.3.1) is inserted. 48/2 procedure Insert (Container : in out Map; Key : in Key_Type; New_Item : in Element_Type); 49/2 Insert inserts Key and New_Item into Container as per the five-parameter Insert, with the difference that if a node with a key equivalent to Key is already in the map, then Constraint_Error is propagated. 50/2 procedure Include (Container : in out Map; Key : in Key_Type; New_Item : in Element_Type); 51/2 Include inserts Key and New_Item into Container as per the five-parameter Insert, with the difference that if a node with a key equivalent to Key is already in the map, then this operation assigns Key and New_Item to the matching node. Any exception raised during assignment is propagated. 52/2 procedure Replace (Container : in out Map; Key : in Key_Type; New_Item : in Element_Type); 53/2 Replace checks if a node with a key equivalent to Key is present in Container. If a match is found, Replace assigns Key and New_Item to the matching node; otherwise, Constraint_Error is propagated. 54/2 procedure Exclude (Container : in out Map; Key : in Key_Type); 55/2 Exclude checks if a node with a key equivalent to Key is present in Container. If a match is found, Exclude removes the node from the map. 56/2 procedure Delete (Container : in out Map; Key : in Key_Type); 57/2 Delete checks if a node with a key equivalent to Key is present in Container. If a match is found, Delete removes the node from the map; otherwise, Constraint_Error is propagated. 58/2 procedure Delete (Container : in out Map; Position : in out Cursor); 59/2 If Position equals No_Element, then Constraint_Error is propagated. If Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Delete removes the node designated by Position from the map. Position is set to No_Element on return. 60/2 function First (Container : Map) return Cursor; 61/2 If Length (Container) = 0, then First returns No_Element. Otherwise, First returns a cursor that designates the first node in Container. 62/2 function Next (Position : Cursor) return Cursor; 63/2 Returns a cursor that designates the successor of the node designated by Position. If Position designates the last node, then No_Element is returned. If Position equals No_Element, then No_Element is returned. 64/2 procedure Next (Position : in out Cursor); 65/2 Equivalent to Position := Next (Position). 66/2 function Find (Container : Map; Key : Key_Type) return Cursor; 67/2 If Length (Container) equals 0, then Find returns No_Element. Otherwise, Find checks if a node with a key equivalent to Key is present in Container. If a match is found, a cursor designating the matching node is returned; otherwise, No_Element is returned. 68/2 function Element (Container : Map; Key : Key_Type) return Element_Type; 69/2 Equivalent to Element (Find (Container, Key)). 70/2 function Contains (Container : Map; Key : Key_Type) return Boolean; 71/2 Equivalent to Find (Container, Key) /= No_Element. Paragraphs 72 and 73 were moved above. 74/2 procedure Iterate (Container : in Map; Process : not null access procedure (Position : in Cursor)); 75/3 Iterate calls Process.all with a cursor that designates each node in Container, starting with the first node and moving the cursor according to the successor relation. Tampering with the cursors of Container is prohibited during the execution of a call on Process.all. Any exception raised by Process.all is propagated. Bounded (Run-Time) Errors 75.1/3 It is a bounded error for the actual function associated with a generic formal subprogram, when called as part of an operation of a map package, to tamper with elements of any map parameter of the operation. Either Program_Error is raised, or the operation works as defined on the value of the map either prior to, or subsequent to, some or all of the modifications to the map. 75.2/3 It is a bounded error to call any subprogram declared in the visible part of a map package when the associated container has been finalized. If the operation takes Container as an in out parameter, then it raises Constraint_Error or Program_Error. Otherwise, the operation either proceeds as it would for an empty container, or it raises Constraint_Error or Program_Error. Erroneous Execution 76/2 A Cursor value is invalid if any of the following have occurred since it was created: 77/2 * The map that contains the node it designates has been finalized; 77.1/3 * The map that contains the node it designates has been used as the Target of a call to Assign, or as the target of an assignment_statement; 78/2 * The map that contains the node it designates has been used as the Source or Target of a call to Move; or 79/3 * The node it designates has been removed from the map that previously contained the node. 80/2 The result of "=" or Has_Element is unspecified if these functions are called with an invalid cursor parameter. Execution is erroneous if any other subprogram declared in Containers.Hashed_Maps or Containers.Ordered_Maps is called with an invalid cursor parameter. 80.1/3 Execution is erroneous if the map associated with the result of a call to Reference or Constant_Reference is finalized before the result object returned by the call to Reference or Constant_Reference is finalized. Implementation Requirements 81/2 No storage associated with a Map object shall be lost upon assignment or scope exit. 82/3 The execution of an assignment_statement for a map shall have the effect of copying the elements from the source map object to the target map object and changing the length of the target object to that of the source object. Implementation Advice 83/2 Move should not copy elements, and should minimize copying of internal data structures. 84/2 If an exception is propagated from a map operation, no storage should be lost, nor any elements removed from a map unless specified by the operation. A.18.5 The Generic Package Containers.Hashed_Maps Static Semantics 1/2 The generic library package Containers.Hashed_Maps has the following declaration: 2/3 with Ada.Iterator_Interfaces; generic type Key_Type is private; type Element_Type is private; with function Hash (Key : Key_Type) return Hash_Type; with function Equivalent_Keys (Left, Right : Key_Type) return Boolean; with function "=" (Left, Right : Element_Type) return Boolean is <>; package Ada.Containers.Hashed_Maps is pragma Preelaborate(Hashed_Maps); pragma Remote_Types(Hashed_Maps); 3/3 type Map is tagged private with Constant_Indexing => Constant_Reference, Variable_Indexing => Reference, Default_Iterator => Iterate, Iterator_Element => Element_Type; pragma Preelaborable_Initialization(Map); 4/2 type Cursor is private; pragma Preelaborable_Initialization(Cursor); 5/2 Empty_Map : constant Map; 6/2 No_Element : constant Cursor; 6.1/3 function Has_Element (Position : Cursor) return Boolean; 6.2/3 package Map_Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, Has_Element); 7/2 function "=" (Left, Right : Map) return Boolean; 8/2 function Capacity (Container : Map) return Count_Type; 9/2 procedure Reserve_Capacity (Container : in out Map; Capacity : in Count_Type); 10/2 function Length (Container : Map) return Count_Type; 11/2 function Is_Empty (Container : Map) return Boolean; 12/2 procedure Clear (Container : in out Map); 13/2 function Key (Position : Cursor) return Key_Type; 14/2 function Element (Position : Cursor) return Element_Type; 15/2 procedure Replace_Element (Container : in out Map; Position : in Cursor; New_Item : in Element_Type); 16/2 procedure Query_Element (Position : in Cursor; Process : not null access procedure (Key : in Key_Type; Element : in Element_Type)); 17/2 procedure Update_Element (Container : in out Map; Position : in Cursor; Process : not null access procedure (Key : in Key_Type; Element : in out Element_Type)); 17.1/3 type Constant_Reference_Type (Element : not null access constant Element_Type) is private with Implicit_Dereference => Element; 17.2/3 type Reference_Type (Element : not null access Element_Type) is private with Implicit_Dereference => Element; 17.3/3 function Constant_Reference (Container : aliased in Map; Position : in Cursor) return Constant_Reference_Type; 17.4/3 function Reference (Container : aliased in out Map; Position : in Cursor) return Reference_Type; 17.5/3 function Constant_Reference (Container : aliased in Map; Key : in Key_Type) return Constant_Reference_Type; 17.6/3 function Reference (Container : aliased in out Map; Key : in Key_Type) return Reference_Type; 17.7/3 procedure Assign (Target : in out Map; Source : in Map); 17.8/3 function Copy (Source : Map; Capacity : Count_Type := 0) return Map; 18/2 procedure Move (Target : in out Map; Source : in out Map); 19/2 procedure Insert (Container : in out Map; Key : in Key_Type; New_Item : in Element_Type; Position : out Cursor; Inserted : out Boolean); 20/2 procedure Insert (Container : in out Map; Key : in Key_Type; Position : out Cursor; Inserted : out Boolean); 21/2 procedure Insert (Container : in out Map; Key : in Key_Type; New_Item : in Element_Type); 22/2 procedure Include (Container : in out Map; Key : in Key_Type; New_Item : in Element_Type); 23/2 procedure Replace (Container : in out Map; Key : in Key_Type; New_Item : in Element_Type); 24/2 procedure Exclude (Container : in out Map; Key : in Key_Type); 25/2 procedure Delete (Container : in out Map; Key : in Key_Type); 26/2 procedure Delete (Container : in out Map; Position : in out Cursor); 27/2 function First (Container : Map) return Cursor; 28/2 function Next (Position : Cursor) return Cursor; 29/2 procedure Next (Position : in out Cursor); 30/2 function Find (Container : Map; Key : Key_Type) return Cursor; 31/2 function Element (Container : Map; Key : Key_Type) return Element_Type; 32/2 function Contains (Container : Map; Key : Key_Type) return Boolean; 33/3 This paragraph was deleted. 34/2 function Equivalent_Keys (Left, Right : Cursor) return Boolean; 35/2 function Equivalent_Keys (Left : Cursor; Right : Key_Type) return Boolean; 36/2 function Equivalent_Keys (Left : Key_Type; Right : Cursor) return Boolean; 37/2 procedure Iterate (Container : in Map; Process : not null access procedure (Position : in Cursor)); 37.1/3 function Iterate (Container : in Map) return Map_Iterator_Interfaces.Forward_Iterator'Class; 38/2 private 39/2 ... -- not specified by the language 40/2 end Ada.Containers.Hashed_Maps; 41/2 An object of type Map contains an expandable hash table, which is used to provide direct access to nodes. The capacity of an object of type Map is the maximum number of nodes that can be inserted into the hash table prior to it being automatically expanded. 42/2 Two keys K1 and K2 are defined to be equivalent if Equivalent_Keys (K1, K2) returns True. 43/2 The actual function for the generic formal function Hash is expected to return the same value each time it is called with a particular key value. For any two equivalent key values, the actual for Hash is expected to return the same value. If the actual for Hash behaves in some other manner, the behavior of this package is unspecified. Which subprograms of this package call Hash, and how many times they call it, is unspecified. 44/2 The actual function for the generic formal function Equivalent_Keys on Key_Type values is expected to return the same value each time it is called with a particular pair of key values. It should define an equivalence relationship, that is, be reflexive, symmetric, and transitive. If the actual for Equivalent_Keys behaves in some other manner, the behavior of this package is unspecified. Which subprograms of this package call Equivalent_Keys, and how many times they call it, is unspecified. 45/2 If the value of a key stored in a node of a map is changed other than by an operation in this package such that at least one of Hash or Equivalent_Keys give different results, the behavior of this package is unspecified. 46/2 Which nodes are the first node and the last node of a map, and which node is the successor of a given node, are unspecified, other than the general semantics described in A.18.4. 47/2 function Capacity (Container : Map) return Count_Type; 48/2 Returns the capacity of Container. 49/2 procedure Reserve_Capacity (Container : in out Map; Capacity : in Count_Type); 50/2 Reserve_Capacity allocates a new hash table such that the length of the resulting map can become at least the value Capacity without requiring an additional call to Reserve_Capacity, and is large enough to hold the current length of Container. Reserve_Capacity then rehashes the nodes in Container onto the new hash table. It replaces the old hash table with the new hash table, and then deallocates the old hash table. Any exception raised during allocation is propagated and Container is not modified. 51/2 Reserve_Capacity tampers with the cursors of Container. 52/2 procedure Clear (Container : in out Map); 53/2 In addition to the semantics described in A.18.4, Clear does not affect the capacity of Container. 53.1/3 procedure Assign (Target : in out Map; Source : in Map); 53.2/3 In addition to the semantics described in A.18.4, if the length of Source is greater than the capacity of Target, Reserve_Capacity (Target, Length (Source)) is called before assigning any elements. 53.3/3 function Copy (Source : Map; Capacity : Count_Type := 0) return Map; 53.4/3 Returns a map whose keys and elements are initialized from the keys and elements of Source. If Capacity is 0, then the map capacity is the length of Source; if Capacity is equal to or greater than the length of Source, the map capacity is at least the specified value. Otherwise, the operation propagates Capacity_Error. 54/2 procedure Insert (Container : in out Map; Key : in Key_Type; New_Item : in Element_Type; Position : out Cursor; Inserted : out Boolean); 55/2 In addition to the semantics described in A.18.4, if Length (Container) equals Capacity (Container), then Insert first calls Reserve_Capacity to increase the capacity of Container to some larger value. 56/2 function Equivalent_Keys (Left, Right : Cursor) return Boolean; 57/2 Equivalent to Equivalent_Keys (Key (Left), Key (Right)). 58/2 function Equivalent_Keys (Left : Cursor; Right : Key_Type) return Boolean; 59/2 Equivalent to Equivalent_Keys (Key (Left), Right). 60/2 function Equivalent_Keys (Left : Key_Type; Right : Cursor) return Boolean; 61/2 Equivalent to Equivalent_Keys (Left, Key (Right)). 61.1/3 function Iterate (Container : in Map) return Map_Iterator_Interfaces.Forward_Iterator'Class; 61.2/3 Iterate returns an iterator object (see 5.5.1) that will generate a value for a loop parameter (see 5.5.2) designating each node in Container, starting with the first node and moving the cursor according to the successor relation. Tampering with the cursors of Container is prohibited while the iterator object exists (in particular, in the sequence_of_statements of the loop_statement whose iterator_specification denotes this object). The iterator object needs finalization. Implementation Advice 62/2 If N is the length of a map, the average time complexity of the subprograms Element, Insert, Include, Replace, Delete, Exclude and Find that take a key parameter should be O(log N). The average time complexity of the subprograms that take a cursor parameter should be O(1). The average time complexity of Reserve_Capacity should be O(N). A.18.6 The Generic Package Containers.Ordered_Maps Static Semantics 1/2 The generic library package Containers.Ordered_Maps has the following declaration: 2/3 with Ada.Iterator_Interfaces; generic type Key_Type is private; type Element_Type is private; with function "<" (Left, Right : Key_Type) return Boolean is <>; with function "=" (Left, Right : Element_Type) return Boolean is <>; package Ada.Containers.Ordered_Maps is pragma Preelaborate(Ordered_Maps); pragma Remote_Types(Ordered_Maps); 3/2 function Equivalent_Keys (Left, Right : Key_Type) return Boolean; 4/3 type Map is tagged private with Constant_Indexing => Constant_Reference, Variable_Indexing => Reference, Default_Iterator => Iterate, Iterator_Element => Element_Type; pragma Preelaborable_Initialization(Map); 5/2 type Cursor is private; pragma Preelaborable_Initialization(Cursor); 6/2 Empty_Map : constant Map; 7/2 No_Element : constant Cursor; 7.1/3 function Has_Element (Position : Cursor) return Boolean; 7.2/3 package Map_Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, Has_Element); 8/2 function "=" (Left, Right : Map) return Boolean; 9/2 function Length (Container : Map) return Count_Type; 10/2 function Is_Empty (Container : Map) return Boolean; 11/2 procedure Clear (Container : in out Map); 12/2 function Key (Position : Cursor) return Key_Type; 13/2 function Element (Position : Cursor) return Element_Type; 14/2 procedure Replace_Element (Container : in out Map; Position : in Cursor; New_Item : in Element_Type); 15/2 procedure Query_Element (Position : in Cursor; Process : not null access procedure (Key : in Key_Type; Element : in Element_Type)); 16/2 procedure Update_Element (Container : in out Map; Position : in Cursor; Process : not null access procedure (Key : in Key_Type; Element : in out Element_Type)); 16.1/3 type Constant_Reference_Type (Element : not null access constant Element_Type) is private with Implicit_Dereference => Element; 16.2/3 type Reference_Type (Element : not null access Element_Type) is private with Implicit_Dereference => Element; 16.3/3 function Constant_Reference (Container : aliased in Map; Position : in Cursor) return Constant_Reference_Type; 16.4/3 function Reference (Container : aliased in out Map; Position : in Cursor) return Reference_Type; 16.5/3 function Constant_Reference (Container : aliased in Map; Key : in Key_Type) return Constant_Reference_Type; 16.6/3 function Reference (Container : aliased in out Map; Key : in Key_Type) return Reference_Type; 16.7/3 procedure Assign (Target : in out Map; Source : in Map); 16.8/3 function Copy (Source : Map) return Map; 17/2 procedure Move (Target : in out Map; Source : in out Map); 18/2 procedure Insert (Container : in out Map; Key : in Key_Type; New_Item : in Element_Type; Position : out Cursor; Inserted : out Boolean); 19/2 procedure Insert (Container : in out Map; Key : in Key_Type; Position : out Cursor; Inserted : out Boolean); 20/2 procedure Insert (Container : in out Map; Key : in Key_Type; New_Item : in Element_Type); 21/2 procedure Include (Container : in out Map; Key : in Key_Type; New_Item : in Element_Type); 22/2 procedure Replace (Container : in out Map; Key : in Key_Type; New_Item : in Element_Type); 23/2 procedure Exclude (Container : in out Map; Key : in Key_Type); 24/2 procedure Delete (Container : in out Map; Key : in Key_Type); 25/2 procedure Delete (Container : in out Map; Position : in out Cursor); 26/2 procedure Delete_First (Container : in out Map); 27/2 procedure Delete_Last (Container : in out Map); 28/2 function First (Container : Map) return Cursor; 29/2 function First_Element (Container : Map) return Element_Type; 30/2 function First_Key (Container : Map) return Key_Type; 31/2 function Last (Container : Map) return Cursor; 32/2 function Last_Element (Container : Map) return Element_Type; 33/2 function Last_Key (Container : Map) return Key_Type; 34/2 function Next (Position : Cursor) return Cursor; 35/2 procedure Next (Position : in out Cursor); 36/2 function Previous (Position : Cursor) return Cursor; 37/2 procedure Previous (Position : in out Cursor); 38/2 function Find (Container : Map; Key : Key_Type) return Cursor; 39/2 function Element (Container : Map; Key : Key_Type) return Element_Type; 40/2 function Floor (Container : Map; Key : Key_Type) return Cursor; 41/2 function Ceiling (Container : Map; Key : Key_Type) return Cursor; 42/2 function Contains (Container : Map; Key : Key_Type) return Boolean; 43/3 This paragraph was deleted. 44/2 function "<" (Left, Right : Cursor) return Boolean; 45/2 function ">" (Left, Right : Cursor) return Boolean; 46/2 function "<" (Left : Cursor; Right : Key_Type) return Boolean; 47/2 function ">" (Left : Cursor; Right : Key_Type) return Boolean; 48/2 function "<" (Left : Key_Type; Right : Cursor) return Boolean; 49/2 function ">" (Left : Key_Type; Right : Cursor) return Boolean; 50/2 procedure Iterate (Container : in Map; Process : not null access procedure (Position : in Cursor)); 51/2 procedure Reverse_Iterate (Container : in Map; Process : not null access procedure (Position : in Cursor)); 51.1/3 function Iterate (Container : in Map) return Map_Iterator_Interfaces.Reversible_Iterator'Class; 51.2/3 function Iterate (Container : in Map; Start : in Cursor) return Map_Iterator_Interfaces.Reversible_Iterator'Class; 52/2 private 53/2 ... -- not specified by the language 54/2 end Ada.Containers.Ordered_Maps; 55/2 Two keys K1 and K2 are equivalent if both K1 < K2 and K2 < K1 return False, using the generic formal "<" operator for keys. Function Equivalent_Keys returns True if Left and Right are equivalent, and False otherwise. 56/3 The actual function for the generic formal function "<" on Key_Type values is expected to return the same value each time it is called with a particular pair of key values. It should define a strict weak ordering relationship (see A.18). If the actual for "<" behaves in some other manner, the behavior of this package is unspecified. Which subprograms of this package call "<" and how many times they call it, is unspecified. 57/2 If the value of a key stored in a map is changed other than by an operation in this package such that at least one of "<" or "=" give different results, the behavior of this package is unspecified. 58/3 The first node of a nonempty map is the one whose key is less than the key of all the other nodes in the map. The last node of a nonempty map is the one whose key is greater than the key of all the other elements in the map. The successor of a node is the node with the smallest key that is larger than the key of the given node. The predecessor of a node is the node with the largest key that is smaller than the key of the given node. All comparisons are done using the generic formal "<" operator for keys. 58.1/3 function Copy (Source : Map) return Map; 58.2/3 Returns a map whose keys and elements are initialized from the corresponding keys and elements of Source. 59/2 procedure Delete_First (Container : in out Map); 60/3 If Container is empty, Delete_First has no effect. Otherwise, the node designated by First (Container) is removed from Container. Delete_First tampers with the cursors of Container. 61/2 procedure Delete_Last (Container : in out Map); 62/3 If Container is empty, Delete_Last has no effect. Otherwise, the node designated by Last (Container) is removed from Container. Delete_Last tampers with the cursors of Container. 63/2 function First_Element (Container : Map) return Element_Type; 64/2 Equivalent to Element (First (Container)). 65/2 function First_Key (Container : Map) return Key_Type; 66/2 Equivalent to Key (First (Container)). 67/2 function Last (Container : Map) return Cursor; 68/2 Returns a cursor that designates the last node in Container. If Container is empty, returns No_Element. 69/2 function Last_Element (Container : Map) return Element_Type; 70/2 Equivalent to Element (Last (Container)). 71/2 function Last_Key (Container : Map) return Key_Type; 72/2 Equivalent to Key (Last (Container)). 73/2 function Previous (Position : Cursor) return Cursor; 74/3 If Position equals No_Element, then Previous returns No_Element. Otherwise, Previous returns a cursor designating the predecessor node of the one designated by Position. If Position designates the first element, then Previous returns No_Element. 75/2 procedure Previous (Position : in out Cursor); 76/2 Equivalent to Position := Previous (Position). 77/2 function Floor (Container : Map; Key : Key_Type) return Cursor; 78/3 Floor searches for the last node whose key is not greater than Key, using the generic formal "<" operator for keys. If such a node is found, a cursor that designates it is returned. Otherwise, No_Element is returned. 79/2 function Ceiling (Container : Map; Key : Key_Type) return Cursor; 80/3 Ceiling searches for the first node whose key is not less than Key, using the generic formal "<" operator for keys. If such a node is found, a cursor that designates it is returned. Otherwise, No_Element is returned. 81/2 function "<" (Left, Right : Cursor) return Boolean; 82/2 Equivalent to Key (Left) < Key (Right). 83/2 function ">" (Left, Right : Cursor) return Boolean; 84/2 Equivalent to Key (Right) < Key (Left). 85/2 function "<" (Left : Cursor; Right : Key_Type) return Boolean; 86/2 Equivalent to Key (Left) < Right. 87/2 function ">" (Left : Cursor; Right : Key_Type) return Boolean; 88/2 Equivalent to Right < Key (Left). 89/2 function "<" (Left : Key_Type; Right : Cursor) return Boolean; 90/2 Equivalent to Left < Key (Right). 91/2 function ">" (Left : Key_Type; Right : Cursor) return Boolean; 92/2 Equivalent to Key (Right) < Left. 93/2 procedure Reverse_Iterate (Container : in Map; Process : not null access procedure (Position : in Cursor)); 94/3 Iterates over the nodes in Container as per procedure Iterate, with the difference that the nodes are traversed in predecessor order, starting with the last node. 94.1/3 function Iterate (Container : in Map) return Map_Iterator_Interfaces.Reversible_Iterator'Class; 94.2/3 Iterate returns a reversible iterator object (see 5.5.1) that will generate a value for a loop parameter (see 5.5.2) designating each node in Container, starting with the first node and moving the cursor according to the successor relation when used as a forward iterator, and starting with the last node and moving the cursor according to the predecessor relation when used as a reverse iterator. Tampering with the cursors of Container is prohibited while the iterator object exists (in particular, in the sequence_of_statements of the loop_statement whose iterator_specification denotes this object). The iterator object needs finalization. 94.3/3 function Iterate (Container : in Map; Start : in Cursor) return Map_Iterator_Interfaces.Reversible_Iterator'Class; 94.4/3 If Start is not No_Element and does not designate an item in Container, then Program_Error is propagated. If Start is No_Element, then Constraint_Error is propagated. Otherwise, Iterate returns a reversible iterator object (see 5.5.1) that will generate a value for a loop parameter (see 5.5.2) designating each node in Container, starting with the node designated by Start and moving the cursor according to the successor relation when used as a forward iterator, or moving the cursor according to the predecessor relation when used as a reverse iterator. Tampering with the cursors of Container is prohibited while the iterator object exists (in particular, in the sequence_of_statements of the loop_statement whose iterator_specification denotes this object). The iterator object needs finalization. Implementation Advice 95/2 If N is the length of a map, then the worst-case time complexity of the Element, Insert, Include, Replace, Delete, Exclude and Find operations that take a key parameter should be O((log N)**2) or better. The worst-case time complexity of the subprograms that take a cursor parameter should be O(1). A.18.7 Sets 1/2 The language-defined generic packages Containers.Hashed_Sets and Containers.Ordered_Sets provide private types Set and Cursor, and a set of operations for each type. A set container allows elements of an arbitrary type to be stored without duplication. A hashed set uses a hash function to organize elements, while an ordered set orders its element per a specified relation. 2/3 This subclause describes the declarations that are common to both kinds of sets. See A.18.8 for a description of the semantics specific to Containers.Hashed_Sets and A.18.9 for a description of the semantics specific to Containers.Ordered_Sets. Static Semantics 3/2 The actual function for the generic formal function "=" on Element_Type values is expected to define a reflexive and symmetric relationship and return the same result value each time it is called with a particular pair of values. If it behaves in some other manner, the function "=" on set values returns an unspecified value. The exact arguments and number of calls of this generic formal function by the function "=" on set values are unspecified. 4/2 The type Set is used to represent sets. The type Set needs finalization (see 7.6). 5/2 A set contains elements. Set cursors designate elements. There exists an equivalence relation on elements, whose definition is different for hashed sets and ordered sets. A set never contains two or more equivalent elements. The length of a set is the number of elements it contains. 6/2 Each nonempty set has two particular elements called the first element and the last element (which may be the same). Each element except for the last element has a successor element. If there are no other intervening operations, starting with the first element and repeatedly going to the successor element will visit each element in the set exactly once until the last element is reached. The exact definition of these terms is different for hashed sets and ordered sets. 7/2 Some operations of these generic packages have access-to-subprogram parameters. To ensure such operations are well-defined, they guard against certain actions by the designated subprogram. In particular, some operations check for "tampering with cursors" of a container because they depend on the set of elements of the container remaining constant, and others check for " tampering with elements" of a container because they depend on elements of the container not being replaced. 8/2 A subprogram is said to tamper with cursors of a set object S if: 9/2 * it inserts or deletes elements of S, that is, it calls the Insert, Include, Clear, Delete, Exclude, or Replace_Element procedures with S as a parameter; or 10/2 * it finalizes S; or 10.1/3 * it calls the Assign procedure with S as the Target parameter; or 11/2 * it calls the Move procedure with S as a parameter; or 12/2 * it calls one of the operations defined to tamper with cursors of S. 13/2 A subprogram is said to tamper with elements of a set object S if: 14/2 * it tampers with cursors of S. 14.1/4 When tampering with cursors is prohibited for a particular set object S, Program_Error is propagated by a call of any language-defined subprogram that is defined to tamper with the cursors of S, leaving S unmodified. Similarly, when tampering with elements is prohibited for a particular set object S, Program_Error is propagated by a call of any language-defined subprogram that is defined to tamper with the elements of S (or tamper with the cursors of S), leaving S unmodified. These checks are made before any other defined behavior of the body of the language-defined subprogram. 15/2 Empty_Set represents the empty Set object. It has a length of 0. If an object of type Set is not otherwise initialized, it is initialized to the same value as Empty_Set. 16/2 No_Element represents a cursor that designates no element. If an object of type Cursor is not otherwise initialized, it is initialized to the same value as No_Element. 17/2 The predefined "=" operator for type Cursor returns True if both cursors are No_Element, or designate the same element in the same container. 18/2 Execution of the default implementation of the Input, Output, Read, or Write attribute of type Cursor raises Program_Error. 18.1/3 Set'Write for a Set object S writes Length(S) elements of the set to the stream. It also may write additional information about the set. 18.2/3 Set'Read reads the representation of a set from the stream, and assigns to Item a set with the same length and elements as was written by Set'Write. 18.3/3 function Has_Element (Position : Cursor) return Boolean; 18.4/3 Returns True if Position designates an element, and returns False otherwise. 19/2 function "=" (Left, Right : Set) return Boolean; 20/2 If Left and Right denote the same set object, then the function returns True. If Left and Right have different lengths, then the function returns False. Otherwise, for each element E in Left, the function returns False if an element equal to E (using the generic formal equality operator) is not present in Right. If the function has not returned a result after checking all of the elements, it returns True. Any exception raised during evaluation of element equality is propagated. 21/2 function Equivalent_Sets (Left, Right : Set) return Boolean; 22/2 If Left and Right denote the same set object, then the function returns True. If Left and Right have different lengths, then the function returns False. Otherwise, for each element E in Left, the function returns False if an element equivalent to E is not present in Right. If the function has not returned a result after checking all of the elements, it returns True. Any exception raised during evaluation of element equivalence is propagated. 23/2 function To_Set (New_Item : Element_Type) return Set; 24/2 Returns a set containing the single element New_Item. 25/2 function Length (Container : Set) return Count_Type; 26/2 Returns the number of elements in Container. 27/2 function Is_Empty (Container : Set) return Boolean; 28/2 Equivalent to Length (Container) = 0. 29/2 procedure Clear (Container : in out Set); 30/2 Removes all the elements from Container. 31/2 function Element (Position : Cursor) return Element_Type; 32/2 If Position equals No_Element, then Constraint_Error is propagated. Otherwise, Element returns the element designated by Position. 33/2 procedure Replace_Element (Container : in out Set; Position : in Cursor; New_Item : in Element_Type); 34/2 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container, then Program_Error is propagated. If an element equivalent to New_Item is already present in Container at a position other than Position, Program_Error is propagated. Otherwise, Replace_Element assigns New_Item to the element designated by Position. Any exception raised by the assignment is propagated. 35/2 procedure Query_Element (Position : in Cursor; Process : not null access procedure (Element : in Element_Type)); 36/3 If Position equals No_Element, then Constraint_Error is propagated. Otherwise, Query_Element calls Process.all with the element designated by Position as the argument. Tampering with the elements of the set that contains the element designated by Position is prohibited during the execution of the call on Process.all. Any exception raised by Process.all is propagated. 36.1/3 type Constant_Reference_Type (Element : not null access constant Element_Type) is private with Implicit_Dereference => Element; 36.2/3 The type Constant_Reference_Type needs finalization. 36.3/3 The default initialization of an object of type Constant_Reference_Type propagates Program_Error. 36.4/3 function Constant_Reference (Container : aliased in Set; Position : in Cursor) return Constant_Reference_Type; 36.5/3 This function (combined with the Constant_Indexing and Implicit_Dereference aspects) provides a convenient way to gain read access to an individual element of a set given a cursor. 36.6/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Constant_Reference returns an object whose discriminant is an access value that designates the element designated by Position. Tampering with the elements of Container is prohibited while the object returned by Constant_Reference exists and has not been finalized. 36.7/3 procedure Assign (Target : in out Set; Source : in Set); 36.8/3 If Target denotes the same object as Source, the operation has no effect. Otherwise, the elements of Source are copied to Target as for an assignment_statement assigning Source to Target. 37/2 procedure Move (Target : in out Set; Source : in out Set); 38/3 If Target denotes the same object as Source, then the operation has no effect. Otherwise, the operation is equivalent to Assign (Target, Source) followed by Clear (Source). 39/2 procedure Insert (Container : in out Set; New_Item : in Element_Type; Position : out Cursor; Inserted : out Boolean); 40/2 Insert checks if an element equivalent to New_Item is already present in Container. If a match is found, Inserted is set to False and Position designates the matching element. Otherwise, Insert adds New_Item to Container; Inserted is set to True and Position designates the newly-inserted element. Any exception raised during allocation is propagated and Container is not modified. 41/2 procedure Insert (Container : in out Set; New_Item : in Element_Type); 42/2 Insert inserts New_Item into Container as per the four-parameter Insert, with the difference that if an element equivalent to New_Item is already in the set, then Constraint_Error is propagated. 43/2 procedure Include (Container : in out Set; New_Item : in Element_Type); 44/2 Include inserts New_Item into Container as per the four-parameter Insert, with the difference that if an element equivalent to New_Item is already in the set, then it is replaced. Any exception raised during assignment is propagated. 45/2 procedure Replace (Container : in out Set; New_Item : in Element_Type); 46/2 Replace checks if an element equivalent to New_Item is already in the set. If a match is found, that element is replaced with New_Item; otherwise, Constraint_Error is propagated. 47/2 procedure Exclude (Container : in out Set; Item : in Element_Type); 48/2 Exclude checks if an element equivalent to Item is present in Container. If a match is found, Exclude removes the element from the set. 49/2 procedure Delete (Container : in out Set; Item : in Element_Type); 50/2 Delete checks if an element equivalent to Item is present in Container. If a match is found, Delete removes the element from the set; otherwise, Constraint_Error is propagated. 51/2 procedure Delete (Container : in out Set; Position : in out Cursor); 52/2 If Position equals No_Element, then Constraint_Error is propagated. If Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Delete removes the element designated by Position from the set. Position is set to No_Element on return. 53/2 procedure Union (Target : in out Set; Source : in Set); 54/2 Union inserts into Target the elements of Source that are not equivalent to some element already in Target. 55/2 function Union (Left, Right : Set) return Set; 56/2 Returns a set comprising all of the elements of Left, and the elements of Right that are not equivalent to some element of Left. 57/2 procedure Intersection (Target : in out Set; Source : in Set); 58/3 Intersection deletes from Target the elements of Target that are not equivalent to some element of Source. 59/2 function Intersection (Left, Right : Set) return Set; 60/2 Returns a set comprising all the elements of Left that are equivalent to the some element of Right. 61/2 procedure Difference (Target : in out Set; Source : in Set); 62/2 If Target denotes the same object as Source, then Difference clears Target. Otherwise, it deletes from Target the elements that are equivalent to some element of Source. 63/2 function Difference (Left, Right : Set) return Set; 64/2 Returns a set comprising the elements of Left that are not equivalent to some element of Right. 65/2 procedure Symmetric_Difference (Target : in out Set; Source : in Set); 66/2 If Target denotes the same object as Source, then Symmetric_Difference clears Target. Otherwise, it deletes from Target the elements that are equivalent to some element of Source, and inserts into Target the elements of Source that are not equivalent to some element of Target. 67/2 function Symmetric_Difference (Left, Right : Set) return Set; 68/2 Returns a set comprising the elements of Left that are not equivalent to some element of Right, and the elements of Right that are not equivalent to some element of Left. 69/2 function Overlap (Left, Right : Set) return Boolean; 70/3 If an element of Left is equivalent to some element of Right, then Overlap returns True. Otherwise, it returns False. 71/2 function Is_Subset (Subset : Set; Of_Set : Set) return Boolean; 72/3 If an element of Subset is not equivalent to some element of Of_Set, then Is_Subset returns False. Otherwise, it returns True. 73/2 function First (Container : Set) return Cursor; 74/2 If Length (Container) = 0, then First returns No_Element. Otherwise, First returns a cursor that designates the first element in Container. 75/2 function Next (Position : Cursor) return Cursor; 76/2 Returns a cursor that designates the successor of the element designated by Position. If Position designates the last element, then No_Element is returned. If Position equals No_Element, then No_Element is returned. 77/2 procedure Next (Position : in out Cursor); 78/2 Equivalent to Position := Next (Position). 79/3 This paragraph was deleted. 80/2 function Find (Container : Set; Item : Element_Type) return Cursor; 81/2 If Length (Container) equals 0, then Find returns No_Element. Otherwise, Find checks if an element equivalent to Item is present in Container. If a match is found, a cursor designating the matching element is returned; otherwise, No_Element is returned. 82/2 function Contains (Container : Set; Item : Element_Type) return Boolean; 82.1/3 Equivalent to Find (Container, Item) /= No_Element. Paragraphs 83 and 84 were moved above. 85/2 procedure Iterate (Container : in Set; Process : not null access procedure (Position : in Cursor)); 86/3 Iterate calls Process.all with a cursor that designates each element in Container, starting with the first element and moving the cursor according to the successor relation. Tampering with the cursors of Container is prohibited during the execution of a call on Process.all. Any exception raised by Process.all is propagated. 87/2 Both Containers.Hashed_Set and Containers.Ordered_Set declare a nested generic package Generic_Keys, which provides operations that allow set manipulation in terms of a key (typically, a portion of an element) instead of a complete element. The formal function Key of Generic_Keys extracts a key value from an element. It is expected to return the same value each time it is called with a particular element. The behavior of Generic_Keys is unspecified if Key behaves in some other manner. 88/2 A key is expected to unambiguously determine a single equivalence class for elements. The behavior of Generic_Keys is unspecified if the formal parameters of this package behave in some other manner. 89/2 function Key (Position : Cursor) return Key_Type; 90/2 Equivalent to Key (Element (Position)). 91/2 The subprograms in package Generic_Keys named Contains, Find, Element, Delete, and Exclude, are equivalent to the corresponding subprograms in the parent package, with the difference that the Key parameter is used to locate an element in the set. 92/2 procedure Replace (Container : in out Set; Key : in Key_Type; New_Item : in Element_Type); 93/2 Equivalent to Replace_Element (Container, Find (Container, Key), New_Item). 94/2 procedure Update_Element_Preserving_Key (Container : in out Set; Position : in Cursor; Process : not null access procedure (Element : in out Element_Type)); 95/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Update_- Element_Preserving_Key uses Key to save the key value K of the element designated by Position. Update_Element_Preserving_Key then calls Process.all with that element as the argument. Tampering with the elements of Container is prohibited during the execution of the call on Process.all. Any exception raised by Process.all is propagated. After Process.all returns, Update_Element_Preserving_Key checks if K determines the same equivalence class as that for the new element; if not, the element is removed from the set and Program_Error is propagated. 96/2 If Element_Type is unconstrained and definite, then the actual Element parameter of Process.all shall be unconstrained. 96.1/3 type Reference_Type (Element : not null access Element_Type) is private with Implicit_Dereference => Element; 96.2/3 The type Reference_Type needs finalization. 96.3/3 The default initialization of an object of type Reference_Type propagates Program_Error. 96.4/3 function Reference_Preserving_Key (Container : aliased in out Set; Position : in Cursor) return Reference_Type; 96.5/3 This function (combined with the Implicit_Dereference aspect) provides a convenient way to gain read and write access to an individual element of a set given a cursor. 96.6/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Reference_Preserving_Key uses Key to save the key value K; then returns an object whose discriminant is an access value that designates the element designated by Position. Tampering with the elements of Container is prohibited while the object returned by Reference_Preserving_Key exists and has not been finalized. When the object returned by Reference_Preserving_Key is finalized, a check is made if K determines the same equivalence class as that for the new element; if not, the element is removed from the set and Program_Error is propagated. 96.7/3 function Constant_Reference (Container : aliased in Set; Key : in Key_Type) return Constant_Reference_Type; 96.8/3 This function (combined with the Implicit_Dereference aspect) provides a convenient way to gain read access to an individual element of a set given a key value. 96.9/3 Equivalent to Constant_Reference (Container, Find (Container, Key)). 96.10/3 function Reference_Preserving_Key (Container : aliased in out Set; Key : in Key_Type) return Reference_Type; 96.11/3 This function (combined with the Implicit_Dereference aspect) provides a convenient way to gain read and write access to an individual element of a set given a key value. 96.12/3 Equivalent to Reference_Preserving_Key (Container, Find (Container, Key)). Bounded (Run-Time) Errors 96.13/3 It is a bounded error for the actual function associated with a generic formal subprogram, when called as part of an operation of a set package, to tamper with elements of any set parameter of the operation. Either Program_Error is raised, or the operation works as defined on the value of the set either prior to, or subsequent to, some or all of the modifications to the set. 96.14/3 It is a bounded error to call any subprogram declared in the visible part of a set package when the associated container has been finalized. If the operation takes Container as an in out parameter, then it raises Constraint_Error or Program_Error. Otherwise, the operation either proceeds as it would for an empty container, or it raises Constraint_Error or Program_Error. Erroneous Execution 97/2 A Cursor value is invalid if any of the following have occurred since it was created: 98/2 * The set that contains the element it designates has been finalized; 98.1/3 * The set that contains the element it designates has been used as the Target of a call to Assign, or as the target of an assignment_statement; 99/2 * The set that contains the element it designates has been used as the Source or Target of a call to Move; or 100/3 * The element it designates has been removed from the set that previously contained the element. 101/2 The result of "=" or Has_Element is unspecified if these functions are called with an invalid cursor parameter. Execution is erroneous if any other subprogram declared in Containers.Hashed_Sets or Containers.Ordered_Sets is called with an invalid cursor parameter. 101.1/3 Execution is erroneous if the set associated with the result of a call to Reference or Constant_Reference is finalized before the result object returned by the call to Reference or Constant_Reference is finalized. Implementation Requirements 102/2 No storage associated with a Set object shall be lost upon assignment or scope exit. 103/3 The execution of an assignment_statement for a set shall have the effect of copying the elements from the source set object to the target set object and changing the length of the target object to that of the source object. Implementation Advice 104/2 Move should not copy elements, and should minimize copying of internal data structures. 105/2 If an exception is propagated from a set operation, no storage should be lost, nor any elements removed from a set unless specified by the operation. A.18.8 The Generic Package Containers.Hashed_Sets Static Semantics 1/2 The generic library package Containers.Hashed_Sets has the following declaration: 2/3 with Ada.Iterator_Interfaces; generic type Element_Type is private; with function Hash (Element : Element_Type) return Hash_Type; with function Equivalent_Elements (Left, Right : Element_Type) return Boolean; with function "=" (Left, Right : Element_Type) return Boolean is <>; package Ada.Containers.Hashed_Sets is pragma Preelaborate(Hashed_Sets); pragma Remote_Types(Hashed_Sets); 3/3 type Set is tagged private with Constant_Indexing => Constant_Reference, Default_Iterator => Iterate, Iterator_Element => Element_Type; pragma Preelaborable_Initialization(Set); 4/2 type Cursor is private; pragma Preelaborable_Initialization(Cursor); 5/2 Empty_Set : constant Set; 6/2 No_Element : constant Cursor; 6.1/3 function Has_Element (Position : Cursor) return Boolean; 6.2/3 package Set_Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, Has_Element); 7/2 function "=" (Left, Right : Set) return Boolean; 8/2 function Equivalent_Sets (Left, Right : Set) return Boolean; 9/2 function To_Set (New_Item : Element_Type) return Set; 10/2 function Capacity (Container : Set) return Count_Type; 11/2 procedure Reserve_Capacity (Container : in out Set; Capacity : in Count_Type); 12/2 function Length (Container : Set) return Count_Type; 13/2 function Is_Empty (Container : Set) return Boolean; 14/2 procedure Clear (Container : in out Set); 15/2 function Element (Position : Cursor) return Element_Type; 16/2 procedure Replace_Element (Container : in out Set; Position : in Cursor; New_Item : in Element_Type); 17/2 procedure Query_Element (Position : in Cursor; Process : not null access procedure (Element : in Element_Type)); 17.1/3 type Constant_Reference_Type (Element : not null access constant Element_Type) is private with Implicit_Dereference => Element; 17.2/3 function Constant_Reference (Container : aliased in Set; Position : in Cursor) return Constant_Reference_Type; 17.3/3 procedure Assign (Target : in out Set; Source : in Set); 17.4/3 function Copy (Source : Set; Capacity : Count_Type := 0) return Set; 18/2 procedure Move (Target : in out Set; Source : in out Set); 19/2 procedure Insert (Container : in out Set; New_Item : in Element_Type; Position : out Cursor; Inserted : out Boolean); 20/2 procedure Insert (Container : in out Set; New_Item : in Element_Type); 21/2 procedure Include (Container : in out Set; New_Item : in Element_Type); 22/2 procedure Replace (Container : in out Set; New_Item : in Element_Type); 23/2 procedure Exclude (Container : in out Set; Item : in Element_Type); 24/2 procedure Delete (Container : in out Set; Item : in Element_Type); 25/2 procedure Delete (Container : in out Set; Position : in out Cursor); 26/2 procedure Union (Target : in out Set; Source : in Set); 27/2 function Union (Left, Right : Set) return Set; 28/2 function "or" (Left, Right : Set) return Set renames Union; 29/2 procedure Intersection (Target : in out Set; Source : in Set); 30/2 function Intersection (Left, Right : Set) return Set; 31/2 function "and" (Left, Right : Set) return Set renames Intersection; 32/2 procedure Difference (Target : in out Set; Source : in Set); 33/2 function Difference (Left, Right : Set) return Set; 34/2 function "-" (Left, Right : Set) return Set renames Difference; 35/2 procedure Symmetric_Difference (Target : in out Set; Source : in Set); 36/2 function Symmetric_Difference (Left, Right : Set) return Set; 37/2 function "xor" (Left, Right : Set) return Set renames Symmetric_Difference; 38/2 function Overlap (Left, Right : Set) return Boolean; 39/2 function Is_Subset (Subset : Set; Of_Set : Set) return Boolean; 40/2 function First (Container : Set) return Cursor; 41/2 function Next (Position : Cursor) return Cursor; 42/2 procedure Next (Position : in out Cursor); 43/2 function Find (Container : Set; Item : Element_Type) return Cursor; 44/2 function Contains (Container : Set; Item : Element_Type) return Boolean; 45/3 This paragraph was deleted. 46/2 function Equivalent_Elements (Left, Right : Cursor) return Boolean; 47/2 function Equivalent_Elements (Left : Cursor; Right : Element_Type) return Boolean; 48/2 function Equivalent_Elements (Left : Element_Type; Right : Cursor) return Boolean; 49/2 procedure Iterate (Container : in Set; Process : not null access procedure (Position : in Cursor)); 49.1/3 function Iterate (Container : in Set) return Set_Iterator_Interfaces.Forward_Iterator'Class; 50/2 generic type Key_Type (<>) is private; with function Key (Element : Element_Type) return Key_Type; with function Hash (Key : Key_Type) return Hash_Type; with function Equivalent_Keys (Left, Right : Key_Type) return Boolean; package Generic_Keys is 51/2 function Key (Position : Cursor) return Key_Type; 52/2 function Element (Container : Set; Key : Key_Type) return Element_Type; 53/2 procedure Replace (Container : in out Set; Key : in Key_Type; New_Item : in Element_Type); 54/2 procedure Exclude (Container : in out Set; Key : in Key_Type); 55/2 procedure Delete (Container : in out Set; Key : in Key_Type); 56/2 function Find (Container : Set; Key : Key_Type) return Cursor; 57/2 function Contains (Container : Set; Key : Key_Type) return Boolean; 58/2 procedure Update_Element_Preserving_Key (Container : in out Set; Position : in Cursor; Process : not null access procedure (Element : in out Element_Type)); 58.1/3 type Reference_Type (Element : not null access Element_Type) is private with Implicit_Dereference => Element; 58.2/3 function Reference_Preserving_Key (Container : aliased in out Set; Position : in Cursor) return Reference_Type; 58.3/3 function Constant_Reference (Container : aliased in Set; Key : in Key_Type) return Constant_Reference_Type; 58.4/3 function Reference_Preserving_Key (Container : aliased in out Set; Key : in Key_Type) return Reference_Type; 59/2 end Generic_Keys; 60/2 private 61/2 ... -- not specified by the language 62/2 end Ada.Containers.Hashed_Sets; 63/2 An object of type Set contains an expandable hash table, which is used to provide direct access to elements. The capacity of an object of type Set is the maximum number of elements that can be inserted into the hash table prior to it being automatically expanded. 64/2 Two elements E1 and E2 are defined to be equivalent if Equivalent_Elements (E1, E2) returns True. 65/2 The actual function for the generic formal function Hash is expected to return the same value each time it is called with a particular element value. For any two equivalent elements, the actual for Hash is expected to return the same value. If the actual for Hash behaves in some other manner, the behavior of this package is unspecified. Which subprograms of this package call Hash, and how many times they call it, is unspecified. 66/2 The actual function for the generic formal function Equivalent_Elements is expected to return the same value each time it is called with a particular pair of Element values. It should define an equivalence relationship, that is, be reflexive, symmetric, and transitive. If the actual for Equivalent_Elements behaves in some other manner, the behavior of this package is unspecified. Which subprograms of this package call Equivalent_Elements, and how many times they call it, is unspecified. 66.1/3 If the actual function for the generic formal function "=" returns True for any pair of nonequivalent elements, then the behavior of the container function "=" is unspecified. 67/2 If the value of an element stored in a set is changed other than by an operation in this package such that at least one of Hash or Equivalent_Elements give different results, the behavior of this package is unspecified. 68/2 Which elements are the first element and the last element of a set, and which element is the successor of a given element, are unspecified, other than the general semantics described in A.18.7. 69/2 function Capacity (Container : Set) return Count_Type; 70/2 Returns the capacity of Container. 71/2 procedure Reserve_Capacity (Container : in out Set; Capacity : in Count_Type); 72/2 Reserve_Capacity allocates a new hash table such that the length of the resulting set can become at least the value Capacity without requiring an additional call to Reserve_Capacity, and is large enough to hold the current length of Container. Reserve_Capacity then rehashes the elements in Container onto the new hash table. It replaces the old hash table with the new hash table, and then deallocates the old hash table. Any exception raised during allocation is propagated and Container is not modified. 73/2 Reserve_Capacity tampers with the cursors of Container. 74/2 procedure Clear (Container : in out Set); 75/2 In addition to the semantics described in A.18.7, Clear does not affect the capacity of Container. 75.1/3 procedure Assign (Target : in out Set; Source : in Set); 75.2/3 In addition to the semantics described in A.18.7, if the length of Source is greater than the capacity of Target, Reserve_Capacity (Target, Length (Source)) is called before assigning any elements. 75.3/3 function Copy (Source : Set; Capacity : Count_Type := 0) return Set; 75.4/3 Returns a set whose elements are initialized from the elements of Source. If Capacity is 0, then the set capacity is the length of Source; if Capacity is equal to or greater than the length of Source, the set capacity is at least the specified value. Otherwise, the operation propagates Capacity_Error. 76/2 procedure Insert (Container : in out Set; New_Item : in Element_Type; Position : out Cursor; Inserted : out Boolean); 77/2 In addition to the semantics described in A.18.7, if Length (Container) equals Capacity (Container), then Insert first calls Reserve_Capacity to increase the capacity of Container to some larger value. 78/2 function First (Container : Set) return Cursor; 79/2 If Length (Container) = 0, then First returns No_Element. Otherwise, First returns a cursor that designates the first hashed element in Container. 80/2 function Equivalent_Elements (Left, Right : Cursor) return Boolean; 81/2 Equivalent to Equivalent_Elements (Element (Left), Element (Right)). 82/2 function Equivalent_Elements (Left : Cursor; Right : Element_Type) return Boolean; 83/2 Equivalent to Equivalent_Elements (Element (Left), Right). 84/2 function Equivalent_Elements (Left : Element_Type; Right : Cursor) return Boolean; 85/2 Equivalent to Equivalent_Elements (Left, Element (Right)). 85.1/3 function Iterate (Container : in Set) return Set_Iterator_Interfaces.Forward_Iterator'Class; 85.2/3 Iterate returns an iterator object (see 5.5.1) that will generate a value for a loop parameter (see 5.5.2) designating each element in Container, starting with the first element and moving the cursor according to the successor relation. Tampering with the cursors of Container is prohibited while the iterator object exists (in particular, in the sequence_of_statements of the loop_statement whose iterator_specification denotes this object). The iterator object needs finalization. 86/2 For any element E, the actual function for the generic formal function Generic_Keys.Hash is expected to be such that Hash (E) = Generic_Keys.Hash (Key (E)). If the actuals for Key or Generic_Keys.Hash behave in some other manner, the behavior of Generic_Keys is unspecified. Which subprograms of Generic_Keys call Generic_Keys.Hash, and how many times they call it, is unspecified. 87/2 For any two elements E1 and E2, the boolean values Equivalent_Elements (E1, E2) and Equivalent_Keys (Key (E1), Key (E2)) are expected to be equal. If the actuals for Key or Equivalent_Keys behave in some other manner, the behavior of Generic_Keys is unspecified. Which subprograms of Generic_Keys call Equivalent_Keys, and how many times they call it, is unspecified. Implementation Advice 88/2 If N is the length of a set, the average time complexity of the subprograms Insert, Include, Replace, Delete, Exclude and Find that take an element parameter should be O(log N). The average time complexity of the subprograms that take a cursor parameter should be O(1). The average time complexity of Reserve_Capacity should be O(N). A.18.9 The Generic Package Containers.Ordered_Sets Static Semantics 1/2 The generic library package Containers.Ordered_Sets has the following declaration: 2/3 with Ada.Iterator_Interfaces; generic type Element_Type is private; with function "<" (Left, Right : Element_Type) return Boolean is <>; with function "=" (Left, Right : Element_Type) return Boolean is <>; package Ada.Containers.Ordered_Sets is pragma Preelaborate(Ordered_Sets); pragma Remote_Types(Ordered_Sets); 3/2 function Equivalent_Elements (Left, Right : Element_Type) return Boolean; 4/3 type Set is tagged private with Constant_Indexing => Constant_Reference, Default_Iterator => Iterate, Iterator_Element => Element_Type; pragma Preelaborable_Initialization(Set); 5/2 type Cursor is private; pragma Preelaborable_Initialization(Cursor); 6/2 Empty_Set : constant Set; 7/2 No_Element : constant Cursor; 7.1/3 function Has_Element (Position : Cursor) return Boolean; 7.2/3 package Set_Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, Has_Element); 8/2 function "=" (Left, Right : Set) return Boolean; 9/2 function Equivalent_Sets (Left, Right : Set) return Boolean; 10/2 function To_Set (New_Item : Element_Type) return Set; 11/2 function Length (Container : Set) return Count_Type; 12/2 function Is_Empty (Container : Set) return Boolean; 13/2 procedure Clear (Container : in out Set); 14/2 function Element (Position : Cursor) return Element_Type; 15/2 procedure Replace_Element (Container : in out Set; Position : in Cursor; New_Item : in Element_Type); 16/2 procedure Query_Element (Position : in Cursor; Process : not null access procedure (Element : in Element_Type)); 16.1/3 type Constant_Reference_Type (Element : not null access constant Element_Type) is private with Implicit_Dereference => Element; 16.2/3 function Constant_Reference (Container : aliased in Set; Position : in Cursor) return Constant_Reference_Type; 16.3/3 procedure Assign (Target : in out Set; Source : in Set); 16.4/3 function Copy (Source : Set) return Set; 17/2 procedure Move (Target : in out Set; Source : in out Set); 18/2 procedure Insert (Container : in out Set; New_Item : in Element_Type; Position : out Cursor; Inserted : out Boolean); 19/2 procedure Insert (Container : in out Set; New_Item : in Element_Type); 20/2 procedure Include (Container : in out Set; New_Item : in Element_Type); 21/2 procedure Replace (Container : in out Set; New_Item : in Element_Type); 22/2 procedure Exclude (Container : in out Set; Item : in Element_Type); 23/2 procedure Delete (Container : in out Set; Item : in Element_Type); 24/2 procedure Delete (Container : in out Set; Position : in out Cursor); 25/2 procedure Delete_First (Container : in out Set); 26/2 procedure Delete_Last (Container : in out Set); 27/2 procedure Union (Target : in out Set; Source : in Set); 28/2 function Union (Left, Right : Set) return Set; 29/2 function "or" (Left, Right : Set) return Set renames Union; 30/2 procedure Intersection (Target : in out Set; Source : in Set); 31/2 function Intersection (Left, Right : Set) return Set; 32/2 function "and" (Left, Right : Set) return Set renames Intersection; 33/2 procedure Difference (Target : in out Set; Source : in Set); 34/2 function Difference (Left, Right : Set) return Set; 35/2 function "-" (Left, Right : Set) return Set renames Difference; 36/2 procedure Symmetric_Difference (Target : in out Set; Source : in Set); 37/2 function Symmetric_Difference (Left, Right : Set) return Set; 38/2 function "xor" (Left, Right : Set) return Set renames Symmetric_Difference; 39/2 function Overlap (Left, Right : Set) return Boolean; 40/2 function Is_Subset (Subset : Set; Of_Set : Set) return Boolean; 41/2 function First (Container : Set) return Cursor; 42/2 function First_Element (Container : Set) return Element_Type; 43/2 function Last (Container : Set) return Cursor; 44/2 function Last_Element (Container : Set) return Element_Type; 45/2 function Next (Position : Cursor) return Cursor; 46/2 procedure Next (Position : in out Cursor); 47/2 function Previous (Position : Cursor) return Cursor; 48/2 procedure Previous (Position : in out Cursor); 49/2 function Find (Container : Set; Item : Element_Type) return Cursor; 50/2 function Floor (Container : Set; Item : Element_Type) return Cursor; 51/2 function Ceiling (Container : Set; Item : Element_Type) return Cursor; 52/2 function Contains (Container : Set; Item : Element_Type) return Boolean; 53/3 This paragraph was deleted. 54/2 function "<" (Left, Right : Cursor) return Boolean; 55/2 function ">" (Left, Right : Cursor) return Boolean; 56/2 function "<" (Left : Cursor; Right : Element_Type) return Boolean; 57/2 function ">" (Left : Cursor; Right : Element_Type) return Boolean; 58/2 function "<" (Left : Element_Type; Right : Cursor) return Boolean; 59/2 function ">" (Left : Element_Type; Right : Cursor) return Boolean; 60/2 procedure Iterate (Container : in Set; Process : not null access procedure (Position : in Cursor)); 61/2 procedure Reverse_Iterate (Container : in Set; Process : not null access procedure (Position : in Cursor)); 61.1/3 function Iterate (Container : in Set) return Set_Iterator_Interfaces.Reversible_Iterator'Class; 61.2/3 function Iterate (Container : in Set; Start : in Cursor) return Set_Iterator_Interfaces.Reversible_Iterator'Class; 62/2 generic type Key_Type (<>) is private; with function Key (Element : Element_Type) return Key_Type; with function "<" (Left, Right : Key_Type) return Boolean is <>; package Generic_Keys is 63/2 function Equivalent_Keys (Left, Right : Key_Type) return Boolean; 64/2 function Key (Position : Cursor) return Key_Type; 65/2 function Element (Container : Set; Key : Key_Type) return Element_Type; 66/2 procedure Replace (Container : in out Set; Key : in Key_Type; New_Item : in Element_Type); 67/2 procedure Exclude (Container : in out Set; Key : in Key_Type); 68/2 procedure Delete (Container : in out Set; Key : in Key_Type); 69/2 function Find (Container : Set; Key : Key_Type) return Cursor; 70/2 function Floor (Container : Set; Key : Key_Type) return Cursor; 71/2 function Ceiling (Container : Set; Key : Key_Type) return Cursor; 72/2 function Contains (Container : Set; Key : Key_Type) return Boolean; 73/2 procedure Update_Element_Preserving_Key (Container : in out Set; Position : in Cursor; Process : not null access procedure (Element : in out Element_Type)); 73.1/3 type Reference_Type (Element : not null access Element_Type) is private with Implicit_Dereference => Element; 73.2/3 function Reference_Preserving_Key (Container : aliased in out Set; Position : in Cursor) return Reference_Type; 73.3/3 function Constant_Reference (Container : aliased in Set; Key : in Key_Type) return Constant_Reference_Type; 73.4/3 function Reference_Preserving_Key (Container : aliased in out Set; Key : in Key_Type) return Reference_Type; 74/2 end Generic_Keys; 75/2 private 76/2 ... -- not specified by the language 77/2 end Ada.Containers.Ordered_Sets; 78/2 Two elements E1 and E2 are equivalent if both E1 < E2 and E2 < E1 return False, using the generic formal "<" operator for elements. Function Equivalent_Elements returns True if Left and Right are equivalent, and False otherwise. 79/3 The actual function for the generic formal function "<" on Element_Type values is expected to return the same value each time it is called with a particular pair of key values. It should define a strict weak ordering relationship (see A.18). If the actual for "<" behaves in some other manner, the behavior of this package is unspecified. Which subprograms of this package call "<" and how many times they call it, is unspecified. 79.1/3 If the actual function for the generic formal function "=" returns True for any pair of nonequivalent elements, then the behavior of the container function "=" is unspecified. 80/2 If the value of an element stored in a set is changed other than by an operation in this package such that at least one of "<" or "=" give different results, the behavior of this package is unspecified. 81/3 The first element of a nonempty set is the one which is less than all the other elements in the set. The last element of a nonempty set is the one which is greater than all the other elements in the set. The successor of an element is the smallest element that is larger than the given element. The predecessor of an element is the largest element that is smaller than the given element. All comparisons are done using the generic formal "<" operator for elements. 81.1/3 function Copy (Source : Set) return Set; 81.2/3 Returns a set whose elements are initialized from the corresponding elements of Source. 82/2 procedure Delete_First (Container : in out Set); 83/3 If Container is empty, Delete_First has no effect. Otherwise, the element designated by First (Container) is removed from Container. Delete_First tampers with the cursors of Container. 84/2 procedure Delete_Last (Container : in out Set); 85/3 If Container is empty, Delete_Last has no effect. Otherwise, the element designated by Last (Container) is removed from Container. Delete_Last tampers with the cursors of Container. 86/2 function First_Element (Container : Set) return Element_Type; 87/2 Equivalent to Element (First (Container)). 88/2 function Last (Container : Set) return Cursor; 89/2 Returns a cursor that designates the last element in Container. If Container is empty, returns No_Element. 90/2 function Last_Element (Container : Set) return Element_Type; 91/2 Equivalent to Element (Last (Container)). 92/2 function Previous (Position : Cursor) return Cursor; 93/3 If Position equals No_Element, then Previous returns No_Element. Otherwise, Previous returns a cursor designating the predecessor element of the one designated by Position. If Position designates the first element, then Previous returns No_Element. 94/2 procedure Previous (Position : in out Cursor); 95/2 Equivalent to Position := Previous (Position). 96/2 function Floor (Container : Set; Item : Element_Type) return Cursor; 97/3 Floor searches for the last element which is not greater than Item. If such an element is found, a cursor that designates it is returned. Otherwise, No_Element is returned. 98/2 function Ceiling (Container : Set; Item : Element_Type) return Cursor; 99/3 Ceiling searches for the first element which is not less than Item. If such an element is found, a cursor that designates it is returned. Otherwise, No_Element is returned. 100/2 function "<" (Left, Right : Cursor) return Boolean; 101/2 Equivalent to Element (Left) < Element (Right). 102/2 function ">" (Left, Right : Cursor) return Boolean; 103/2 Equivalent to Element (Right) < Element (Left). 104/2 function "<" (Left : Cursor; Right : Element_Type) return Boolean; 105/2 Equivalent to Element (Left) < Right. 106/2 function ">" (Left : Cursor; Right : Element_Type) return Boolean; 107/2 Equivalent to Right < Element (Left). 108/2 function "<" (Left : Element_Type; Right : Cursor) return Boolean; 109/2 Equivalent to Left < Element (Right). 110/2 function ">" (Left : Element_Type; Right : Cursor) return Boolean; 111/2 Equivalent to Element (Right) < Left. 112/2 procedure Reverse_Iterate (Container : in Set; Process : not null access procedure (Position : in Cursor)); 113/3 Iterates over the elements in Container as per procedure Iterate, with the difference that the elements are traversed in predecessor order, starting with the last element. 113.1/3 function Iterate (Container : in Set) return Set_Iterator_Interfaces.Reversible_Iterator'Class; 113.2/3 Iterate returns a reversible iterator object (see 5.5.1) that will generate a value for a loop parameter (see 5.5.2) designating each element in Container, starting with the first element and moving the cursor according to the successor relation when used as a forward iterator, and starting with the last element and moving the cursor according to the predecessor relation when used as a reverse iterator. Tampering with the cursors of Container is prohibited while the iterator object exists (in particular, in the sequence_of_statements of the loop_statement whose iterator_specification denotes this object). The iterator object needs finalization. 113.3/3 function Iterate (Container : in Set; Start : in Cursor) return Set_Iterator_Interfaces.Reversible_Iterator'Class; 113.4/3 If Start is not No_Element and does not designate an item in Container, then Program_Error is propagated. If Start is No_Element, then Constraint_Error is propagated. Otherwise, Iterate returns a reversible iterator object (see 5.5.1) that will generate a value for a loop parameter (see 5.5.2) designating each element in Container, starting with the element designated by Start and moving the cursor according to the successor relation when used as a forward iterator, or moving the cursor according to the predecessor relation when used as a reverse iterator. Tampering with the cursors of Container is prohibited while the iterator object exists (in particular, in the sequence_of_statements of the loop_statement whose iterator_specification denotes this object). The iterator object needs finalization. 114/2 For any two elements E1 and E2, the boolean values (E1 < E2) and (Key(E1) < Key(E2)) are expected to be equal. If the actuals for Key or Generic_Keys."<" behave in some other manner, the behavior of this package is unspecified. Which subprograms of this package call Key and Generic_Keys."<", and how many times the functions are called, is unspecified. 115/2 In addition to the semantics described in A.18.7, the subprograms in package Generic_Keys named Floor and Ceiling, are equivalent to the corresponding subprograms in the parent package, with the difference that the Key subprogram parameter is compared to elements in the container using the Key and "<" generic formal functions. The function named Equivalent_Keys in package Generic_Keys returns True if both Left < Right and Right < Left return False using the generic formal "<" operator, and returns True otherwise. Implementation Advice 116/2 If N is the length of a set, then the worst-case time complexity of the Insert, Include, Replace, Delete, Exclude and Find operations that take an element parameter should be O((log N)**2) or better. The worst-case time complexity of the subprograms that take a cursor parameter should be O(1). A.18.10 The Generic Package Containers.Multiway_Trees 1/3 The language-defined generic package Containers.Multiway_Trees provides private types Tree and Cursor, and a set of operations for each type. A multiway tree container is well-suited to represent nested structures. 2/4 A multiway tree container object manages a tree of nodes, consisting of a root node and a set of internal nodes; each internal node contains an element and pointers to the parent, first child, last child, next (successor) sibling, and previous (predecessor) sibling internal nodes. A cursor designates a particular node within a tree (and by extension the element contained in that node, if any). A cursor keeps designating the same node (and element) as long as the node is part of the container, even if the node is moved within the container. 3/4 A subtree is a particular node (which roots the subtree) and all of its child nodes (including all of the children of the child nodes, recursively). The root node is always present and has neither an associated element value nor any parent node; it has pointers to its first child and its last child, if any. The root node provides a place to add nodes to an otherwise empty tree and represents the base of the tree. 4/3 A node that has no children is called a leaf node. The ancestors of a node are the node itself, its parent node, the parent of the parent node, and so on until a node with no parent is reached. Similarly, the descendants of a node are the node itself, its child nodes, the children of each child node, and so on. 5/3 The nodes of a subtree can be visited in several different orders. For a depth-first order, after visiting a node, the nodes of its child list are each visited in depth-first order, with each child node visited in natural order (first child to last child). Static Semantics 6/3 The generic library package Containers.Multiway_Trees has the following declaration: 7/3 with Ada.Iterator_Interfaces; generic type Element_Type is private; with function "=" (Left, Right : Element_Type) return Boolean is <>; package Ada.Containers.Multiway_Trees is pragma Preelaborate(Multiway_Trees); pragma Remote_Types(Multiway_Trees); 8/3 type Tree is tagged private with Constant_Indexing => Constant_Reference, Variable_Indexing => Reference, Default_Iterator => Iterate, Iterator_Element => Element_Type; pragma Preelaborable_Initialization(Tree); 9/3 type Cursor is private; pragma Preelaborable_Initialization(Cursor); 10/3 Empty_Tree : constant Tree; 11/3 No_Element : constant Cursor; 12/3 function Has_Element (Position : Cursor) return Boolean; 13/3 package Tree_Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, Has_Element); 14/3 function Equal_Subtree (Left_Position : Cursor; Right_Position: Cursor) return Boolean; 15/3 function "=" (Left, Right : Tree) return Boolean; 16/3 function Is_Empty (Container : Tree) return Boolean; 17/3 function Node_Count (Container : Tree) return Count_Type; 18/3 function Subtree_Node_Count (Position : Cursor) return Count_Type; 19/3 function Depth (Position : Cursor) return Count_Type; 20/3 function Is_Root (Position : Cursor) return Boolean; 21/3 function Is_Leaf (Position : Cursor) return Boolean; 22/3 function Root (Container : Tree) return Cursor; 23/3 procedure Clear (Container : in out Tree); 24/3 function Element (Position : Cursor) return Element_Type; 25/3 procedure Replace_Element (Container : in out Tree; Position : in Cursor; New_Item : in Element_Type); 26/3 procedure Query_Element (Position : in Cursor; Process : not null access procedure (Element : in Element_Type)); 27/3 procedure Update_Element (Container : in out Tree; Position : in Cursor; Process : not null access procedure (Element : in out Element_Type)); 28/3 type Constant_Reference_Type (Element : not null access constant Element_Type) is private with Implicit_Dereference => Element; 29/3 type Reference_Type (Element : not null access Element_Type) is private with Implicit_Dereference => Element; 30/3 function Constant_Reference (Container : aliased in Tree; Position : in Cursor) return Constant_Reference_Type; 31/3 function Reference (Container : aliased in out Tree; Position : in Cursor) return Reference_Type; 32/3 procedure Assign (Target : in out Tree; Source : in Tree); 33/3 function Copy (Source : Tree) return Tree; 34/3 procedure Move (Target : in out Tree; Source : in out Tree); 35/3 procedure Delete_Leaf (Container : in out Tree; Position : in out Cursor); 36/3 procedure Delete_Subtree (Container : in out Tree; Position : in out Cursor); 37/3 procedure Swap (Container : in out Tree; I, J : in Cursor); 38/3 function Find (Container : Tree; Item : Element_Type) return Cursor; 39/3 function Find_In_Subtree (Position : Cursor; Item : Element_Type) return Cursor; 40/3 function Ancestor_Find (Position : Cursor; Item : Element_Type) return Cursor; 41/3 function Contains (Container : Tree; Item : Element_Type) return Boolean; 42/3 procedure Iterate (Container : in Tree; Process : not null access procedure (Position : in Cursor)); 43/3 procedure Iterate_Subtree (Position : in Cursor; Process : not null access procedure (Position : in Cursor)); 44/3 function Iterate (Container : in Tree) return Tree_Iterator_Interfaces.Forward_Iterator'Class; 45/3 function Iterate_Subtree (Position : in Cursor) return Tree_Iterator_Interfaces.Forward_Iterator'Class; 46/3 function Child_Count (Parent : Cursor) return Count_Type; 47/3 function Child_Depth (Parent, Child : Cursor) return Count_Type; 48/3 procedure Insert_Child (Container : in out Tree; Parent : in Cursor; Before : in Cursor; New_Item : in Element_Type; Count : in Count_Type := 1); 49/3 procedure Insert_Child (Container : in out Tree; Parent : in Cursor; Before : in Cursor; New_Item : in Element_Type; Position : out Cursor; Count : in Count_Type := 1); 50/3 procedure Insert_Child (Container : in out Tree; Parent : in Cursor; Before : in Cursor; Position : out Cursor; Count : in Count_Type := 1); 51/3 procedure Prepend_Child (Container : in out Tree; Parent : in Cursor; New_Item : in Element_Type; Count : in Count_Type := 1); 52/3 procedure Append_Child (Container : in out Tree; Parent : in Cursor; New_Item : in Element_Type; Count : in Count_Type := 1); 53/3 procedure Delete_Children (Container : in out Tree; Parent : in Cursor); 54/3 procedure Copy_Subtree (Target : in out Tree; Parent : in Cursor; Before : in Cursor; Source : in Cursor); 55/3 procedure Splice_Subtree (Target : in out Tree; Parent : in Cursor; Before : in Cursor; Source : in out Tree; Position : in out Cursor); 56/3 procedure Splice_Subtree (Container: in out Tree; Parent : in Cursor; Before : in Cursor; Position : in Cursor); 57/3 procedure Splice_Children (Target : in out Tree; Target_Parent : in Cursor; Before : in Cursor; Source : in out Tree; Source_Parent : in Cursor); 58/3 procedure Splice_Children (Container : in out Tree; Target_Parent : in Cursor; Before : in Cursor; Source_Parent : in Cursor); 59/3 function Parent (Position : Cursor) return Cursor; 60/3 function First_Child (Parent : Cursor) return Cursor; 61/3 function First_Child_Element (Parent : Cursor) return Element_Type; 62/3 function Last_Child (Parent : Cursor) return Cursor; 63/3 function Last_Child_Element (Parent : Cursor) return Element_Type; 64/3 function Next_Sibling (Position : Cursor) return Cursor; 65/3 function Previous_Sibling (Position : Cursor) return Cursor; 66/3 procedure Next_Sibling (Position : in out Cursor); 67/3 procedure Previous_Sibling (Position : in out Cursor); 68/3 procedure Iterate_Children (Parent : in Cursor; Process : not null access procedure (Position : in Cursor)); 69/3 procedure Reverse_Iterate_Children (Parent : in Cursor; Process : not null access procedure (Position : in Cursor)); 70/3 function Iterate_Children (Container : in Tree; Parent : in Cursor) return Tree_Iterator_Interfaces.Reversible_Iterator'Class; 71/3 private ... -- not specified by the language end Ada.Containers.Multiway_Trees; 72/3 The actual function for the generic formal function "=" on Element_Type values is expected to define a reflexive and symmetric relationship and return the same result value each time it is called with a particular pair of values. If it behaves in some other manner, the functions Find, Reverse_Find, Equal_Subtree, and "=" on tree values return an unspecified value. The exact arguments and number of calls of this generic formal function by the functions Find, Reverse_Find, Equal_Subtree, and "=" on tree values are unspecified. 73/3 The type Tree is used to represent trees. The type Tree needs finalization (see 7.6). 74/3 Empty_Tree represents the empty Tree object. It contains only the root node (Node_Count (Empty_Tree) returns 1). If an object of type Tree is not otherwise initialized, it is initialized to the same value as Empty_Tree. 75/3 No_Element represents a cursor that designates no element. If an object of type Cursor is not otherwise initialized, it is initialized to the same value as No_Element. 76/3 The predefined "=" operator for type Cursor returns True if both cursors are No_Element, or designate the same element in the same container. 77/3 Execution of the default implementation of the Input, Output, Read, or Write attribute of type Cursor raises Program_Error. 78/3 Tree'Write for a Tree object T writes Node_Count(T) - 1 elements of the tree to the stream. It also may write additional information about the tree. 79/3 Tree'Read reads the representation of a tree from the stream, and assigns to Item a tree with the same elements and structure as was written by Tree'Write. 80/3 Some operations of this generic package have access-to-subprogram parameters. To ensure such operations are well-defined, they guard against certain actions by the designated subprogram. In particular, some operations check for "tampering with cursors" of a container because they depend on the set of elements of the container remaining constant, and others check for "tampering with elements" of a container because they depend on elements of the container not being replaced. 81/3 A subprogram is said to tamper with cursors of a tree object T if: 82/3 * it inserts or deletes elements of T, that is, it calls the Clear, Delete_Leaf, Insert_Child, Delete_Children, Delete_Subtree, or Copy_Subtree procedures with T as a parameter; or 83/3 * it reorders the elements of T, that is, it calls the Splice_Subtree or Splice_Children procedures with T as a parameter; or 84/3 * it finalizes T; or 85/3 * it calls Assign with T as the Target parameter; or 86/3 * it calls the Move procedure with T as a parameter. 87/3 A subprogram is said to tamper with elements of a tree object T if: 88/3 * it tampers with cursors of T; or 89/3 * it replaces one or more elements of T, that is, it calls the Replace_Element or Swap procedures with T as a parameter. 90/4 When tampering with cursors is prohibited for a particular tree object T, Program_Error is propagated by a call of any language-defined subprogram that is defined to tamper with the cursors of T, leaving T unmodified. Similarly, when tampering with elements is prohibited for a particular tree object T, Program_Error is propagated by a call of any language-defined subprogram that is defined to tamper with the elements of T (or tamper with the cursors of T), leaving T unmodified. These checks are made before any other defined behavior of the body of the language-defined subprogram. 91/3 function Has_Element (Position : Cursor) return Boolean; 92/3 Returns True if Position designates an element, and returns False otherwise. In particular, Has_Element returns False if the cursor designates a root node or equals No_Element. 93/3 function Equal_Subtree (Left_Position : Cursor; Right_Position: Cursor) return Boolean; 94/3 If Left_Position or Right_Position equals No_Element, propagates Constraint_Error. If the number of child nodes of the element designated by Left_Position is different from the number of child nodes of the element designated by Right_Position, the function returns False. If Left_Position designates a root node and Right_Position does not, the function returns False. If Right_Position designates a root node and Left_Position does not, the function returns False. Unless both cursors designate a root node, the elements are compared using the generic formal equality operator. If the result of the element comparison is False, the function returns False. Otherwise, it calls Equal_Subtree on a cursor designating each child element of the element designated by Left_Position and a cursor designating the corresponding child element of the element designated by Right_Position. If any such call returns False, the function returns False; otherwise, it returns True. Any exception raised during the evaluation of element equality is propagated. 95/3 function "=" (Left, Right : Tree) return Boolean; 96/3 If Left and Right denote the same tree object, then the function returns True. Otherwise, it calls Equal_Subtree with cursors designating the root nodes of Left and Right; the result is returned. Any exception raised during the evaluation of Equal_Subtree is propagated. 97/3 function Node_Count (Container : Tree) return Count_Type; 98/3 Node_Count returns the number of nodes in Container. 99/3 function Subtree_Node_Count (Position : Cursor) return Count_Type; 100/3 If Position is No_Element, Subtree_Node_Count returns 0; otherwise, Subtree_Node_Count returns the number of nodes in the subtree that is rooted by Position. 101/3 function Is_Empty (Container : Tree) return Boolean; 102/3 Equivalent to Node_Count (Container) = 1. 103/3 function Depth (Position : Cursor) return Count_Type; 104/3 If Position equals No_Element, Depth returns 0; otherwise, Depth returns the number of ancestor nodes of the node designated by Position (including the node itself). 105/3 function Is_Root (Position : Cursor) return Boolean; 106/3 Is_Root returns True if the Position designates the root node of some tree; and returns False otherwise. 107/3 function Is_Leaf (Position : Cursor) return Boolean; 108/3 Is_Leaf returns True if Position designates a node that does not have any child nodes; and returns False otherwise. 109/3 function Root (Container : Tree) return Cursor; 110/3 Root returns a cursor that designates the root node of Container. 111/3 procedure Clear (Container : in out Tree); 112/3 Removes all the elements from Container. 113/3 function Element (Position : Cursor) return Element_Type; 114/3 If Position equals No_Element, then Constraint_Error is propagated; if Position designates the root node of a tree, then Program_Error is propagated. Otherwise, Element returns the element designated by Position. 115/3 procedure Replace_Element (Container : in out Tree; Position : in Cursor; New_Item : in Element_Type); 116/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container (including if it designates the root node), then Program_Error is propagated. Otherwise, Replace_Element assigns the value New_Item to the element designated by Position. 117/3 procedure Query_Element (Position : in Cursor; Process : not null access procedure (Element : in Element_Type)); 118/3 If Position equals No_Element, then Constraint_Error is propagated; if Position designates the root node of a tree, then Program_Error is propagated. Otherwise, Query_Element calls Process.all with the element designated by Position as the argument. Tampering with the elements of the tree that contains the element designated by Position is prohibited during the execution of the call on Process.all. Any exception raised by Process.all is propagated. 119/3 procedure Update_Element (Container : in out Tree; Position : in Cursor; Process : not null access procedure (Element : in out Element_Type)); 120/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container (including if it designates the root node), then Program_Error is propagated. Otherwise, Update_Element calls Process.all with the element designated by Position as the argument. Tampering with the elements of Container is prohibited during the execution of the call on Process.all. Any exception raised by Process.all is propagated. 121/3 If Element_Type is unconstrained and definite, then the actual Element parameter of Process.all shall be unconstrained. 122/3 type Constant_Reference_Type (Element : not null access constant Element_Type) is private with Implicit_Dereference => Element; 123/3 type Reference_Type (Element : not null access Element_Type) is private with Implicit_Dereference => Element; 124/3 The types Constant_Reference_Type and Reference_Type need finalization. 125/3 The default initialization of an object of type Constant_Reference_Type or Reference_Type propagates Program_Error. 126/3 function Constant_Reference (Container : aliased in Tree; Position : in Cursor) return Constant_Reference_Type; 127/3 This function (combined with the Constant_Indexing and Implicit_Dereference aspects) provides a convenient way to gain read access to an individual element of a tree given a cursor. 128/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Constant_Reference returns an object whose discriminant is an access value that designates the element designated by Position. Tampering with the elements of Container is prohibited while the object returned by Constant_Reference exists and has not been finalized. 129/3 function Reference (Container : aliased in out Tree; Position : in Cursor) return Reference_Type; 130/3 This function (combined with the Variable_Indexing and Implicit_Dereference aspects) provides a convenient way to gain read and write access to an individual element of a tree given a cursor. 131/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container, then Program_Error is propagated. Otherwise, Reference returns an object whose discriminant is an access value that designates the element designated by Position. Tampering with the elements of Container is prohibited while the object returned by Reference exists and has not been finalized. 132/3 procedure Assign (Target : in out Tree; Source : in Tree); 133/3 If Target denotes the same object as Source, the operation has no effect. Otherwise, the elements of Source are copied to Target as for an assignment_statement assigning Source to Target. 134/3 function Copy (Source : Tree) return Tree; 135/3 Returns a tree with the same structure as Source and whose elements are initialized from the corresponding elements of Source. 136/3 procedure Move (Target : in out Tree; Source : in out Tree); 137/3 If Target denotes the same object as Source, then the operation has no effect. Otherwise, Move first calls Clear (Target). Then, the nodes other than the root node in Source are moved to Target (in the same positions). After Move completes, Node_Count (Target) is the number of nodes originally in Source, and Node_Count (Source) is 1. 138/3 procedure Delete_Leaf (Container : in out Tree; Position : in out Cursor); 139/3 If Position equals No_Element, then Constraint_Error is propagated; if Position does not designate an element in Container (including if it designates the root node), then Program_Error is propagated. If the element designated by position has any child elements, then Constraint_Error is propagated. Otherwise, Delete_Leaf removes (from Container) the element designated by Position. Finally, Position is set to No_Element. 140/3 procedure Delete_Subtree (Container : in out Tree; Position : in out Cursor); 141/3 If Position equals No_Element, then Constraint_Error is propagated. If Position does not designate an element in Container (including if it designates the root node), then Program_Error is propagated. Otherwise, Delete_Subtree removes (from Container) the subtree designated by Position (that is, all descendants of the node designated by Position including the node itself), and Position is set to No_Element. 142/3 procedure Swap (Container : in out Tree; I, J : in Cursor); 143/3 If either I or J equals No_Element, then Constraint_Error is propagated. If either I or J do not designate an element in Container (including if either designates the root node), then Program_Error is propagated. Otherwise, Swap exchanges the values of the elements designated by I and J. 144/3 function Find (Container : Tree; Item : Element_Type) return Cursor; 145/3 Find searches the elements of Container for an element equal to Item (using the generic formal equality operator). The search starts at the root node. The search traverses the tree in a depth-first order. If no equal element is found, then Find returns No_Element. Otherwise, it returns a cursor designating the first equal element encountered. 146/3 function Find_In_Subtree (Position : Cursor; Item : Element_Type) return Cursor; 147/3 If Position equals No_Element, then Constraint_Error is propagated. Find_In_Subtree searches the subtree rooted by Position for an element equal to Item (using the generic formal equality operator). The search starts at the element designated by Position. The search traverses the subtree in a depth-first order. If no equal element is found, then Find returns No_Element. Otherwise, it returns a cursor designating the first equal element encountered. 148/3 function Ancestor_Find (Position : Cursor; Item : Element_Type) return Cursor; 149/3 If Position equals No_Element, then Constraint_Error is propagated. Otherwise, Ancestor_Find searches for an element equal to Item (using the generic formal equality operator). The search starts at the node designated by Position, and checks each ancestor proceeding toward the root of the subtree. If no equal element is found, then Ancestor_Find returns No_Element. Otherwise, it returns a cursor designating the first equal element encountered. 150/3 function Contains (Container : Tree; Item : Element_Type) return Boolean; 151/3 Equivalent to Find (Container, Item) /= No_Element. 152/3 procedure Iterate (Container : in Tree; Process : not null access procedure (Position : in Cursor)); 153/4 Iterate calls Process.all with a cursor that designates each element in Container, starting from the root node and proceeding in a depth-first order. Tampering with the cursors of Container is prohibited during the execution of a call on Process.all. Any exception raised by Process.all is propagated. 154/3 procedure Iterate_Subtree (Position : in Cursor; Process : not null access procedure (Position : in Cursor)); 155/4 If Position equals No_Element, then Constraint_Error is propagated. Otherwise, Iterate_Subtree calls Process.all with a cursor that designates each element in the subtree rooted by the node designated by Position, starting from the node designated by Position and proceeding in a depth-first order. Tampering with the cursors of the tree that contains the element designated by Position is prohibited during the execution of a call on Process.all. Any exception raised by Process.all is propagated. 156/3 function Iterate (Container : in Tree) return Tree_Iterator_Interfaces.Forward_Iterator'Class; 157/4 Iterate returns an iterator object (see 5.5.1) that will generate a value for a loop parameter (see 5.5.2) designating each element in Container, starting from the root node and proceeding in a depth-first order. Tampering with the cursors of Container is prohibited while the iterator object exists (in particular, in the sequence_of_statements of the loop_statement whose iterator_specification denotes this object). The iterator object needs finalization. 158/3 function Iterate_Subtree (Position : in Cursor) return Tree_Iterator_Interfaces.Forward_Iterator'Class; 159/4 If Position equals No_Element, then Constraint_Error is propagated. Otherwise, Iterate_Subtree returns an iterator object (see 5.5.1) that will generate a value for a loop parameter (see 5.5.2) designating each element in the subtree rooted by the node designated by Position, starting from the node designated by Position and proceeding in a depth-first order. If Position equals No_Element, then Constraint_Error is propagated. Tampering with the cursors of the container that contains the node designated by Position is prohibited while the iterator object exists (in particular, in the sequence_of_statements of the loop_statement whose iterator_specification denotes this object). The iterator object needs finalization. 160/3 function Child_Count (Parent : Cursor) return Count_Type; 161/3 Child_Count returns the number of child nodes of the node designated by Parent. 162/3 function Child_Depth (Parent, Child : Cursor) return Count_Type; 163/3 If Child or Parent is equal to No_Element, then Constraint_Error is propagated. Otherwise, Child_Depth returns the number of ancestor nodes of Child (including Child itself), up to but not including Parent; Program_Error is propagated if Parent is not an ancestor of Child. 164/3 procedure Insert_Child (Container : in out Tree; Parent : in Cursor; Before : in Cursor; New_Item : in Element_Type; Count : in Count_Type := 1); 165/3 If Parent equals No_Element, then Constraint_Error is propagated. If Parent does not designate a node in Container, then Program_Error is propagated. If Before is not equal to No_Element, and does not designate a node in Container, then Program_Error is propagated. If Before is not equal to No_Element, and Parent does not designate the parent node of the node designated by Before, then Constraint_Error is propagated. Otherwise, Insert_Child allocates Count nodes containing copies of New_Item and inserts them as children of Parent. If Parent already has child nodes, then the new nodes are inserted prior to the node designated by Before, or, if Before equals No_Element, the new nodes are inserted after the last existing child node of Parent. Any exception raised during allocation of internal storage is propagated, and Container is not modified. 166/3 procedure Insert_Child (Container : in out Tree; Parent : in Cursor; Before : in Cursor; New_Item : in Element_Type; Position : out Cursor; Count : in Count_Type := 1); 167/3 If Parent equals No_Element, then Constraint_Error is propagated. If Parent does not designate a node in Container, then Program_Error is propagated. If Before is not equal to No_Element, and does not designate a node in Container, then Program_Error is propagated. If Before is not equal to No_Element, and Parent does not designate the parent node of the node designated by Before, then Constraint_Error is propagated. Otherwise, Insert_Child allocates Count nodes containing copies of New_Item and inserts them as children of Parent. If Parent already has child nodes, then the new nodes are inserted prior to the node designated by Before, or, if Before equals No_Element, the new nodes are inserted after the last existing child node of Parent. Position designates the first newly-inserted node, or if Count equals 0, then Position is assigned the value of Before. Any exception raised during allocation of internal storage is propagated, and Container is not modified. 168/3 procedure Insert_Child (Container : in out Tree; Parent : in Cursor; Before : in Cursor; Position : out Cursor; Count : in Count_Type := 1); 169/3 If Parent equals No_Element, then Constraint_Error is propagated. If Parent does not designate a node in Container, then Program_Error is propagated. If Before is not equal to No_Element, and does not designate a node in Container, then Program_Error is propagated. If Before is not equal to No_Element, and Parent does not designate the parent node of the node designated by Before, then Constraint_Error is propagated. Otherwise, Insert_Child allocates Count nodes, the elements contained in the new nodes are initialized by default (see 3.3.1), and the new nodes are inserted as children of Parent. If Parent already has child nodes, then the new nodes are inserted prior to the node designated by Before, or, if Before equals No_Element, the new nodes are inserted after the last existing child node of Parent. Position designates the first newly-inserted node, or if Count equals 0, then Position is assigned the value of Before. Any exception raised during allocation of internal storage is propagated, and Container is not modified. 170/3 procedure Prepend_Child (Container : in out Tree; Parent : in Cursor; New_Item : in Element_Type; Count : in Count_Type := 1); 171/3 Equivalent to Insert_Child (Container, Parent, First_Child (Container, Parent), New_Item, Count). 172/3 procedure Append_Child (Container : in out Tree; Parent : in Cursor; New_Item : in Element_Type; Count : in Count_Type := 1); 173/3 Equivalent to Insert_Child (Container, Parent, No_Element, New_Item, Count). 174/3 procedure Delete_Children (Container : in out Tree; Parent : in Cursor); 175/3 If Parent equals No_Element, then Constraint_Error is propagated. If Parent does not designate a node in Container, Program_Error is propagated. Otherwise, Delete_Children removes (from Container) all of the descendants of Parent other than Parent itself. 176/3 procedure Copy_Subtree (Target : in out Tree; Parent : in Cursor; Before : in Cursor; Source : in Cursor); 177/3 If Parent equals No_Element, then Constraint_Error is propagated. If Parent does not designate a node in Target, then Program_Error is propagated. If Before is not equal to No_Element, and does not designate a node in Target, then Program_Error is propagated. If Before is not equal to No_Element, and Parent does not designate the parent node of the node designated by Before, then Constraint_Error is propagated. If Source designates a root node, then Constraint_Error is propagated. If Source is equal to No_Element, then the operation has no effect. Otherwise, the subtree rooted by Source (which can be from any tree; it does not have to be a subtree of Target) is copied (new nodes are allocated to create a new subtree with the same structure as the Source subtree, with each element initialized from the corresponding element of the Source subtree) and inserted into Target as a child of Parent. If Parent already has child nodes, then the new nodes are inserted prior to the node designated by Before, or, if Before equals No_Element, the new nodes are inserted after the last existing child node of Parent. The parent of the newly created subtree is set to Parent, and the overall count of Target is incremented by Subtree_Node_Count (Source). Any exception raised during allocation of internal storage is propagated, and Container is not modified. 178/3 procedure Splice_Subtree (Target : in out Tree; Parent : in Cursor; Before : in Cursor; Source : in out Tree; Position : in out Cursor); 179/3 If Parent equals No_Element, then Constraint_Error is propagated. If Parent does not designate a node in Target, then Program_Error is propagated. If Before is not equal to No_Element, and does not designate a node in Target, then Program_Error is propagated. If Before is not equal to No_Element, and Parent does not designate the parent node of the node designated by Before, then Constraint_Error is propagated. If Position equals No_Element, Constraint_Error is propagated. If Position does not designate a node in Source or designates a root node, then Program_Error is propagated. If Source denotes the same object as Target, then: if Position equals Before there is no effect; if Position designates an ancestor of Parent (including Parent itself), Constraint_Error is propagated; otherwise, the subtree rooted by the element designated by Position is moved to be a child of Parent. If Parent already has child nodes, then the moved nodes are inserted prior to the node designated by Before, or, if Before equals No_Element, the moved nodes are inserted after the last existing child node of Parent. In each of these cases, Position and the count of Target are unchanged, and the parent of the element designated by Position is set to Parent. 180/3 Otherwise (if Source does not denote the same object as Target), the subtree designated by Position is removed from Source and moved to Target. The subtree is inserted as a child of Parent. If Parent already has child nodes, then the moved nodes are inserted prior to the node designated by Before, or, if Before equals No_Element, the moved nodes are inserted after the last existing child node of Parent. In each of these cases, the count of Target is incremented by Subtree_Node_Count (Position), and the count of Source is decremented by Subtree_Node_Count (Position), Position is updated to represent an element in Target. 181/3 procedure Splice_Subtree (Container: in out Tree; Parent : in Cursor; Before : in Cursor; Position : in Cursor); 182/3 If Parent equals No_Element, then Constraint_Error is propagated. If Parent does not designate a node in Container, then Program_Error is propagated. If Before is not equal to No_Element, and does not designate a node in Container, then Program_Error is propagated. If Before is not equal to No_Element, and Parent does not designate the parent node of the node designated by Before, then Constraint_Error is propagated. If Position equals No_Element, Constraint_Error is propagated. If Position does not designate a node in Container or designates a root node, then Program_Error is propagated. If Position equals Before, there is no effect. If Position designates an ancestor of Parent (including Parent itself), Constraint_Error is propagated. Otherwise, the subtree rooted by the element designated by Position is moved to be a child of Parent. If Parent already has child nodes, then the moved nodes are inserted prior to the node designated by Before, or, if Before equals No_Element, the moved nodes are inserted after the last existing child node of Parent. The parent of the element designated by Position is set to Parent. 183/3 procedure Splice_Children (Target : in out Tree; Target_Parent : in Cursor; Before : in Cursor; Source : in out Tree; Source_Parent : in Cursor); 184/3 If Target_Parent equals No_Element, then Constraint_Error is propagated. If Target_Parent does not designate a node in Target, then Program_Error is propagated. If Before is not equal to No_Element, and does not designate an element in Target, then Program_Error is propagated. If Source_Parent equals No_Element, then Constraint_Error is propagated. If Source_Parent does not designate a node in Source, then Program_Error is propagated. If Before is not equal to No_Element, and Target_Parent does not designate the parent node of the node designated by Before, then Constraint_Error is propagated. 185/3 If Source denotes the same object as Target, then: 186/3 * if Target_Parent equals Source_Parent there is no effect; else 187/3 * if Source_Parent is an ancestor of Target_Parent other than Target_Parent itself, then Constraint_Error is propagated; else 188/3 * the child elements (and the further descendants) of Source_Parent are moved to be child elements of Target_Parent. If Target_Parent already has child elements, then the moved elements are inserted prior to the node designated by Before, or, if Before equals No_Element, the moved elements are inserted after the last existing child node of Target_Parent. The parent of each moved child element is set to Target_Parent. 189/3 Otherwise (if Source does not denote the same object as Target), the child elements (and the further descendants) of Source_Parent are removed from Source and moved to Target. The child elements are inserted as children of Target_Parent. If Target_Parent already has child elements, then the moved elements are inserted prior to the node designated by Before, or, if Before equals No_Element, the moved elements are inserted after the last existing child node of Target_Parent. In each of these cases, the overall count of Target is incremented by Subtree_Node_Count (Source_Parent)-1, and the overall count of Source is decremented by Subtree_Node_Count (Source_Parent)-1. 190/3 procedure Splice_Children (Container : in out Tree; Target_Parent : in Cursor; Before : in Cursor; Source_Parent : in Cursor); 191/3 If Target_Parent equals No_Element, then Constraint_Error is propagated. If Target_Parent does not designate a node in Container, then Program_Error is propagated. If Before is not equal to No_Element, and does not designate an element in Container, then Program_Error is propagated. If Source_Parent equals No_Element, then Constraint_Error is propagated. If Source_Parent does not designate a node in Container, then Program_Error is propagated. If Before is not equal to No_Element, and Target_Parent does not designate the parent node of the node designated by Before, then Constraint_Error is propagated. If Target_Parent equals Source_Parent there is no effect. If Source_Parent is an ancestor of Target_Parent other than Target_Parent itself, then Constraint_Error is propagated. Otherwise, the child elements (and the further descendants) of Source_Parent are moved to be child elements of Target_Parent. If Target_Parent already has child elements, then the moved elements are inserted prior to the node designated by Before, or, if Before equals No_Element, the moved elements are inserted after the last existing child node of Target_Parent. The parent of each moved child element is set to Target_Parent. 192/3 function Parent (Position : Cursor) return Cursor; 193/3 If Position is equal to No_Element or designates a root node, No_Element is returned. Otherwise, a cursor designating the parent node of the node designated by Position is returned. 194/3 function First_Child (Parent : Cursor) return Cursor; 195/3 If Parent is equal to No_Element, then Constraint_Error is propagated. Otherwise, First_Child returns a cursor designating the first child node of the node designated by Parent; if there is no such node, No_Element is returned. 196/3 function First_Child_Element (Parent : Cursor) return Element_Type; 197/3 Equivalent to Element (First_Child (Parent)). 198/3 function Last_Child (Parent : Cursor) return Cursor; 199/3 If Parent is equal to No_Element, then Constraint_Error is propagated. Otherwise, Last_Child returns a cursor designating the last child node of the node designated by Parent; if there is no such node, No_Element is returned. 200/3 function Last_Child_Element (Parent : Cursor) return Element_Type; 201/3 Equivalent to Element (Last_Child (Parent)). 202/3 function Next_Sibling (Position : Cursor) return Cursor; 203/3 If Position equals No_Element or designates the last child node of its parent, then Next_Sibling returns the value No_Element. Otherwise, it returns a cursor that designates the successor (with the same parent) of the node designated by Position. 204/3 function Previous_Sibling (Position : Cursor) return Cursor; 205/3 If Position equals No_Element or designates the first child node of its parent, then Previous_Sibling returns the value No_Element. Otherwise, it returns a cursor that designates the predecessor (with the same parent) of the node designated by Position. 206/3 procedure Next_Sibling (Position : in out Cursor); 207/3 Equivalent to Position := Next_Sibling (Position); 208/3 procedure Previous_Sibling (Position : in out Cursor); 209/3 Equivalent to Position := Previous_Sibling (Position); 210/3 procedure Iterate_Children (Parent : in Cursor; Process : not null access procedure (Position : in Cursor)); 211/3 If Parent equals No_Element, then Constraint_Error is propagated. 212/3 Iterate_Children calls Process.all with a cursor that designates each child node of Parent, starting with the first child node and moving the cursor as per the Next_Sibling function. 213/3 Tampering with the cursors of the tree containing Parent is prohibited during the execution of a call on Process.all. Any exception raised by Process.all is propagated. 214/3 procedure Reverse_Iterate_Children (Parent : in Cursor; Process : not null access procedure (Position : in Cursor)); 215/3 If Parent equals No_Element, then Constraint_Error is propagated. 216/3 Reverse_Iterate_Children calls Process.all with a cursor that designates each child node of Parent, starting with the last child node and moving the cursor as per the Previous_Sibling function. 217/3 Tampering with the cursors of the tree containing Parent is prohibited during the execution of a call on Process.all. Any exception raised by Process.all is propagated. 218/3 function Iterate_Children (Container : in Tree; Parent : in Cursor) return Tree_Iterator_Interfaces.Reversible_Iterator'Class; 219/3 Iterate_Children returns a reversible iterator object (see 5.5.1) that will generate a value for a loop parameter (see 5.5.2) designating each child node of Parent. If Parent equals No_Element, then Constraint_Error is propagated. If Parent does not designate a node in Container, then Program_Error is propagated. Otherwise, when used as a forward iterator, the nodes are designated starting with the first child node and moving the cursor as per the function Next_Sibling; when used as a reverse iterator, the nodes are designated starting with the last child node and moving the cursor as per the function Previous_Sibling. Tampering with the cursors of Container is prohibited while the iterator object exists (in particular, in the sequence_of_statements of the loop_statement whose iterator_specification denotes this object). The iterator object needs finalization. Bounded (Run-Time) Errors 220/3 It is a bounded error for the actual function associated with a generic formal subprogram, when called as part of an operation of this package, to tamper with elements of any Tree parameter of the operation. Either Program_Error is raised, or the operation works as defined on the value of the Tree either prior to, or subsequent to, some or all of the modifications to the Tree. 221/3 It is a bounded error to call any subprogram declared in the visible part of Containers.Multiway_Trees when the associated container has been finalized. If the operation takes Container as an in out parameter, then it raises Constraint_Error or Program_Error. Otherwise, the operation either proceeds as it would for an empty container, or it raises Constraint_Error or Program_Error. Erroneous Execution 222/3 A Cursor value is invalid if any of the following have occurred since it was created: 223/3 * The tree that contains the element it designates has been finalized; 224/3 * The tree that contains the element it designates has been used as the Source or Target of a call to Move; 225/3 * The tree that contains the element it designates has been used as the Target of a call to Assign or the target of an assignment_statement; 226/3 * The element it designates has been removed from the tree that previously contained the element. 227/3 The result of "=" or Has_Element is unspecified if it is called with an invalid cursor parameter. Execution is erroneous if any other subprogram declared in Containers.Multiway_Trees is called with an invalid cursor parameter. 228/3 Execution is erroneous if the tree associated with the result of a call to Reference or Constant_Reference is finalized before the result object returned by the call to Reference or Constant_Reference is finalized. Implementation Requirements 229/3 No storage associated with a multiway tree object shall be lost upon assignment or scope exit. 230/3 The execution of an assignment_statement for a tree shall have the effect of copying the elements from the source tree object to the target tree object and changing the node count of the target object to that of the source object. Implementation Advice 231/3 Containers.Multiway_Trees should be implemented similarly to a multiway tree. In particular, if N is the overall number of nodes for a particular tree, then the worst-case time complexity of Element, Parent, First_Child, Last_Child, Next_Sibling, Previous_Sibling, Insert_Child with Count=1, and Delete should be O(log N). 232/3 Move should not copy elements, and should minimize copying of internal data structures. 233/3 If an exception is propagated from a tree operation, no storage should be lost, nor any elements removed from a tree unless specified by the operation. A.18.11 The Generic Package Containers.Indefinite_Vectors 1/2 The language-defined generic package Containers.Indefinite_Vectors provides a private type Vector and a set of operations. It provides the same operations as the package Containers.Vectors (see A.18.2), with the difference that the generic formal Element_Type is indefinite. Static Semantics 2/3 The declaration of the generic library package Containers.Indefinite_Vectors has the same contents and semantics as Containers.Vectors except: 3/2 * The generic formal Element_Type is indefinite. 4/2 * The procedures with the profiles: 5/2 procedure Insert (Container : in out Vector; Before : in Extended_Index; Count : in Count_Type := 1); 6/2 procedure Insert (Container : in out Vector; Before : in Cursor; Position : out Cursor; Count : in Count_Type := 1); 7/2 are omitted. 8/2 * The actual Element parameter of access subprogram Process of Update_Element may be constrained even if Element_Type is unconstrained. 9/4 * The operations "&", Append, Insert, Prepend, Replace_Element, and To_Vector that have a formal parameter of type Element_Type perform indefinite insertion (see A.18). A.18.12 The Generic Package Containers.Indefinite_Doubly_Linked_Lists 1/2 The language-defined generic package Containers.Indefinite_Doubly_Linked_Lists provides private types List and Cursor, and a set of operations for each type. It provides the same operations as the package Containers.Doubly_Linked_Lists (see A.18.3), with the difference that the generic formal Element_Type is indefinite. Static Semantics 2/3 The declaration of the generic library package Containers.Indefinite_- Doubly_Linked_Lists has the same contents and semantics as Containers.Doubly_- Linked_Lists except: 3/2 * The generic formal Element_Type is indefinite. 4/2 * The procedure with the profile: 5/2 procedure Insert (Container : in out List; Before : in Cursor; Position : out Cursor; Count : in Count_Type := 1); 6/2 is omitted. 7/2 * The actual Element parameter of access subprogram Process of Update_Element may be constrained even if Element_Type is unconstrained. 8/4 * The operations Append, Insert, Prepend, and Replace_Element that have a formal parameter of type Element_Type perform indefinite insertion (see A.18). A.18.13 The Generic Package Containers.Indefinite_Hashed_Maps 1/2 The language-defined generic package Containers.Indefinite_Hashed_Maps provides a map with the same operations as the package Containers.Hashed_Maps (see A.18.5), with the difference that the generic formal types Key_Type and Element_Type are indefinite. Static Semantics 2/3 The declaration of the generic library package Containers.Indefinite_Hashed_Maps has the same contents and semantics as Containers.Hashed_Maps except: 3/2 * The generic formal Key_Type is indefinite. 4/2 * The generic formal Element_Type is indefinite. 5/2 * The procedure with the profile: 6/2 procedure Insert (Container : in out Map; Key : in Key_Type; Position : out Cursor; Inserted : out Boolean); 7/2 is omitted. 8/2 * The actual Element parameter of access subprogram Process of Update_Element may be constrained even if Element_Type is unconstrained. 9/4 * The operations Include, Insert, Replace, and Replace_Element that have a formal parameter of type Element_Type perform indefinite insertion (see A.18). A.18.14 The Generic Package Containers.Indefinite_Ordered_Maps 1/2 The language-defined generic package Containers.Indefinite_Ordered_Maps provides a map with the same operations as the package Containers.Ordered_Maps (see A.18.6), with the difference that the generic formal types Key_Type and Element_Type are indefinite. Static Semantics 2/3 The declaration of the generic library package Containers.Indefinite_Ordered_Maps has the same contents and semantics as Containers.Ordered_Maps except: 3/2 * The generic formal Key_Type is indefinite. 4/2 * The generic formal Element_Type is indefinite. 5/2 * The procedure with the profile: 6/2 procedure Insert (Container : in out Map; Key : in Key_Type; Position : out Cursor; Inserted : out Boolean); 7/2 is omitted. 8/2 * The actual Element parameter of access subprogram Process of Update_Element may be constrained even if Element_Type is unconstrained. 9/4 * The operations Include, Insert, Replace, and Replace_Element that have a formal parameter of type Element_Type perform indefinite insertion (see A.18). A.18.15 The Generic Package Containers.Indefinite_Hashed_Sets 1/2 The language-defined generic package Containers.Indefinite_Hashed_Sets provides a set with the same operations as the package Containers.Hashed_Sets (see A.18.8), with the difference that the generic formal type Element_Type is indefinite. Static Semantics 2/3 The declaration of the generic library package Containers.Indefinite_Hashed_Sets has the same contents and semantics as Containers.Hashed_Sets except: 3/2 * The generic formal Element_Type is indefinite. 4/2 * The actual Element parameter of access subprogram Process of Update_- Element_Preserving_Key may be constrained even if Element_Type is unconstrained. 5/4 * The operations Include, Insert, Replace, Replace_Element, and To_Set that have a formal parameter of type Element_Type perform indefinite insertion (see A.18). A.18.16 The Generic Package Containers.Indefinite_Ordered_Sets 1/2 The language-defined generic package Containers.Indefinite_Ordered_Sets provides a set with the same operations as the package Containers.Ordered_Sets (see A.18.9), with the difference that the generic formal type Element_Type is indefinite. Static Semantics 2/3 The declaration of the generic library package Containers.Indefinite_Ordered_Sets has the same contents and semantics as Containers.Ordered_Sets except: 3/2 * The generic formal Element_Type is indefinite. 4/2 * The actual Element parameter of access subprogram Process of Update_- Element_Preserving_Key may be constrained even if Element_Type is unconstrained. 5/4 * The operations Include, Insert, Replace, Replace_Element, and To_Set that have a formal parameter of type Element_Type perform indefinite insertion (see A.18). A.18.17 The Generic Package Containers.Indefinite_Multiway_Trees 1/3 The language-defined generic package Containers.Indefinite_Multiway_Trees provides a multiway tree with the same operations as the package Containers.Multiway_Trees (see A.18.10), with the difference that the generic formal Element_Type is indefinite. Static Semantics 2/3 The declaration of the generic library package Containers.Indefinite_Multiway_Trees has the same contents and semantics as Containers.Multiway_Trees except: 3/3 * The generic formal Element_Type is indefinite. 4/3 * The procedure with the profile: 5/3 procedure Insert_Child (Container : in out Tree; Parent : in Cursor; Before : in Cursor; Position : out Cursor; Count : in Count_Type := 1); 6/3 is omitted. 7/3 * The actual Element parameter of access subprogram Process of Update_Element may be constrained even if Element_Type is unconstrained. 8/4 * The operations Append_Child, Insert_Child, Prepend_Child, and Replace_Element that have a formal parameter of type Element_Type perform indefinite insertion (see A.18). A.18.18 The Generic Package Containers.Indefinite_Holders 1/3 The language-defined generic package Containers.Indefinite_Holders provides a private type Holder and a set of operations for that type. A holder container holds a single element of an indefinite type. 2/3 A holder container allows the declaration of an object that can be used like an uninitialized variable or component of an indefinite type. 3/3 A holder container may be empty. An empty holder does not contain an element. Static Semantics 4/3 The generic library package Containers.Indefinite_Holders has the following declaration: 5/3 generic type Element_Type (<>) is private; with function "=" (Left, Right : Element_Type) return Boolean is <>; package Ada.Containers.Indefinite_Holders is pragma Preelaborate(Indefinite_Holders); pragma Remote_Types(Indefinite_Holders); 6/3 type Holder is tagged private; pragma Preelaborable_Initialization (Holder); 7/3 Empty_Holder : constant Holder; 8/3 function "=" (Left, Right : Holder) return Boolean; 9/3 function To_Holder (New_Item : Element_Type) return Holder; 10/3 function Is_Empty (Container : Holder) return Boolean; 11/3 procedure Clear (Container : in out Holder); 12/3 function Element (Container : Holder) return Element_Type; 13/3 procedure Replace_Element (Container : in out Holder; New_Item : in Element_Type); 14/3 procedure Query_Element (Container : in Holder; Process : not null access procedure (Element : in Element_Type)); 15/3 procedure Update_Element (Container : in out Holder; Process : not null access procedure (Element : in out Element_Type)); 16/3 type Constant_Reference_Type (Element : not null access constant Element_Type) is private with Implicit_Dereference => Element; 17/3 type Reference_Type (Element : not null access Element_Type) is private with Implicit_Dereference => Element; 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; 20/3 procedure Assign (Target : in out Holder; Source : in Holder); 21/3 function Copy (Source : Holder) return Holder; 22/3 procedure Move (Target : in out Holder; Source : in out Holder); 23/3 private 24/3 ... -- not specified by the language 25/3 end Ada.Containers.Indefinite_Holders; 26/3 The actual function for the generic formal function "=" on Element_Type values is expected to define a reflexive and symmetric relationship and return the same result value each time it is called with a particular pair of values. If it behaves in some other manner, the function "=" on holder values returns an unspecified value. The exact arguments and number of calls of this generic formal function by the function "=" on holder values are unspecified. 27/3 The type Holder is used to represent holder containers. The type Holder needs finalization (see 7.6). 28/3 Empty_Holder represents an empty holder object. If an object of type Holder is not otherwise initialized, it is initialized to the same value as Empty_Holder. 29/3 Some operations of this generic package have access-to-subprogram parameters. To ensure such operations are well-defined, they guard against certain actions by the designated subprogram. In particular, some operations check for "tampering with the element" of a container because they depend on the element of the container not being replaced. 30/3 A subprogram is said to tamper with the element of a holder object H if: 31/3 * It clears the element contained by H, that is, it calls the Clear procedure with H as a parameter; 32/3 * It replaces the element contained by H, that is, it calls the Replace_Element procedure with H as a parameter; 33/3 * It calls the Move procedure with H as a parameter; 34/3 * It finalizes H. 35/4 When tampering with the element is prohibited for a particular holder object H, Program_Error is propagated by a call of any language-defined subprogram that is defined to tamper with the element of H, leaving H unmodified. These checks are made before any other defined behavior of the body of the language-defined subprogram. 36/3 function "=" (Left, Right : Holder) return Boolean; 37/3 If Left and Right denote the same holder object, then the function returns True. Otherwise, it compares the element contained in Left to the element contained in Right using the generic formal equality operator, returning the result of that operation. Any exception raised during the evaluation of element equality is propagated. 38/3 function To_Holder (New_Item : Element_Type) return Holder; 39/4 Returns a nonempty holder containing an element initialized to New_Item. To_Holder performs indefinite insertion (see A.18). 40/3 function Is_Empty (Container : Holder) return Boolean; 41/3 Returns True if Container is empty, and False if it contains an element. 42/3 procedure Clear (Container : in out Holder); 43/3 Removes the element from Container. Container is empty after a successful Clear operation. 44/3 function Element (Container : Holder) return Element_Type; 45/3 If Container is empty, Constraint_Error is propagated. Otherwise, returns the element stored in Container. 46/3 procedure Replace_Element (Container : in out Holder; New_Item : in Element_Type); 47/4 Replace_Element assigns the value New_Item into Container, replacing any preexisting content of Container; Replace_Element performs indefinite insertion (see A.18). Container is not empty after a successful call to Replace_Element. 48/3 procedure Query_Element (Container : in Holder; Process : not null access procedure (Element : in Element_Type)); 49/3 If Container is empty, Constraint_Error is propagated. Otherwise, Query_Element calls Process.all with the contained element as the argument. Tampering with the element of Container is prohibited during the execution of the call on Process.all. Any exception raised by Process.all is propagated. 50/3 procedure Update_Element (Container : in out Holder; Process : not null access procedure (Element : in out Element_Type)); 51/3 If Container is empty, Constraint_Error is propagated. Otherwise, Update_Element calls Process.all with the contained element as the argument. Tampering with the element of Container is prohibited during the execution of the call on Process.all. Any exception raised by Process.all is propagated. 52/3 type Constant_Reference_Type (Element : not null access constant Element_Type) is private with Implicit_Dereference => Element; 53/3 type Reference_Type (Element : not null access Element_Type) is private with Implicit_Dereference => Element; 54/3 The types Constant_Reference_Type and Reference_Type need finalization. 55/3 The default initialization of an object of type Constant_Reference_Type or Reference_Type propagates Program_Error. 56/3 function Constant_Reference (Container : aliased in Holder) return Constant_Reference_Type; 57/3 This function (combined with the Implicit_Dereference aspect) provides a convenient way to gain read access to the contained element of a holder container. 58/3 If Container is empty, Constraint_Error is propagated. Otherwise, Constant_Reference returns an object whose discriminant is an access value that designates the contained element. Tampering with the elements of Container is prohibited while the object returned by Constant_Reference exists and has not been finalized. 59/3 function Reference (Container : aliased in out Holder) return Reference_Type; 60/3 This function (combined with the Implicit_Dereference aspects) provides a convenient way to gain read and write access to the contained element of a holder container. 61/3 If Container is empty, Constraint_Error is propagated. Otherwise, Reference returns an object whose discriminant is an access value that designates the contained element. Tampering with the elements of Container is prohibited while the object returned by Reference exists and has not been finalized. 62/3 procedure Assign (Target : in out Holder; Source : in Holder); 63/3 If Target denotes the same object as Source, the operation has no effect. If Source is empty, Clear (Target) is called. Otherwise, Replace_Element (Target, Element (Source)) is called. 64/3 function Copy (Source : Holder) return Holder; 65/3 If Source is empty, returns an empty holder container; otherwise, returns To_Holder (Element (Source)). 66/3 procedure Move (Target : in out Holder; Source : in out Holder); 67/3 If Target denotes the same object as Source, then the operation has no effect. Otherwise, the element contained by Source (if any) is removed from Source and inserted into Target, replacing any preexisting content. Source is empty after a successful call to Move. Bounded (Run-Time) Errors 68/3 It is a bounded error for the actual function associated with a generic formal subprogram, when called as part of an operation of this package, to tamper with the element of any Holder parameter of the operation. Either Program_Error is raised, or the operation works as defined on the value of the Holder either prior to, or subsequent to, some or all of the modifications to the Holder. 69/3 It is a bounded error to call any subprogram declared in the visible part of Containers.Indefinite_Holders when the associated container has been finalized. If the operation takes Container as an in out parameter, then it raises Constraint_Error or Program_Error. Otherwise, the operation either proceeds as it would for an empty container, or it raises Constraint_Error or Program_Error. Erroneous Execution 70/3 Execution is erroneous if the holder container associated with the result of a call to Reference or Constant_Reference is finalized before the result object returned by the call to Reference or Constant_Reference is finalized. Implementation Requirements 71/3 No storage associated with a holder object shall be lost upon assignment or scope exit. 72/3 The execution of an assignment_statement for a holder container shall have the effect of copying the element (if any) from the source holder object to the target holder object. Implementation Advice 73/3 Move should not copy the element, and should minimize copying of internal data structures. 74/3 If an exception is propagated from a holder operation, no storage should be lost, nor should the element be removed from a holder container unless specified by the operation. A.18.19 The Generic Package Containers.Bounded_Vectors 1/3 The language-defined generic package Containers.Bounded_Vectors provides a private type Vector and a set of operations. It provides the same operations as the package Containers.Vectors (see A.18.2), with the difference that the maximum storage is bounded. Static Semantics 2/3 The declaration of the generic library package Containers.Bounded_Vectors has the same contents and semantics as Containers.Vectors except: 3/3 * The pragma Preelaborate is replaced with pragma Pure. 4/3 * The type Vector is declared with a discriminant that specifies the capacity: 5/3 type Vector (Capacity : Count_Type) is tagged private; 6/3 * The type Vector needs finalization if and only if type Element_Type needs finalization. 7/3 * In function Copy, if the Capacity parameter is equal to or greater than the length of Source, the vector capacity exactly equals the value of the Capacity parameter. 8/3 * The description of Reserve_Capacity is replaced with: 9/3 If the specified Capacity is larger than the capacity of Container, then Reserve_Capacity propagates Capacity_Error. Otherwise, the operation has no effect. Bounded (Run-Time) Errors 10/3 It is a bounded error to assign from a bounded vector object while tampering with elements or cursors of that object is prohibited. Either Program_Error is raised by the assignment, execution proceeds with the target object prohibiting tampering with elements or cursors, or execution proceeds normally. Erroneous Execution 11/3 When a bounded vector object V is finalized, if tampering with cursors is prohibited for V other than due to an assignment from another vector, then execution is erroneous. Implementation Requirements 12/3 For each instance of Containers.Vectors and each instance of Containers.Bounded_Vectors, if the two instances meet the following conditions, then the output generated by the Vector'Output or Vector'Write subprograms of either instance shall be readable by the Vector'Input or Vector'Read of the other instance, respectively: 13/3 * the Element_Type parameters of the two instances are statically matching subtypes of the same type; and 14/3 * the output generated by Element_Type'Output or Element_Type'Write is readable by Element_Type'Input or Element_Type'Read, respectively (where Element_Type denotes the type of the two actual Element_Type parameters); and 15/3 * the preceding two conditions also hold for the Index_Type parameters of the instances. Implementation Advice 16/3 Bounded vector objects should be implemented without implicit pointers or dynamic allocation. 17/3 The implementation advice for procedure Move to minimize copying does not apply. A.18.20 The Generic Package Containers.Bounded_Doubly_Linked_Lists 1/3 The language-defined generic package Containers.Bounded_Doubly_Linked_Lists provides a private type List and a set of operations. It provides the same operations as the package Containers.Doubly_Linked_Lists (see A.18.3), with the difference that the maximum storage is bounded. Static Semantics 2/3 The declaration of the generic library package Containers.Bounded_Doubly_Linked_Lists has the same contents and semantics as Containers.Doubly_Linked_Lists except: 3/3 * The pragma Preelaborate is replaced with pragma Pure. 4/3 * The type List is declared with a discriminant that specifies the capacity (maximum number of elements) as follows: 5/3 type List (Capacity : Count_Type) is tagged private; 6/3 * The type List needs finalization if and only if type Element_Type needs finalization. 7/3 * The allocation of internal storage includes a check that the capacity is not exceeded, and Capacity_Error is raised if this check fails. 8/3 * In procedure Assign, if Source length is greater than Target capacity, then Capacity_Error is propagated. 9/3 * The function Copy is replaced with: 10/3 function Copy (Source : List; Capacity : Count_Type := 0) return List; 11/3 If Capacity is 0, then the list capacity is the length of Source; if Capacity is equal to or greater than the length of Source, the list capacity equals the value of the Capacity parameter; otherwise, the operation propagates Capacity_Error. 12/3 * In the three-parameter procedure Splice whose Source has type List, if the sum of the length of Target and the length of Source is greater than the capacity of Target, then Splice propagates Capacity_Error. 13/3 * In the four-parameter procedure Splice, if the length of Target equals the capacity of Target, then Splice propagates Capacity_Error. Bounded (Run-Time) Errors 14/3 It is a bounded error to assign from a bounded list object while tampering with elements or cursors of that object is prohibited. Either Program_Error is raised by the assignment, execution proceeds with the target object prohibiting tampering with elements or cursors, or execution proceeds normally. Erroneous Execution 15/3 When a bounded list object L is finalized, if tampering with cursors is prohibited for L other than due to an assignment from another list, then execution is erroneous. Implementation Requirements 16/3 For each instance of Containers.Doubly_Linked_Lists and each instance of Containers.Bounded_Doubly_Linked_Lists, if the two instances meet the following conditions, then the output generated by the List'Output or List'Write subprograms of either instance shall be readable by the List'Input or List'Read of the other instance, respectively: 17/3 * the Element_Type parameters of the two instances are statically matching subtypes of the same type; and 18/3 * the output generated by Element_Type'Output or Element_Type'Write is readable by Element_Type'Input or Element_Type'Read, respectively (where Element_Type denotes the type of the two actual Element_Type parameters). Implementation Advice 19/3 Bounded list objects should be implemented without implicit pointers or dynamic allocation. 20/3 The implementation advice for procedure Move to minimize copying does not apply. A.18.21 The Generic Package Containers.Bounded_Hashed_Maps 1/3 The language-defined generic package Containers.Bounded_Hashed_Maps provides a private type Map and a set of operations. It provides the same operations as the package Containers.Hashed_Maps (see A.18.5), with the difference that the maximum storage is bounded. Static Semantics 2/3 The declaration of the generic library package Containers.Bounded_Hashed_Maps has the same contents and semantics as Containers.Hashed_Maps except: 3/3 * The pragma Preelaborate is replaced with pragma Pure. 4/3 * The type Map is declared with discriminants that specify both the capacity (number of elements) and modulus (number of distinct hash values) of the hash table as follows: 5/3 type Map (Capacity : Count_Type; Modulus : Hash_Type) is tagged private; 6/3 * The type Map needs finalization if and only if type Key_Type or type Element_Type needs finalization. 7/3 * The description of Reserve_Capacity is replaced with: 8/3 If the specified Capacity is larger than the capacity of Container, then Reserve_Capacity propagates Capacity_Error. Otherwise, the operation has no effect. 9/3 * An additional operation is added immediately following Reserve_Capacity: 10/3 function Default_Modulus (Capacity : Count_Type) return Hash_Type; 11/3 Default_Modulus returns an implementation-defined value for the number of distinct hash values to be used for the given capacity (maximum number of elements). 12/3 * The function Copy is replaced with: 13/3 function Copy (Source : Map; Capacity : Count_Type := 0; Modulus : Hash_Type := 0) return Map; 14/3 Returns a map with key/element pairs initialized from the values in Source. If Capacity is 0, then the map capacity is the length of Source; if Capacity is equal to or greater than the length of Source, the map capacity is the value of the Capacity parameter; otherwise, the operation propagates Capacity_Error. If the Modulus argument is 0, then the map modulus is the value returned by a call to Default_Modulus with the map capacity as its argument; otherwise, the map modulus is the value of the Modulus parameter. Bounded (Run-Time) Errors 15/3 It is a bounded error to assign from a bounded map object while tampering with elements or cursors of that object is prohibited. Either Program_Error is raised by the assignment, execution proceeds with the target object prohibiting tampering with elements or cursors, or execution proceeds normally. Erroneous Execution 16/3 When a bounded map object M is finalized, if tampering with cursors is prohibited for M other than due to an assignment from another map, then execution is erroneous. Implementation Requirements 17/3 For each instance of Containers.Hashed_Maps and each instance of Containers.Bounded_Hashed_Maps, if the two instances meet the following conditions, then the output generated by the Map'Output or Map'Write subprograms of either instance shall be readable by the Map'Input or Map'Read of the other instance, respectively: 18/3 * the Element_Type parameters of the two instances are statically matching subtypes of the same type; and 19/3 * the output generated by Element_Type'Output or Element_Type'Write is readable by Element_Type'Input or Element_Type'Read, respectively (where Element_Type denotes the type of the two actual Element_Type parameters); and 20/3 * the preceding two conditions also hold for the Key_Type parameters of the instances. Implementation Advice 21/3 Bounded hashed map objects should be implemented without implicit pointers or dynamic allocation. 22/3 The implementation advice for procedure Move to minimize copying does not apply. A.18.22 The Generic Package Containers.Bounded_Ordered_Maps 1/3 The language-defined generic package Containers.Bounded_Ordered_Maps provides a private type Map and a set of operations. It provides the same operations as the package Containers.Ordered_Maps (see A.18.6), with the difference that the maximum storage is bounded. Static Semantics 2/3 The declaration of the generic library package Containers.Bounded_Ordered_Maps has the same contents and semantics as Containers.Ordered_Maps except: 3/3 * The pragma Preelaborate is replaced with pragma Pure. 4/3 * The type Map is declared with a discriminant that specifies the capacity (maximum number of elements) as follows: 5/3 type Map (Capacity : Count_Type) is tagged private; 6/3 * The type Map needs finalization if and only if type Key_Type or type Element_Type needs finalization. 7/3 * The allocation of a new node includes a check that the capacity is not exceeded, and Capacity_Error is raised if this check fails. 8/3 * In procedure Assign, if Source length is greater than Target capacity, then Capacity_Error is propagated. 9/3 * The function Copy is replaced with: 10/3 function Copy (Source : Map; Capacity : Count_Type := 0) return Map; 11/3 Returns a map with key/element pairs initialized from the values in Source. If Capacity is 0, then the map capacity is the length of Source; if Capacity is equal to or greater than the length of Source, the map capacity is the specified value; otherwise, the operation propagates Capacity_Error. Bounded (Run-Time) Errors 12/3 It is a bounded error to assign from a bounded map object while tampering with elements or cursors of that object is prohibited. Either Program_Error is raised by the assignment, execution proceeds with the target object prohibiting tampering with elements or cursors, or execution proceeds normally. Erroneous Execution 13/3 When a bounded map object M is finalized, if tampering with cursors is prohibited for M other than due to an assignment from another map, then execution is erroneous. Implementation Requirements 14/3 For each instance of Containers.Ordered_Maps and each instance of Containers.Bounded_Ordered_Maps, if the two instances meet the following conditions, then the output generated by the Map'Output or Map'Write subprograms of either instance shall be readable by the Map'Input or Map'Read of the other instance, respectively: 15/3 * the Element_Type parameters of the two instances are statically matching subtypes of the same type; and 16/3 * the output generated by Element_Type'Output or Element_Type'Write is readable by Element_Type'Input or Element_Type'Read, respectively (where Element_Type denotes the type of the two actual Element_Type parameters); and 17/3 * the preceding two conditions also hold for the Key_Type parameters of the instances. Implementation Advice 18/3 Bounded ordered map objects should be implemented without implicit pointers or dynamic allocation. 19/3 The implementation advice for procedure Move to minimize copying does not apply. A.18.23 The Generic Package Containers.Bounded_Hashed_Sets 1/3 The language-defined generic package Containers.Bounded_Hashed_Sets provides a private type Set and a set of operations. It provides the same operations as the package Containers.Hashed_Sets (see A.18.8), with the difference that the maximum storage is bounded. Static Semantics 2/3 The declaration of the generic library package Containers.Bounded_Hashed_Sets has the same contents and semantics as Containers.Hashed_Sets except: 3/3 * The pragma Preelaborate is replaced with pragma Pure. 4/3 * The type Set is declared with discriminants that specify both the capacity (number of elements) and modulus (number of distinct hash values) of the hash table as follows: 5/3 type Set (Capacity : Count_Type; Modulus : Hash_Type) is tagged private; 6/3 * The type Set needs finalization if and only if type Element_Type needs finalization. 7/3 * The description of Reserve_Capacity is replaced with: 8/3 If the specified Capacity is larger than the capacity of Container, then Reserve_Capacity propagates Capacity_Error. Otherwise, the operation has no effect. 9/3 * An additional operation is added immediately following Reserve_Capacity: 10/3 function Default_Modulus (Capacity : Count_Type) return Hash_Type; 11/3 Default_Modulus returns an implementation-defined value for the number of distinct hash values to be used for the given capacity (maximum number of elements). 12/3 * The function Copy is replaced with: 13/3 function Copy (Source : Set; Capacity : Count_Type := 0; Modulus : Hash_Type := 0) return Set; 14/3 Returns a set whose elements are initialized from the values in Source. If Capacity is 0, then the set capacity is the length of Source; if Capacity is equal to or greater than the length of Source, the set capacity is the value of the Capacity parameter; otherwise, the operation propagates Capacity_Error. If the Modulus argument is 0, then the set modulus is the value returned by a call to Default_Modulus with the set capacity as its argument; otherwise, the set modulus is the value of the Modulus parameter. Bounded (Run-Time) Errors 15/3 It is a bounded error to assign from a bounded set object while tampering with elements or cursors of that object is prohibited. Either Program_Error is raised by the assignment, execution proceeds with the target object prohibiting tampering with elements or cursors, or execution proceeds normally. Erroneous Execution 16/3 When a bounded set object S is finalized, if tampering with cursors is prohibited for S other than due to an assignment from another set, then execution is erroneous. Implementation Requirements 17/3 For each instance of Containers.Hashed_Sets and each instance of Containers.Bounded_Hashed_Sets, if the two instances meet the following conditions, then the output generated by the Set'Output or Set'Write subprograms of either instance shall be readable by the Set'Input or Set'Read of the other instance, respectively: 18/3 * the Element_Type parameters of the two instances are statically matching subtypes of the same type; and 19/3 * the output generated by Element_Type'Output or Element_Type'Write is readable by Element_Type'Input or Element_Type'Read, respectively (where Element_Type denotes the type of the two actual Element_Type parameters). Implementation Advice 20/3 Bounded hashed set objects should be implemented without implicit pointers or dynamic allocation. 21/3 The implementation advice for procedure Move to minimize copying does not apply. A.18.24 The Generic Package Containers.Bounded_Ordered_Sets 1/3 The language-defined generic package Containers.Bounded_Ordered_Sets provides a private type Set and a set of operations. It provides the same operations as the package Containers.Ordered_Sets (see A.18.9), with the difference that the maximum storage is bounded. Static Semantics 2/3 The declaration of the generic library package Containers.Bounded_Ordered_Sets has the same contents and semantics as Containers.Ordered_Sets except: 3/3 * The pragma Preelaborate is replaced with pragma Pure. 4/3 * The type Set is declared with a discriminant that specifies the capacity (maximum number of elements) as follows: 5/3 type Set (Capacity : Count_Type) is tagged private; 6/3 * The type Set needs finalization if and only if type Element_Type needs finalization. 7/3 * If Insert (or Include) adds an element, a check is made that the capacity is not exceeded, and Capacity_Error is raised if this check fails. 8/3 * In procedure Assign, if Source length is greater than Target capacity, then Capacity_Error is propagated. 9/3 * The function Copy is replaced with: 10/3 function Copy (Source : Set; Capacity : Count_Type := 0) return Set; 11/3 Returns a set whose elements are initialized from the values in Source. If Capacity is 0, then the set capacity is the length of Source; if Capacity is equal to or greater than the length of Source, the set capacity is the specified value; otherwise, the operation propagates Capacity_Error. Bounded (Run-Time) Errors 12/3 It is a bounded error to assign from a bounded set object while tampering with elements or cursors of that object is prohibited. Either Program_Error is raised by the assignment, execution proceeds with the target object prohibiting tampering with elements or cursors, or execution proceeds normally. Erroneous Execution 13/3 When a bounded set object S is finalized, if tampering with cursors is prohibited for S other than due to an assignment from another set, then execution is erroneous. Implementation Requirements 14/3 For each instance of Containers.Ordered_Sets and each instance of Containers.Bounded_Ordered_Sets, if the two instances meet the following conditions, then the output generated by the Set'Output or Set'Write subprograms of either instance shall be readable by the Set'Input or Set'Read of the other instance, respectively: 15/3 * the Element_Type parameters of the two instances are statically matching subtypes of the same type; and 16/3 * the output generated by Element_Type'Output or Element_Type'Write is readable by Element_Type'Input or Element_Type'Read, respectively (where Element_Type denotes the type of the two actual Element_Type parameters). Implementation Advice 17/3 Bounded ordered set objects should be implemented without implicit pointers or dynamic allocation. 18/3 The implementation advice for procedure Move to minimize copying does not apply. A.18.25 The Generic Package Containers.Bounded_Multiway_Trees 1/3 The language-defined generic package Containers.Bounded_Multiway_Trees provides a private type Tree and a set of operations. It provides the same operations as the package Containers.Multiway_Trees (see A.18.10), with the difference that the maximum storage is bounded. Static Semantics 2/3 The declaration of the generic library package Containers.Bounded_Multiway_Trees has the same contents and semantics as Containers.Multiway_Trees except: 3/3 * The pragma Preelaborate is replaced with pragma Pure. 4/3 * The type Tree is declared with a discriminant that specifies the capacity (maximum number of elements) as follows: 5/3 type Tree (Capacity : Count_Type) is tagged private; 6/3 * The type Tree needs finalization if and only if type Element_Type needs finalization. 7/3 * The allocation of internal storage includes a check that the capacity is not exceeded, and Capacity_Error is raised if this check fails. 8/3 * In procedure Assign, if Source length is greater than Target capacity, then Capacity_Error is propagated. 9/3 * Function Copy is declared as follows: 10/4 function Copy (Source : Tree; Capacity : Count_Type := 0) return Tree; 11/3 If Capacity is 0, then the tree capacity is the count of Source; if Capacity is equal to or greater than Source.Count, the tree capacity equals the value of the Capacity parameter; otherwise, the operation propagates Capacity_Error. 12/3 * In the five-parameter procedure Splice_Subtree, if Source is not the same object as Target, and if the sum of Target.Count and Subtree_Node_Count (Position) is greater than Target.Capacity, then Splice_Subtree propagates Capacity_Error. 13/3 * In the five-parameter procedure Splice_Children, if Source is not the same object as Target, and if the sum of Target.Count and Subtree_Node_Count (Source_Parent)-1 is greater than Target.Capacity, then Splice_Children propagates Capacity_Error. Bounded (Run-Time) Errors 14/3 It is a bounded error to assign from a bounded tree object while tampering with elements or cursors of that object is prohibited. Either Program_Error is raised by the assignment, execution proceeds with the target object prohibiting tampering with elements or cursors, or execution proceeds normally. Erroneous Execution 15/3 When a bounded tree object T is finalized, if tampering with cursors is prohibited for T other than due to an assignment from another tree, then execution is erroneous. Implementation Requirements 16/3 For each instance of Containers.Multiway_Trees and each instance of Containers.Bounded_Multiway_Trees, if the two instances meet the following conditions, then the output generated by the Tree'Output or Tree'Write subprograms of either instance shall be readable by the Tree'Input or Tree'Read of the other instance, respectively: 17/3 * the Element_Type parameters of the two instances are statically matching subtypes of the same type; and 18/3 * the output generated by Element_Type'Output or Element_Type'Write is readable by Element_Type'Input or Element_Type'Read, respectively (where Element_Type denotes the type of the two actual Element_Type parameters). Implementation Advice 19/3 Bounded tree objects should be implemented without implicit pointers or dynamic allocation. 20/3 The implementation advice for procedure Move to minimize copying does not apply. A.18.26 Array Sorting 1/3 The language-defined generic procedures Containers.Generic_Array_Sort, Containers.Generic_Constrained_Array_Sort, and Containers.Generic_Sort provide sorting on arbitrary array types. Static Semantics 2/2 The generic library procedure Containers.Generic_Array_Sort has the following declaration: 3/2 generic type Index_Type is (<>); type Element_Type is private; type Array_Type is array (Index_Type range <>) of Element_Type; with function "<" (Left, Right : Element_Type) return Boolean is <>; procedure Ada.Containers.Generic_Array_Sort (Container : in out Array_Type); pragma Pure(Ada.Containers.Generic_Array_Sort); 4/2 Reorders the elements of Container such that the elements are sorted smallest first as determined by the generic formal "<" operator provided. Any exception raised during evaluation of "<" is propagated. 5/3 The actual function for the generic formal function "<" of Generic_Array_Sort is expected to return the same value each time it is called with a particular pair of element values. It should define a strict weak ordering relationship (see A.18); it should not modify Container. If the actual for "<" behaves in some other manner, the behavior of the instance of Generic_Array_Sort is unspecified. The number of times Generic_Array_Sort calls "<" is unspecified. 6/2 The generic library procedure Containers.Generic_Constrained_Array_Sort has the following declaration: 7/2 generic type Index_Type is (<>); type Element_Type is private; type Array_Type is array (Index_Type) of Element_Type; with function "<" (Left, Right : Element_Type) return Boolean is <>; procedure Ada.Containers.Generic_Constrained_Array_Sort (Container : in out Array_Type); pragma Pure(Ada.Containers.Generic_Constrained_Array_Sort); 8/2 Reorders the elements of Container such that the elements are sorted smallest first as determined by the generic formal "<" operator provided. Any exception raised during evaluation of "<" is propagated. 9/3 The actual function for the generic formal function "<" of Generic_Constrained_Array_Sort is expected to return the same value each time it is called with a particular pair of element values. It should define a strict weak ordering relationship (see A.18); it should not modify Container. If the actual for "<" behaves in some other manner, the behavior of the instance of Generic_Constrained_Array_Sort is unspecified. The number of times Generic_Constrained_Array_Sort calls "<" is unspecified. 9.1/3 The generic library procedure Containers.Generic_Sort has the following declaration: 9.2/4 generic type Index_Type is (<>); with function Before (Left, Right : Index_Type) return Boolean; with procedure Swap (Left, Right : in Index_Type); procedure Ada.Containers.Generic_Sort (First, Last : Index_Type'Base); pragma Pure(Ada.Containers.Generic_Sort); 9.3/3 Reorders the elements of an indexable structure, over the range First .. Last, such that the elements are sorted in the ordering determined by the generic formal function Before; Before should return True if Left is to be sorted before Right. The generic formal Before compares the elements having the given indices, and the generic formal Swap exchanges the values of the indicated elements. Any exception raised during evaluation of Before or Swap is propagated. 9.4/3 The actual function for the generic formal function Before of Generic_Sort is expected to return the same value each time it is called with index values that identify a particular pair of element values. It should define a strict weak ordering relationship (see A.18); it should not modify the elements. The actual function for the generic formal Swap should exchange the values of the indicated elements. If the actual for either Before or Swap behaves in some other manner, the behavior of Generic_Sort is unspecified. The number of times the Generic_Sort calls Before or Swap is unspecified. Implementation Advice 10/2 The worst-case time complexity of a call on an instance of Containers.Generic_Array_Sort or Containers.Generic_Constrained_Array_Sort should be O(N**2) or better, and the average time complexity should be better than O(N**2), where N is the length of the Container parameter. 11/2 Containers.Generic_Array_Sort and Containers.Generic_Constrained_Array_Sort should minimize copying of elements. 12/3 The worst-case time complexity of a call on an instance of Containers.Generic_Sort should be O(N**2) or better, and the average time complexity should be better than O(N**2), where N is the difference between the Last and First parameters plus 1. 13/3 Containers.Generic_Sort should minimize calls to the generic formal Swap. A.18.27 The Generic Package Containers.Synchronized_Queue_Interfaces 1/3 The language-defined generic package Containers.Synchronized_Queue_Interfaces provides interface type Queue, and a set of operations for that type. Interface Queue specifies a first-in, first-out queue. Static Semantics 2/3 The generic library package Containers.Synchronized_Queue_Interfaces has the following declaration: 3/3 generic type Element_Type is private; package Ada.Containers.Synchronized_Queue_Interfaces is pragma Pure(Synchronized_Queue_Interfaces); 4/3 type Queue is synchronized interface; 5/3 procedure Enqueue (Container : in out Queue; New_Item : in Element_Type) is abstract with Synchronization => By_Entry; 6/3 procedure Dequeue (Container : in out Queue; Element : out Element_Type) is abstract with Synchronization => By_Entry; 7/3 function Current_Use (Container : Queue) return Count_Type is abstract; function Peak_Use (Container : Queue) return Count_Type is abstract; 8/3 end Ada.Containers.Synchronized_Queue_Interfaces; 9/3 procedure Enqueue (Container : in out Queue; New_Item : in Element_Type) is abstract; 10/3 A queue type that implements this interface is allowed to have a bounded capacity. If the queue object has a bounded capacity, and the number of existing elements equals the capacity, then Enqueue blocks until storage becomes available; otherwise, Enqueue does not block. In any case, it then copies New_Item onto the queue. 11/3 procedure Dequeue (Container : in out Queue; Element : out Element_Type) is abstract; 12/3 If the queue is empty, then Dequeue blocks until an item becomes available. In any case, it then assigns the element at the head of the queue to Element, and removes it from the queue. 13/3 function Current_Use (Container : Queue) return Count_Type is abstract; 14/3 Returns the number of elements currently in the queue. 15/3 function Peak_Use (Container : Queue) return Count_Type is abstract; 16/3 Returns the maximum number of elements that have been in the queue at any one time. NOTES 17/3 51 Unlike other language-defined containers, there are no queues whose element types are indefinite. Elements of an indefinite type can be handled by defining the element of the queue to be a holder container (see A.18.18) of the indefinite type, or to be an explicit access type that designates the indefinite type. A.18.28 The Generic Package Containers.Unbounded_Synchronized_Queues Static Semantics 1/3 The language-defined generic package Containers.Unbounded_Synchronized_Queues provides type Queue, which implements the interface type Containers.Synchronized_Queue_Interfaces.Queue. 2/3 with System; with Ada.Containers.Synchronized_Queue_Interfaces; generic with package Queue_Interfaces is new Ada.Containers.Synchronized_Queue_Interfaces (<>); Default_Ceiling : System.Any_Priority := System.Priority'Last; package Ada.Containers.Unbounded_Synchronized_Queues is pragma Preelaborate(Unbounded_Synchronized_Queues); 3/3 package Implementation is ... -- not specified by the language end Implementation; 4/3 protected type Queue (Ceiling : System.Any_Priority := Default_Ceiling) with Priority => Ceiling is new Queue_Interfaces.Queue with 5/3 overriding entry Enqueue (New_Item : in Queue_Interfaces.Element_Type); overriding entry Dequeue (Element : out Queue_Interfaces.Element_Type); 6/3 overriding function Current_Use return Count_Type; overriding function Peak_Use return Count_Type; 7/3 private ... -- not specified by the language end Queue; 8/3 private 9/3 ... -- not specified by the language 10/3 end Ada.Containers.Unbounded_Synchronized_Queues; 11/3 The type Queue is used to represent task-safe queues. 12/3 The capacity for instances of type Queue is unbounded. A.18.29 The Generic Package Containers.Bounded_Synchronized_Queues Static Semantics 1/3 The language-defined generic package Containers.Bounded_Synchronized_Queues provides type Queue, which implements the interface type Containers.Synchronized_Queue_Interfaces.Queue. 2/3 with System; with Ada.Containers.Synchronized_Queue_Interfaces; generic with package Queue_Interfaces is new Ada.Containers.Synchronized_Queue_Interfaces (<>); Default_Capacity : Count_Type; Default_Ceiling : System.Any_Priority := System.Priority'Last; package Ada.Containers.Bounded_Synchronized_Queues is pragma Preelaborate(Bounded_Synchronized_Queues); 3/3 package Implementation is ... -- not specified by the language end Implementation; 4/3 protected type Queue (Capacity : Count_Type := Default_Capacity; Ceiling : System.Any_Priority := Default_Ceiling) with Priority => Ceiling is new Queue_Interfaces.Queue with 5/3 overriding entry Enqueue (New_Item : in Queue_Interfaces.Element_Type); overriding entry Dequeue (Element : out Queue_Interfaces.Element_Type); 6/3 overriding function Current_Use return Count_Type; overriding function Peak_Use return Count_Type; 7/3 private ... -- not specified by the language end Queue; 8/3 private 9/3 ... -- not specified by the language 10/3 end Ada.Containers.Bounded_Synchronized_Queues; 11/3 The semantics are the same as for Unbounded_Synchronized_Queues, except: 12/3 * The capacity for instances of type Queue is bounded and specified by the discriminant Capacity. Implementation Advice 13/3 Bounded queue objects should be implemented without implicit pointers or dynamic allocation. A.18.30 The Generic Package Containers.Unbounded_Priority_Queues Static Semantics 1/3 The language-defined generic package Containers.Unbounded_Priority_Queues provides type Queue, which implements the interface type Containers.Synchronized_Queue_Interfaces.Queue. 2/3 with System; with Ada.Containers.Synchronized_Queue_Interfaces; generic with package Queue_Interfaces is new Ada.Containers.Synchronized_Queue_Interfaces (<>); type Queue_Priority is private; with function Get_Priority (Element : Queue_Interfaces.Element_Type) return Queue_Priority is <>; with function Before (Left, Right : Queue_Priority) return Boolean is <>; Default_Ceiling : System.Any_Priority := System.Priority'Last; package Ada.Containers.Unbounded_Priority_Queues is pragma Preelaborate(Unbounded_Priority_Queues); 3/3 package Implementation is ... -- not specified by the language end Implementation; 4/3 protected type Queue (Ceiling : System.Any_Priority := Default_Ceiling) with Priority => Ceiling is new Queue_Interfaces.Queue with 5/3 overriding entry Enqueue (New_Item : in Queue_Interfaces.Element_Type); overriding entry Dequeue (Element : out Queue_Interfaces.Element_Type); 6/3 not overriding procedure Dequeue_Only_High_Priority (At_Least : in Queue_Priority; Element : in out Queue_Interfaces.Element_Type; Success : out Boolean); 7/3 overriding function Current_Use return Count_Type; overriding function Peak_Use return Count_Type; 8/3 private ... -- not specified by the language end Queue; 9/3 private 10/3 ... -- not specified by the language 11/3 end Ada.Containers.Unbounded_Priority_Queues; 12/3 The type Queue is used to represent task-safe priority queues. 13/3 The capacity for instances of type Queue is unbounded. 14/3 Two elements E1 and E2 are equivalent if Before(Get_Priority(E1), Get_Priority(E2)) and Before(Get_Priority(E2), Get_Priority(E1)) both return False. 15/3 The actual functions for Get_Priority and Before are expected to return the same value each time they are called with the same actuals, and should not modify their actuals. Before should define a strict weak ordering relationship (see A.18). If the actual functions behave in some other manner, the behavior of Unbounded_Priority_Queues is unspecified. 16/3 Enqueue inserts an item according to the order specified by the Before function on the result of Get_Priority on the elements; Before should return True if Left is to be inserted before Right. If the queue already contains elements equivalent to New_Item, then it is inserted after the existing equivalent elements. 17/3 For a call on Dequeue_Only_High_Priority, if the head of the nonempty queue is E, and the function Before(At_Least, Get_Priority(E)) returns False, then E is assigned to Element and then removed from the queue, and Success is set to True; otherwise, Success is set to False and Element is unchanged. A.18.31 The Generic Package Containers.Bounded_Priority_Queues Static Semantics 1/3 The language-defined generic package Containers.Bounded_Priority_Queues provides type Queue, which implements the interface type Containers.Synchronized_Queue_Interfaces.Queue. 2/3 with System; with Ada.Containers.Synchronized_Queue_Interfaces; generic with package Queue_Interfaces is new Ada.Containers.Synchronized_Queue_Interfaces (<>); type Queue_Priority is private; with function Get_Priority (Element : Queue_Interfaces.Element_Type) return Queue_Priority is <>; with function Before (Left, Right : Queue_Priority) return Boolean is <>; Default_Capacity : Count_Type; Default_Ceiling : System.Any_Priority := System.Priority'Last; package Ada.Containers.Bounded_Priority_Queues is pragma Preelaborate(Bounded_Priority_Queues); 3/3 package Implementation is ... -- not specified by the language end Implementation; 4/3 protected type Queue (Capacity : Count_Type := Default_Capacity; Ceiling : System.Any_Priority := Default_Ceiling) with Priority => Ceiling is new Queue_Interfaces.Queue with 5/3 overriding entry Enqueue (New_Item : in Queue_Interfaces.Element_Type); overriding entry Dequeue (Element : out Queue_Interfaces.Element_Type); 6/3 not overriding procedure Dequeue_Only_High_Priority (At_Least : in Queue_Priority; Element : in out Queue_Interfaces.Element_Type; Success : out Boolean); 7/3 overriding function Current_Use return Count_Type; overriding function Peak_Use return Count_Type; 8/3 private ... -- not specified by the language end Queue; 9/3 private 10/3 ... -- not specified by the language 11/3 end Ada.Containers.Bounded_Priority_Queues; 12/3 The semantics are the same as for Unbounded_Priority_Queues, except: 13/3 * The capacity for instances of type Queue is bounded and specified by the discriminant Capacity. Implementation Advice 14/3 Bounded priority queue objects should be implemented without implicit pointers or dynamic allocation. A.18.32 Example of Container Use Examples 1/3 The following example is an implementation of Dijkstra's shortest path algorithm in a directed graph with positive distances. The graph is represented by a map from nodes to sets of edges. 2/3 with Ada.Containers.Vectors; with Ada.Containers.Doubly_Linked_Lists; use Ada.Containers; generic type Node is range <>; package Shortest_Paths is type Distance is new Float range 0.0 .. Float'Last; type Edge is record To, From : Node; Length : Distance; end record; 3/3 package Node_Maps is new Vectors (Node, Node); -- The algorithm builds a map to indicate the node used to reach a given -- node in the shortest distance. 4/3 package Adjacency_Lists is new Doubly_Linked_Lists (Edge); use Adjacency_Lists; 5/3 package Graphs is new Vectors (Node, Adjacency_Lists.List); 6/3 package Paths is new Doubly_Linked_Lists (Node); 7/3 function Shortest_Path (G : Graphs.Vector; Source : Node; Target : Node) return Paths.List with Pre => G (Source) /= Adjacency_Lists.Empty_List; 8/3 end Shortest_Paths; 9/3 package body Shortest_Paths is function Shortest_Path (G : Graphs.Vector; Source : Node; Target : Node) return Paths.List is use Adjacency_Lists, Node_Maps, Paths, Graphs; Reached : array (Node) of Boolean := (others => False); -- The set of nodes whose shortest distance to the source is known. 10/3 Reached_From : array (Node) of Node; So_Far : array (Node) of Distance := (others => Distance'Last); The_Path : Paths.List := Paths.Empty_List; Nearest_Distance : Distance; Next : Node; begin So_Far(Source) := 0.0; 11/3 while not Reached(Target) loop Nearest_Distance := Distance'Last; 12/3 -- Find closest node not reached yet, by iterating over all nodes. -- A more efficient algorithm uses a priority queue for this step. 13/3 Next := Source; for N in Node'First .. Node'Last loop if not Reached(N) and then So_Far(N) < Nearest_Distance then Next := N; Nearest_Distance := So_Far(N); end if; end loop; 14/3 if Nearest_Distance = Distance'Last then -- No next node found, graph is not connected return Paths.Empty_List; 15/3 else Reached(Next) := True; end if; 16/3 -- Update minimum distance to newly reachable nodes. 17/3 for E of G (Next) loop if not Reached(E.To) then Nearest_Distance := E.Length + So_Far(Next); 18/3 if Nearest_Distance < So_Far(E.To) then Reached_From(E.To) := Next; So_Far(E.To) := Nearest_Distance; end if; end if; end loop; end loop; 19/3 -- Rebuild path from target to source. 20/3 declare N : Node := Target; begin while N /= Source loop N := Reached_From(N); Prepend (The_Path, N); end loop; end; 21/3 return The_Path; end; end Shortest_Paths; 22/3 Note that the effect of the Constant_Indexing aspect (on type Vector) and the Implicit_Dereference aspect (on type Reference_Type) is that 23/3 G (Next) 24/3 is a convenient short hand for 25/3 G.Constant_Reference (Next).Element.all 26/3 Similarly, the effect of the loop: 27/3 for E of G (Next) loop if not Reached(E.To) then ... end if; end loop; 28/3 is the same as: 29/4 for C in G (Next).Iterate loop declare E : Edge renames G (Next)(C); begin if not Reached(E.To) then ... end if; end; end loop; 30/3 which is the same as: 31/4 declare L : Adjacency_Lists.List renames G (Next); C : Adjacency_Lists.Cursor := L.First; begin while Has_Element (C) loop declare E : Edge renames L(C); begin if not Reached(E.To) then ... end if; end; C := L.Next (C); end loop; end; A.19 The Package Locales 1/3 A locale identifies a geopolitical place or region and its associated language, which can be used to determine other internationalization-related characteristics. Static Semantics 2/3 The library package Locales has the following declaration: 3/3 package Ada.Locales is pragma Preelaborate(Locales); pragma Remote_Types(Locales); 4/4 type Language_Code is new String (1 .. 3) with Dynamic_Predicate => (for all E of Language_Code => E in 'a' .. 'z'); type Country_Code is new String (1 .. 2) with Dynamic_Predicate => (for all E of Country_Code => E in 'A' .. 'Z'); 5/3 Language_Unknown : constant Language_Code := "und"; Country_Unknown : constant Country_Code := "ZZ"; 6/3 function Language return Language_Code; function Country return Country_Code; 7/3 end Ada.Locales; 8/3 The active locale is the locale associated with the partition of the current task. 9/3 Language_Code is a lower-case string representation of an ISO 639-3 alpha-3 code that identifies a language. 10/3 Country_Code is an upper-case string representation of an ISO 3166-1 alpha-2 code that identifies a country. 11/3 Function Language returns the code of the language associated with the active locale. If the Language_Code associated with the active locale cannot be determined from the environment, then Language returns Language_Unknown. 12/3 Function Country returns the code of the country associated with the active locale. If the Country_Code associated with the active locale cannot be determined from the environment, then Country returns Country_Unknown.