| ------------------------------------------------------------------------------ |
| -- -- |
| -- GNAT RUN-TIME COMPONENTS -- |
| -- -- |
| -- A D A . S T R I N G S . S U P E R B O U N D E D -- |
| -- -- |
| -- S p e c -- |
| -- -- |
| -- Copyright (C) 2003-2022, Free Software Foundation, Inc. -- |
| -- -- |
| -- GNAT is free software; you can redistribute it and/or modify it under -- |
| -- terms of the GNU General Public License as published by the Free Soft- -- |
| -- ware Foundation; either version 3, or (at your option) any later ver- -- |
| -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- |
| -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- |
| -- or FITNESS FOR A PARTICULAR PURPOSE. -- |
| -- -- |
| -- As a special exception under Section 7 of GPL version 3, you are granted -- |
| -- additional permissions described in the GCC Runtime Library Exception, -- |
| -- version 3.1, as published by the Free Software Foundation. -- |
| -- -- |
| -- You should have received a copy of the GNU General Public License and -- |
| -- a copy of the GCC Runtime Library Exception along with this program; -- |
| -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- |
| -- <http://www.gnu.org/licenses/>. -- |
| -- -- |
| -- GNAT was originally developed by the GNAT team at New York University. -- |
| -- Extensive contributions were provided by Ada Core Technologies Inc. -- |
| -- -- |
| ------------------------------------------------------------------------------ |
| |
| -- This non generic package contains most of the implementation of the |
| -- generic package Ada.Strings.Bounded.Generic_Bounded_Length. |
| |
| -- It defines type Super_String as a discriminated record with the maximum |
| -- length as the discriminant. Individual instantiations of Strings.Bounded |
| -- use this type with an appropriate discriminant value set. |
| |
| -- Preconditions in this unit are meant for analysis only, not for run-time |
| -- checking, so that the expected exceptions are raised. This is enforced by |
| -- setting the corresponding assertion policy to Ignore. Postconditions and |
| -- contract cases should not be executed at runtime as well, in order not to |
| -- slow down the execution of these functions. |
| |
| pragma Assertion_Policy (Pre => Ignore, |
| Post => Ignore, |
| Contract_Cases => Ignore, |
| Ghost => Ignore); |
| |
| with Ada.Strings.Maps; use type Ada.Strings.Maps.Character_Mapping_Function; |
| with Ada.Strings.Search; |
| |
| package Ada.Strings.Superbounded with SPARK_Mode is |
| pragma Preelaborate; |
| |
| -- Type Bounded_String in Ada.Strings.Bounded.Generic_Bounded_Length is |
| -- derived from Super_String, with the constraint of the maximum length. |
| |
| type Super_String_Data is new String with Relaxed_Initialization; |
| |
| type Super_String (Max_Length : Positive) is record |
| Current_Length : Natural := 0; |
| Data : Super_String_Data (1 .. Max_Length); |
| -- A previous version had a default initial value for Data, which is |
| -- no longer necessary, because we now special-case this type in the |
| -- compiler, so "=" composes properly for descendants of this type. |
| -- Leaving it out is more efficient. |
| end record |
| with |
| Predicate => |
| Current_Length <= Max_Length |
| and then Data (1 .. Current_Length)'Initialized; |
| |
| -- The subprograms defined for Super_String are similar to those |
| -- defined for Bounded_String, except that they have different names, so |
| -- that they can be renamed in Ada.Strings.Bounded.Generic_Bounded_Length. |
| |
| function Super_Length (Source : Super_String) return Natural |
| is (Source.Current_Length) |
| with Global => null; |
| |
| -------------------------------------------------------- |
| -- Conversion, Concatenation, and Selection Functions -- |
| -------------------------------------------------------- |
| |
| function To_Super_String |
| (Source : String; |
| Max_Length : Positive; |
| Drop : Truncation := Error) return Super_String |
| with |
| Pre => (if Source'Length > Max_Length then Drop /= Error), |
| Post => To_Super_String'Result.Max_Length = Max_Length, |
| Contract_Cases => |
| (Source'Length <= Max_Length |
| => |
| Super_To_String (To_Super_String'Result) = Source, |
| |
| Source'Length > Max_Length and then Drop = Left |
| => |
| Super_To_String (To_Super_String'Result) = |
| Source (Source'Last - Max_Length + 1 .. Source'Last), |
| |
| others -- Drop = Right |
| => |
| Super_To_String (To_Super_String'Result) = |
| Source (Source'First .. Source'First - 1 + Max_Length)), |
| Global => null; |
| -- Note the additional parameter Max_Length, which specifies the maximum |
| -- length setting of the resulting Super_String value. |
| |
| -- The following procedures have declarations (and semantics) that are |
| -- exactly analogous to those declared in Ada.Strings.Bounded. |
| |
| function Super_To_String (Source : Super_String) return String |
| is (String (Source.Data (1 .. Source.Current_Length))); |
| |
| procedure Set_Super_String |
| (Target : out Super_String; |
| Source : String; |
| Drop : Truncation := Error) |
| with |
| Pre => |
| (if Source'Length > Target.Max_Length then Drop /= Error), |
| Contract_Cases => |
| (Source'Length <= Target.Max_Length |
| => |
| Super_To_String (Target) = Source, |
| |
| Source'Length > Target.Max_Length and then Drop = Left |
| => |
| Super_To_String (Target) = |
| Source (Source'Last - Target.Max_Length + 1 .. Source'Last), |
| |
| others -- Drop = Right |
| => |
| Super_To_String (Target) = |
| Source (Source'First .. Source'First - 1 + Target.Max_Length)), |
| Global => null; |
| |
| function Super_Append |
| (Left : Super_String; |
| Right : Super_String; |
| Drop : Truncation := Error) return Super_String |
| with |
| Pre => |
| Left.Max_Length = Right.Max_Length |
| and then |
| (if Super_Length (Left) > Left.Max_Length - Super_Length (Right) |
| then Drop /= Error), |
| Post => Super_Append'Result.Max_Length = Left.Max_Length, |
| Contract_Cases => |
| (Super_Length (Left) <= Left.Max_Length - Super_Length (Right) |
| => |
| Super_Length (Super_Append'Result) = |
| Super_Length (Left) + Super_Length (Right) |
| and then |
| Super_Slice (Super_Append'Result, 1, Super_Length (Left)) = |
| Super_To_String (Left) |
| and then |
| (if Super_Length (Right) > 0 then |
| Super_Slice (Super_Append'Result, |
| Super_Length (Left) + 1, |
| Super_Length (Super_Append'Result)) = |
| Super_To_String (Right)), |
| |
| Super_Length (Left) > Left.Max_Length - Super_Length (Right) |
| and then Drop = Strings.Left |
| => |
| Super_Length (Super_Append'Result) = Left.Max_Length |
| and then |
| (if Super_Length (Right) < Left.Max_Length then |
| String'(Super_Slice (Super_Append'Result, |
| 1, Left.Max_Length - Super_Length (Right))) = |
| Super_Slice (Left, |
| Super_Length (Left) - Left.Max_Length |
| + Super_Length (Right) + 1, |
| Super_Length (Left))) |
| and then |
| Super_Slice (Super_Append'Result, |
| Left.Max_Length - Super_Length (Right) + 1, Left.Max_Length) = |
| Super_To_String (Right), |
| |
| others -- Drop = Right |
| => |
| Super_Length (Super_Append'Result) = Left.Max_Length |
| and then |
| Super_Slice (Super_Append'Result, 1, Super_Length (Left)) = |
| Super_To_String (Left) |
| and then |
| (if Super_Length (Left) < Left.Max_Length then |
| String'(Super_Slice (Super_Append'Result, |
| Super_Length (Left) + 1, Left.Max_Length)) = |
| Super_Slice (Right, |
| 1, Left.Max_Length - Super_Length (Left)))), |
| Global => null; |
| |
| function Super_Append |
| (Left : Super_String; |
| Right : String; |
| Drop : Truncation := Error) return Super_String |
| with |
| Pre => |
| (if Right'Length > Left.Max_Length - Super_Length (Left) |
| then Drop /= Error), |
| Post => Super_Append'Result.Max_Length = Left.Max_Length, |
| Contract_Cases => |
| (Super_Length (Left) <= Left.Max_Length - Right'Length |
| => |
| Super_Length (Super_Append'Result) = |
| Super_Length (Left) + Right'Length |
| and then |
| Super_Slice (Super_Append'Result, 1, Super_Length (Left)) = |
| Super_To_String (Left) |
| and then |
| (if Right'Length > 0 then |
| Super_Slice (Super_Append'Result, |
| Super_Length (Left) + 1, |
| Super_Length (Super_Append'Result)) = |
| Right), |
| |
| Super_Length (Left) > Left.Max_Length - Right'Length |
| and then Drop = Strings.Left |
| => |
| Super_Length (Super_Append'Result) = Left.Max_Length |
| and then |
| (if Right'Length < Left.Max_Length then |
| |
| -- The result is the end of Left followed by Right |
| |
| String'(Super_Slice (Super_Append'Result, |
| 1, Left.Max_Length - Right'Length)) = |
| Super_Slice (Left, |
| Super_Length (Left) - Left.Max_Length + Right'Length |
| + 1, |
| Super_Length (Left)) |
| and then |
| Super_Slice (Super_Append'Result, |
| Left.Max_Length - Right'Length + 1, Left.Max_Length) = |
| Right |
| else |
| -- The result is the last Max_Length characters of Right |
| |
| Super_To_String (Super_Append'Result) = |
| Right (Right'Last - Left.Max_Length + 1 .. Right'Last)), |
| |
| others -- Drop = Right |
| => |
| Super_Length (Super_Append'Result) = Left.Max_Length |
| and then |
| Super_Slice (Super_Append'Result, 1, Super_Length (Left)) = |
| Super_To_String (Left) |
| and then |
| (if Super_Length (Left) < Left.Max_Length then |
| Super_Slice (Super_Append'Result, |
| Super_Length (Left) + 1, Left.Max_Length) = |
| Right (Right'First |
| .. Left.Max_Length - Super_Length (Left) |
| - 1 + Right'First))), |
| Global => null; |
| |
| function Super_Append |
| (Left : String; |
| Right : Super_String; |
| Drop : Truncation := Error) return Super_String |
| with |
| Pre => |
| (if Left'Length > Right.Max_Length - Super_Length (Right) |
| then Drop /= Error), |
| Post => Super_Append'Result.Max_Length = Right.Max_Length, |
| Contract_Cases => |
| (Left'Length <= Right.Max_Length - Super_Length (Right) |
| => |
| Super_Length (Super_Append'Result) = |
| Left'Length + Super_Length (Right) |
| and then Super_Slice (Super_Append'Result, 1, Left'Length) = Left |
| and then |
| (if Super_Length (Right) > 0 then |
| Super_Slice (Super_Append'Result, |
| Left'Length + 1, Super_Length (Super_Append'Result)) = |
| Super_To_String (Right)), |
| |
| Left'Length > Right.Max_Length - Super_Length (Right) |
| and then Drop = Strings.Left |
| => |
| Super_Length (Super_Append'Result) = Right.Max_Length |
| and then |
| (if Super_Length (Right) < Right.Max_Length then |
| Super_Slice (Super_Append'Result, |
| 1, Right.Max_Length - Super_Length (Right)) = |
| Left |
| (Left'Last - Right.Max_Length + Super_Length (Right) + 1 |
| .. Left'Last)) |
| and then |
| Super_Slice (Super_Append'Result, |
| Right.Max_Length - Super_Length (Right) + 1, |
| Right.Max_Length) = |
| Super_To_String (Right), |
| |
| others -- Drop = Right |
| => |
| Super_Length (Super_Append'Result) = Right.Max_Length |
| and then |
| (if Left'Length < Right.Max_Length then |
| |
| -- The result is Left followed by the beginning of Right |
| |
| Super_Slice (Super_Append'Result, 1, Left'Length) = Left |
| and then |
| String'(Super_Slice (Super_Append'Result, |
| Left'Length + 1, Right.Max_Length)) = |
| Super_Slice (Right, 1, Right.Max_Length - Left'Length) |
| else |
| -- The result is the first Max_Length characters of Left |
| |
| Super_To_String (Super_Append'Result) = |
| Left (Left'First .. Right.Max_Length - 1 + Left'First))), |
| Global => null; |
| |
| function Super_Append |
| (Left : Super_String; |
| Right : Character; |
| Drop : Truncation := Error) return Super_String |
| with |
| Pre => |
| (if Super_Length (Left) = Left.Max_Length then Drop /= Error), |
| Post => Super_Append'Result.Max_Length = Left.Max_Length, |
| Contract_Cases => |
| (Super_Length (Left) < Left.Max_Length |
| => |
| Super_Length (Super_Append'Result) = Super_Length (Left) + 1 |
| and then |
| Super_Slice (Super_Append'Result, 1, Super_Length (Left)) = |
| Super_To_String (Left) |
| and then |
| Super_Element (Super_Append'Result, Super_Length (Left) + 1) = |
| Right, |
| |
| Super_Length (Left) = Left.Max_Length and then Drop = Strings.Right |
| => |
| Super_Length (Super_Append'Result) = Left.Max_Length |
| and then |
| Super_To_String (Super_Append'Result) = Super_To_String (Left), |
| |
| others -- Drop = Left |
| => |
| Super_Length (Super_Append'Result) = Left.Max_Length |
| and then |
| String'(Super_Slice (Super_Append'Result, |
| 1, Left.Max_Length - 1)) = |
| Super_Slice (Left, 2, Left.Max_Length) |
| and then |
| Super_Element (Super_Append'Result, Left.Max_Length) = Right), |
| Global => null; |
| |
| function Super_Append |
| (Left : Character; |
| Right : Super_String; |
| Drop : Truncation := Error) return Super_String |
| with |
| Pre => |
| (if Super_Length (Right) = Right.Max_Length then Drop /= Error), |
| Post => Super_Append'Result.Max_Length = Right.Max_Length, |
| Contract_Cases => |
| (Super_Length (Right) < Right.Max_Length |
| => |
| Super_Length (Super_Append'Result) = Super_Length (Right) + 1 |
| and then |
| Super_Slice (Super_Append'Result, 2, Super_Length (Right) + 1) = |
| Super_To_String (Right) |
| and then Super_Element (Super_Append'Result, 1) = Left, |
| |
| Super_Length (Right) = Right.Max_Length and then Drop = Strings.Left |
| => |
| Super_Length (Super_Append'Result) = Right.Max_Length |
| and then |
| Super_To_String (Super_Append'Result) = Super_To_String (Right), |
| |
| others -- Drop = Right |
| => |
| Super_Length (Super_Append'Result) = Right.Max_Length |
| and then |
| String'(Super_Slice (Super_Append'Result, 2, Right.Max_Length)) = |
| Super_Slice (Right, 1, Right.Max_Length - 1) |
| and then Super_Element (Super_Append'Result, 1) = Left), |
| Global => null; |
| |
| procedure Super_Append |
| (Source : in out Super_String; |
| New_Item : Super_String; |
| Drop : Truncation := Error) |
| with |
| Pre => |
| Source.Max_Length = New_Item.Max_Length |
| and then |
| (if Super_Length (Source) > |
| Source.Max_Length - Super_Length (New_Item) |
| then Drop /= Error), |
| Contract_Cases => |
| (Super_Length (Source) <= Source.Max_Length - Super_Length (New_Item) |
| => |
| Super_Length (Source) = |
| Super_Length (Source'Old) + Super_Length (New_Item) |
| and then |
| Super_Slice (Source, 1, Super_Length (Source'Old)) = |
| Super_To_String (Source'Old) |
| and then |
| (if Super_Length (New_Item) > 0 then |
| Super_Slice (Source, |
| Super_Length (Source'Old) + 1, Super_Length (Source)) = |
| Super_To_String (New_Item)), |
| |
| Super_Length (Source) > Source.Max_Length - Super_Length (New_Item) |
| and then Drop = Left |
| => |
| Super_Length (Source) = Source.Max_Length |
| and then |
| (if Super_Length (New_Item) < Source.Max_Length then |
| String'(Super_Slice (Source, |
| 1, Source.Max_Length - Super_Length (New_Item))) = |
| Super_Slice (Source'Old, |
| Super_Length (Source'Old) - Source.Max_Length |
| + Super_Length (New_Item) + 1, |
| Super_Length (Source'Old))) |
| and then |
| Super_Slice (Source, |
| Source.Max_Length - Super_Length (New_Item) + 1, |
| Source.Max_Length) = |
| Super_To_String (New_Item), |
| |
| others -- Drop = Right |
| => |
| Super_Length (Source) = Source.Max_Length |
| and then |
| Super_Slice (Source, 1, Super_Length (Source'Old)) = |
| Super_To_String (Source'Old) |
| and then |
| (if Super_Length (Source'Old) < Source.Max_Length then |
| String'(Super_Slice (Source, |
| Super_Length (Source'Old) + 1, Source.Max_Length)) = |
| Super_Slice (New_Item, |
| 1, Source.Max_Length - Super_Length (Source'Old)))), |
| Global => null; |
| |
| procedure Super_Append |
| (Source : in out Super_String; |
| New_Item : String; |
| Drop : Truncation := Error) |
| with |
| Pre => |
| (if New_Item'Length > Source.Max_Length - Super_Length (Source) |
| then Drop /= Error), |
| Contract_Cases => |
| (Super_Length (Source) <= Source.Max_Length - New_Item'Length |
| => |
| Super_Length (Source) = Super_Length (Source'Old) + New_Item'Length |
| and then |
| Super_Slice (Source, 1, Super_Length (Source'Old)) = |
| Super_To_String (Source'Old) |
| and then |
| (if New_Item'Length > 0 then |
| Super_Slice (Source, |
| Super_Length (Source'Old) + 1, Super_Length (Source)) = |
| New_Item), |
| |
| Super_Length (Source) > Source.Max_Length - New_Item'Length |
| and then Drop = Left |
| => |
| Super_Length (Source) = Source.Max_Length |
| and then |
| (if New_Item'Length < Source.Max_Length then |
| |
| -- The result is the end of Source followed by New_Item |
| |
| String'(Super_Slice (Source, |
| 1, Source.Max_Length - New_Item'Length)) = |
| Super_Slice (Source'Old, |
| Super_Length (Source'Old) - Source.Max_Length |
| + New_Item'Length + 1, |
| Super_Length (Source'Old)) |
| and then |
| Super_Slice (Source, |
| Source.Max_Length - New_Item'Length + 1, |
| Source.Max_Length) = |
| New_Item |
| else |
| -- The result is the last Max_Length characters of |
| -- New_Item. |
| |
| Super_To_String (Source) = New_Item |
| (New_Item'Last - Source.Max_Length + 1 .. New_Item'Last)), |
| |
| others -- Drop = Right |
| => |
| Super_Length (Source) = Source.Max_Length |
| and then |
| Super_Slice (Source, 1, Super_Length (Source'Old)) = |
| Super_To_String (Source'Old) |
| and then |
| (if Super_Length (Source'Old) < Source.Max_Length then |
| Super_Slice (Source, |
| Super_Length (Source'Old) + 1, Source.Max_Length) = |
| New_Item (New_Item'First |
| .. Source.Max_Length - Super_Length (Source'Old) - 1 |
| + New_Item'First))), |
| Global => null; |
| |
| procedure Super_Append |
| (Source : in out Super_String; |
| New_Item : Character; |
| Drop : Truncation := Error) |
| with |
| Pre => |
| (if Super_Length (Source) = Source.Max_Length then Drop /= Error), |
| Contract_Cases => |
| (Super_Length (Source) < Source.Max_Length |
| => |
| Super_Length (Source) = Super_Length (Source'Old) + 1 |
| and then |
| Super_Slice (Source, 1, Super_Length (Source'Old)) = |
| Super_To_String (Source'Old) |
| and then |
| Super_Element (Source, Super_Length (Source'Old) + 1) = New_Item, |
| |
| Super_Length (Source) = Source.Max_Length and then Drop = Right |
| => |
| Super_Length (Source) = Source.Max_Length |
| and then Super_To_String (Source) = Super_To_String (Source'Old), |
| |
| others -- Drop = Left |
| => |
| Super_Length (Source) = Source.Max_Length |
| and then |
| String'(Super_Slice (Source, 1, Source.Max_Length - 1)) = |
| Super_Slice (Source'Old, 2, Source.Max_Length) |
| and then Super_Element (Source, Source.Max_Length) = New_Item), |
| Global => null; |
| |
| function Concat |
| (Left : Super_String; |
| Right : Super_String) return Super_String |
| with |
| Pre => Left.Max_Length = Right.Max_Length |
| and then Super_Length (Left) <= Left.Max_Length - Super_Length (Right), |
| Post => Concat'Result.Max_Length = Left.Max_Length |
| and then |
| Super_Length (Concat'Result) = |
| Super_Length (Left) + Super_Length (Right) |
| and then |
| Super_Slice (Concat'Result, 1, Super_Length (Left)) = |
| Super_To_String (Left) |
| and then |
| (if Super_Length (Right) > 0 then |
| Super_Slice (Concat'Result, |
| Super_Length (Left) + 1, Super_Length (Concat'Result)) = |
| Super_To_String (Right)), |
| Global => null; |
| |
| function Concat |
| (Left : Super_String; |
| Right : String) return Super_String |
| with |
| Pre => Right'Length <= Left.Max_Length - Super_Length (Left), |
| Post => Concat'Result.Max_Length = Left.Max_Length |
| and then |
| Super_Length (Concat'Result) = Super_Length (Left) + Right'Length |
| and then |
| Super_Slice (Concat'Result, 1, Super_Length (Left)) = |
| Super_To_String (Left) |
| and then |
| (if Right'Length > 0 then |
| Super_Slice (Concat'Result, |
| Super_Length (Left) + 1, Super_Length (Concat'Result)) = |
| Right), |
| Global => null; |
| |
| function Concat |
| (Left : String; |
| Right : Super_String) return Super_String |
| with |
| Pre => Left'Length <= Right.Max_Length - Super_Length (Right), |
| Post => Concat'Result.Max_Length = Right.Max_Length |
| and then |
| Super_Length (Concat'Result) = Left'Length + Super_Length (Right) |
| and then Super_Slice (Concat'Result, 1, Left'Length) = Left |
| and then |
| (if Super_Length (Right) > 0 then |
| Super_Slice (Concat'Result, |
| Left'Length + 1, Super_Length (Concat'Result)) = |
| Super_To_String (Right)), |
| Global => null; |
| |
| function Concat |
| (Left : Super_String; |
| Right : Character) return Super_String |
| with |
| Pre => Super_Length (Left) < Left.Max_Length, |
| Post => Concat'Result.Max_Length = Left.Max_Length |
| and then Super_Length (Concat'Result) = Super_Length (Left) + 1 |
| and then |
| Super_Slice (Concat'Result, 1, Super_Length (Left)) = |
| Super_To_String (Left) |
| and then Super_Element (Concat'Result, Super_Length (Left) + 1) = Right, |
| Global => null; |
| |
| function Concat |
| (Left : Character; |
| Right : Super_String) return Super_String |
| with |
| Pre => Super_Length (Right) < Right.Max_Length, |
| Post => Concat'Result.Max_Length = Right.Max_Length |
| and then Super_Length (Concat'Result) = 1 + Super_Length (Right) |
| and then Super_Element (Concat'Result, 1) = Left |
| and then |
| Super_Slice (Concat'Result, 2, Super_Length (Concat'Result)) = |
| Super_To_String (Right), |
| Global => null; |
| |
| function Super_Element |
| (Source : Super_String; |
| Index : Positive) return Character |
| is (if Index <= Source.Current_Length |
| then Source.Data (Index) |
| else raise Index_Error) |
| with Pre => Index <= Super_Length (Source), |
| Global => null; |
| |
| procedure Super_Replace_Element |
| (Source : in out Super_String; |
| Index : Positive; |
| By : Character) |
| with |
| Pre => Index <= Super_Length (Source), |
| Post => Super_Length (Source) = Super_Length (Source'Old) |
| and then |
| (for all K in 1 .. Super_Length (Source) => |
| Super_Element (Source, K) = |
| (if K = Index then By else Super_Element (Source'Old, K))), |
| Global => null; |
| |
| function Super_Slice |
| (Source : Super_String; |
| Low : Positive; |
| High : Natural) return String |
| is (if Low - 1 > Source.Current_Length or else High > Source.Current_Length |
| |
| -- Note: test of High > Length is in accordance with AI95-00128 |
| |
| then raise Index_Error |
| else |
| -- Note: in this case, superflat bounds are not a problem, we just |
| -- get the null string in accordance with normal Ada slice rules. |
| |
| String (Source.Data (Low .. High))) |
| with Pre => Low - 1 <= Super_Length (Source) |
| and then High <= Super_Length (Source), |
| Global => null; |
| |
| function Super_Slice |
| (Source : Super_String; |
| Low : Positive; |
| High : Natural) return Super_String |
| with |
| Pre => |
| Low - 1 <= Super_Length (Source) and then High <= Super_Length (Source), |
| Post => Super_Slice'Result.Max_Length = Source.Max_Length |
| and then |
| Super_To_String (Super_Slice'Result) = |
| Super_Slice (Source, Low, High), |
| Global => null; |
| |
| procedure Super_Slice |
| (Source : Super_String; |
| Target : out Super_String; |
| Low : Positive; |
| High : Natural) |
| with |
| Pre => Source.Max_Length = Target.Max_Length |
| and then Low - 1 <= Super_Length (Source) |
| and then High <= Super_Length (Source), |
| Post => Super_To_String (Target) = Super_Slice (Source, Low, High), |
| Global => null; |
| |
| function "=" |
| (Left : Super_String; |
| Right : Super_String) return Boolean |
| with |
| Pre => Left.Max_Length = Right.Max_Length, |
| Post => "="'Result = (Super_To_String (Left) = Super_To_String (Right)), |
| Global => null; |
| |
| function Equal |
| (Left : Super_String; |
| Right : Super_String) return Boolean renames "="; |
| |
| function Equal |
| (Left : Super_String; |
| Right : String) return Boolean |
| with |
| Post => Equal'Result = (Super_To_String (Left) = Right), |
| Global => null; |
| |
| function Equal |
| (Left : String; |
| Right : Super_String) return Boolean |
| with |
| Post => Equal'Result = (Left = Super_To_String (Right)), |
| Global => null; |
| |
| function Less |
| (Left : Super_String; |
| Right : Super_String) return Boolean |
| with |
| Pre => Left.Max_Length = Right.Max_Length, |
| Post => |
| Less'Result = (Super_To_String (Left) < Super_To_String (Right)), |
| Global => null; |
| |
| function Less |
| (Left : Super_String; |
| Right : String) return Boolean |
| with |
| Post => Less'Result = (Super_To_String (Left) < Right), |
| Global => null; |
| |
| function Less |
| (Left : String; |
| Right : Super_String) return Boolean |
| with |
| Post => Less'Result = (Left < Super_To_String (Right)), |
| Global => null; |
| |
| function Less_Or_Equal |
| (Left : Super_String; |
| Right : Super_String) return Boolean |
| with |
| Pre => Left.Max_Length = Right.Max_Length, |
| Post => |
| Less_Or_Equal'Result = |
| (Super_To_String (Left) <= Super_To_String (Right)), |
| Global => null; |
| |
| function Less_Or_Equal |
| (Left : Super_String; |
| Right : String) return Boolean |
| with |
| Post => Less_Or_Equal'Result = (Super_To_String (Left) <= Right), |
| Global => null; |
| |
| function Less_Or_Equal |
| (Left : String; |
| Right : Super_String) return Boolean |
| with |
| Post => Less_Or_Equal'Result = (Left <= Super_To_String (Right)), |
| Global => null; |
| |
| function Greater |
| (Left : Super_String; |
| Right : Super_String) return Boolean |
| with |
| Pre => Left.Max_Length = Right.Max_Length, |
| Post => |
| Greater'Result = (Super_To_String (Left) > Super_To_String (Right)), |
| Global => null; |
| |
| function Greater |
| (Left : Super_String; |
| Right : String) return Boolean |
| with |
| Post => Greater'Result = (Super_To_String (Left) > Right), |
| Global => null; |
| |
| function Greater |
| (Left : String; |
| Right : Super_String) return Boolean |
| with |
| Post => Greater'Result = (Left > Super_To_String (Right)), |
| Global => null; |
| |
| function Greater_Or_Equal |
| (Left : Super_String; |
| Right : Super_String) return Boolean |
| with |
| Pre => Left.Max_Length = Right.Max_Length, |
| Post => |
| Greater_Or_Equal'Result = |
| (Super_To_String (Left) >= Super_To_String (Right)), |
| Global => null; |
| |
| function Greater_Or_Equal |
| (Left : Super_String; |
| Right : String) return Boolean |
| with |
| Post => Greater_Or_Equal'Result = (Super_To_String (Left) >= Right), |
| Global => null; |
| |
| function Greater_Or_Equal |
| (Left : String; |
| Right : Super_String) return Boolean |
| with |
| Post => Greater_Or_Equal'Result = (Left >= Super_To_String (Right)), |
| Global => null; |
| |
| ---------------------- |
| -- Search Functions -- |
| ---------------------- |
| |
| function Super_Index |
| (Source : Super_String; |
| Pattern : String; |
| Going : Direction := Forward; |
| Mapping : Maps.Character_Mapping := Maps.Identity) return Natural |
| with |
| Pre => Pattern'Length > 0, |
| Post => Super_Index'Result <= Super_Length (Source), |
| Contract_Cases => |
| |
| -- If Source is the empty string, then 0 is returned |
| |
| (Super_Length (Source) = 0 |
| => |
| Super_Index'Result = 0, |
| |
| -- If some slice of Source matches Pattern, then a valid index is |
| -- returned. |
| |
| Super_Length (Source) > 0 |
| and then |
| (for some J in 1 .. Super_Length (Source) - (Pattern'Length - 1) => |
| Search.Match (Super_To_String (Source), Pattern, Mapping, J)) |
| => |
| -- The result is in the considered range of Source |
| |
| Super_Index'Result in |
| 1 .. Super_Length (Source) - (Pattern'Length - 1) |
| |
| -- The slice beginning at the returned index matches Pattern |
| |
| and then Search.Match |
| (Super_To_String (Source), Pattern, Mapping, Super_Index'Result) |
| |
| -- The result is the smallest or largest index which satisfies |
| -- the matching, respectively when Going = Forward and Going = |
| -- Backward. |
| |
| and then |
| (for all J in 1 .. Super_Length (Source) => |
| (if (if Going = Forward |
| then J <= Super_Index'Result - 1 |
| else J - 1 in Super_Index'Result |
| .. Super_Length (Source) - Pattern'Length) |
| then not (Search.Match |
| (Super_To_String (Source), Pattern, Mapping, J)))), |
| |
| -- Otherwise, 0 is returned |
| |
| others |
| => |
| Super_Index'Result = 0), |
| Global => null; |
| |
| function Super_Index |
| (Source : Super_String; |
| Pattern : String; |
| Going : Direction := Forward; |
| Mapping : Maps.Character_Mapping_Function) return Natural |
| with |
| Pre => Pattern'Length /= 0 and then Mapping /= null, |
| Post => Super_Index'Result <= Super_Length (Source), |
| Contract_Cases => |
| |
| -- If Source is the empty string, then 0 is returned |
| |
| (Super_Length (Source) = 0 |
| => |
| Super_Index'Result = 0, |
| |
| -- If some slice of Source matches Pattern, then a valid index is |
| -- returned. |
| |
| Super_Length (Source) > 0 |
| and then |
| (for some J in 1 .. Super_Length (Source) - (Pattern'Length - 1) => |
| Search.Match (Super_To_String (Source), Pattern, Mapping, J)) |
| => |
| -- The result is in the considered range of Source |
| |
| Super_Index'Result in |
| 1 .. Super_Length (Source) - (Pattern'Length - 1) |
| |
| -- The slice beginning at the returned index matches Pattern |
| |
| and then Search.Match |
| (Super_To_String (Source), Pattern, Mapping, Super_Index'Result) |
| |
| -- The result is the smallest or largest index which satisfies |
| -- the matching, respectively when Going = Forward and Going = |
| -- Backward. |
| |
| and then |
| (for all J in 1 .. Super_Length (Source) => |
| (if (if Going = Forward |
| then J <= Super_Index'Result - 1 |
| else J - 1 in Super_Index'Result |
| .. Super_Length (Source) - Pattern'Length) |
| then not (Search.Match |
| (Super_To_String (Source), Pattern, Mapping, J)))), |
| |
| -- Otherwise, 0 is returned |
| |
| others |
| => |
| Super_Index'Result = 0), |
| Global => null; |
| |
| function Super_Index |
| (Source : Super_String; |
| Set : Maps.Character_Set; |
| Test : Membership := Inside; |
| Going : Direction := Forward) return Natural |
| with |
| Post => Super_Index'Result <= Super_Length (Source), |
| Contract_Cases => |
| |
| -- If no character of Source satisfies the property Test on Set, |
| -- then 0 is returned. |
| |
| ((for all C of Super_To_String (Source) => |
| (Test = Inside) /= Maps.Is_In (C, Set)) |
| => |
| Super_Index'Result = 0, |
| |
| -- Otherwise, an index in the range of Source is returned |
| |
| others |
| => |
| -- The result is in the range of Source |
| |
| Super_Index'Result in 1 .. Super_Length (Source) |
| |
| -- The character at the returned index satisfies the property |
| -- Test on Set. |
| |
| and then |
| (Test = Inside) = |
| Maps.Is_In (Super_Element (Source, Super_Index'Result), Set) |
| |
| -- The result is the smallest or largest index which satisfies |
| -- the property, respectively when Going = Forward and Going = |
| -- Backward. |
| |
| and then |
| (for all J in 1 .. Super_Length (Source) => |
| (if J /= Super_Index'Result |
| and then (J < Super_Index'Result) = (Going = Forward) |
| then (Test = Inside) |
| /= Maps.Is_In (Super_Element (Source, J), Set)))), |
| Global => null; |
| |
| function Super_Index |
| (Source : Super_String; |
| Pattern : String; |
| From : Positive; |
| Going : Direction := Forward; |
| Mapping : Maps.Character_Mapping := Maps.Identity) return Natural |
| with |
| Pre => |
| (if Super_Length (Source) /= 0 then From <= Super_Length (Source)) |
| and then Pattern'Length /= 0, |
| Post => Super_Index'Result <= Super_Length (Source), |
| Contract_Cases => |
| |
| -- If Source is the empty string, then 0 is returned |
| |
| (Super_Length (Source) = 0 |
| => |
| Super_Index'Result = 0, |
| |
| -- If some slice of Source matches Pattern, then a valid index is |
| -- returned. |
| |
| Super_Length (Source) > 0 |
| and then |
| (for some J in |
| (if Going = Forward then From else 1) |
| .. (if Going = Forward then Super_Length (Source) else From) |
| - (Pattern'Length - 1) => |
| Search.Match (Super_To_String (Source), Pattern, Mapping, J)) |
| => |
| -- The result is in the considered range of Source |
| |
| Super_Index'Result in |
| (if Going = Forward then From else 1) |
| .. (if Going = Forward then Super_Length (Source) else From) |
| - (Pattern'Length - 1) |
| |
| -- The slice beginning at the returned index matches Pattern |
| |
| and then Search.Match |
| (Super_To_String (Source), Pattern, Mapping, Super_Index'Result) |
| |
| -- The result is the smallest or largest index which satisfies |
| -- the matching, respectively when Going = Forward and Going = |
| -- Backward. |
| |
| and then |
| (for all J in 1 .. Super_Length (Source) => |
| (if (if Going = Forward |
| then J in From .. Super_Index'Result - 1 |
| else J - 1 in Super_Index'Result |
| .. From - Pattern'Length) |
| then not (Search.Match |
| (Super_To_String (Source), Pattern, Mapping, J)))), |
| |
| -- Otherwise, 0 is returned |
| |
| others |
| => |
| Super_Index'Result = 0), |
| Global => null; |
| |
| function Super_Index |
| (Source : Super_String; |
| Pattern : String; |
| From : Positive; |
| Going : Direction := Forward; |
| Mapping : Maps.Character_Mapping_Function) return Natural |
| with |
| Pre => |
| (if Super_Length (Source) /= 0 then From <= Super_Length (Source)) |
| and then Pattern'Length /= 0 |
| and then Mapping /= null, |
| Post => Super_Index'Result <= Super_Length (Source), |
| Contract_Cases => |
| |
| -- If Source is the empty string, then 0 is returned |
| |
| (Super_Length (Source) = 0 |
| => |
| Super_Index'Result = 0, |
| |
| -- If some slice of Source matches Pattern, then a valid index is |
| -- returned. |
| |
| Super_Length (Source) > 0 |
| and then |
| (for some J in |
| (if Going = Forward then From else 1) |
| .. (if Going = Forward then Super_Length (Source) else From) |
| - (Pattern'Length - 1) => |
| Search.Match (Super_To_String (Source), Pattern, Mapping, J)) |
| => |
| -- The result is in the considered range of Source |
| |
| Super_Index'Result in |
| (if Going = Forward then From else 1) |
| .. (if Going = Forward then Super_Length (Source) else From) |
| - (Pattern'Length - 1) |
| |
| -- The slice beginning at the returned index matches Pattern |
| |
| and then Search.Match |
| (Super_To_String (Source), Pattern, Mapping, Super_Index'Result) |
| |
| -- The result is the smallest or largest index which satisfies |
| -- the matching, respectively when Going = Forward and Going = |
| -- Backward. |
| |
| and then |
| (for all J in 1 .. Super_Length (Source) => |
| (if (if Going = Forward |
| then J in From .. Super_Index'Result - 1 |
| else J - 1 in Super_Index'Result |
| .. From - Pattern'Length) |
| then not (Search.Match |
| (Super_To_String (Source), Pattern, Mapping, J)))), |
| |
| -- Otherwise, 0 is returned |
| |
| others |
| => |
| Super_Index'Result = 0), |
| Global => null; |
| |
| function Super_Index |
| (Source : Super_String; |
| Set : Maps.Character_Set; |
| From : Positive; |
| Test : Membership := Inside; |
| Going : Direction := Forward) return Natural |
| with |
| Pre => |
| (if Super_Length (Source) /= 0 then From <= Super_Length (Source)), |
| Post => Super_Index'Result <= Super_Length (Source), |
| Contract_Cases => |
| |
| -- If Source is the empty string, or no character of the considered |
| -- slice of Source satisfies the property Test on Set, then 0 is |
| -- returned. |
| |
| (Super_Length (Source) = 0 |
| or else |
| (for all J in 1 .. Super_Length (Source) => |
| (if J = From or else (J > From) = (Going = Forward) then |
| (Test = Inside) /= |
| Maps.Is_In (Super_Element (Source, J), Set))) |
| => |
| Super_Index'Result = 0, |
| |
| -- Otherwise, an index in the considered range of Source is returned |
| |
| others |
| => |
| -- The result is in the considered range of Source |
| |
| Super_Index'Result in 1 .. Super_Length (Source) |
| and then |
| (Super_Index'Result = From |
| or else (Super_Index'Result > From) = (Going = Forward)) |
| |
| -- The character at the returned index satisfies the property |
| -- Test on Set. |
| |
| and then |
| (Test = Inside) = |
| Maps.Is_In (Super_Element (Source, Super_Index'Result), Set) |
| |
| -- The result is the smallest or largest index which satisfies |
| -- the property, respectively when Going = Forward and Going = |
| -- Backward. |
| |
| and then |
| (for all J in 1 .. Super_Length (Source) => |
| (if J /= Super_Index'Result |
| and then (J < Super_Index'Result) = (Going = Forward) |
| and then (J = From |
| or else (J > From) = (Going = Forward)) |
| then (Test = Inside) |
| /= Maps.Is_In (Super_Element (Source, J), Set)))), |
| Global => null; |
| |
| function Super_Index_Non_Blank |
| (Source : Super_String; |
| Going : Direction := Forward) return Natural |
| with |
| Post => Super_Index_Non_Blank'Result <= Super_Length (Source), |
| Contract_Cases => |
| |
| -- If all characters of Source are Space characters, then 0 is |
| -- returned. |
| |
| ((for all C of Super_To_String (Source) => C = ' ') |
| => |
| Super_Index_Non_Blank'Result = 0, |
| |
| -- Otherwise, an index in the range of Source is returned |
| |
| others |
| => |
| -- The result is in the range of Source |
| |
| Super_Index_Non_Blank'Result in 1 .. Super_Length (Source) |
| |
| -- The character at the returned index is not a Space character |
| |
| and then |
| Super_Element (Source, Super_Index_Non_Blank'Result) /= ' ' |
| |
| -- The result is the smallest or largest index which is not a |
| -- Space character, respectively when Going = Forward and Going |
| -- = Backward. |
| |
| and then |
| (for all J in 1 .. Super_Length (Source) => |
| (if J /= Super_Index_Non_Blank'Result |
| and then |
| (J < Super_Index_Non_Blank'Result) = (Going = Forward) |
| then Super_Element (Source, J) = ' '))), |
| Global => null; |
| |
| function Super_Index_Non_Blank |
| (Source : Super_String; |
| From : Positive; |
| Going : Direction := Forward) return Natural |
| with |
| Pre => |
| (if Super_Length (Source) /= 0 then From <= Super_Length (Source)), |
| Post => Super_Index_Non_Blank'Result <= Super_Length (Source), |
| Contract_Cases => |
| |
| -- If Source is the empty string, or all characters of the |
| -- considered slice of Source are Space characters, then 0 |
| -- is returned. |
| |
| (Super_Length (Source) = 0 |
| or else |
| (for all J in 1 .. Super_Length (Source) => |
| (if J = From or else (J > From) = (Going = Forward) then |
| Super_Element (Source, J) = ' ')) |
| => |
| Super_Index_Non_Blank'Result = 0, |
| |
| -- Otherwise, an index in the considered range of Source is returned |
| |
| others |
| => |
| -- The result is in the considered range of Source |
| |
| Super_Index_Non_Blank'Result in 1 .. Super_Length (Source) |
| and then |
| (Super_Index_Non_Blank'Result = From |
| or else |
| (Super_Index_Non_Blank'Result > From) = (Going = Forward)) |
| |
| -- The character at the returned index is not a Space character |
| |
| and then |
| Super_Element (Source, Super_Index_Non_Blank'Result) /= ' ' |
| |
| -- The result is the smallest or largest index which isn't a |
| -- Space character, respectively when Going = Forward and Going |
| -- = Backward. |
| |
| and then |
| (for all J in 1 .. Super_Length (Source) => |
| (if J /= Super_Index_Non_Blank'Result |
| and then |
| (J < Super_Index_Non_Blank'Result) = (Going = Forward) |
| and then (J = From |
| or else (J > From) = (Going = Forward)) |
| then Super_Element (Source, J) = ' '))), |
| Global => null; |
| |
| function Super_Count |
| (Source : Super_String; |
| Pattern : String; |
| Mapping : Maps.Character_Mapping := Maps.Identity) return Natural |
| with |
| Pre => Pattern'Length /= 0, |
| Global => null; |
| |
| function Super_Count |
| (Source : Super_String; |
| Pattern : String; |
| Mapping : Maps.Character_Mapping_Function) return Natural |
| with |
| Pre => Pattern'Length /= 0 and then Mapping /= null, |
| Global => null; |
| |
| function Super_Count |
| (Source : Super_String; |
| Set : Maps.Character_Set) return Natural |
| with |
| Global => null; |
| |
| procedure Super_Find_Token |
| (Source : Super_String; |
| Set : Maps.Character_Set; |
| From : Positive; |
| Test : Membership; |
| First : out Positive; |
| Last : out Natural) |
| with |
| Pre => |
| (if Super_Length (Source) /= 0 then From <= Super_Length (Source)), |
| Contract_Cases => |
| |
| -- If Source is the empty string, or if no character of the |
| -- considered slice of Source satisfies the property Test on |
| -- Set, then First is set to From and Last is set to 0. |
| |
| (Super_Length (Source) = 0 |
| or else |
| (for all J in From .. Super_Length (Source) => |
| (Test = Inside) /= Maps.Is_In (Super_Element (Source, J), Set)) |
| => |
| First = From and then Last = 0, |
| |
| -- Otherwise, First and Last are set to valid indexes |
| |
| others |
| => |
| -- First and Last are in the considered range of Source |
| |
| First in From .. Super_Length (Source) |
| and then Last in First .. Super_Length (Source) |
| |
| -- No character between From and First satisfies the property |
| -- Test on Set. |
| |
| and then |
| (for all J in From .. First - 1 => |
| (Test = Inside) /= |
| Maps.Is_In (Super_Element (Source, J), Set)) |
| |
| -- All characters between First and Last satisfy the property |
| -- Test on Set. |
| |
| and then |
| (for all J in First .. Last => |
| (Test = Inside) = |
| Maps.Is_In (Super_Element (Source, J), Set)) |
| |
| -- If Last is not Source'Last, then the character at position |
| -- Last + 1 does not satify the property Test on Set. |
| |
| and then |
| (if Last < Super_Length (Source) |
| then |
| (Test = Inside) /= |
| Maps.Is_In (Super_Element (Source, Last + 1), Set))), |
| Global => null; |
| |
| procedure Super_Find_Token |
| (Source : Super_String; |
| Set : Maps.Character_Set; |
| Test : Membership; |
| First : out Positive; |
| Last : out Natural) |
| with |
| Contract_Cases => |
| |
| -- If Source is the empty string, or if no character of the considered |
| -- slice of Source satisfies the property Test on Set, then First is |
| -- set to 1 and Last is set to 0. |
| |
| (Super_Length (Source) = 0 |
| or else |
| (for all J in 1 .. Super_Length (Source) => |
| (Test = Inside) /= Maps.Is_In (Super_Element (Source, J), Set)) |
| => |
| First = 1 and then Last = 0, |
| |
| -- Otherwise, First and Last are set to valid indexes |
| |
| others |
| => |
| -- First and Last are in the considered range of Source |
| |
| First in 1 .. Super_Length (Source) |
| and then Last in First .. Super_Length (Source) |
| |
| -- No character between 1 and First satisfies the property Test on |
| -- Set. |
| |
| and then |
| (for all J in 1 .. First - 1 => |
| (Test = Inside) /= |
| Maps.Is_In (Super_Element (Source, J), Set)) |
| |
| -- All characters between First and Last satisfy the property |
| -- Test on Set. |
| |
| and then |
| (for all J in First .. Last => |
| (Test = Inside) = |
| Maps.Is_In (Super_Element (Source, J), Set)) |
| |
| -- If Last is not Source'Last, then the character at position |
| -- Last + 1 does not satify the property Test on Set. |
| |
| and then |
| (if Last < Super_Length (Source) |
| then |
| (Test = Inside) /= |
| Maps.Is_In (Super_Element (Source, Last + 1), Set))), |
| Global => null; |
| |
| ------------------------------------ |
| -- String Translation Subprograms -- |
| ------------------------------------ |
| |
| function Super_Translate |
| (Source : Super_String; |
| Mapping : Maps.Character_Mapping) return Super_String |
| with |
| Post => Super_Translate'Result.Max_Length = Source.Max_Length |
| and then Super_Length (Super_Translate'Result) = Super_Length (Source) |
| and then |
| (for all K in 1 .. Super_Length (Source) => |
| Super_Element (Super_Translate'Result, K) = |
| Ada.Strings.Maps.Value (Mapping, Super_Element (Source, K))), |
| Global => null; |
| |
| procedure Super_Translate |
| (Source : in out Super_String; |
| Mapping : Maps.Character_Mapping) |
| with |
| Post => Super_Length (Source) = Super_Length (Source'Old) |
| and then |
| (for all K in 1 .. Super_Length (Source) => |
| Super_Element (Source, K) = |
| Ada.Strings.Maps.Value (Mapping, Super_Element (Source'Old, K))), |
| Global => null; |
| |
| function Super_Translate |
| (Source : Super_String; |
| Mapping : Maps.Character_Mapping_Function) return Super_String |
| with |
| Pre => Mapping /= null, |
| Post => Super_Translate'Result.Max_Length = Source.Max_Length |
| and then Super_Length (Super_Translate'Result) = Super_Length (Source) |
| and then |
| (for all K in 1 .. Super_Length (Source) => |
| Super_Element (Super_Translate'Result, K) = |
| Mapping (Super_Element (Source, K))), |
| Global => null; |
| |
| procedure Super_Translate |
| (Source : in out Super_String; |
| Mapping : Maps.Character_Mapping_Function) |
| with |
| Pre => Mapping /= null, |
| Post => Super_Length (Source) = Super_Length (Source'Old) |
| and then |
| (for all K in 1 .. Super_Length (Source) => |
| Super_Element (Source, K) = |
| Mapping (Super_Element (Source'Old, K))), |
| Global => null; |
| |
| --------------------------------------- |
| -- String Transformation Subprograms -- |
| --------------------------------------- |
| |
| function Super_Replace_Slice |
| (Source : Super_String; |
| Low : Positive; |
| High : Natural; |
| By : String; |
| Drop : Truncation := Error) return Super_String |
| with |
| Pre => |
| Low - 1 <= Super_Length (Source) |
| and then |
| (if Drop = Error |
| then (if High >= Low |
| then Low - 1 |
| <= Source.Max_Length - By'Length |
| - Integer'Max (Super_Length (Source) - High, 0) |
| else Super_Length (Source) <= |
| Source.Max_Length - By'Length)), |
| Post => |
| Super_Replace_Slice'Result.Max_Length = Source.Max_Length, |
| Contract_Cases => |
| (Low - 1 <= Source.Max_Length - By'Length - Integer'Max |
| (Super_Length (Source) - Integer'Max (High, Low - 1), 0) |
| => |
| -- Total length is lower than Max_Length: nothing is dropped |
| |
| -- Note that if High < Low, the insertion is done before Low, so in |
| -- all cases the starting position of the slice of Source remaining |
| -- after the replaced Slice is Integer'Max (High + 1, Low). |
| |
| Super_Length (Super_Replace_Slice'Result) = |
| Low - 1 + By'Length + Integer'Max |
| (Super_Length (Source) - Integer'Max (High, Low - 1), 0) |
| and then |
| String'(Super_Slice (Super_Replace_Slice'Result, 1, Low - 1)) = |
| Super_Slice (Source, 1, Low - 1) |
| and then |
| Super_Slice (Super_Replace_Slice'Result, |
| Low, Low - 1 + By'Length) = By |
| and then |
| (if Integer'Max (High, Low - 1) < Super_Length (Source) then |
| String'(Super_Slice (Super_Replace_Slice'Result, |
| Low + By'Length, |
| Super_Length (Super_Replace_Slice'Result))) = |
| Super_Slice (Source, |
| Integer'Max (High + 1, Low), Super_Length (Source))), |
| |
| Low - 1 > Source.Max_Length - By'Length - Integer'Max |
| (Super_Length (Source) - Integer'Max (High, Low - 1), 0) |
| and then Drop = Left |
| => |
| -- Final_Super_Slice is the length of the slice of Source remaining |
| -- after the replaced part. |
| (declare |
| Final_Super_Slice : constant Natural := |
| Integer'Max |
| (Super_Length (Source) - Integer'Max (High, Low - 1), 0); |
| begin |
| -- The result is of maximal length and ends by the last |
| -- Final_Super_Slice characters of Source. |
| |
| Super_Length (Super_Replace_Slice'Result) = Source.Max_Length |
| and then |
| (if Final_Super_Slice > 0 then |
| String'(Super_Slice (Super_Replace_Slice'Result, |
| Source.Max_Length - Final_Super_Slice + 1, |
| Source.Max_Length)) = |
| Super_Slice (Source, |
| Integer'Max (High + 1, Low), Super_Length (Source))) |
| |
| -- Depending on when we reach Max_Length, either the first |
| -- part of Source is fully dropped and By is partly dropped, |
| -- or By is fully added and the first part of Source is partly |
| -- dropped. |
| |
| and then |
| (if Source.Max_Length - Final_Super_Slice - By'Length <= 0 then |
| |
| -- The first (possibly zero) characters of By are dropped |
| |
| (if Final_Super_Slice < Source.Max_Length then |
| Super_Slice (Super_Replace_Slice'Result, |
| 1, Source.Max_Length - Final_Super_Slice) = |
| By (By'Last - Source.Max_Length + Final_Super_Slice |
| + 1 |
| .. By'Last)) |
| |
| else -- By is added to the result |
| |
| Super_Slice (Super_Replace_Slice'Result, |
| Source.Max_Length - Final_Super_Slice - By'Length + 1, |
| Source.Max_Length - Final_Super_Slice) = |
| By |
| |
| -- The first characters of Source (1 .. Low - 1) are |
| -- dropped. |
| |
| and then |
| String'(Super_Slice (Super_Replace_Slice'Result, 1, |
| Source.Max_Length - Final_Super_Slice - By'Length)) = |
| Super_Slice (Source, |
| Low - Source.Max_Length |
| + Final_Super_Slice + By'Length, |
| Low - 1))), |
| |
| others -- Drop = Right |
| => |
| -- The result is of maximal length and starts by the first Low - 1 |
| -- characters of Source. |
| |
| Super_Length (Super_Replace_Slice'Result) = Source.Max_Length |
| and then |
| String'(Super_Slice (Super_Replace_Slice'Result, 1, Low - 1)) = |
| Super_Slice (Source, 1, Low - 1) |
| |
| -- Depending on when we reach Max_Length, either the last part |
| -- of Source is fully dropped and By is partly dropped, or By |
| -- is fully added and the last part of Source is partly dropped. |
| |
| and then |
| (if Low - 1 >= Source.Max_Length - By'Length then |
| |
| -- The last characters of By are dropped |
| |
| Super_Slice (Super_Replace_Slice'Result, |
| Low, Source.Max_Length) = |
| By (By'First .. Source.Max_Length - Low + By'First) |
| |
| else -- By is fully added |
| |
| Super_Slice (Super_Replace_Slice'Result, |
| Low, Low + By'Length - 1) = By |
| |
| -- Then Source starting from Natural'Max (High + 1, Low) |
| -- is added but the last characters are dropped. |
| |
| and then |
| String'(Super_Slice (Super_Replace_Slice'Result, |
| Low + By'Length, Source.Max_Length)) = |
| Super_Slice (Source, Integer'Max (High + 1, Low), |
| Integer'Max (High + 1, Low) + |
| (Source.Max_Length - Low - By'Length)))), |
| Global => null; |
| |
| procedure Super_Replace_Slice |
| (Source : in out Super_String; |
| Low : Positive; |
| High : Natural; |
| By : String; |
| Drop : Truncation := Error) |
| with |
| Pre => |
| Low - 1 <= Super_Length (Source) |
| and then |
| (if Drop = Error |
| then (if High >= Low |
| then Low - 1 |
| <= Source.Max_Length - By'Length |
| - Natural'Max (Super_Length (Source) - High, 0) |
| else Super_Length (Source) <= |
| Source.Max_Length - By'Length)), |
| Contract_Cases => |
| (Low - 1 <= Source.Max_Length - By'Length - Integer'Max |
| (Super_Length (Source) - Integer'Max (High, Low - 1), 0) |
| => |
| -- Total length is lower than Max_Length: nothing is dropped |
| |
| -- Note that if High < Low, the insertion is done before Low, so in |
| -- all cases the starting position of the slice of Source remaining |
| -- after the replaced Slice is Integer'Max (High + 1, Low). |
| |
| Super_Length (Source) = Low - 1 + By'Length + Integer'Max |
| (Super_Length (Source'Old) - Integer'Max (High, Low - 1), 0) |
| and then |
| String'(Super_Slice (Source, 1, Low - 1)) = |
| Super_Slice (Source'Old, 1, Low - 1) |
| and then Super_Slice (Source, Low, Low - 1 + By'Length) = By |
| and then |
| (if Integer'Max (High, Low - 1) < Super_Length (Source'Old) then |
| String'(Super_Slice (Source, |
| Low + By'Length, Super_Length (Source))) = |
| Super_Slice (Source'Old, |
| Integer'Max (High + 1, Low), |
| Super_Length (Source'Old))), |
| |
| Low - 1 > Source.Max_Length - By'Length - Integer'Max |
| (Super_Length (Source) - Integer'Max (High, Low - 1), 0) |
| and then Drop = Left |
| => |
| -- Final_Super_Slice is the length of the slice of Source remaining |
| -- after the replaced part. |
| (declare |
| Final_Super_Slice : constant Natural := |
| Integer'Max (0, |
| Super_Length (Source'Old) - Integer'Max (High, Low - 1)); |
| begin |
| -- The result is of maximal length and ends by the last |
| -- Final_Super_Slice characters of Source. |
| |
| Super_Length (Source) = Source.Max_Length |
| and then |
| (if Final_Super_Slice > 0 then |
| String'(Super_Slice (Source, |
| Source.Max_Length - Final_Super_Slice + 1, |
| Source.Max_Length)) = |
| Super_Slice (Source'Old, |
| Integer'Max (High + 1, Low), |
| Super_Length (Source'Old))) |
| |
| -- Depending on when we reach Max_Length, either the first |
| -- part of Source is fully dropped and By is partly dropped, |
| -- or By is fully added and the first part of Source is partly |
| -- dropped. |
| |
| and then |
| (if Source.Max_Length - Final_Super_Slice - By'Length <= 0 |
| then |
| -- The first characters of By are dropped |
| |
| (if Final_Super_Slice < Source.Max_Length then |
| Super_Slice (Source, |
| 1, Source.Max_Length - Final_Super_Slice) = |
| By (By'Last - Source.Max_Length + Final_Super_Slice |
| + 1 |
| .. By'Last)) |
| |
| else -- By is added to the result |
| |
| Super_Slice (Source, |
| Source.Max_Length - Final_Super_Slice - By'Length + 1, |
| Source.Max_Length - Final_Super_Slice) = By |
| |
| -- The first characters of Source (1 .. Low - 1) are |
| -- dropped. |
| |
| and then |
| String'(Super_Slice (Source, 1, |
| Source.Max_Length - Final_Super_Slice - By'Length)) = |
| Super_Slice (Source'Old, |
| Low - Source.Max_Length + Final_Super_Slice |
| + By'Length, |
| Low - 1))), |
| |
| others -- Drop = Right |
| => |
| -- The result is of maximal length and starts by the first Low - 1 |
| -- characters of Source. |
| |
| Super_Length (Source) = Source.Max_Length |
| and then |
| String'(Super_Slice (Source, 1, Low - 1)) = |
| Super_Slice (Source'Old, 1, Low - 1) |
| |
| -- Depending on when we reach Max_Length, either the last part |
| -- of Source is fully dropped and By is partly dropped, or By |
| -- is fully added and the last part of Source is partly dropped. |
| |
| and then |
| (if Low - 1 >= Source.Max_Length - By'Length then |
| |
| -- The last characters of By are dropped |
| |
| Super_Slice (Source, Low, Source.Max_Length) = |
| By (By'First .. Source.Max_Length - Low + By'First) |
| |
| else -- By is fully added |
| |
| Super_Slice (Source, Low, Low + By'Length - 1) = By |
| |
| -- Then Source starting from Natural'Max (High + 1, Low) |
| -- is added but the last characters are dropped. |
| |
| and then |
| String'(Super_Slice (Source, |
| Low + By'Length, Source.Max_Length)) = |
| Super_Slice (Source'Old, Integer'Max (High + 1, Low), |
| Integer'Max (High + 1, Low) + |
| (Source.Max_Length - Low - By'Length)))), |
| Global => null; |
| |
| function Super_Insert |
| (Source : Super_String; |
| Before : Positive; |
| New_Item : String; |
| Drop : Truncation := Error) return Super_String |
| with |
| Pre => |
| Before - 1 <= Super_Length (Source) |
| and then |
| (if New_Item'Length > Source.Max_Length - Super_Length (Source) |
| then Drop /= Error), |
| Post => Super_Insert'Result.Max_Length = Source.Max_Length, |
| Contract_Cases => |
| (Super_Length (Source) <= Source.Max_Length - New_Item'Length |
| => |
| -- Total length is lower than Max_Length: nothing is dropped |
| |
| Super_Length (Super_Insert'Result) = |
| Super_Length (Source) + New_Item'Length |
| and then |
| String'(Super_Slice (Super_Insert'Result, 1, Before - 1)) = |
| Super_Slice (Source, 1, Before - 1) |
| and then |
| Super_Slice (Super_Insert'Result, |
| Before, Before - 1 + New_Item'Length) = |
| New_Item |
| and then |
| (if Before <= Super_Length (Source) then |
| String'(Super_Slice (Super_Insert'Result, |
| Before + New_Item'Length, |
| Super_Length (Super_Insert'Result))) = |
| Super_Slice (Source, Before, Super_Length (Source))), |
| |
| Super_Length (Source) > Source.Max_Length - New_Item'Length |
| and then Drop = Left |
| => |
| -- The result is of maximal length and ends by the last characters |
| -- of Source. |
| |
| Super_Length (Super_Insert'Result) = Source.Max_Length |
| and then |
| (if Before <= Super_Length (Source) then |
| String'(Super_Slice (Super_Insert'Result, |
| Source.Max_Length - Super_Length (Source) + Before, |
| Source.Max_Length)) = |
| Super_Slice (Source, Before, Super_Length (Source))) |
| |
| -- Depending on when we reach Max_Length, either the first part |
| -- of Source is fully dropped and New_Item is partly dropped, or |
| -- New_Item is fully added and the first part of Source is partly |
| -- dropped. |
| |
| and then |
| (if Source.Max_Length - Super_Length (Source) - 1 + Before |
| < New_Item'Length |
| then |
| -- The first characters of New_Item are dropped |
| |
| (if Super_Length (Source) - Before + 1 < Source.Max_Length |
| then |
| Super_Slice (Super_Insert'Result, 1, |
| Source.Max_Length - Super_Length (Source) - 1 + Before) = |
| New_Item |
| (New_Item'Last - Source.Max_Length |
| + Super_Length (Source) - Before + 2 |
| .. New_Item'Last)) |
| |
| else -- New_Item is added to the result |
| |
| Super_Slice (Super_Insert'Result, |
| Source.Max_Length - Super_Length (Source) - New_Item'Length |
| + Before, |
| Source.Max_Length - Super_Length (Source) - 1 + Before) = |
| New_Item |
| |
| -- The first characters of Source (1 .. Before - 1) are |
| -- dropped. |
| |
| and then |
| String'(Super_Slice (Super_Insert'Result, |
| 1, Source.Max_Length - Super_Length (Source) |
| - New_Item'Length - 1 + Before)) = |
| Super_Slice (Source, |
| Super_Length (Source) - Source.Max_Length |
| + New_Item'Length + 1, |
| Before - 1)), |
| |
| others -- Drop = Right |
| => |
| -- The result is of maximal length and starts by the first |
| -- characters of Source. |
| |
| Super_Length (Super_Insert'Result) = Source.Max_Length |
| and then |
| String'(Super_Slice (Super_Insert'Result, 1, Before - 1)) = |
| Super_Slice (Source, 1, Before - 1) |
| |
| -- Depending on when we reach Max_Length, either the last part |
| -- of Source is fully dropped and New_Item is partly dropped, or |
| -- New_Item is fully added and the last part of Source is partly |
| -- dropped. |
| |
| and then |
| (if Before - 1 >= Source.Max_Length - New_Item'Length then |
| |
| -- The last characters of New_Item are dropped |
| |
| Super_Slice (Super_Insert'Result, Before, Source.Max_Length) = |
| New_Item (New_Item'First |
| .. Source.Max_Length - Before + New_Item'First) |
| |
| else -- New_Item is fully added |
| |
| Super_Slice (Super_Insert'Result, |
| Before, Before + New_Item'Length - 1) = |
| New_Item |
| |
| -- Then Source starting from Before is added but the |
| -- last characters are dropped. |
| |
| and then |
| String'(Super_Slice (Super_Insert'Result, |
| Before + New_Item'Length, Source.Max_Length)) = |
| Super_Slice (Source, |
| Before, Source.Max_Length - New_Item'Length))), |
| Global => null; |
| |
| procedure Super_Insert |
| (Source : in out Super_String; |
| Before : Positive; |
| New_Item : String; |
| Drop : Truncation := Error) |
| with |
| Pre => |
| Before - 1 <= Super_Length (Source) |
| and then |
| (if New_Item'Length > Source.Max_Length - Super_Length (Source) |
| then Drop /= Error), |
| Contract_Cases => |
| (Super_Length (Source) <= Source.Max_Length - New_Item'Length |
| => |
| -- Total length is lower than Max_Length: nothing is dropped |
| |
| Super_Length (Source) = Super_Length (Source'Old) + New_Item'Length |
| and then |
| String'(Super_Slice (Source, 1, Before - 1)) = |
| Super_Slice (Source'Old, 1, Before - 1) |
| and then |
| Super_Slice (Source, Before, Before - 1 + New_Item'Length) = |
| New_Item |
| and then |
| (if Before <= Super_Length (Source'Old) then |
| String'(Super_Slice (Source, |
| Before + New_Item'Length, Super_Length (Source))) = |
| Super_Slice (Source'Old, |
| Before, Super_Length (Source'Old))), |
| |
| Super_Length (Source) > Source.Max_Length - New_Item'Length |
| and then Drop = Left |
| => |
| -- The result is of maximal length and ends by the last characters |
| -- of Source. |
| |
| Super_Length (Source) = Source.Max_Length |
| and then |
| (if Before <= Super_Length (Source'Old) then |
| String'(Super_Slice (Source, |
| Source.Max_Length - Super_Length (Source'Old) + Before, |
| Source.Max_Length)) = |
| Super_Slice (Source'Old, |
| Before, Super_Length (Source'Old))) |
| |
| -- Depending on when we reach Max_Length, either the first part |
| -- of Source is fully dropped and New_Item is partly dropped, or |
| -- New_Item is fully added and the first part of Source is partly |
| -- dropped. |
| |
| and then |
| (if Source.Max_Length - Super_Length (Source'Old) - 1 + Before |
| < New_Item'Length |
| then |
| -- The first characters of New_Item are dropped |
| |
| (if Super_Length (Source'Old) - Before + 1 < Source.Max_Length |
| then |
| Super_Slice (Source, |
| 1, Source.Max_Length - Super_Length (Source'Old) |
| - 1 + Before) = |
| New_Item |
| (New_Item'Last - Source.Max_Length |
| + Super_Length (Source'Old) - Before + 2 |
| .. New_Item'Last)) |
| |
| else -- New_Item is added to the result |
| |
| Super_Slice (Source, |
| Source.Max_Length - Super_Length (Source'Old) |
| - New_Item'Length + Before, |
| Source.Max_Length - Super_Length (Source'Old) - 1 + Before) |
| = New_Item |
| |
| -- The first characters of Source (1 .. Before - 1) are |
| -- dropped. |
| |
| and then |
| String'(Super_Slice (Source, 1, |
| Source.Max_Length - Super_Length (Source'Old) |
| - New_Item'Length - 1 + Before)) = |
| Super_Slice (Source'Old, |
| Super_Length (Source'Old) |
| - Source.Max_Length + New_Item'Length + 1, |
| Before - 1)), |
| |
| others -- Drop = Right |
| => |
| -- The result is of maximal length and starts by the first |
| -- characters of Source. |
| |
| Super_Length (Source) = Source.Max_Length |
| and then |
| String'(Super_Slice (Source, 1, Before - 1)) = |
| Super_Slice (Source'Old, 1, Before - 1) |
| |
| -- Depending on when we reach Max_Length, either the last part |
| -- of Source is fully dropped and New_Item is partly dropped, or |
| -- New_Item is fully added and the last part of Source is partly |
| -- dropped. |
| |
| and then |
| (if Before - 1 >= Source.Max_Length - New_Item'Length then |
| |
| -- The last characters of New_Item are dropped |
| |
| Super_Slice (Source, Before, Source.Max_Length) = |
| New_Item (New_Item'First |
| .. Source.Max_Length - Before + New_Item'First) |
| |
| else -- New_Item is fully added |
| |
| Super_Slice (Source, Before, Before + New_Item'Length - 1) = |
| New_Item |
| |
| -- Then Source starting from Before is added but the |
| -- last characters are dropped. |
| |
| and then |
| String'(Super_Slice (Source, |
| Before + New_Item'Length, Source.Max_Length)) = |
| Super_Slice (Source'Old, |
| Before, Source.Max_Length - New_Item'Length))), |
| Global => null; |
| |
| function Super_Overwrite |
| (Source : Super_String; |
| Position : Positive; |
| New_Item : String; |
| Drop : Truncation := Error) return Super_String |
| with |
| Pre => |
| Position - 1 <= Super_Length (Source) |
| and then (if New_Item'Length > Source.Max_Length - (Position - 1) |
| then Drop /= Error), |
| Post => Super_Overwrite'Result.Max_Length = Source.Max_Length, |
| Contract_Cases => |
| (Position - 1 <= Source.Max_Length - New_Item'Length |
| => |
| -- The length is unchanged, unless New_Item overwrites further than |
| -- the end of Source. In this contract case, we suppose New_Item |
| -- doesn't overwrite further than Max_Length. |
| |
| Super_Length (Super_Overwrite'Result) = |
| Integer'Max (Super_Length (Source), Position - 1 + New_Item'Length) |
| and then |
| String'(Super_Slice (Super_Overwrite'Result, 1, Position - 1)) = |
| Super_Slice (Source, 1, Position - 1) |
| and then Super_Slice (Super_Overwrite'Result, |
| Position, Position - 1 + New_Item'Length) = |
| New_Item |
| and then |
| (if Position - 1 + New_Item'Length < Super_Length (Source) then |
| |
| -- There are some unchanged characters of Source remaining |
| -- after New_Item. |
| |
| String'(Super_Slice (Super_Overwrite'Result, |
| Position + New_Item'Length, Super_Length (Source))) = |
| Super_Slice (Source, |
| Position + New_Item'Length, Super_Length (Source))), |
| |
| Position - 1 > Source.Max_Length - New_Item'Length and then Drop = Left |
| => |
| Super_Length (Super_Overwrite'Result) = Source.Max_Length |
| |
| -- If a part of the result has to be dropped, it means New_Item is |
| -- overwriting further than the end of Source. Thus the result is |
| -- necessarily ending by New_Item. However, we don't know whether |
| -- New_Item covers all Max_Length characters or some characters of |
| -- Source are remaining at the left. |
| |
| and then |
| (if New_Item'Length > Source.Max_Length then |
| |
| -- New_Item covers all Max_Length characters |
| |
| Super_To_String (Super_Overwrite'Result) = |
| New_Item |
| (New_Item'Last - Source.Max_Length + 1 .. New_Item'Last) |
| else |
| -- New_Item fully appears at the end |
| |
| Super_Slice (Super_Overwrite'Result, |
| Source.Max_Length - New_Item'Length + 1, |
| Source.Max_Length) = |
| New_Item |
| |
| -- The left of Source is cut |
| |
| and then |
| String'(Super_Slice (Super_Overwrite'Result, |
| 1, Source.Max_Length - New_Item'Length)) = |
| Super_Slice (Source, |
| Position - Source.Max_Length + New_Item'Length, |
| Position - 1)), |
| |
| others -- Drop = Right |
| => |
| -- The result is of maximal length and starts by the first |
| -- characters of Source. |
| |
| Super_Length (Super_Overwrite'Result) = Source.Max_Length |
| and then |
| String'(Super_Slice (Super_Overwrite'Result, 1, Position - 1)) = |
| Super_Slice (Source, 1, Position - 1) |
| |
| -- Then New_Item is written until Max_Length |
| |
| and then Super_Slice (Super_Overwrite'Result, |
| Position, Source.Max_Length) = |
| New_Item (New_Item'First |
| .. Source.Max_Length - Position + New_Item'First)), |
| Global => null; |
| |
| procedure Super_Overwrite |
| (Source : in out Super_String; |
| Position : Positive; |
| New_Item : String; |
| Drop : Truncation := Error) |
| with |
| Pre => |
| Position - 1 <= Super_Length (Source) |
| and then (if New_Item'Length > Source.Max_Length - (Position - 1) |
| then Drop /= Error), |
| Contract_Cases => |
| (Position - 1 <= Source.Max_Length - New_Item'Length |
| => |
| -- The length is unchanged, unless New_Item overwrites further than |
| -- the end of Source. In this contract case, we suppose New_Item |
| -- doesn't overwrite further than Max_Length. |
| |
| Super_Length (Source) = Integer'Max |
| (Super_Length (Source'Old), Position - 1 + New_Item'Length) |
| and then |
| String'(Super_Slice (Source, 1, Position - 1)) = |
| Super_Slice (Source'Old, 1, Position - 1) |
| and then Super_Slice (Source, |
| Position, Position - 1 + New_Item'Length) = |
| New_Item |
| and then |
| (if Position - 1 + New_Item'Length < Super_Length (Source'Old) |
| then |
| -- There are some unchanged characters of Source remaining |
| -- after New_Item. |
| |
| String'(Super_Slice (Source, |
| Position + New_Item'Length, Super_Length (Source'Old))) = |
| Super_Slice (Source'Old, |
| Position + New_Item'Length, Super_Length (Source'Old))), |
| |
| Position - 1 > Source.Max_Length - New_Item'Length and then Drop = Left |
| => |
| Super_Length (Source) = Source.Max_Length |
| |
| -- If a part of the result has to be dropped, it means New_Item is |
| -- overwriting further than the end of Source. Thus the result is |
| -- necessarily ending by New_Item. However, we don't know whether |
| -- New_Item covers all Max_Length characters or some characters of |
| -- Source are remaining at the left. |
| |
| and then |
| (if New_Item'Length > Source.Max_Length then |
| |
| -- New_Item covers all Max_Length characters |
| |
| Super_To_String (Source) = |
| New_Item |
| (New_Item'Last - Source.Max_Length + 1 .. New_Item'Last) |
| else |
| -- New_Item fully appears at the end |
| |
| Super_Slice (Source, |
| Source.Max_Length - New_Item'Length + 1, |
| Source.Max_Length) = |
| New_Item |
| |
| -- The left of Source is cut |
| |
| and then |
| String'(Super_Slice (Source, |
| 1, Source.Max_Length - New_Item'Length)) = |
| Super_Slice (Source'Old, |
| Position - Source.Max_Length + New_Item'Length, |
| Position - 1)), |
| |
| others -- Drop = Right |
| => |
| -- The result is of maximal length and starts by the first |
| -- characters of Source. |
| |
| Super_Length (Source) = Source.Max_Length |
| and then |
| String'(Super_Slice (Source, 1, Position - 1)) = |
| Super_Slice (Source'Old, 1, Position - 1) |
| |
| -- New_Item is written until Max_Length |
| |
| and then Super_Slice (Source, Position, Source.Max_Length) = |
| New_Item (New_Item'First |
| .. Source.Max_Length - Position + New_Item'First)), |
| Global => null; |
| |
| function Super_Delete |
| (Source : Super_String; |
| From : Positive; |
| Through : Natural) return Super_String |
| with |
| Pre => |
| (if Through >= From then From - 1 <= Super_Length (Source)), |
| Post => Super_Delete'Result.Max_Length = Source.Max_Length, |
| Contract_Cases => |
| (Through >= From => |
| Super_Length (Super_Delete'Result) = |
| From - 1 + Natural'Max (Super_Length (Source) - Through, 0) |
| and then |
| String'(Super_Slice (Super_Delete'Result, 1, From - 1)) = |
| Super_Slice (Source, 1, From - 1) |
| and then |
| (if Through < Super_Length (Source) then |
| String'(Super_Slice (Super_Delete'Result, |
| From, Super_Length (Super_Delete'Result))) = |
| Super_Slice (Source, Through + 1, Super_Length (Source))), |
| others => |
| Super_Delete'Result = Source), |
| Global => null; |
| |
| procedure Super_Delete |
| (Source : in out Super_String; |
| From : Positive; |
| Through : Natural) |
| with |
| Pre => |
| (if Through >= From then From - 1 <= Super_Length (Source)), |
| Contract_Cases => |
| (Through >= From => |
| Super_Length (Source) = |
| From - 1 + Natural'Max (Super_Length (Source'Old) - Through, 0) |
| and then |
| String'(Super_Slice (Source, 1, From - 1)) = |
| Super_Slice (Source'Old, 1, From - 1) |
| and then |
| (if Through < Super_Length (Source) then |
| String'(Super_Slice (Source, From, Super_Length (Source))) = |
| Super_Slice (Source'Old, |
| Through + 1, Super_Length (Source'Old))), |
| others => |
| Source = Source'Old), |
| Global => null; |
| |
| --------------------------------- |
| -- String Selector Subprograms -- |
| --------------------------------- |
| |
| function Super_Trim |
| (Source : Super_String; |
| Side : Trim_End) return Super_String |
| with |
| Post => Super_Trim'Result.Max_Length = Source.Max_Length, |
| Contract_Cases => |
| |
| -- If all characters in Source are Space, the returned string is empty |
| |
| ((for all C of Super_To_String (Source) => C = ' ') |
| => |
| Super_Length (Super_Trim'Result) = 0, |
| |
| -- Otherwise, the returned string is a slice of Source |
| |
| others |
| => |
| (declare |
| Low : constant Positive := |
| (if Side = Right then 1 |
| else Super_Index_Non_Blank (Source, Forward)); |
| High : constant Positive := |
| (if Side = Left then Super_Length (Source) |
| else Super_Index_Non_Blank (Source, Backward)); |
| begin |
| Super_To_String (Super_Trim'Result) = |
| Super_Slice (Source, Low, High))), |
| Global => null; |
| |
| procedure Super_Trim |
| (Source : in out Super_String; |
| Side : Trim_End) |
| with |
| Contract_Cases => |
| |
| -- If all characters in Source are Space, the returned string is empty |
| |
| ((for all C of Super_To_String (Source) => C = ' ') |
| => |
| Super_Length (Source) = 0, |
| |
| -- Otherwise, the returned string is a slice of Source |
| |
| others |
| => |
| (declare |
| Low : constant Positive := |
| (if Side = Right then 1 |
| else Super_Index_Non_Blank (Source'Old, Forward)); |
| High : constant Positive := |
| (if Side = Left then Super_Length (Source'Old) |
| else Super_Index_Non_Blank (Source'Old, Backward)); |
| begin |
| Super_To_String (Source) = Super_Slice (Source'Old, Low, High))), |
| Global => null; |
| |
| function Super_Trim |
| (Source : Super_String; |
| Left : Maps.Character_Set; |
| Right : Maps.Character_Set) return Super_String |
| with |
| Post => Super_Trim'Result.Max_Length = Source.Max_Length, |
| Contract_Cases => |
| |
| -- If all characters in Source are contained in one of the sets Left or |
| -- Right, then the returned string is empty. |
| |
| ((for all C of Super_To_String (Source) => Maps.Is_In (C, Left)) |
| or else |
| (for all C of Super_To_String (Source) => Maps.Is_In (C, Right)) |
| => |
| Super_Length (Super_Trim'Result) = 0, |
| |
| -- Otherwise, the returned string is a slice of Source |
| |
| others |
| => |
| (declare |
| Low : constant Positive := |
| Super_Index (Source, Left, Outside, Forward); |
| High : constant Positive := |
| Super_Index (Source, Right, Outside, Backward); |
| begin |
| Super_To_String (Super_Trim'Result) = |
| Super_Slice (Source, Low, High))), |
| Global => null; |
| |
| procedure Super_Trim |
| (Source : in out Super_String; |
| Left : Maps.Character_Set; |
| Right : Maps.Character_Set) |
| with |
| Contract_Cases => |
| |
| -- If all characters in Source are contained in one of the sets Left or |
| -- Right, then the returned string is empty. |
| |
| ((for all C of Super_To_String (Source) => Maps.Is_In (C, Left)) |
| or else |
| (for all C of Super_To_String (Source) => Maps.Is_In (C, Right)) |
| => |
| Super_Length (Source) = 0, |
| |
| -- Otherwise, the returned string is a slice of Source |
| |
| others |
| => |
| (declare |
| Low : constant Positive := |
| Super_Index (Source'Old, Left, Outside, Forward); |
| High : constant Positive := |
| Super_Index (Source'Old, Right, Outside, Backward); |
| begin |
| Super_To_String (Source) = Super_Slice (Source'Old, Low, High))), |
| Global => null; |
| |
| function Super_Head |
| (Source : Super_String; |
| Count : Natural; |
| Pad : Character := Space; |
| Drop : Truncation := Error) return Super_String |
| with |
| Pre => (if Count > Source.Max_Length then Drop /= Error), |
| Post => Super_Head'Result.Max_Length = Source.Max_Length, |
| Contract_Cases => |
| (Count <= Super_Length (Source) |
| => |
| -- Source is cut |
| |
| Super_To_String (Super_Head'Result) = Super_Slice (Source, 1, Count), |
| Count > Super_Length (Source) and then Count <= Source.Max_Length |
| => |
| -- Source is followed by Pad characters |
| |
| Super_Length (Super_Head'Result) = Count |
| and then |
| Super_Slice (Super_Head'Result, 1, Super_Length (Source)) = |
| Super_To_String (Source) |
| and then |
| String'(Super_Slice (Super_Head'Result, |
| Super_Length (Source) + 1, Count)) = |
| [1 .. Count - Super_Length (Source) => Pad], |
| Count > Source.Max_Length and then Drop = Right |
| => |
| -- Source is followed by Pad characters |
| |
| Super_Length (Super_Head'Result) = Source.Max_Length |
| and then |
| Super_Slice (Super_Head'Result, 1, Super_Length (Source)) = |
| Super_To_String (Source) |
| and then |
| String'(Super_Slice (Super_Head'Result, |
| Super_Length (Source) + 1, Source.Max_Length)) = |
| [1 .. Source.Max_Length - Super_Length (Source) => Pad], |
| Count - Super_Length (Source) > Source.Max_Length and then Drop = Left |
| => |
| -- Source is fully dropped on the left |
| |
| Super_To_String (Super_Head'Result) = |
| [1 .. Source.Max_Length => Pad], |
| others |
| => |
| -- Source is partly dropped on the left |
| |
| Super_Length (Super_Head'Result) = Source.Max_Length |
| and then |
| String'(Super_Slice (Super_Head'Result, |
| 1, Source.Max_Length - Count + Super_Length (Source))) = |
| Super_Slice (Source, |
| Count - Source.Max_Length + 1, Super_Length (Source)) |
| and then |
| String'(Super_Slice (Super_Head'Result, |
| Source.Max_Length - Count + Super_Length (Source) + 1, |
| Source.Max_Length)) = |
| [1 .. Count - Super_Length (Source) => Pad]), |
| Global => null; |
| |
| procedure Super_Head |
| (Source : in out Super_String; |
| Count : Natural; |
| Pad : Character := Space; |
| Drop : Truncation := Error) |
| with |
| Pre => (if Count > Source.Max_Length then Drop /= Error), |
| Contract_Cases => |
| (Count <= Super_Length (Source) |
| => |
| -- Source is cut |
| |
| Super_To_String (Source) = Super_Slice (Source'Old, 1, Count), |
| Count > Super_Length (Source) and then Count <= Source.Max_Length |
| => |
| -- Source is followed by Pad characters |
| |
| Super_Length (Source) = Count |
| and then |
| Super_Slice (Source, 1, Super_Length (Source'Old)) = |
| Super_To_String (Source'Old) |
| and then |
| String'(Super_Slice (Source, |
| Super_Length (Source'Old) + 1, Count)) = |
| [1 .. Count - Super_Length (Source'Old) => Pad], |
| Count > Source.Max_Length and then Drop = Right |
| => |
| -- Source is followed by Pad characters |
| |
| Super_Length (Source) = Source.Max_Length |
| and then |
| Super_Slice (Source, 1, Super_Length (Source'Old)) = |
| Super_To_String (Source'Old) |
| and then |
| String'(Super_Slice (Source, |
| Super_Length (Source'Old) + 1, Source.Max_Length)) = |
| [1 .. Source.Max_Length - Super_Length (Source'Old) => Pad], |
| Count - Super_Length (Source) > Source.Max_Length and then Drop = Left |
| => |
| -- Source is fully dropped on the left |
| |
| Super_To_String (Source) = [1 .. Source.Max_Length => Pad], |
| others |
| => |
| -- Source is partly dropped on the left |
| |
| Super_Length (Source) = Source.Max_Length |
| and then |
| String'(Super_Slice (Source, |
| 1, Source.Max_Length - Count + Super_Length (Source'Old))) = |
| Super_Slice (Source'Old, |
| Count - Source.Max_Length + 1, Super_Length (Source'Old)) |
| and then |
| String'(Super_Slice (Source, |
| Source.Max_Length - Count + Super_Length (Source'Old) + 1, |
| Source.Max_Length)) = |
| [1 .. Count - Super_Length (Source'Old) => Pad]), |
| Global => null; |
| |
| function Super_Tail |
| (Source : Super_String; |
| Count : Natural; |
| Pad : Character := Space; |
| Drop : Truncation := Error) return Super_String |
| with |
| Pre => (if Count > Source.Max_Length then Drop /= Error), |
| Post => Super_Tail'Result.Max_Length = Source.Max_Length, |
| Contract_Cases => |
| (Count < Super_Length (Source) |
| => |
| -- Source is cut |
| |
| (if Count > 0 then |
| Super_To_String (Super_Tail'Result) = |
| Super_Slice (Source, |
| Super_Length (Source) - Count + 1, Super_Length (Source)) |
| else Super_Length (Super_Tail'Result) = 0), |
| Count >= Super_Length (Source) and then Count < Source.Max_Length |
| => |
| -- Source is preceded by Pad characters |
| |
| Super_Length (Super_Tail'Result) = Count |
| and then |
| String'(Super_Slice (Super_Tail'Result, |
| 1, Count - Super_Length (Source))) = |
| [1 .. Count - Super_Length (Source) => Pad] |
| and then |
| Super_Slice (Super_Tail'Result, |
| Count - Super_Length (Source) + 1, Count) = |
| Super_To_String (Source), |
| Count >= Source.Max_Length and then Drop = Left |
| => |
| -- Source is preceded by Pad characters |
| |
| Super_Length (Super_Tail'Result) = Source.Max_Length |
| and then |
| String'(Super_Slice (Super_Tail'Result, |
| 1, Source.Max_Length - Super_Length (Source))) = |
| [1 .. Source.Max_Length - Super_Length (Source) => Pad] |
| and then |
| (if Super_Length (Source) > 0 then |
| Super_Slice (Super_Tail'Result, |
| Source.Max_Length - Super_Length (Source) + 1, |
| Source.Max_Length) = |
| Super_To_String (Source)), |
| Count - Super_Length (Source) >= Source.Max_Length |
| and then Drop /= Left |
| => |
| -- Source is fully dropped on the right |
| |
| Super_To_String (Super_Tail'Result) = |
| [1 .. Source.Max_Length => Pad], |
| others |
| => |
| -- Source is partly dropped on the right |
| |
| Super_Length (Super_Tail'Result) = Source.Max_Length |
| and then |
| String'(Super_Slice (Super_Tail'Result, |
| 1, Count - Super_Length (Source))) = |
| [1 .. Count - Super_Length (Source) => Pad] |
| and then |
| String'(Super_Slice (Super_Tail'Result, |
| Count - Super_Length (Source) + 1, Source.Max_Length)) = |
| Super_Slice (Source, |
| 1, Source.Max_Length - Count + Super_Length (Source))), |
| Global => null; |
| |
| procedure Super_Tail |
| (Source : in out Super_String; |
| Count : Natural; |
| Pad : Character := Space; |
| Drop : Truncation := Error) |
| with |
| Pre => (if Count > Source.Max_Length then Drop /= Error), |
| Contract_Cases => |
| (Count < Super_Length (Source) |
| => |
| -- Source is cut |
| |
| (if Count > 0 then |
| Super_To_String (Source) = |
| Super_Slice (Source'Old, |
| Super_Length (Source'Old) - Count + 1, |
| Super_Length (Source'Old)) |
| else Super_Length (Source) = 0), |
| Count >= Super_Length (Source) and then Count < Source.Max_Length |
| => |
| -- Source is preceded by Pad characters |
| |
| Super_Length (Source) = Count |
| and then |
| String'(Super_Slice (Source, |
| 1, Count - Super_Length (Source'Old))) = |
| [1 .. Count - Super_Length (Source'Old) => Pad] |
| and then |
| Super_Slice (Source, |
| Count - Super_Length (Source'Old) + 1, Count) = |
| Super_To_String (Source'Old), |
| Count >= Source.Max_Length and then Drop = Left |
| => |
| -- Source is preceded by Pad characters |
| |
| Super_Length (Source) = Source.Max_Length |
| and then |
| String'(Super_Slice (Source, |
| 1, Source.Max_Length - Super_Length (Source'Old))) = |
| [1 .. Source.Max_Length - Super_Length (Source'Old) => Pad] |
| and then |
| (if Super_Length (Source'Old) > 0 then |
| Super_Slice (Source, |
| Source.Max_Length - Super_Length (Source'Old) + 1, |
| Source.Max_Length) = |
| Super_To_String (Source'Old)), |
| Count - Super_Length (Source) >= Source.Max_Length |
| and then Drop /= Left |
| => |
| -- Source is fully dropped on the right |
| |
| Super_To_String (Source) = [1 .. Source.Max_Length => Pad], |
| others |
| => |
| -- Source is partly dropped on the right |
| |
| Super_Length (Source) = Source.Max_Length |
| and then |
| String'(Super_Slice (Source, |
| 1, Count - Super_Length (Source'Old))) = |
| [1 .. Count - Super_Length (Source'Old) => Pad] |
| and then |
| String'(Super_Slice (Source, |
| Count - Super_Length (Source'Old) + 1, Source.Max_Length)) = |
| Super_Slice (Source'Old, |
| 1, Source.Max_Length - Count + Super_Length (Source'Old))), |
| Global => null; |
| |
| ------------------------------------ |
| -- String Constructor Subprograms -- |
| ------------------------------------ |
| |
| -- Note: in some of the following routines, there is an extra parameter |
| -- Max_Length which specifies the value of the maximum length for the |
| -- resulting Super_String value. |
| |
| function Times |
| (Left : Natural; |
| Right : Character; |
| Max_Length : Positive) return Super_String |
| with |
| Pre => Left <= Max_Length, |
| Post => Times'Result.Max_Length = Max_Length |
| and then Super_To_String (Times'Result) = [1 .. Left => Right], |
| Global => null; |
| -- Note the additional parameter Max_Length |
| |
| function Times |
| (Left : Natural; |
| Right : String; |
| Max_Length : Positive) return Super_String |
| with |
| Pre => (if Left /= 0 then Right'Length <= Max_Length / Left), |
| Post => Times'Result.Max_Length = Max_Length |
| and then Super_Length (Times'Result) = Left * Right'Length |
| and then |
| (if Right'Length > 0 then |
| (for all K in 1 .. Left * Right'Length => |
| Super_Element (Times'Result, K) = |
| Right (Right'First + (K - 1) mod Right'Length))), |
| Global => null; |
| -- Note the additional parameter Max_Length |
| |
| function Times |
| (Left : Natural; |
| Right : Super_String) return Super_String |
| with |
| Pre => |
| (if Left /= 0 then Super_Length (Right) <= Right.Max_Length / Left), |
| Post => Times'Result.Max_Length = Right.Max_Length |
| and then Super_Length (Times'Result) = Left * Super_Length (Right) |
| and then |
| (if Super_Length (Right) > 0 then |
| (for all K in 1 .. Left * Super_Length (Right) => |
| Super_Element (Times'Result, K) = |
| Super_Element (Right, 1 + (K - 1) mod Super_Length (Right)))), |
| Global => null; |
| |
| function Super_Replicate |
| (Count : Natural; |
| Item : Character; |
| Drop : Truncation := Error; |
| Max_Length : Positive) return Super_String |
| with |
| Pre => (if Count > Max_Length then Drop /= Error), |
| Post => Super_Replicate'Result.Max_Length = Max_Length |
| and then Super_To_String (Super_Replicate'Result) = |
| [1 .. Natural'Min (Max_Length, Count) => Item], |
| Global => null; |
| -- Note the additional parameter Max_Length |
| |
| function Super_Replicate |
| (Count : Natural; |
| Item : String; |
| Drop : Truncation := Error; |
| Max_Length : Positive) return Super_String |
| with |
| Pre => |
| (if Count /= 0 and then Item'Length > Max_Length / Count |
| then Drop /= Error), |
| Post => Super_Replicate'Result.Max_Length = Max_Length, |
| Contract_Cases => |
| (Count = 0 or else Item'Length <= Max_Length / Count |
| => |
| Super_Length (Super_Replicate'Result) = Count * Item'Length |
| and then |
| (if Item'Length > 0 then |
| (for all K in 1 .. Count * Item'Length => |
| Super_Element (Super_Replicate'Result, K) = |
| Item (Item'First + (K - 1) mod Item'Length))), |
| Count /= 0 |
| and then Item'Length > Max_Length / Count |
| and then Drop = Right |
| => |
| Super_Length (Super_Replicate'Result) = Max_Length |
| and then |
| (for all K in 1 .. Max_Length => |
| Super_Element (Super_Replicate'Result, K) = |
| Item (Item'First + (K - 1) mod Item'Length)), |
| others -- Drop = Left |
| => |
| Super_Length (Super_Replicate'Result) = Max_Length |
| and then |
| (for all K in 1 .. Max_Length => |
| Super_Element (Super_Replicate'Result, K) = |
| Item (Item'Last - (Max_Length - K) mod Item'Length))), |
| Global => null; |
| -- Note the additional parameter Max_Length |
| |
| function Super_Replicate |
| (Count : Natural; |
| Item : Super_String; |
| Drop : Truncation := Error) return Super_String |
| with |
| Pre => |
| (if Count /= 0 |
| and then Super_Length (Item) > Item.Max_Length / Count |
| then Drop /= Error), |
| Post => Super_Replicate'Result.Max_Length = Item.Max_Length, |
| Contract_Cases => |
| ((if Count /= 0 then Super_Length (Item) <= Item.Max_Length / Count) |
| => |
| Super_Length (Super_Replicate'Result) = Count * Super_Length (Item) |
| and then |
| (if Super_Length (Item) > 0 then |
| (for all K in 1 .. Count * Super_Length (Item) => |
| Super_Element (Super_Replicate'Result, K) = |
| Super_Element (Item, |
| 1 + (K - 1) mod Super_Length (Item)))), |
| Count /= 0 |
| and then Super_Length (Item) > Item.Max_Length / Count |
| and then Drop = Right |
| => |
| Super_Length (Super_Replicate'Result) = Item.Max_Length |
| and then |
| (for all K in 1 .. Item.Max_Length => |
| Super_Element (Super_Replicate'Result, K) = |
| Super_Element (Item, 1 + (K - 1) mod Super_Length (Item))), |
| others -- Drop = Left |
| => |
| Super_Length (Super_Replicate'Result) = Item.Max_Length |
| and then |
| (for all K in 1 .. Item.Max_Length => |
| Super_Element (Super_Replicate'Result, K) = |
| Super_Element (Item, |
| Super_Length (Item) |
| - (Item.Max_Length - K) mod Super_Length (Item)))), |
| Global => null; |
| |
| private |
| -- Pragma Inline declarations |
| |
| pragma Inline ("="); |
| pragma Inline (Less); |
| pragma Inline (Less_Or_Equal); |
| pragma Inline (Greater); |
| pragma Inline (Greater_Or_Equal); |
| pragma Inline (Concat); |
| pragma Inline (Super_Count); |
| pragma Inline (Super_Element); |
| pragma Inline (Super_Find_Token); |
| pragma Inline (Super_Index); |
| pragma Inline (Super_Index_Non_Blank); |
| pragma Inline (Super_Length); |
| pragma Inline (Super_Replace_Element); |
| pragma Inline (Super_Slice); |
| pragma Inline (Super_To_String); |
| |
| end Ada.Strings.Superbounded; |