1 ------------------------------------------------------------------------------
3 -- GNAT RUN-TIME COMPONENTS --
5 -- A D A . S T R I N G S . S U P E R B O U N D E D --
9 -- Copyright (C) 2003-2024, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
30 ------------------------------------------------------------------------------
32 -- This non generic package contains most of the implementation of the
33 -- generic package Ada.Strings.Bounded.Generic_Bounded_Length.
35 -- It defines type Super_String as a discriminated record with the maximum
36 -- length as the discriminant. Individual instantiations of Strings.Bounded
37 -- use this type with an appropriate discriminant value set.
39 -- Preconditions in this unit are meant for analysis only, not for run-time
40 -- checking, so that the expected exceptions are raised. This is enforced by
41 -- setting the corresponding assertion policy to Ignore. Postconditions and
42 -- contract cases should not be executed at runtime as well, in order not to
43 -- slow down the execution of these functions.
45 pragma Assertion_Policy
(Pre
=> Ignore
,
47 Contract_Cases
=> Ignore
,
50 with Ada
.Strings
.Maps
; use type Ada
.Strings
.Maps
.Character_Mapping_Function
;
51 with Ada
.Strings
.Search
;
52 with Ada
.Strings
.Text_Buffers
;
54 package Ada
.Strings
.Superbounded
with
60 -- Type Bounded_String in Ada.Strings.Bounded.Generic_Bounded_Length is
61 -- derived from Super_String, with the constraint of the maximum length.
63 type Super_String_Data
is new String with Relaxed_Initialization
;
65 type Super_String
(Max_Length
: Positive) is record
66 Current_Length
: Natural := 0;
67 Data
: Super_String_Data
(1 .. Max_Length
);
68 -- A previous version had a default initial value for Data, which is
69 -- no longer necessary, because we now special-case this type in the
70 -- compiler, so "=" composes properly for descendants of this type.
71 -- Leaving it out is more efficient.
75 Current_Length
<= Max_Length
76 and then Data
(1 .. Current_Length
)'Initialized,
77 Put_Image
=> Put_Image
;
79 -- The subprograms defined for Super_String are similar to those
80 -- defined for Bounded_String, except that they have different names, so
81 -- that they can be renamed in Ada.Strings.Bounded.Generic_Bounded_Length.
83 function Super_Length
(Source
: Super_String
) return Natural
84 is (Source
.Current_Length
)
87 --------------------------------------------------------
88 -- Conversion, Concatenation, and Selection Functions --
89 --------------------------------------------------------
91 function To_Super_String
93 Max_Length
: Positive;
94 Drop
: Truncation
:= Error
) return Super_String
96 Pre
=> (if Source
'Length > Max_Length
then Drop
/= Error
),
97 Post
=> To_Super_String
'Result.Max_Length
= Max_Length
,
99 (Source
'Length <= Max_Length
101 Super_To_String
(To_Super_String
'Result) = Source
,
103 Source
'Length > Max_Length
and then Drop
= Left
105 Super_To_String
(To_Super_String
'Result) =
106 Source
(Source
'Last - Max_Length
+ 1 .. Source
'Last),
108 others -- Drop = Right
110 Super_To_String
(To_Super_String
'Result) =
111 Source
(Source
'First .. Source
'First - 1 + Max_Length
)),
113 -- Note the additional parameter Max_Length, which specifies the maximum
114 -- length setting of the resulting Super_String value.
116 -- The following procedures have declarations (and semantics) that are
117 -- exactly analogous to those declared in Ada.Strings.Bounded.
119 function Super_To_String
(Source
: Super_String
) return String
120 is (String (Source
.Data
(1 .. Source
.Current_Length
)));
122 procedure Set_Super_String
123 (Target
: out Super_String
;
125 Drop
: Truncation
:= Error
)
128 (if Source
'Length > Target
.Max_Length
then Drop
/= Error
),
130 (Source
'Length <= Target
.Max_Length
132 Super_To_String
(Target
) = Source
,
134 Source
'Length > Target
.Max_Length
and then Drop
= Left
136 Super_To_String
(Target
) =
137 Source
(Source
'Last - Target
.Max_Length
+ 1 .. Source
'Last),
139 others -- Drop = Right
141 Super_To_String
(Target
) =
142 Source
(Source
'First .. Source
'First - 1 + Target
.Max_Length
)),
145 function Super_Append
146 (Left
: Super_String
;
147 Right
: Super_String
;
148 Drop
: Truncation
:= Error
) return Super_String
151 Left
.Max_Length
= Right
.Max_Length
153 (if Super_Length
(Left
) > Left
.Max_Length
- Super_Length
(Right
)
155 Post
=> Super_Append
'Result.Max_Length
= Left
.Max_Length
,
157 (Super_Length
(Left
) <= Left
.Max_Length
- Super_Length
(Right
)
159 Super_Length
(Super_Append
'Result) =
160 Super_Length
(Left
) + Super_Length
(Right
)
162 Super_Slice
(Super_Append
'Result, 1, Super_Length
(Left
)) =
163 Super_To_String
(Left
)
165 (if Super_Length
(Right
) > 0 then
166 Super_Slice
(Super_Append
'Result,
167 Super_Length
(Left
) + 1,
168 Super_Length
(Super_Append
'Result)) =
169 Super_To_String
(Right
)),
171 Super_Length
(Left
) > Left
.Max_Length
- Super_Length
(Right
)
172 and then Drop
= Strings
.Left
174 Super_Length
(Super_Append
'Result) = Left
.Max_Length
176 (if Super_Length
(Right
) < Left
.Max_Length
then
177 String'(Super_Slice (Super_Append'Result,
178 1, Left.Max_Length - Super_Length (Right))) =
180 Super_Length (Left) - Left.Max_Length
181 + Super_Length (Right) + 1,
182 Super_Length (Left)))
184 Super_Slice (Super_Append'Result,
185 Left.Max_Length - Super_Length (Right) + 1, Left.Max_Length) =
186 Super_To_String (Right),
188 others -- Drop = Right
190 Super_Length (Super_Append'Result) = Left.Max_Length
192 Super_Slice (Super_Append'Result, 1, Super_Length (Left)) =
193 Super_To_String (Left)
195 (if Super_Length (Left) < Left.Max_Length then
196 String'(Super_Slice
(Super_Append
'Result,
197 Super_Length
(Left
) + 1, Left
.Max_Length
)) =
199 1, Left
.Max_Length
- Super_Length
(Left
)))),
202 function Super_Append
203 (Left
: Super_String
;
205 Drop
: Truncation
:= Error
) return Super_String
208 (if Right
'Length > Left
.Max_Length
- Super_Length
(Left
)
210 Post
=> Super_Append
'Result.Max_Length
= Left
.Max_Length
,
212 (Super_Length
(Left
) <= Left
.Max_Length
- Right
'Length
214 Super_Length
(Super_Append
'Result) =
215 Super_Length
(Left
) + Right
'Length
217 Super_Slice
(Super_Append
'Result, 1, Super_Length
(Left
)) =
218 Super_To_String
(Left
)
220 (if Right
'Length > 0 then
221 Super_Slice
(Super_Append
'Result,
222 Super_Length
(Left
) + 1,
223 Super_Length
(Super_Append
'Result)) =
226 Super_Length
(Left
) > Left
.Max_Length
- Right
'Length
227 and then Drop
= Strings
.Left
229 Super_Length
(Super_Append
'Result) = Left
.Max_Length
231 (if Right
'Length < Left
.Max_Length
then
233 -- The result is the end of Left followed by Right
235 String'(Super_Slice (Super_Append'Result,
236 1, Left.Max_Length - Right'Length)) =
238 Super_Length (Left) - Left.Max_Length + Right'Length
242 Super_Slice (Super_Append'Result,
243 Left.Max_Length - Right'Length + 1, Left.Max_Length) =
246 -- The result is the last Max_Length characters of Right
248 Super_To_String (Super_Append'Result) =
249 Right (Right'Last - Left.Max_Length + 1 .. Right'Last)),
251 others -- Drop = Right
253 Super_Length (Super_Append'Result) = Left.Max_Length
255 Super_Slice (Super_Append'Result, 1, Super_Length (Left)) =
256 Super_To_String (Left)
258 (if Super_Length (Left) < Left.Max_Length then
259 Super_Slice (Super_Append'Result,
260 Super_Length (Left) + 1, Left.Max_Length) =
262 .. Left.Max_Length - Super_Length (Left)
263 - 1 + Right'First))),
266 function Super_Append
268 Right : Super_String;
269 Drop : Truncation := Error) return Super_String
272 (if Left'Length > Right.Max_Length - Super_Length (Right)
274 Post => Super_Append'Result.Max_Length = Right.Max_Length,
276 (Left'Length <= Right.Max_Length - Super_Length (Right)
278 Super_Length (Super_Append'Result) =
279 Left'Length + Super_Length (Right)
280 and then Super_Slice (Super_Append'Result, 1, Left'Length) = Left
282 (if Super_Length (Right) > 0 then
283 Super_Slice (Super_Append'Result,
284 Left'Length + 1, Super_Length (Super_Append'Result)) =
285 Super_To_String (Right)),
287 Left'Length > Right.Max_Length - Super_Length (Right)
288 and then Drop = Strings.Left
290 Super_Length (Super_Append'Result) = Right.Max_Length
292 (if Super_Length (Right) < Right.Max_Length then
293 Super_Slice (Super_Append'Result,
294 1, Right.Max_Length - Super_Length (Right)) =
296 (Left'Last - Right.Max_Length + Super_Length (Right) + 1
299 Super_Slice (Super_Append'Result,
300 Right.Max_Length - Super_Length (Right) + 1,
302 Super_To_String (Right),
304 others -- Drop = Right
306 Super_Length (Super_Append'Result) = Right.Max_Length
308 (if Left'Length < Right.Max_Length then
310 -- The result is Left followed by the beginning of Right
312 Super_Slice (Super_Append'Result, 1, Left'Length) = Left
314 String'(Super_Slice
(Super_Append
'Result,
315 Left
'Length + 1, Right
.Max_Length
)) =
316 Super_Slice
(Right
, 1, Right
.Max_Length
- Left
'Length)
318 -- The result is the first Max_Length characters of Left
320 Super_To_String
(Super_Append
'Result) =
321 Left
(Left
'First .. Right
.Max_Length
- 1 + Left
'First))),
324 function Super_Append
325 (Left
: Super_String
;
327 Drop
: Truncation
:= Error
) return Super_String
330 (if Super_Length
(Left
) = Left
.Max_Length
then Drop
/= Error
),
331 Post
=> Super_Append
'Result.Max_Length
= Left
.Max_Length
,
333 (Super_Length
(Left
) < Left
.Max_Length
335 Super_Length
(Super_Append
'Result) = Super_Length
(Left
) + 1
337 Super_Slice
(Super_Append
'Result, 1, Super_Length
(Left
)) =
338 Super_To_String
(Left
)
340 Super_Element
(Super_Append
'Result, Super_Length
(Left
) + 1) =
343 Super_Length
(Left
) = Left
.Max_Length
and then Drop
= Strings
.Right
345 Super_Length
(Super_Append
'Result) = Left
.Max_Length
347 Super_To_String
(Super_Append
'Result) = Super_To_String
(Left
),
349 others -- Drop = Left
351 Super_Length
(Super_Append
'Result) = Left
.Max_Length
353 String'(Super_Slice (Super_Append'Result,
354 1, Left.Max_Length - 1)) =
355 Super_Slice (Left, 2, Left.Max_Length)
357 Super_Element (Super_Append'Result, Left.Max_Length) = Right),
360 function Super_Append
362 Right : Super_String;
363 Drop : Truncation := Error) return Super_String
366 (if Super_Length (Right) = Right.Max_Length then Drop /= Error),
367 Post => Super_Append'Result.Max_Length = Right.Max_Length,
369 (Super_Length (Right) < Right.Max_Length
371 Super_Length (Super_Append'Result) = Super_Length (Right) + 1
373 Super_Slice (Super_Append'Result, 2, Super_Length (Right) + 1) =
374 Super_To_String (Right)
375 and then Super_Element (Super_Append'Result, 1) = Left,
377 Super_Length (Right) = Right.Max_Length and then Drop = Strings.Left
379 Super_Length (Super_Append'Result) = Right.Max_Length
381 Super_To_String (Super_Append'Result) = Super_To_String (Right),
383 others -- Drop = Right
385 Super_Length (Super_Append'Result) = Right.Max_Length
387 String'(Super_Slice
(Super_Append
'Result, 2, Right
.Max_Length
)) =
388 Super_Slice
(Right
, 1, Right
.Max_Length
- 1)
389 and then Super_Element
(Super_Append
'Result, 1) = Left
),
392 procedure Super_Append
393 (Source
: in out Super_String
;
394 New_Item
: Super_String
;
395 Drop
: Truncation
:= Error
)
398 Source
.Max_Length
= New_Item
.Max_Length
400 (if Super_Length
(Source
) >
401 Source
.Max_Length
- Super_Length
(New_Item
)
404 (Super_Length
(Source
) <= Source
.Max_Length
- Super_Length
(New_Item
)
406 Super_Length
(Source
) =
407 Super_Length
(Source
'Old) + Super_Length
(New_Item
)
409 Super_Slice
(Source
, 1, Super_Length
(Source
'Old)) =
410 Super_To_String
(Source
'Old)
412 (if Super_Length
(New_Item
) > 0 then
414 Super_Length
(Source
'Old) + 1, Super_Length
(Source
)) =
415 Super_To_String
(New_Item
)),
417 Super_Length
(Source
) > Source
.Max_Length
- Super_Length
(New_Item
)
420 Super_Length
(Source
) = Source
.Max_Length
422 (if Super_Length
(New_Item
) < Source
.Max_Length
then
423 String'(Super_Slice (Source,
424 1, Source.Max_Length - Super_Length (New_Item))) =
425 Super_Slice (Source'Old,
426 Super_Length (Source'Old) - Source.Max_Length
427 + Super_Length (New_Item) + 1,
428 Super_Length (Source'Old)))
431 Source.Max_Length - Super_Length (New_Item) + 1,
433 Super_To_String (New_Item),
435 others -- Drop = Right
437 Super_Length (Source) = Source.Max_Length
439 Super_Slice (Source, 1, Super_Length (Source'Old)) =
440 Super_To_String (Source'Old)
442 (if Super_Length (Source'Old) < Source.Max_Length then
443 String'(Super_Slice
(Source
,
444 Super_Length
(Source
'Old) + 1, Source
.Max_Length
)) =
445 Super_Slice
(New_Item
,
446 1, Source
.Max_Length
- Super_Length
(Source
'Old)))),
449 procedure Super_Append
450 (Source
: in out Super_String
;
452 Drop
: Truncation
:= Error
)
455 (if New_Item
'Length > Source
.Max_Length
- Super_Length
(Source
)
458 (Super_Length
(Source
) <= Source
.Max_Length
- New_Item
'Length
460 Super_Length
(Source
) = Super_Length
(Source
'Old) + New_Item
'Length
462 Super_Slice
(Source
, 1, Super_Length
(Source
'Old)) =
463 Super_To_String
(Source
'Old)
465 (if New_Item
'Length > 0 then
467 Super_Length
(Source
'Old) + 1, Super_Length
(Source
)) =
470 Super_Length
(Source
) > Source
.Max_Length
- New_Item
'Length
473 Super_Length
(Source
) = Source
.Max_Length
475 (if New_Item
'Length < Source
.Max_Length
then
477 -- The result is the end of Source followed by New_Item
479 String'(Super_Slice (Source,
480 1, Source.Max_Length - New_Item'Length)) =
481 Super_Slice (Source'Old,
482 Super_Length (Source'Old) - Source.Max_Length
483 + New_Item'Length + 1,
484 Super_Length (Source'Old))
487 Source.Max_Length - New_Item'Length + 1,
491 -- The result is the last Max_Length characters of
494 Super_To_String (Source) = New_Item
495 (New_Item'Last - Source.Max_Length + 1 .. New_Item'Last)),
497 others -- Drop = Right
499 Super_Length (Source) = Source.Max_Length
501 Super_Slice (Source, 1, Super_Length (Source'Old)) =
502 Super_To_String (Source'Old)
504 (if Super_Length (Source'Old) < Source.Max_Length then
506 Super_Length (Source'Old) + 1, Source.Max_Length) =
507 New_Item (New_Item'First
508 .. Source.Max_Length - Super_Length (Source'Old) - 1
512 procedure Super_Append
513 (Source : in out Super_String;
514 New_Item : Character;
515 Drop : Truncation := Error)
518 (if Super_Length (Source) = Source.Max_Length then Drop /= Error),
520 (Super_Length (Source) < Source.Max_Length
522 Super_Length (Source) = Super_Length (Source'Old) + 1
524 Super_Slice (Source, 1, Super_Length (Source'Old)) =
525 Super_To_String (Source'Old)
527 Super_Element (Source, Super_Length (Source'Old) + 1) = New_Item,
529 Super_Length (Source) = Source.Max_Length and then Drop = Right
531 Super_Length (Source) = Source.Max_Length
532 and then Super_To_String (Source) = Super_To_String (Source'Old),
534 others -- Drop = Left
536 Super_Length (Source) = Source.Max_Length
538 String'(Super_Slice
(Source
, 1, Source
.Max_Length
- 1)) =
539 Super_Slice
(Source
'Old, 2, Source
.Max_Length
)
540 and then Super_Element
(Source
, Source
.Max_Length
) = New_Item
),
544 (Left
: Super_String
;
545 Right
: Super_String
) return Super_String
547 Pre
=> Left
.Max_Length
= Right
.Max_Length
548 and then Super_Length
(Left
) <= Left
.Max_Length
- Super_Length
(Right
),
549 Post
=> Concat
'Result.Max_Length
= Left
.Max_Length
551 Super_Length
(Concat
'Result) =
552 Super_Length
(Left
) + Super_Length
(Right
)
554 Super_Slice
(Concat
'Result, 1, Super_Length
(Left
)) =
555 Super_To_String
(Left
)
557 (if Super_Length
(Right
) > 0 then
558 Super_Slice
(Concat
'Result,
559 Super_Length
(Left
) + 1, Super_Length
(Concat
'Result)) =
560 Super_To_String
(Right
)),
564 (Left
: Super_String
;
565 Right
: String) return Super_String
567 Pre
=> Right
'Length <= Left
.Max_Length
- Super_Length
(Left
),
568 Post
=> Concat
'Result.Max_Length
= Left
.Max_Length
570 Super_Length
(Concat
'Result) = Super_Length
(Left
) + Right
'Length
572 Super_Slice
(Concat
'Result, 1, Super_Length
(Left
)) =
573 Super_To_String
(Left
)
575 (if Right
'Length > 0 then
576 Super_Slice
(Concat
'Result,
577 Super_Length
(Left
) + 1, Super_Length
(Concat
'Result)) =
583 Right
: Super_String
) return Super_String
585 Pre
=> Left
'Length <= Right
.Max_Length
- Super_Length
(Right
),
586 Post
=> Concat
'Result.Max_Length
= Right
.Max_Length
588 Super_Length
(Concat
'Result) = Left
'Length + Super_Length
(Right
)
589 and then Super_Slice
(Concat
'Result, 1, Left
'Length) = Left
591 (if Super_Length
(Right
) > 0 then
592 Super_Slice
(Concat
'Result,
593 Left
'Length + 1, Super_Length
(Concat
'Result)) =
594 Super_To_String
(Right
)),
598 (Left
: Super_String
;
599 Right
: Character) return Super_String
601 Pre
=> Super_Length
(Left
) < Left
.Max_Length
,
602 Post
=> Concat
'Result.Max_Length
= Left
.Max_Length
603 and then Super_Length
(Concat
'Result) = Super_Length
(Left
) + 1
605 Super_Slice
(Concat
'Result, 1, Super_Length
(Left
)) =
606 Super_To_String
(Left
)
607 and then Super_Element
(Concat
'Result, Super_Length
(Left
) + 1) = Right
,
612 Right
: Super_String
) return Super_String
614 Pre
=> Super_Length
(Right
) < Right
.Max_Length
,
615 Post
=> Concat
'Result.Max_Length
= Right
.Max_Length
616 and then Super_Length
(Concat
'Result) = 1 + Super_Length
(Right
)
617 and then Super_Element
(Concat
'Result, 1) = Left
619 Super_Slice
(Concat
'Result, 2, Super_Length
(Concat
'Result)) =
620 Super_To_String
(Right
),
623 function Super_Element
624 (Source
: Super_String
;
625 Index
: Positive) return Character
626 is (if Index
<= Source
.Current_Length
627 then Source
.Data
(Index
)
628 else raise Index_Error
)
629 with Pre
=> Index
<= Super_Length
(Source
),
632 procedure Super_Replace_Element
633 (Source
: in out Super_String
;
637 Pre
=> Index
<= Super_Length
(Source
),
638 Post
=> Super_Length
(Source
) = Super_Length
(Source
'Old)
640 (for all K
in 1 .. Super_Length
(Source
) =>
641 Super_Element
(Source
, K
) =
642 (if K
= Index
then By
else Super_Element
(Source
'Old, K
))),
646 (Source
: Super_String
;
648 High
: Natural) return String
649 is (if Low
- 1 > Source
.Current_Length
or else High
> Source
.Current_Length
651 -- Note: test of High > Length is in accordance with AI95-00128
653 then raise Index_Error
655 -- Note: in this case, superflat bounds are not a problem, we just
656 -- get the null string in accordance with normal Ada slice rules.
658 String (Source
.Data
(Low
.. High
)))
659 with Pre
=> Low
- 1 <= Super_Length
(Source
)
660 and then High
<= Super_Length
(Source
),
664 (Source
: Super_String
;
666 High
: Natural) return Super_String
669 Low
- 1 <= Super_Length
(Source
) and then High
<= Super_Length
(Source
),
670 Post
=> Super_Slice
'Result.Max_Length
= Source
.Max_Length
672 Super_To_String
(Super_Slice
'Result) =
673 Super_Slice
(Source
, Low
, High
),
676 procedure Super_Slice
677 (Source
: Super_String
;
678 Target
: out Super_String
;
682 Pre
=> Source
.Max_Length
= Target
.Max_Length
683 and then Low
- 1 <= Super_Length
(Source
)
684 and then High
<= Super_Length
(Source
),
685 Post
=> Super_To_String
(Target
) = Super_Slice
(Source
, Low
, High
),
689 (Left
: Super_String
;
690 Right
: Super_String
) return Boolean
692 Post
=> "="'Result = (Super_To_String (Left) = Super_To_String (Right)),
696 (Left : Super_String;
697 Right : Super_String) return Boolean renames "=";
700 (Left : Super_String;
701 Right : String) return Boolean
703 Post => Equal'Result = (Super_To_String (Left) = Right),
708 Right : Super_String) return Boolean
710 Post => Equal'Result = (Left = Super_To_String (Right)),
714 (Left : Super_String;
715 Right : Super_String) return Boolean
717 Pre => Left.Max_Length = Right.Max_Length,
719 Less'Result = (Super_To_String (Left) < Super_To_String (Right)),
723 (Left : Super_String;
724 Right : String) return Boolean
726 Post => Less'Result = (Super_To_String (Left) < Right),
731 Right : Super_String) return Boolean
733 Post => Less'Result = (Left < Super_To_String (Right)),
736 function Less_Or_Equal
737 (Left : Super_String;
738 Right : Super_String) return Boolean
740 Pre => Left.Max_Length = Right.Max_Length,
742 Less_Or_Equal'Result =
743 (Super_To_String (Left) <= Super_To_String (Right)),
746 function Less_Or_Equal
747 (Left : Super_String;
748 Right : String) return Boolean
750 Post => Less_Or_Equal'Result = (Super_To_String (Left) <= Right),
753 function Less_Or_Equal
755 Right : Super_String) return Boolean
757 Post => Less_Or_Equal'Result = (Left <= Super_To_String (Right)),
761 (Left : Super_String;
762 Right : Super_String) return Boolean
764 Pre => Left.Max_Length = Right.Max_Length,
766 Greater'Result = (Super_To_String (Left) > Super_To_String (Right)),
770 (Left : Super_String;
771 Right : String) return Boolean
773 Post => Greater'Result = (Super_To_String (Left) > Right),
778 Right : Super_String) return Boolean
780 Post => Greater'Result = (Left > Super_To_String (Right)),
783 function Greater_Or_Equal
784 (Left : Super_String;
785 Right : Super_String) return Boolean
787 Pre => Left.Max_Length = Right.Max_Length,
789 Greater_Or_Equal'Result =
790 (Super_To_String (Left) >= Super_To_String (Right)),
793 function Greater_Or_Equal
794 (Left : Super_String;
795 Right : String) return Boolean
797 Post => Greater_Or_Equal'Result = (Super_To_String (Left) >= Right),
800 function Greater_Or_Equal
802 Right : Super_String) return Boolean
804 Post => Greater_Or_Equal'Result = (Left >= Super_To_String (Right)),
807 ----------------------
808 -- Search Functions --
809 ----------------------
812 (Source : Super_String;
814 Going : Direction := Forward;
815 Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
817 Pre => Pattern'Length > 0,
818 Post => Super_Index'Result <= Super_Length (Source),
821 -- If Source is the empty string, then 0 is returned
823 (Super_Length (Source) = 0
825 Super_Index'Result = 0,
827 -- If some slice of Source matches Pattern, then a valid index is
830 Super_Length (Source) > 0
832 (for some J in 1 .. Super_Length (Source) - (Pattern'Length - 1) =>
833 Search.Match (Super_To_String (Source), Pattern, Mapping, J))
835 -- The result is in the considered range of Source
837 Super_Index'Result in
838 1 .. Super_Length (Source) - (Pattern'Length - 1)
840 -- The slice beginning at the returned index matches Pattern
842 and then Search.Match
843 (Super_To_String (Source), Pattern, Mapping, Super_Index'Result)
845 -- The result is the smallest or largest index which satisfies
846 -- the matching, respectively when Going = Forward and Going =
850 (for all J in 1 .. Super_Length (Source) =>
851 (if (if Going = Forward
852 then J <= Super_Index'Result - 1
853 else J - 1 in Super_Index'Result
854 .. Super_Length (Source) - Pattern'Length)
855 then not (Search.Match
856 (Super_To_String (Source), Pattern, Mapping, J)))),
858 -- Otherwise, 0 is returned
862 Super_Index'Result = 0),
866 (Source : Super_String;
868 Going : Direction := Forward;
869 Mapping : Maps.Character_Mapping_Function) return Natural
871 Pre => Pattern'Length /= 0 and then Mapping /= null,
872 Post => Super_Index'Result <= Super_Length (Source),
875 -- If Source is the empty string, then 0 is returned
877 (Super_Length (Source) = 0
879 Super_Index'Result = 0,
881 -- If some slice of Source matches Pattern, then a valid index is
884 Super_Length (Source) > 0
886 (for some J in 1 .. Super_Length (Source) - (Pattern'Length - 1) =>
887 Search.Match (Super_To_String (Source), Pattern, Mapping, J))
889 -- The result is in the considered range of Source
891 Super_Index'Result in
892 1 .. Super_Length (Source) - (Pattern'Length - 1)
894 -- The slice beginning at the returned index matches Pattern
896 and then Search.Match
897 (Super_To_String (Source), Pattern, Mapping, Super_Index'Result)
899 -- The result is the smallest or largest index which satisfies
900 -- the matching, respectively when Going = Forward and Going =
904 (for all J in 1 .. Super_Length (Source) =>
905 (if (if Going = Forward
906 then J <= Super_Index'Result - 1
907 else J - 1 in Super_Index'Result
908 .. Super_Length (Source) - Pattern'Length)
909 then not (Search.Match
910 (Super_To_String (Source), Pattern, Mapping, J)))),
912 -- Otherwise, 0 is returned
916 Super_Index'Result = 0),
920 (Source : Super_String;
921 Set : Maps.Character_Set;
922 Test : Membership := Inside;
923 Going : Direction := Forward) return Natural
925 Post => Super_Index'Result <= Super_Length (Source),
928 -- If no character of Source satisfies the property Test on Set,
929 -- then 0 is returned.
931 ((for all C of Super_To_String (Source) =>
932 (Test = Inside) /= Maps.Is_In (C, Set))
934 Super_Index'Result = 0,
936 -- Otherwise, an index in the range of Source is returned
940 -- The result is in the range of Source
942 Super_Index'Result in 1 .. Super_Length (Source)
944 -- The character at the returned index satisfies the property
949 Maps.Is_In (Super_Element (Source, Super_Index'Result), Set)
951 -- The result is the smallest or largest index which satisfies
952 -- the property, respectively when Going = Forward and Going =
956 (for all J in 1 .. Super_Length (Source) =>
957 (if J /= Super_Index'Result
958 and then (J < Super_Index'Result) = (Going = Forward)
960 /= Maps.Is_In (Super_Element (Source, J), Set)))),
964 (Source : Super_String;
967 Going : Direction := Forward;
968 Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
971 (if Super_Length (Source) /= 0 then From <= Super_Length (Source))
972 and then Pattern'Length /= 0,
973 Post => Super_Index'Result <= Super_Length (Source),
976 -- If Source is the empty string, then 0 is returned
978 (Super_Length (Source) = 0
980 Super_Index'Result = 0,
982 -- If some slice of Source matches Pattern, then a valid index is
985 Super_Length (Source) > 0
988 (if Going = Forward then From else 1)
989 .. (if Going = Forward then Super_Length (Source) else From)
990 - (Pattern'Length - 1) =>
991 Search.Match (Super_To_String (Source), Pattern, Mapping, J))
993 -- The result is in the considered range of Source
995 Super_Index'Result in
996 (if Going = Forward then From else 1)
997 .. (if Going = Forward then Super_Length (Source) else From)
998 - (Pattern'Length - 1)
1000 -- The slice beginning at the returned index matches Pattern
1002 and then Search.Match
1003 (Super_To_String (Source), Pattern, Mapping, Super_Index'Result)
1005 -- The result is the smallest or largest index which satisfies
1006 -- the matching, respectively when Going = Forward and Going =
1010 (for all J in 1 .. Super_Length (Source) =>
1011 (if (if Going = Forward
1012 then J in From .. Super_Index'Result - 1
1013 else J - 1 in Super_Index'Result
1014 .. From - Pattern'Length)
1015 then not (Search.Match
1016 (Super_To_String (Source), Pattern, Mapping, J)))),
1018 -- Otherwise, 0 is returned
1022 Super_Index'Result = 0),
1025 function Super_Index
1026 (Source : Super_String;
1029 Going : Direction := Forward;
1030 Mapping : Maps.Character_Mapping_Function) return Natural
1033 (if Super_Length (Source) /= 0 then From <= Super_Length (Source))
1034 and then Pattern'Length /= 0
1035 and then Mapping /= null,
1036 Post => Super_Index'Result <= Super_Length (Source),
1039 -- If Source is the empty string, then 0 is returned
1041 (Super_Length (Source) = 0
1043 Super_Index'Result = 0,
1045 -- If some slice of Source matches Pattern, then a valid index is
1048 Super_Length (Source) > 0
1051 (if Going = Forward then From else 1)
1052 .. (if Going = Forward then Super_Length (Source) else From)
1053 - (Pattern'Length - 1) =>
1054 Search.Match (Super_To_String (Source), Pattern, Mapping, J))
1056 -- The result is in the considered range of Source
1058 Super_Index'Result in
1059 (if Going = Forward then From else 1)
1060 .. (if Going = Forward then Super_Length (Source) else From)
1061 - (Pattern'Length - 1)
1063 -- The slice beginning at the returned index matches Pattern
1065 and then Search.Match
1066 (Super_To_String (Source), Pattern, Mapping, Super_Index'Result)
1068 -- The result is the smallest or largest index which satisfies
1069 -- the matching, respectively when Going = Forward and Going =
1073 (for all J in 1 .. Super_Length (Source) =>
1074 (if (if Going = Forward
1075 then J in From .. Super_Index'Result - 1
1076 else J - 1 in Super_Index'Result
1077 .. From - Pattern'Length)
1078 then not (Search.Match
1079 (Super_To_String (Source), Pattern, Mapping, J)))),
1081 -- Otherwise, 0 is returned
1085 Super_Index'Result = 0),
1088 function Super_Index
1089 (Source : Super_String;
1090 Set : Maps.Character_Set;
1092 Test : Membership := Inside;
1093 Going : Direction := Forward) return Natural
1096 (if Super_Length (Source) /= 0 then From <= Super_Length (Source)),
1097 Post => Super_Index'Result <= Super_Length (Source),
1100 -- If Source is the empty string, or no character of the considered
1101 -- slice of Source satisfies the property Test on Set, then 0 is
1104 (Super_Length (Source) = 0
1106 (for all J in 1 .. Super_Length (Source) =>
1107 (if J = From or else (J > From) = (Going = Forward) then
1109 Maps.Is_In (Super_Element (Source, J), Set)))
1111 Super_Index'Result = 0,
1113 -- Otherwise, an index in the considered range of Source is returned
1117 -- The result is in the considered range of Source
1119 Super_Index'Result in 1 .. Super_Length (Source)
1121 (Super_Index'Result = From
1122 or else (Super_Index'Result > From) = (Going = Forward))
1124 -- The character at the returned index satisfies the property
1129 Maps.Is_In (Super_Element (Source, Super_Index'Result), Set)
1131 -- The result is the smallest or largest index which satisfies
1132 -- the property, respectively when Going = Forward and Going =
1136 (for all J in 1 .. Super_Length (Source) =>
1137 (if J /= Super_Index'Result
1138 and then (J < Super_Index'Result) = (Going = Forward)
1140 or else (J > From) = (Going = Forward))
1141 then (Test = Inside)
1142 /= Maps.Is_In (Super_Element (Source, J), Set)))),
1145 function Super_Index_Non_Blank
1146 (Source : Super_String;
1147 Going : Direction := Forward) return Natural
1149 Post => Super_Index_Non_Blank'Result <= Super_Length (Source),
1152 -- If all characters of Source are Space characters, then 0 is
1155 ((for all C of Super_To_String (Source) => C = ' ')
1157 Super_Index_Non_Blank'Result = 0,
1159 -- Otherwise, an index in the range of Source is returned
1163 -- The result is in the range of Source
1165 Super_Index_Non_Blank'Result in 1 .. Super_Length (Source)
1167 -- The character at the returned index is not a Space character
1170 Super_Element (Source, Super_Index_Non_Blank'Result) /= ' '
1172 -- The result is the smallest or largest index which is not a
1173 -- Space character, respectively when Going = Forward and Going
1177 (for all J in 1 .. Super_Length (Source) =>
1178 (if J /= Super_Index_Non_Blank'Result
1180 (J < Super_Index_Non_Blank'Result) = (Going = Forward)
1181 then Super_Element (Source, J) = ' '))),
1184 function Super_Index_Non_Blank
1185 (Source : Super_String;
1187 Going : Direction := Forward) return Natural
1190 (if Super_Length (Source) /= 0 then From <= Super_Length (Source)),
1191 Post => Super_Index_Non_Blank'Result <= Super_Length (Source),
1194 -- If Source is the empty string, or all characters of the
1195 -- considered slice of Source are Space characters, then 0
1198 (Super_Length (Source) = 0
1200 (for all J in 1 .. Super_Length (Source) =>
1201 (if J = From or else (J > From) = (Going = Forward) then
1202 Super_Element (Source, J) = ' '))
1204 Super_Index_Non_Blank'Result = 0,
1206 -- Otherwise, an index in the considered range of Source is returned
1210 -- The result is in the considered range of Source
1212 Super_Index_Non_Blank'Result in 1 .. Super_Length (Source)
1214 (Super_Index_Non_Blank'Result = From
1216 (Super_Index_Non_Blank'Result > From) = (Going = Forward))
1218 -- The character at the returned index is not a Space character
1221 Super_Element (Source, Super_Index_Non_Blank'Result) /= ' '
1223 -- The result is the smallest or largest index which isn't a
1224 -- Space character, respectively when Going = Forward and Going
1228 (for all J in 1 .. Super_Length (Source) =>
1229 (if J /= Super_Index_Non_Blank'Result
1231 (J < Super_Index_Non_Blank'Result) = (Going = Forward)
1233 or else (J > From) = (Going = Forward))
1234 then Super_Element (Source, J) = ' '))),
1237 function Super_Count
1238 (Source : Super_String;
1240 Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
1242 Pre => Pattern'Length /= 0,
1245 function Super_Count
1246 (Source : Super_String;
1248 Mapping : Maps.Character_Mapping_Function) return Natural
1250 Pre => Pattern'Length /= 0 and then Mapping /= null,
1253 function Super_Count
1254 (Source : Super_String;
1255 Set : Maps.Character_Set) return Natural
1259 procedure Super_Find_Token
1260 (Source : Super_String;
1261 Set : Maps.Character_Set;
1264 First : out Positive;
1268 (if Super_Length (Source) /= 0 then From <= Super_Length (Source)),
1271 -- If Source is the empty string, or if no character of the
1272 -- considered slice of Source satisfies the property Test on
1273 -- Set, then First is set to From and Last is set to 0.
1275 (Super_Length (Source) = 0
1277 (for all J in From .. Super_Length (Source) =>
1278 (Test = Inside) /= Maps.Is_In (Super_Element (Source, J), Set))
1280 First = From and then Last = 0,
1282 -- Otherwise, First and Last are set to valid indexes
1286 -- First and Last are in the considered range of Source
1288 First in From .. Super_Length (Source)
1289 and then Last in First .. Super_Length (Source)
1291 -- No character between From and First satisfies the property
1295 (for all J in From .. First - 1 =>
1297 Maps.Is_In (Super_Element (Source, J), Set))
1299 -- All characters between First and Last satisfy the property
1303 (for all J in First .. Last =>
1305 Maps.Is_In (Super_Element (Source, J), Set))
1307 -- If Last is not Source'Last, then the character at position
1308 -- Last + 1 does not satify the property Test on Set.
1311 (if Last < Super_Length (Source)
1314 Maps.Is_In (Super_Element (Source, Last + 1), Set))),
1317 procedure Super_Find_Token
1318 (Source : Super_String;
1319 Set : Maps.Character_Set;
1321 First : out Positive;
1326 -- If Source is the empty string, or if no character of the considered
1327 -- slice of Source satisfies the property Test on Set, then First is
1328 -- set to 1 and Last is set to 0.
1330 (Super_Length (Source) = 0
1332 (for all J in 1 .. Super_Length (Source) =>
1333 (Test = Inside) /= Maps.Is_In (Super_Element (Source, J), Set))
1335 First = 1 and then Last = 0,
1337 -- Otherwise, First and Last are set to valid indexes
1341 -- First and Last are in the considered range of Source
1343 First in 1 .. Super_Length (Source)
1344 and then Last in First .. Super_Length (Source)
1346 -- No character between 1 and First satisfies the property Test on
1350 (for all J in 1 .. First - 1 =>
1352 Maps.Is_In (Super_Element (Source, J), Set))
1354 -- All characters between First and Last satisfy the property
1358 (for all J in First .. Last =>
1360 Maps.Is_In (Super_Element (Source, J), Set))
1362 -- If Last is not Source'Last, then the character at position
1363 -- Last + 1 does not satify the property Test on Set.
1366 (if Last < Super_Length (Source)
1369 Maps.Is_In (Super_Element (Source, Last + 1), Set))),
1372 ------------------------------------
1373 -- String Translation Subprograms --
1374 ------------------------------------
1376 function Super_Translate
1377 (Source : Super_String;
1378 Mapping : Maps.Character_Mapping) return Super_String
1380 Post => Super_Translate'Result.Max_Length = Source.Max_Length
1381 and then Super_Length (Super_Translate'Result) = Super_Length (Source)
1383 (for all K in 1 .. Super_Length (Source) =>
1384 Super_Element (Super_Translate'Result, K) =
1385 Ada.Strings.Maps.Value (Mapping, Super_Element (Source, K))),
1388 procedure Super_Translate
1389 (Source : in out Super_String;
1390 Mapping : Maps.Character_Mapping)
1392 Post => Super_Length (Source) = Super_Length (Source'Old)
1394 (for all K in 1 .. Super_Length (Source) =>
1395 Super_Element (Source, K) =
1396 Ada.Strings.Maps.Value (Mapping, Super_Element (Source'Old, K))),
1399 function Super_Translate
1400 (Source : Super_String;
1401 Mapping : Maps.Character_Mapping_Function) return Super_String
1403 Pre => Mapping /= null,
1404 Post => Super_Translate'Result.Max_Length = Source.Max_Length
1405 and then Super_Length (Super_Translate'Result) = Super_Length (Source)
1407 (for all K in 1 .. Super_Length (Source) =>
1408 Super_Element (Super_Translate'Result, K) =
1409 Mapping (Super_Element (Source, K))),
1411 pragma Annotate (GNATprove, False_Positive,
1412 "call via access-to-subprogram",
1413 "function Mapping must always terminate");
1415 procedure Super_Translate
1416 (Source : in out Super_String;
1417 Mapping : Maps.Character_Mapping_Function)
1419 Pre => Mapping /= null,
1420 Post => Super_Length (Source) = Super_Length (Source'Old)
1422 (for all K in 1 .. Super_Length (Source) =>
1423 Super_Element (Source, K) =
1424 Mapping (Super_Element (Source'Old, K))),
1426 pragma Annotate (GNATprove, False_Positive,
1427 "call via access-to-subprogram",
1428 "function Mapping must always terminate");
1430 ---------------------------------------
1431 -- String Transformation Subprograms --
1432 ---------------------------------------
1434 function Super_Replace_Slice
1435 (Source : Super_String;
1439 Drop : Truncation := Error) return Super_String
1442 Low - 1 <= Super_Length (Source)
1445 then (if High >= Low
1447 <= Source.Max_Length - By'Length
1448 - Integer'Max (Super_Length (Source) - High, 0)
1449 else Super_Length (Source) <=
1450 Source.Max_Length - By'Length)),
1452 Super_Replace_Slice'Result.Max_Length = Source.Max_Length,
1454 (Low - 1 <= Source.Max_Length - By'Length - Integer'Max
1455 (Super_Length (Source) - Integer'Max (High, Low - 1), 0)
1457 -- Total length is lower than Max_Length: nothing is dropped
1459 -- Note that if High < Low, the insertion is done before Low, so in
1460 -- all cases the starting position of the slice of Source remaining
1461 -- after the replaced Slice is Integer'Max (High + 1, Low).
1463 Super_Length (Super_Replace_Slice'Result) =
1464 Low - 1 + By'Length + Integer'Max
1465 (Super_Length (Source) - Integer'Max (High, Low - 1), 0)
1467 String'(Super_Slice
(Super_Replace_Slice
'Result, 1, Low
- 1)) =
1468 Super_Slice
(Source
, 1, Low
- 1)
1470 Super_Slice
(Super_Replace_Slice
'Result,
1471 Low
, Low
- 1 + By
'Length) = By
1473 (if Integer'Max (High
, Low
- 1) < Super_Length
(Source
) then
1474 String'(Super_Slice (Super_Replace_Slice'Result,
1476 Super_Length (Super_Replace_Slice'Result))) =
1477 Super_Slice (Source,
1478 Integer'Max (High + 1, Low), Super_Length (Source))),
1480 Low - 1 > Source.Max_Length - By'Length - Integer'Max
1481 (Super_Length (Source) - Integer'Max (High, Low - 1), 0)
1482 and then Drop = Left
1484 -- Final_Super_Slice is the length of the slice of Source remaining
1485 -- after the replaced part.
1487 Final_Super_Slice : constant Natural :=
1489 (Super_Length (Source) - Integer'Max (High, Low - 1), 0);
1491 -- The result is of maximal length and ends by the last
1492 -- Final_Super_Slice characters of Source.
1494 Super_Length (Super_Replace_Slice'Result) = Source.Max_Length
1496 (if Final_Super_Slice > 0 then
1497 String'(Super_Slice
(Super_Replace_Slice
'Result,
1498 Source
.Max_Length
- Final_Super_Slice
+ 1,
1499 Source
.Max_Length
)) =
1500 Super_Slice
(Source
,
1501 Integer'Max (High
+ 1, Low
), Super_Length
(Source
)))
1503 -- Depending on when we reach Max_Length, either the first
1504 -- part of Source is fully dropped and By is partly dropped,
1505 -- or By is fully added and the first part of Source is partly
1509 (if Source
.Max_Length
- Final_Super_Slice
- By
'Length <= 0 then
1511 -- The first (possibly zero) characters of By are dropped
1513 (if Final_Super_Slice
< Source
.Max_Length
then
1514 Super_Slice
(Super_Replace_Slice
'Result,
1515 1, Source
.Max_Length
- Final_Super_Slice
) =
1516 By
(By
'Last - Source
.Max_Length
+ Final_Super_Slice
1520 else -- By is added to the result
1522 Super_Slice
(Super_Replace_Slice
'Result,
1523 Source
.Max_Length
- Final_Super_Slice
- By
'Length + 1,
1524 Source
.Max_Length
- Final_Super_Slice
) =
1527 -- The first characters of Source (1 .. Low - 1) are
1531 String'(Super_Slice (Super_Replace_Slice'Result, 1,
1532 Source.Max_Length - Final_Super_Slice - By'Length)) =
1533 Super_Slice (Source,
1534 Low - Source.Max_Length
1535 + Final_Super_Slice + By'Length,
1538 others -- Drop = Right
1540 -- The result is of maximal length and starts by the first Low - 1
1541 -- characters of Source.
1543 Super_Length (Super_Replace_Slice'Result) = Source.Max_Length
1545 String'(Super_Slice
(Super_Replace_Slice
'Result, 1, Low
- 1)) =
1546 Super_Slice
(Source
, 1, Low
- 1)
1548 -- Depending on when we reach Max_Length, either the last part
1549 -- of Source is fully dropped and By is partly dropped, or By
1550 -- is fully added and the last part of Source is partly dropped.
1553 (if Low
- 1 >= Source
.Max_Length
- By
'Length then
1555 -- The last characters of By are dropped
1557 Super_Slice
(Super_Replace_Slice
'Result,
1558 Low
, Source
.Max_Length
) =
1559 By
(By
'First .. Source
.Max_Length
- Low
+ By
'First)
1561 else -- By is fully added
1563 Super_Slice
(Super_Replace_Slice
'Result,
1564 Low
, Low
+ By
'Length - 1) = By
1566 -- Then Source starting from Natural'Max (High + 1, Low)
1567 -- is added but the last characters are dropped.
1570 String'(Super_Slice (Super_Replace_Slice'Result,
1571 Low + By'Length, Source.Max_Length)) =
1572 Super_Slice (Source, Integer'Max (High + 1, Low),
1573 Integer'Max (High + 1, Low) +
1574 (Source.Max_Length - Low - By'Length)))),
1577 procedure Super_Replace_Slice
1578 (Source : in out Super_String;
1582 Drop : Truncation := Error)
1585 Low - 1 <= Super_Length (Source)
1588 then (if High >= Low
1590 <= Source.Max_Length - By'Length
1591 - Natural'Max (Super_Length (Source) - High, 0)
1592 else Super_Length (Source) <=
1593 Source.Max_Length - By'Length)),
1595 (Low - 1 <= Source.Max_Length - By'Length - Integer'Max
1596 (Super_Length (Source) - Integer'Max (High, Low - 1), 0)
1598 -- Total length is lower than Max_Length: nothing is dropped
1600 -- Note that if High < Low, the insertion is done before Low, so in
1601 -- all cases the starting position of the slice of Source remaining
1602 -- after the replaced Slice is Integer'Max (High + 1, Low).
1604 Super_Length (Source) = Low - 1 + By'Length + Integer'Max
1605 (Super_Length (Source'Old) - Integer'Max (High, Low - 1), 0)
1607 String'(Super_Slice
(Source
, 1, Low
- 1)) =
1608 Super_Slice
(Source
'Old, 1, Low
- 1)
1609 and then Super_Slice
(Source
, Low
, Low
- 1 + By
'Length) = By
1611 (if Integer'Max (High
, Low
- 1) < Super_Length
(Source
'Old) then
1612 String'(Super_Slice (Source,
1613 Low + By'Length, Super_Length (Source))) =
1614 Super_Slice (Source'Old,
1615 Integer'Max (High + 1, Low),
1616 Super_Length (Source'Old))),
1618 Low - 1 > Source.Max_Length - By'Length - Integer'Max
1619 (Super_Length (Source) - Integer'Max (High, Low - 1), 0)
1620 and then Drop = Left
1622 -- Final_Super_Slice is the length of the slice of Source remaining
1623 -- after the replaced part.
1625 Final_Super_Slice : constant Natural :=
1627 Super_Length (Source'Old) - Integer'Max (High, Low - 1));
1629 -- The result is of maximal length and ends by the last
1630 -- Final_Super_Slice characters of Source.
1632 Super_Length (Source) = Source.Max_Length
1634 (if Final_Super_Slice > 0 then
1635 String'(Super_Slice
(Source
,
1636 Source
.Max_Length
- Final_Super_Slice
+ 1,
1637 Source
.Max_Length
)) =
1638 Super_Slice
(Source
'Old,
1639 Integer'Max (High
+ 1, Low
),
1640 Super_Length
(Source
'Old)))
1642 -- Depending on when we reach Max_Length, either the first
1643 -- part of Source is fully dropped and By is partly dropped,
1644 -- or By is fully added and the first part of Source is partly
1648 (if Source
.Max_Length
- Final_Super_Slice
- By
'Length <= 0
1650 -- The first characters of By are dropped
1652 (if Final_Super_Slice
< Source
.Max_Length
then
1653 Super_Slice
(Source
,
1654 1, Source
.Max_Length
- Final_Super_Slice
) =
1655 By
(By
'Last - Source
.Max_Length
+ Final_Super_Slice
1659 else -- By is added to the result
1661 Super_Slice
(Source
,
1662 Source
.Max_Length
- Final_Super_Slice
- By
'Length + 1,
1663 Source
.Max_Length
- Final_Super_Slice
) = By
1665 -- The first characters of Source (1 .. Low - 1) are
1669 String'(Super_Slice (Source, 1,
1670 Source.Max_Length - Final_Super_Slice - By'Length)) =
1671 Super_Slice (Source'Old,
1672 Low - Source.Max_Length + Final_Super_Slice
1676 others -- Drop = Right
1678 -- The result is of maximal length and starts by the first Low - 1
1679 -- characters of Source.
1681 Super_Length (Source) = Source.Max_Length
1683 String'(Super_Slice
(Source
, 1, Low
- 1)) =
1684 Super_Slice
(Source
'Old, 1, Low
- 1)
1686 -- Depending on when we reach Max_Length, either the last part
1687 -- of Source is fully dropped and By is partly dropped, or By
1688 -- is fully added and the last part of Source is partly dropped.
1691 (if Low
- 1 >= Source
.Max_Length
- By
'Length then
1693 -- The last characters of By are dropped
1695 Super_Slice
(Source
, Low
, Source
.Max_Length
) =
1696 By
(By
'First .. Source
.Max_Length
- Low
+ By
'First)
1698 else -- By is fully added
1700 Super_Slice
(Source
, Low
, Low
+ By
'Length - 1) = By
1702 -- Then Source starting from Natural'Max (High + 1, Low)
1703 -- is added but the last characters are dropped.
1706 String'(Super_Slice (Source,
1707 Low + By'Length, Source.Max_Length)) =
1708 Super_Slice (Source'Old, Integer'Max (High + 1, Low),
1709 Integer'Max (High + 1, Low) +
1710 (Source.Max_Length - Low - By'Length)))),
1713 function Super_Insert
1714 (Source : Super_String;
1717 Drop : Truncation := Error) return Super_String
1720 Before - 1 <= Super_Length (Source)
1722 (if New_Item'Length > Source.Max_Length - Super_Length (Source)
1723 then Drop /= Error),
1724 Post => Super_Insert'Result.Max_Length = Source.Max_Length,
1726 (Super_Length (Source) <= Source.Max_Length - New_Item'Length
1728 -- Total length is lower than Max_Length: nothing is dropped
1730 Super_Length (Super_Insert'Result) =
1731 Super_Length (Source) + New_Item'Length
1733 String'(Super_Slice
(Super_Insert
'Result, 1, Before
- 1)) =
1734 Super_Slice
(Source
, 1, Before
- 1)
1736 Super_Slice
(Super_Insert
'Result,
1737 Before
, Before
- 1 + New_Item
'Length) =
1740 (if Before
<= Super_Length
(Source
) then
1741 String'(Super_Slice (Super_Insert'Result,
1742 Before + New_Item'Length,
1743 Super_Length (Super_Insert'Result))) =
1744 Super_Slice (Source, Before, Super_Length (Source))),
1746 Super_Length (Source) > Source.Max_Length - New_Item'Length
1747 and then Drop = Left
1749 -- The result is of maximal length and ends by the last characters
1752 Super_Length (Super_Insert'Result) = Source.Max_Length
1754 (if Before <= Super_Length (Source) then
1755 String'(Super_Slice
(Super_Insert
'Result,
1756 Source
.Max_Length
- Super_Length
(Source
) + Before
,
1757 Source
.Max_Length
)) =
1758 Super_Slice
(Source
, Before
, Super_Length
(Source
)))
1760 -- Depending on when we reach Max_Length, either the first part
1761 -- of Source is fully dropped and New_Item is partly dropped, or
1762 -- New_Item is fully added and the first part of Source is partly
1766 (if Source
.Max_Length
- Super_Length
(Source
) - 1 + Before
1769 -- The first characters of New_Item are dropped
1771 (if Super_Length
(Source
) - Before
+ 1 < Source
.Max_Length
1773 Super_Slice
(Super_Insert
'Result, 1,
1774 Source
.Max_Length
- Super_Length
(Source
) - 1 + Before
) =
1776 (New_Item
'Last - Source
.Max_Length
1777 + Super_Length
(Source
) - Before
+ 2
1780 else -- New_Item is added to the result
1782 Super_Slice
(Super_Insert
'Result,
1783 Source
.Max_Length
- Super_Length
(Source
) - New_Item
'Length
1785 Source
.Max_Length
- Super_Length
(Source
) - 1 + Before
) =
1788 -- The first characters of Source (1 .. Before - 1) are
1792 String'(Super_Slice (Super_Insert'Result,
1793 1, Source.Max_Length - Super_Length (Source)
1794 - New_Item'Length - 1 + Before)) =
1795 Super_Slice (Source,
1796 Super_Length (Source) - Source.Max_Length
1797 + New_Item'Length + 1,
1800 others -- Drop = Right
1802 -- The result is of maximal length and starts by the first
1803 -- characters of Source.
1805 Super_Length (Super_Insert'Result) = Source.Max_Length
1807 String'(Super_Slice
(Super_Insert
'Result, 1, Before
- 1)) =
1808 Super_Slice
(Source
, 1, Before
- 1)
1810 -- Depending on when we reach Max_Length, either the last part
1811 -- of Source is fully dropped and New_Item is partly dropped, or
1812 -- New_Item is fully added and the last part of Source is partly
1816 (if Before
- 1 >= Source
.Max_Length
- New_Item
'Length then
1818 -- The last characters of New_Item are dropped
1820 Super_Slice
(Super_Insert
'Result, Before
, Source
.Max_Length
) =
1821 New_Item
(New_Item
'First
1822 .. Source
.Max_Length
- Before
+ New_Item
'First)
1824 else -- New_Item is fully added
1826 Super_Slice
(Super_Insert
'Result,
1827 Before
, Before
+ New_Item
'Length - 1) =
1830 -- Then Source starting from Before is added but the
1831 -- last characters are dropped.
1834 String'(Super_Slice (Super_Insert'Result,
1835 Before + New_Item'Length, Source.Max_Length)) =
1836 Super_Slice (Source,
1837 Before, Source.Max_Length - New_Item'Length))),
1840 procedure Super_Insert
1841 (Source : in out Super_String;
1844 Drop : Truncation := Error)
1847 Before - 1 <= Super_Length (Source)
1849 (if New_Item'Length > Source.Max_Length - Super_Length (Source)
1850 then Drop /= Error),
1852 (Super_Length (Source) <= Source.Max_Length - New_Item'Length
1854 -- Total length is lower than Max_Length: nothing is dropped
1856 Super_Length (Source) = Super_Length (Source'Old) + New_Item'Length
1858 String'(Super_Slice
(Source
, 1, Before
- 1)) =
1859 Super_Slice
(Source
'Old, 1, Before
- 1)
1861 Super_Slice
(Source
, Before
, Before
- 1 + New_Item
'Length) =
1864 (if Before
<= Super_Length
(Source
'Old) then
1865 String'(Super_Slice (Source,
1866 Before + New_Item'Length, Super_Length (Source))) =
1867 Super_Slice (Source'Old,
1868 Before, Super_Length (Source'Old))),
1870 Super_Length (Source) > Source.Max_Length - New_Item'Length
1871 and then Drop = Left
1873 -- The result is of maximal length and ends by the last characters
1876 Super_Length (Source) = Source.Max_Length
1878 (if Before <= Super_Length (Source'Old) then
1879 String'(Super_Slice
(Source
,
1880 Source
.Max_Length
- Super_Length
(Source
'Old) + Before
,
1881 Source
.Max_Length
)) =
1882 Super_Slice
(Source
'Old,
1883 Before
, Super_Length
(Source
'Old)))
1885 -- Depending on when we reach Max_Length, either the first part
1886 -- of Source is fully dropped and New_Item is partly dropped, or
1887 -- New_Item is fully added and the first part of Source is partly
1891 (if Source
.Max_Length
- Super_Length
(Source
'Old) - 1 + Before
1894 -- The first characters of New_Item are dropped
1896 (if Super_Length
(Source
'Old) - Before
+ 1 < Source
.Max_Length
1898 Super_Slice
(Source
,
1899 1, Source
.Max_Length
- Super_Length
(Source
'Old)
1902 (New_Item
'Last - Source
.Max_Length
1903 + Super_Length
(Source
'Old) - Before
+ 2
1906 else -- New_Item is added to the result
1908 Super_Slice
(Source
,
1909 Source
.Max_Length
- Super_Length
(Source
'Old)
1910 - New_Item
'Length + Before
,
1911 Source
.Max_Length
- Super_Length
(Source
'Old) - 1 + Before
)
1914 -- The first characters of Source (1 .. Before - 1) are
1918 String'(Super_Slice (Source, 1,
1919 Source.Max_Length - Super_Length (Source'Old)
1920 - New_Item'Length - 1 + Before)) =
1921 Super_Slice (Source'Old,
1922 Super_Length (Source'Old)
1923 - Source.Max_Length + New_Item'Length + 1,
1926 others -- Drop = Right
1928 -- The result is of maximal length and starts by the first
1929 -- characters of Source.
1931 Super_Length (Source) = Source.Max_Length
1933 String'(Super_Slice
(Source
, 1, Before
- 1)) =
1934 Super_Slice
(Source
'Old, 1, Before
- 1)
1936 -- Depending on when we reach Max_Length, either the last part
1937 -- of Source is fully dropped and New_Item is partly dropped, or
1938 -- New_Item is fully added and the last part of Source is partly
1942 (if Before
- 1 >= Source
.Max_Length
- New_Item
'Length then
1944 -- The last characters of New_Item are dropped
1946 Super_Slice
(Source
, Before
, Source
.Max_Length
) =
1947 New_Item
(New_Item
'First
1948 .. Source
.Max_Length
- Before
+ New_Item
'First)
1950 else -- New_Item is fully added
1952 Super_Slice
(Source
, Before
, Before
+ New_Item
'Length - 1) =
1955 -- Then Source starting from Before is added but the
1956 -- last characters are dropped.
1959 String'(Super_Slice (Source,
1960 Before + New_Item'Length, Source.Max_Length)) =
1961 Super_Slice (Source'Old,
1962 Before, Source.Max_Length - New_Item'Length))),
1965 function Super_Overwrite
1966 (Source : Super_String;
1967 Position : Positive;
1969 Drop : Truncation := Error) return Super_String
1972 Position - 1 <= Super_Length (Source)
1973 and then (if New_Item'Length > Source.Max_Length - (Position - 1)
1974 then Drop /= Error),
1975 Post => Super_Overwrite'Result.Max_Length = Source.Max_Length,
1977 (Position - 1 <= Source.Max_Length - New_Item'Length
1979 -- The length is unchanged, unless New_Item overwrites further than
1980 -- the end of Source. In this contract case, we suppose New_Item
1981 -- doesn't overwrite further than Max_Length.
1983 Super_Length (Super_Overwrite'Result) =
1984 Integer'Max (Super_Length (Source), Position - 1 + New_Item'Length)
1986 String'(Super_Slice
(Super_Overwrite
'Result, 1, Position
- 1)) =
1987 Super_Slice
(Source
, 1, Position
- 1)
1988 and then Super_Slice
(Super_Overwrite
'Result,
1989 Position
, Position
- 1 + New_Item
'Length) =
1992 (if Position
- 1 + New_Item
'Length < Super_Length
(Source
) then
1994 -- There are some unchanged characters of Source remaining
1997 String'(Super_Slice (Super_Overwrite'Result,
1998 Position + New_Item'Length, Super_Length (Source))) =
1999 Super_Slice (Source,
2000 Position + New_Item'Length, Super_Length (Source))),
2002 Position - 1 > Source.Max_Length - New_Item'Length and then Drop = Left
2004 Super_Length (Super_Overwrite'Result) = Source.Max_Length
2006 -- If a part of the result has to be dropped, it means New_Item is
2007 -- overwriting further than the end of Source. Thus the result is
2008 -- necessarily ending by New_Item. However, we don't know whether
2009 -- New_Item covers all Max_Length characters or some characters of
2010 -- Source are remaining at the left.
2013 (if New_Item'Length >= Source.Max_Length then
2015 -- New_Item covers all Max_Length characters
2017 Super_To_String (Super_Overwrite'Result) =
2019 (New_Item'Last - Source.Max_Length + 1 .. New_Item'Last)
2021 -- New_Item fully appears at the end
2023 Super_Slice (Super_Overwrite'Result,
2024 Source.Max_Length - New_Item'Length + 1,
2025 Source.Max_Length) =
2028 -- The left of Source is cut
2031 String'(Super_Slice
(Super_Overwrite
'Result,
2032 1, Source
.Max_Length
- New_Item
'Length)) =
2033 Super_Slice
(Source
,
2034 Position
- Source
.Max_Length
+ New_Item
'Length,
2037 others -- Drop = Right
2039 -- The result is of maximal length and starts by the first
2040 -- characters of Source.
2042 Super_Length
(Super_Overwrite
'Result) = Source
.Max_Length
2044 String'(Super_Slice (Super_Overwrite'Result, 1, Position - 1)) =
2045 Super_Slice (Source, 1, Position - 1)
2047 -- Then New_Item is written until Max_Length
2049 and then Super_Slice (Super_Overwrite'Result,
2050 Position, Source.Max_Length) =
2051 New_Item (New_Item'First
2052 .. Source.Max_Length - Position + New_Item'First)),
2055 procedure Super_Overwrite
2056 (Source : in out Super_String;
2057 Position : Positive;
2059 Drop : Truncation := Error)
2062 Position - 1 <= Super_Length (Source)
2063 and then (if New_Item'Length > Source.Max_Length - (Position - 1)
2064 then Drop /= Error),
2066 (Position - 1 <= Source.Max_Length - New_Item'Length
2068 -- The length is unchanged, unless New_Item overwrites further than
2069 -- the end of Source. In this contract case, we suppose New_Item
2070 -- doesn't overwrite further than Max_Length.
2072 Super_Length (Source) = Integer'Max
2073 (Super_Length (Source'Old), Position - 1 + New_Item'Length)
2075 String'(Super_Slice
(Source
, 1, Position
- 1)) =
2076 Super_Slice
(Source
'Old, 1, Position
- 1)
2077 and then Super_Slice
(Source
,
2078 Position
, Position
- 1 + New_Item
'Length) =
2081 (if Position
- 1 + New_Item
'Length < Super_Length
(Source
'Old)
2083 -- There are some unchanged characters of Source remaining
2086 String'(Super_Slice (Source,
2087 Position + New_Item'Length, Super_Length (Source'Old))) =
2088 Super_Slice (Source'Old,
2089 Position + New_Item'Length, Super_Length (Source'Old))),
2091 Position - 1 > Source.Max_Length - New_Item'Length and then Drop = Left
2093 Super_Length (Source) = Source.Max_Length
2095 -- If a part of the result has to be dropped, it means New_Item is
2096 -- overwriting further than the end of Source. Thus the result is
2097 -- necessarily ending by New_Item. However, we don't know whether
2098 -- New_Item covers all Max_Length characters or some characters of
2099 -- Source are remaining at the left.
2102 (if New_Item'Length >= Source.Max_Length then
2104 -- New_Item covers all Max_Length characters
2106 Super_To_String (Source) =
2108 (New_Item'Last - Source.Max_Length + 1 .. New_Item'Last)
2110 -- New_Item fully appears at the end
2112 Super_Slice (Source,
2113 Source.Max_Length - New_Item'Length + 1,
2114 Source.Max_Length) =
2117 -- The left of Source is cut
2120 String'(Super_Slice
(Source
,
2121 1, Source
.Max_Length
- New_Item
'Length)) =
2122 Super_Slice
(Source
'Old,
2123 Position
- Source
.Max_Length
+ New_Item
'Length,
2126 others -- Drop = Right
2128 -- The result is of maximal length and starts by the first
2129 -- characters of Source.
2131 Super_Length
(Source
) = Source
.Max_Length
2133 String'(Super_Slice (Source, 1, Position - 1)) =
2134 Super_Slice (Source'Old, 1, Position - 1)
2136 -- New_Item is written until Max_Length
2138 and then Super_Slice (Source, Position, Source.Max_Length) =
2139 New_Item (New_Item'First
2140 .. Source.Max_Length - Position + New_Item'First)),
2143 function Super_Delete
2144 (Source : Super_String;
2146 Through : Natural) return Super_String
2149 (if Through >= From then From - 1 <= Super_Length (Source)),
2150 Post => Super_Delete'Result.Max_Length = Source.Max_Length,
2153 Super_Length (Super_Delete'Result) =
2154 From - 1 + Natural'Max (Super_Length (Source) - Through, 0)
2156 String'(Super_Slice
(Super_Delete
'Result, 1, From
- 1)) =
2157 Super_Slice
(Source
, 1, From
- 1)
2159 (if Through
< Super_Length
(Source
) then
2160 String'(Super_Slice (Super_Delete'Result,
2161 From, Super_Length (Super_Delete'Result))) =
2162 Super_Slice (Source, Through + 1, Super_Length (Source))),
2164 Super_Delete'Result = Source),
2167 procedure Super_Delete
2168 (Source : in out Super_String;
2173 (if Through >= From then From - 1 <= Super_Length (Source)),
2176 Super_Length (Source) =
2177 From - 1 + Natural'Max (Super_Length (Source'Old) - Through, 0)
2179 String'(Super_Slice
(Source
, 1, From
- 1)) =
2180 Super_Slice
(Source
'Old, 1, From
- 1)
2182 (if Through
< Super_Length
(Source
) then
2183 String'(Super_Slice (Source, From, Super_Length (Source))) =
2184 Super_Slice (Source'Old,
2185 Through + 1, Super_Length (Source'Old))),
2187 Source = Source'Old),
2190 ---------------------------------
2191 -- String Selector Subprograms --
2192 ---------------------------------
2195 (Source : Super_String;
2196 Side : Trim_End) return Super_String
2198 Post => Super_Trim'Result.Max_Length = Source.Max_Length,
2201 -- If all characters in Source are Space, the returned string is empty
2203 ((for all C of Super_To_String (Source) => C = ' ')
2205 Super_Length (Super_Trim'Result) = 0,
2207 -- Otherwise, the returned string is a slice of Source
2212 Low : constant Positive :=
2213 (if Side = Right then 1
2214 else Super_Index_Non_Blank (Source, Forward));
2215 High : constant Positive :=
2216 (if Side = Left then Super_Length (Source)
2217 else Super_Index_Non_Blank (Source, Backward));
2219 Super_To_String (Super_Trim'Result) =
2220 Super_Slice (Source, Low, High))),
2223 procedure Super_Trim
2224 (Source : in out Super_String;
2229 -- If all characters in Source are Space, the returned string is empty
2231 ((for all C of Super_To_String (Source) => C = ' ')
2233 Super_Length (Source) = 0,
2235 -- Otherwise, the returned string is a slice of Source
2240 Low : constant Positive :=
2241 (if Side = Right then 1
2242 else Super_Index_Non_Blank (Source'Old, Forward));
2243 High : constant Positive :=
2244 (if Side = Left then Super_Length (Source'Old)
2245 else Super_Index_Non_Blank (Source'Old, Backward));
2247 Super_To_String (Source) = Super_Slice (Source'Old, Low, High))),
2251 (Source : Super_String;
2252 Left : Maps.Character_Set;
2253 Right : Maps.Character_Set) return Super_String
2255 Post => Super_Trim'Result.Max_Length = Source.Max_Length,
2258 -- If all characters in Source are contained in one of the sets Left or
2259 -- Right, then the returned string is empty.
2261 ((for all C of Super_To_String (Source) => Maps.Is_In (C, Left))
2263 (for all C of Super_To_String (Source) => Maps.Is_In (C, Right))
2265 Super_Length (Super_Trim'Result) = 0,
2267 -- Otherwise, the returned string is a slice of Source
2272 Low : constant Positive :=
2273 Super_Index (Source, Left, Outside, Forward);
2274 High : constant Positive :=
2275 Super_Index (Source, Right, Outside, Backward);
2277 Super_To_String (Super_Trim'Result) =
2278 Super_Slice (Source, Low, High))),
2281 procedure Super_Trim
2282 (Source : in out Super_String;
2283 Left : Maps.Character_Set;
2284 Right : Maps.Character_Set)
2288 -- If all characters in Source are contained in one of the sets Left or
2289 -- Right, then the returned string is empty.
2291 ((for all C of Super_To_String (Source) => Maps.Is_In (C, Left))
2293 (for all C of Super_To_String (Source) => Maps.Is_In (C, Right))
2295 Super_Length (Source) = 0,
2297 -- Otherwise, the returned string is a slice of Source
2302 Low : constant Positive :=
2303 Super_Index (Source'Old, Left, Outside, Forward);
2304 High : constant Positive :=
2305 Super_Index (Source'Old, Right, Outside, Backward);
2307 Super_To_String (Source) = Super_Slice (Source'Old, Low, High))),
2311 (Source : Super_String;
2313 Pad : Character := Space;
2314 Drop : Truncation := Error) return Super_String
2316 Pre => (if Count > Source.Max_Length then Drop /= Error),
2317 Post => Super_Head'Result.Max_Length = Source.Max_Length,
2319 (Count <= Super_Length (Source)
2323 Super_To_String (Super_Head'Result) = Super_Slice (Source, 1, Count),
2324 Count > Super_Length (Source) and then Count <= Source.Max_Length
2326 -- Source is followed by Pad characters
2328 Super_Length (Super_Head'Result) = Count
2330 Super_Slice (Super_Head'Result, 1, Super_Length (Source)) =
2331 Super_To_String (Source)
2333 String'(Super_Slice
(Super_Head
'Result,
2334 Super_Length
(Source
) + 1, Count
)) =
2335 [1 .. Count
- Super_Length
(Source
) => Pad
],
2336 Count
> Source
.Max_Length
and then Drop
= Right
2338 -- Source is followed by Pad characters
2340 Super_Length
(Super_Head
'Result) = Source
.Max_Length
2342 Super_Slice
(Super_Head
'Result, 1, Super_Length
(Source
)) =
2343 Super_To_String
(Source
)
2345 String'(Super_Slice (Super_Head'Result,
2346 Super_Length (Source) + 1, Source.Max_Length)) =
2347 [1 .. Source.Max_Length - Super_Length (Source) => Pad],
2348 Count - Super_Length (Source) > Source.Max_Length and then Drop = Left
2350 -- Source is fully dropped on the left
2352 Super_To_String (Super_Head'Result) =
2353 [1 .. Source.Max_Length => Pad],
2356 -- Source is partly dropped on the left
2358 Super_Length (Super_Head'Result) = Source.Max_Length
2360 String'(Super_Slice
(Super_Head
'Result,
2361 1, Source
.Max_Length
- Count
+ Super_Length
(Source
))) =
2362 Super_Slice
(Source
,
2363 Count
- Source
.Max_Length
+ 1, Super_Length
(Source
))
2365 String'(Super_Slice (Super_Head'Result,
2366 Source.Max_Length - Count + Super_Length (Source) + 1,
2367 Source.Max_Length)) =
2368 [1 .. Count - Super_Length (Source) => Pad]),
2371 procedure Super_Head
2372 (Source : in out Super_String;
2374 Pad : Character := Space;
2375 Drop : Truncation := Error)
2377 Pre => (if Count > Source.Max_Length then Drop /= Error),
2379 (Count <= Super_Length (Source)
2383 Super_To_String (Source) = Super_Slice (Source'Old, 1, Count),
2384 Count > Super_Length (Source) and then Count <= Source.Max_Length
2386 -- Source is followed by Pad characters
2388 Super_Length (Source) = Count
2390 Super_Slice (Source, 1, Super_Length (Source'Old)) =
2391 Super_To_String (Source'Old)
2393 String'(Super_Slice
(Source
,
2394 Super_Length
(Source
'Old) + 1, Count
)) =
2395 [1 .. Count
- Super_Length
(Source
'Old) => Pad
],
2396 Count
> Source
.Max_Length
and then Drop
= Right
2398 -- Source is followed by Pad characters
2400 Super_Length
(Source
) = Source
.Max_Length
2402 Super_Slice
(Source
, 1, Super_Length
(Source
'Old)) =
2403 Super_To_String
(Source
'Old)
2405 String'(Super_Slice (Source,
2406 Super_Length (Source'Old) + 1, Source.Max_Length)) =
2407 [1 .. Source.Max_Length - Super_Length (Source'Old) => Pad],
2408 Count - Super_Length (Source) > Source.Max_Length and then Drop = Left
2410 -- Source is fully dropped on the left
2412 Super_To_String (Source) = [1 .. Source.Max_Length => Pad],
2415 -- Source is partly dropped on the left
2417 Super_Length (Source) = Source.Max_Length
2419 String'(Super_Slice
(Source
,
2420 1, Source
.Max_Length
- Count
+ Super_Length
(Source
'Old))) =
2421 Super_Slice
(Source
'Old,
2422 Count
- Source
.Max_Length
+ 1, Super_Length
(Source
'Old))
2424 String'(Super_Slice (Source,
2425 Source.Max_Length - Count + Super_Length (Source'Old) + 1,
2426 Source.Max_Length)) =
2427 [1 .. Count - Super_Length (Source'Old) => Pad]),
2431 (Source : Super_String;
2433 Pad : Character := Space;
2434 Drop : Truncation := Error) return Super_String
2436 Pre => (if Count > Source.Max_Length then Drop /= Error),
2437 Post => Super_Tail'Result.Max_Length = Source.Max_Length,
2439 (Count < Super_Length (Source)
2444 Super_To_String (Super_Tail'Result) =
2445 Super_Slice (Source,
2446 Super_Length (Source) - Count + 1, Super_Length (Source))
2447 else Super_Length (Super_Tail'Result) = 0),
2448 Count >= Super_Length (Source) and then Count < Source.Max_Length
2450 -- Source is preceded by Pad characters
2452 Super_Length (Super_Tail'Result) = Count
2454 String'(Super_Slice
(Super_Tail
'Result,
2455 1, Count
- Super_Length
(Source
))) =
2456 [1 .. Count
- Super_Length
(Source
) => Pad
]
2458 Super_Slice
(Super_Tail
'Result,
2459 Count
- Super_Length
(Source
) + 1, Count
) =
2460 Super_To_String
(Source
),
2461 Count
>= Source
.Max_Length
and then Drop
= Left
2463 -- Source is preceded by Pad characters
2465 Super_Length
(Super_Tail
'Result) = Source
.Max_Length
2467 String'(Super_Slice (Super_Tail'Result,
2468 1, Source.Max_Length - Super_Length (Source))) =
2469 [1 .. Source.Max_Length - Super_Length (Source) => Pad]
2471 (if Super_Length (Source) > 0 then
2472 Super_Slice (Super_Tail'Result,
2473 Source.Max_Length - Super_Length (Source) + 1,
2474 Source.Max_Length) =
2475 Super_To_String (Source)),
2476 Count - Super_Length (Source) >= Source.Max_Length
2477 and then Drop /= Left
2479 -- Source is fully dropped on the right
2481 Super_To_String (Super_Tail'Result) =
2482 [1 .. Source.Max_Length => Pad],
2485 -- Source is partly dropped on the right
2487 Super_Length (Super_Tail'Result) = Source.Max_Length
2489 String'(Super_Slice
(Super_Tail
'Result,
2490 1, Count
- Super_Length
(Source
))) =
2491 [1 .. Count
- Super_Length
(Source
) => Pad
]
2493 String'(Super_Slice (Super_Tail'Result,
2494 Count - Super_Length (Source) + 1, Source.Max_Length)) =
2495 Super_Slice (Source,
2496 1, Source.Max_Length - Count + Super_Length (Source))),
2499 procedure Super_Tail
2500 (Source : in out Super_String;
2502 Pad : Character := Space;
2503 Drop : Truncation := Error)
2505 Pre => (if Count > Source.Max_Length then Drop /= Error),
2507 (Count < Super_Length (Source)
2512 Super_To_String (Source) =
2513 Super_Slice (Source'Old,
2514 Super_Length (Source'Old) - Count + 1,
2515 Super_Length (Source'Old))
2516 else Super_Length (Source) = 0),
2517 Count >= Super_Length (Source) and then Count < Source.Max_Length
2519 -- Source is preceded by Pad characters
2521 Super_Length (Source) = Count
2523 String'(Super_Slice
(Source
,
2524 1, Count
- Super_Length
(Source
'Old))) =
2525 [1 .. Count
- Super_Length
(Source
'Old) => Pad
]
2527 Super_Slice
(Source
,
2528 Count
- Super_Length
(Source
'Old) + 1, Count
) =
2529 Super_To_String
(Source
'Old),
2530 Count
>= Source
.Max_Length
and then Drop
= Left
2532 -- Source is preceded by Pad characters
2534 Super_Length
(Source
) = Source
.Max_Length
2536 String'(Super_Slice (Source,
2537 1, Source.Max_Length - Super_Length (Source'Old))) =
2538 [1 .. Source.Max_Length - Super_Length (Source'Old) => Pad]
2540 (if Super_Length (Source'Old) > 0 then
2541 Super_Slice (Source,
2542 Source.Max_Length - Super_Length (Source'Old) + 1,
2543 Source.Max_Length) =
2544 Super_To_String (Source'Old)),
2545 Count - Super_Length (Source) >= Source.Max_Length
2546 and then Drop /= Left
2548 -- Source is fully dropped on the right
2550 Super_To_String (Source) = [1 .. Source.Max_Length => Pad],
2553 -- Source is partly dropped on the right
2555 Super_Length (Source) = Source.Max_Length
2557 String'(Super_Slice
(Source
,
2558 1, Count
- Super_Length
(Source
'Old))) =
2559 [1 .. Count
- Super_Length
(Source
'Old) => Pad
]
2561 String'(Super_Slice (Source,
2562 Count - Super_Length (Source'Old) + 1, Source.Max_Length)) =
2563 Super_Slice (Source'Old,
2564 1, Source.Max_Length - Count + Super_Length (Source'Old))),
2567 ------------------------------------
2568 -- String Constructor Subprograms --
2569 ------------------------------------
2571 -- Note: in some of the following routines, there is an extra parameter
2572 -- Max_Length which specifies the value of the maximum length for the
2573 -- resulting Super_String value.
2578 Max_Length : Positive) return Super_String
2580 Pre => Left <= Max_Length,
2581 Post => Times'Result.Max_Length = Max_Length
2582 and then Super_To_String (Times'Result) = [1 .. Left => Right],
2584 -- Note the additional parameter Max_Length
2589 Max_Length : Positive) return Super_String
2591 Pre => (if Left /= 0 then Right'Length <= Max_Length / Left),
2592 Post => Times'Result.Max_Length = Max_Length
2593 and then Super_Length (Times'Result) = Left * Right'Length
2595 (if Right'Length > 0 then
2596 (for all K in 1 .. Left * Right'Length =>
2597 Super_Element (Times'Result, K) =
2598 Right (Right'First + (K - 1) mod Right'Length))),
2600 -- Note the additional parameter Max_Length
2604 Right : Super_String) return Super_String
2607 (if Left /= 0 then Super_Length (Right) <= Right.Max_Length / Left),
2608 Post => Times'Result.Max_Length = Right.Max_Length
2609 and then Super_Length (Times'Result) = Left * Super_Length (Right)
2611 (if Super_Length (Right) > 0 then
2612 (for all K in 1 .. Left * Super_Length (Right) =>
2613 Super_Element (Times'Result, K) =
2614 Super_Element (Right, 1 + (K - 1) mod Super_Length (Right)))),
2617 function Super_Replicate
2620 Drop : Truncation := Error;
2621 Max_Length : Positive) return Super_String
2623 Pre => (if Count > Max_Length then Drop /= Error),
2624 Post => Super_Replicate'Result.Max_Length = Max_Length
2625 and then Super_To_String (Super_Replicate'Result) =
2626 [1 .. Natural'Min (Max_Length, Count) => Item],
2628 -- Note the additional parameter Max_Length
2630 function Super_Replicate
2633 Drop : Truncation := Error;
2634 Max_Length : Positive) return Super_String
2637 (if Count /= 0 and then Item'Length > Max_Length / Count
2638 then Drop /= Error),
2639 Post => Super_Replicate'Result.Max_Length = Max_Length,
2641 (Count = 0 or else Item'Length <= Max_Length / Count
2643 Super_Length (Super_Replicate'Result) = Count * Item'Length
2645 (if Item'Length > 0 then
2646 (for all K in 1 .. Count * Item'Length =>
2647 Super_Element (Super_Replicate'Result, K) =
2648 Item (Item'First + (K - 1) mod Item'Length))),
2650 and then Item'Length > Max_Length / Count
2651 and then Drop = Right
2653 Super_Length (Super_Replicate'Result) = Max_Length
2655 (for all K in 1 .. Max_Length =>
2656 Super_Element (Super_Replicate'Result, K) =
2657 Item (Item'First + (K - 1) mod Item'Length)),
2658 others -- Drop = Left
2660 Super_Length (Super_Replicate'Result) = Max_Length
2662 (for all K in 1 .. Max_Length =>
2663 Super_Element (Super_Replicate'Result, K) =
2664 Item (Item'Last - (Max_Length - K) mod Item'Length))),
2666 -- Note the additional parameter Max_Length
2668 function Super_Replicate
2670 Item : Super_String;
2671 Drop : Truncation := Error) return Super_String
2675 and then Super_Length (Item) > Item.Max_Length / Count
2676 then Drop /= Error),
2677 Post => Super_Replicate'Result.Max_Length = Item.Max_Length,
2679 ((if Count /= 0 then Super_Length (Item) <= Item.Max_Length / Count)
2681 Super_Length (Super_Replicate'Result) = Count * Super_Length (Item)
2683 (if Super_Length (Item) > 0 then
2684 (for all K in 1 .. Count * Super_Length (Item) =>
2685 Super_Element (Super_Replicate'Result, K) =
2686 Super_Element (Item,
2687 1 + (K - 1) mod Super_Length (Item)))),
2689 and then Super_Length (Item) > Item.Max_Length / Count
2690 and then Drop = Right
2692 Super_Length (Super_Replicate'Result) = Item.Max_Length
2694 (for all K in 1 .. Item.Max_Length =>
2695 Super_Element (Super_Replicate'Result, K) =
2696 Super_Element (Item, 1 + (K - 1) mod Super_Length (Item))),
2697 others -- Drop = Left
2699 Super_Length (Super_Replicate'Result) = Item.Max_Length
2701 (for all K in 1 .. Item.Max_Length =>
2702 Super_Element (Super_Replicate'Result, K) =
2703 Super_Element (Item,
2705 - (Item.Max_Length - K) mod Super_Length (Item)))),
2709 (S : in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class;
2710 Source : Super_String);
2713 -- Pragma Inline declarations
2715 pragma Inline ("=");
2716 pragma Inline (Less);
2717 pragma Inline (Less_Or_Equal);
2718 pragma Inline (Greater);
2719 pragma Inline (Greater_Or_Equal);
2720 pragma Inline (Concat);
2721 pragma Inline (Super_Count);
2722 pragma Inline (Super_Element);
2723 pragma Inline (Super_Find_Token);
2724 pragma Inline (Super_Index);
2725 pragma Inline (Super_Index_Non_Blank);
2726 pragma Inline (Super_Length);
2727 pragma Inline (Super_Replace_Element);
2728 pragma Inline (Super_Slice);
2729 pragma Inline (Super_To_String);
2731 end Ada.Strings.Superbounded;