blob: ae4339f2957b27924a75edb3ec01e227e67c6116 [file] [log] [blame]
------------------------------------------------------------------------------
-- --
-- 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-2021, 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,