Next: , Previous: A.4.4, Up: A.4


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.

1.a

Reason: The transformation operations for fixed− and bounded−length strings that are not necessarily length preserving are supplied for Unbounded_String as procedures as well as functions. This allows an implementation to do an initial allocation for an unbounded string and to avoid further allocations as long as the length does not exceed the allocated length.
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

     {00161AI95−00161−01}    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

     {00301AI95−00301−01}    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

     {00301AI95−00301−01}    function Unbounded_Slice
           (Source in Unbounded_String;
            Low    in Positive;
            High   in Natural)
               return Unbounded_String;

22.2/2

     {00301AI95−00301−01}    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

     {00301AI95−00301−01}    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

     {00301AI95−00301−01}    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

     {00301AI95−00301−01}    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

     {00301AI95−00301−01}    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;

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
{00360AI95−00360−01} 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 (non−private) 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

79

79.1/2
{00301AI95−00301−01} 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/2
{00301AI95−00301−01} 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 routines 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.

88.a/2

Implementation Note: {00301AI95−00301−01} A sample implementation of the private part of the package and several of the subprograms appears in the Ada 95 Rationale.
Incompatibilities With Ada 95

88.b/2

{00360AI95−00360−01} {incompatibilities with Ada 95} Amendment Correction: Type Unbounded_String is defined to need finalization. If the restriction No_Nested_Finalization (see D.7) applies to the partition, and Unbounded_String does not have a controlled part, it will not be allowed in local objects in Ada 2005 whereas it would be allowed in original Ada 95. Such code is not portable, as most Ada compilers have a controlled part in Unbounded_String, and thus would be illegal.

88.c/2

{00301AI95−00301−01} Procedure Set_Unbounded_String, two Unbounded_Slice subprograms, and overloaded versions of Index and Index_Non_Blank are newly added to Strings.Unbounded. If Strings.Unbounded is referenced in a use_clause, and an entity E with the same defining_identifier as a new entity in Strings.Unbounded is defined in a package that is also referenced in a use_clause, the entity E may no longer be use−visible, resulting in errors. This should be rare and is easily fixed if it does occur.
Extensions to Ada 95

88.d/2

{00161AI95−00161−01} {extensions to Ada 95} Amendment Correction: Added a pragma Preelaborable_Initialization to type Unbounded_String, so that it can be used to declare default−initialized objects in preelaborated units.