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-2023, 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 Pre
=> Left
.Max_Length
= Right
.Max_Length
,
693 Post
=> "="'Result = (Super_To_String (Left) = Super_To_String (Right)),
697 (Left : Super_String;
698 Right : Super_String) return Boolean renames "=";
701 (Left : Super_String;
702 Right : String) return Boolean
704 Post => Equal'Result = (Super_To_String (Left) = Right),
709 Right : Super_String) return Boolean
711 Post => Equal'Result = (Left = Super_To_String (Right)),
715 (Left : Super_String;
716 Right : Super_String) return Boolean
718 Pre => Left.Max_Length = Right.Max_Length,
720 Less'Result = (Super_To_String (Left) < Super_To_String (Right)),
724 (Left : Super_String;
725 Right : String) return Boolean
727 Post => Less'Result = (Super_To_String (Left) < Right),
732 Right : Super_String) return Boolean
734 Post => Less'Result = (Left < Super_To_String (Right)),
737 function Less_Or_Equal
738 (Left : Super_String;
739 Right : Super_String) return Boolean
741 Pre => Left.Max_Length = Right.Max_Length,
743 Less_Or_Equal'Result =
744 (Super_To_String (Left) <= Super_To_String (Right)),
747 function Less_Or_Equal
748 (Left : Super_String;
749 Right : String) return Boolean
751 Post => Less_Or_Equal'Result = (Super_To_String (Left) <= Right),
754 function Less_Or_Equal
756 Right : Super_String) return Boolean
758 Post => Less_Or_Equal'Result = (Left <= Super_To_String (Right)),
762 (Left : Super_String;
763 Right : Super_String) return Boolean
765 Pre => Left.Max_Length = Right.Max_Length,
767 Greater'Result = (Super_To_String (Left) > Super_To_String (Right)),
771 (Left : Super_String;
772 Right : String) return Boolean
774 Post => Greater'Result = (Super_To_String (Left) > Right),
779 Right : Super_String) return Boolean
781 Post => Greater'Result = (Left > Super_To_String (Right)),
784 function Greater_Or_Equal
785 (Left : Super_String;
786 Right : Super_String) return Boolean
788 Pre => Left.Max_Length = Right.Max_Length,
790 Greater_Or_Equal'Result =
791 (Super_To_String (Left) >= Super_To_String (Right)),
794 function Greater_Or_Equal
795 (Left : Super_String;
796 Right : String) return Boolean
798 Post => Greater_Or_Equal'Result = (Super_To_String (Left) >= Right),
801 function Greater_Or_Equal
803 Right : Super_String) return Boolean
805 Post => Greater_Or_Equal'Result = (Left >= Super_To_String (Right)),
808 ----------------------
809 -- Search Functions --
810 ----------------------
813 (Source : Super_String;
815 Going : Direction := Forward;
816 Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
818 Pre => Pattern'Length > 0,
819 Post => Super_Index'Result <= Super_Length (Source),
822 -- If Source is the empty string, then 0 is returned
824 (Super_Length (Source) = 0
826 Super_Index'Result = 0,
828 -- If some slice of Source matches Pattern, then a valid index is
831 Super_Length (Source) > 0
833 (for some J in 1 .. Super_Length (Source) - (Pattern'Length - 1) =>
834 Search.Match (Super_To_String (Source), Pattern, Mapping, J))
836 -- The result is in the considered range of Source
838 Super_Index'Result in
839 1 .. Super_Length (Source) - (Pattern'Length - 1)
841 -- The slice beginning at the returned index matches Pattern
843 and then Search.Match
844 (Super_To_String (Source), Pattern, Mapping, Super_Index'Result)
846 -- The result is the smallest or largest index which satisfies
847 -- the matching, respectively when Going = Forward and Going =
851 (for all J in 1 .. Super_Length (Source) =>
852 (if (if Going = Forward
853 then J <= Super_Index'Result - 1
854 else J - 1 in Super_Index'Result
855 .. Super_Length (Source) - Pattern'Length)
856 then not (Search.Match
857 (Super_To_String (Source), Pattern, Mapping, J)))),
859 -- Otherwise, 0 is returned
863 Super_Index'Result = 0),
867 (Source : Super_String;
869 Going : Direction := Forward;
870 Mapping : Maps.Character_Mapping_Function) return Natural
872 Pre => Pattern'Length /= 0 and then Mapping /= null,
873 Post => Super_Index'Result <= Super_Length (Source),
876 -- If Source is the empty string, then 0 is returned
878 (Super_Length (Source) = 0
880 Super_Index'Result = 0,
882 -- If some slice of Source matches Pattern, then a valid index is
885 Super_Length (Source) > 0
887 (for some J in 1 .. Super_Length (Source) - (Pattern'Length - 1) =>
888 Search.Match (Super_To_String (Source), Pattern, Mapping, J))
890 -- The result is in the considered range of Source
892 Super_Index'Result in
893 1 .. Super_Length (Source) - (Pattern'Length - 1)
895 -- The slice beginning at the returned index matches Pattern
897 and then Search.Match
898 (Super_To_String (Source), Pattern, Mapping, Super_Index'Result)
900 -- The result is the smallest or largest index which satisfies
901 -- the matching, respectively when Going = Forward and Going =
905 (for all J in 1 .. Super_Length (Source) =>
906 (if (if Going = Forward
907 then J <= Super_Index'Result - 1
908 else J - 1 in Super_Index'Result
909 .. Super_Length (Source) - Pattern'Length)
910 then not (Search.Match
911 (Super_To_String (Source), Pattern, Mapping, J)))),
913 -- Otherwise, 0 is returned
917 Super_Index'Result = 0),
921 (Source : Super_String;
922 Set : Maps.Character_Set;
923 Test : Membership := Inside;
924 Going : Direction := Forward) return Natural
926 Post => Super_Index'Result <= Super_Length (Source),
929 -- If no character of Source satisfies the property Test on Set,
930 -- then 0 is returned.
932 ((for all C of Super_To_String (Source) =>
933 (Test = Inside) /= Maps.Is_In (C, Set))
935 Super_Index'Result = 0,
937 -- Otherwise, an index in the range of Source is returned
941 -- The result is in the range of Source
943 Super_Index'Result in 1 .. Super_Length (Source)
945 -- The character at the returned index satisfies the property
950 Maps.Is_In (Super_Element (Source, Super_Index'Result), Set)
952 -- The result is the smallest or largest index which satisfies
953 -- the property, respectively when Going = Forward and Going =
957 (for all J in 1 .. Super_Length (Source) =>
958 (if J /= Super_Index'Result
959 and then (J < Super_Index'Result) = (Going = Forward)
961 /= Maps.Is_In (Super_Element (Source, J), Set)))),
965 (Source : Super_String;
968 Going : Direction := Forward;
969 Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
972 (if Super_Length (Source) /= 0 then From <= Super_Length (Source))
973 and then Pattern'Length /= 0,
974 Post => Super_Index'Result <= Super_Length (Source),
977 -- If Source is the empty string, then 0 is returned
979 (Super_Length (Source) = 0
981 Super_Index'Result = 0,
983 -- If some slice of Source matches Pattern, then a valid index is
986 Super_Length (Source) > 0
989 (if Going = Forward then From else 1)
990 .. (if Going = Forward then Super_Length (Source) else From)
991 - (Pattern'Length - 1) =>
992 Search.Match (Super_To_String (Source), Pattern, Mapping, J))
994 -- The result is in the considered range of Source
996 Super_Index'Result in
997 (if Going = Forward then From else 1)
998 .. (if Going = Forward then Super_Length (Source) else From)
999 - (Pattern'Length - 1)
1001 -- The slice beginning at the returned index matches Pattern
1003 and then Search.Match
1004 (Super_To_String (Source), Pattern, Mapping, Super_Index'Result)
1006 -- The result is the smallest or largest index which satisfies
1007 -- the matching, respectively when Going = Forward and Going =
1011 (for all J in 1 .. Super_Length (Source) =>
1012 (if (if Going = Forward
1013 then J in From .. Super_Index'Result - 1
1014 else J - 1 in Super_Index'Result
1015 .. From - Pattern'Length)
1016 then not (Search.Match
1017 (Super_To_String (Source), Pattern, Mapping, J)))),
1019 -- Otherwise, 0 is returned
1023 Super_Index'Result = 0),
1026 function Super_Index
1027 (Source : Super_String;
1030 Going : Direction := Forward;
1031 Mapping : Maps.Character_Mapping_Function) return Natural
1034 (if Super_Length (Source) /= 0 then From <= Super_Length (Source))
1035 and then Pattern'Length /= 0
1036 and then Mapping /= null,
1037 Post => Super_Index'Result <= Super_Length (Source),
1040 -- If Source is the empty string, then 0 is returned
1042 (Super_Length (Source) = 0
1044 Super_Index'Result = 0,
1046 -- If some slice of Source matches Pattern, then a valid index is
1049 Super_Length (Source) > 0
1052 (if Going = Forward then From else 1)
1053 .. (if Going = Forward then Super_Length (Source) else From)
1054 - (Pattern'Length - 1) =>
1055 Search.Match (Super_To_String (Source), Pattern, Mapping, J))
1057 -- The result is in the considered range of Source
1059 Super_Index'Result in
1060 (if Going = Forward then From else 1)
1061 .. (if Going = Forward then Super_Length (Source) else From)
1062 - (Pattern'Length - 1)
1064 -- The slice beginning at the returned index matches Pattern
1066 and then Search.Match
1067 (Super_To_String (Source), Pattern, Mapping, Super_Index'Result)
1069 -- The result is the smallest or largest index which satisfies
1070 -- the matching, respectively when Going = Forward and Going =
1074 (for all J in 1 .. Super_Length (Source) =>
1075 (if (if Going = Forward
1076 then J in From .. Super_Index'Result - 1
1077 else J - 1 in Super_Index'Result
1078 .. From - Pattern'Length)
1079 then not (Search.Match
1080 (Super_To_String (Source), Pattern, Mapping, J)))),
1082 -- Otherwise, 0 is returned
1086 Super_Index'Result = 0),
1089 function Super_Index
1090 (Source : Super_String;
1091 Set : Maps.Character_Set;
1093 Test : Membership := Inside;
1094 Going : Direction := Forward) return Natural
1097 (if Super_Length (Source) /= 0 then From <= Super_Length (Source)),
1098 Post => Super_Index'Result <= Super_Length (Source),
1101 -- If Source is the empty string, or no character of the considered
1102 -- slice of Source satisfies the property Test on Set, then 0 is
1105 (Super_Length (Source) = 0
1107 (for all J in 1 .. Super_Length (Source) =>
1108 (if J = From or else (J > From) = (Going = Forward) then
1110 Maps.Is_In (Super_Element (Source, J), Set)))
1112 Super_Index'Result = 0,
1114 -- Otherwise, an index in the considered range of Source is returned
1118 -- The result is in the considered range of Source
1120 Super_Index'Result in 1 .. Super_Length (Source)
1122 (Super_Index'Result = From
1123 or else (Super_Index'Result > From) = (Going = Forward))
1125 -- The character at the returned index satisfies the property
1130 Maps.Is_In (Super_Element (Source, Super_Index'Result), Set)
1132 -- The result is the smallest or largest index which satisfies
1133 -- the property, respectively when Going = Forward and Going =
1137 (for all J in 1 .. Super_Length (Source) =>
1138 (if J /= Super_Index'Result
1139 and then (J < Super_Index'Result) = (Going = Forward)
1141 or else (J > From) = (Going = Forward))
1142 then (Test = Inside)
1143 /= Maps.Is_In (Super_Element (Source, J), Set)))),
1146 function Super_Index_Non_Blank
1147 (Source : Super_String;
1148 Going : Direction := Forward) return Natural
1150 Post => Super_Index_Non_Blank'Result <= Super_Length (Source),
1153 -- If all characters of Source are Space characters, then 0 is
1156 ((for all C of Super_To_String (Source) => C = ' ')
1158 Super_Index_Non_Blank'Result = 0,
1160 -- Otherwise, an index in the range of Source is returned
1164 -- The result is in the range of Source
1166 Super_Index_Non_Blank'Result in 1 .. Super_Length (Source)
1168 -- The character at the returned index is not a Space character
1171 Super_Element (Source, Super_Index_Non_Blank'Result) /= ' '
1173 -- The result is the smallest or largest index which is not a
1174 -- Space character, respectively when Going = Forward and Going
1178 (for all J in 1 .. Super_Length (Source) =>
1179 (if J /= Super_Index_Non_Blank'Result
1181 (J < Super_Index_Non_Blank'Result) = (Going = Forward)
1182 then Super_Element (Source, J) = ' '))),
1185 function Super_Index_Non_Blank
1186 (Source : Super_String;
1188 Going : Direction := Forward) return Natural
1191 (if Super_Length (Source) /= 0 then From <= Super_Length (Source)),
1192 Post => Super_Index_Non_Blank'Result <= Super_Length (Source),
1195 -- If Source is the empty string, or all characters of the
1196 -- considered slice of Source are Space characters, then 0
1199 (Super_Length (Source) = 0
1201 (for all J in 1 .. Super_Length (Source) =>
1202 (if J = From or else (J > From) = (Going = Forward) then
1203 Super_Element (Source, J) = ' '))
1205 Super_Index_Non_Blank'Result = 0,
1207 -- Otherwise, an index in the considered range of Source is returned
1211 -- The result is in the considered range of Source
1213 Super_Index_Non_Blank'Result in 1 .. Super_Length (Source)
1215 (Super_Index_Non_Blank'Result = From
1217 (Super_Index_Non_Blank'Result > From) = (Going = Forward))
1219 -- The character at the returned index is not a Space character
1222 Super_Element (Source, Super_Index_Non_Blank'Result) /= ' '
1224 -- The result is the smallest or largest index which isn't a
1225 -- Space character, respectively when Going = Forward and Going
1229 (for all J in 1 .. Super_Length (Source) =>
1230 (if J /= Super_Index_Non_Blank'Result
1232 (J < Super_Index_Non_Blank'Result) = (Going = Forward)
1234 or else (J > From) = (Going = Forward))
1235 then Super_Element (Source, J) = ' '))),
1238 function Super_Count
1239 (Source : Super_String;
1241 Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
1243 Pre => Pattern'Length /= 0,
1246 function Super_Count
1247 (Source : Super_String;
1249 Mapping : Maps.Character_Mapping_Function) return Natural
1251 Pre => Pattern'Length /= 0 and then Mapping /= null,
1254 function Super_Count
1255 (Source : Super_String;
1256 Set : Maps.Character_Set) return Natural
1260 procedure Super_Find_Token
1261 (Source : Super_String;
1262 Set : Maps.Character_Set;
1265 First : out Positive;
1269 (if Super_Length (Source) /= 0 then From <= Super_Length (Source)),
1272 -- If Source is the empty string, or if no character of the
1273 -- considered slice of Source satisfies the property Test on
1274 -- Set, then First is set to From and Last is set to 0.
1276 (Super_Length (Source) = 0
1278 (for all J in From .. Super_Length (Source) =>
1279 (Test = Inside) /= Maps.Is_In (Super_Element (Source, J), Set))
1281 First = From and then Last = 0,
1283 -- Otherwise, First and Last are set to valid indexes
1287 -- First and Last are in the considered range of Source
1289 First in From .. Super_Length (Source)
1290 and then Last in First .. Super_Length (Source)
1292 -- No character between From and First satisfies the property
1296 (for all J in From .. First - 1 =>
1298 Maps.Is_In (Super_Element (Source, J), Set))
1300 -- All characters between First and Last satisfy the property
1304 (for all J in First .. Last =>
1306 Maps.Is_In (Super_Element (Source, J), Set))
1308 -- If Last is not Source'Last, then the character at position
1309 -- Last + 1 does not satify the property Test on Set.
1312 (if Last < Super_Length (Source)
1315 Maps.Is_In (Super_Element (Source, Last + 1), Set))),
1318 procedure Super_Find_Token
1319 (Source : Super_String;
1320 Set : Maps.Character_Set;
1322 First : out Positive;
1327 -- If Source is the empty string, or if no character of the considered
1328 -- slice of Source satisfies the property Test on Set, then First is
1329 -- set to 1 and Last is set to 0.
1331 (Super_Length (Source) = 0
1333 (for all J in 1 .. Super_Length (Source) =>
1334 (Test = Inside) /= Maps.Is_In (Super_Element (Source, J), Set))
1336 First = 1 and then Last = 0,
1338 -- Otherwise, First and Last are set to valid indexes
1342 -- First and Last are in the considered range of Source
1344 First in 1 .. Super_Length (Source)
1345 and then Last in First .. Super_Length (Source)
1347 -- No character between 1 and First satisfies the property Test on
1351 (for all J in 1 .. First - 1 =>
1353 Maps.Is_In (Super_Element (Source, J), Set))
1355 -- All characters between First and Last satisfy the property
1359 (for all J in First .. Last =>
1361 Maps.Is_In (Super_Element (Source, J), Set))
1363 -- If Last is not Source'Last, then the character at position
1364 -- Last + 1 does not satify the property Test on Set.
1367 (if Last < Super_Length (Source)
1370 Maps.Is_In (Super_Element (Source, Last + 1), Set))),
1373 ------------------------------------
1374 -- String Translation Subprograms --
1375 ------------------------------------
1377 function Super_Translate
1378 (Source : Super_String;
1379 Mapping : Maps.Character_Mapping) return Super_String
1381 Post => Super_Translate'Result.Max_Length = Source.Max_Length
1382 and then Super_Length (Super_Translate'Result) = Super_Length (Source)
1384 (for all K in 1 .. Super_Length (Source) =>
1385 Super_Element (Super_Translate'Result, K) =
1386 Ada.Strings.Maps.Value (Mapping, Super_Element (Source, K))),
1389 procedure Super_Translate
1390 (Source : in out Super_String;
1391 Mapping : Maps.Character_Mapping)
1393 Post => Super_Length (Source) = Super_Length (Source'Old)
1395 (for all K in 1 .. Super_Length (Source) =>
1396 Super_Element (Source, K) =
1397 Ada.Strings.Maps.Value (Mapping, Super_Element (Source'Old, K))),
1400 function Super_Translate
1401 (Source : Super_String;
1402 Mapping : Maps.Character_Mapping_Function) return Super_String
1404 Pre => Mapping /= null,
1405 Post => Super_Translate'Result.Max_Length = Source.Max_Length
1406 and then Super_Length (Super_Translate'Result) = Super_Length (Source)
1408 (for all K in 1 .. Super_Length (Source) =>
1409 Super_Element (Super_Translate'Result, K) =
1410 Mapping (Super_Element (Source, K))),
1412 pragma Annotate (GNATprove, False_Positive,
1413 "call via access-to-subprogram",
1414 "function Mapping must always terminate");
1416 procedure Super_Translate
1417 (Source : in out Super_String;
1418 Mapping : Maps.Character_Mapping_Function)
1420 Pre => Mapping /= null,
1421 Post => Super_Length (Source) = Super_Length (Source'Old)
1423 (for all K in 1 .. Super_Length (Source) =>
1424 Super_Element (Source, K) =
1425 Mapping (Super_Element (Source'Old, K))),
1427 pragma Annotate (GNATprove, False_Positive,
1428 "call via access-to-subprogram",
1429 "function Mapping must always terminate");
1431 ---------------------------------------
1432 -- String Transformation Subprograms --
1433 ---------------------------------------
1435 function Super_Replace_Slice
1436 (Source : Super_String;
1440 Drop : Truncation := Error) return Super_String
1443 Low - 1 <= Super_Length (Source)
1446 then (if High >= Low
1448 <= Source.Max_Length - By'Length
1449 - Integer'Max (Super_Length (Source) - High, 0)
1450 else Super_Length (Source) <=
1451 Source.Max_Length - By'Length)),
1453 Super_Replace_Slice'Result.Max_Length = Source.Max_Length,
1455 (Low - 1 <= Source.Max_Length - By'Length - Integer'Max
1456 (Super_Length (Source) - Integer'Max (High, Low - 1), 0)
1458 -- Total length is lower than Max_Length: nothing is dropped
1460 -- Note that if High < Low, the insertion is done before Low, so in
1461 -- all cases the starting position of the slice of Source remaining
1462 -- after the replaced Slice is Integer'Max (High + 1, Low).
1464 Super_Length (Super_Replace_Slice'Result) =
1465 Low - 1 + By'Length + Integer'Max
1466 (Super_Length (Source) - Integer'Max (High, Low - 1), 0)
1468 String'(Super_Slice
(Super_Replace_Slice
'Result, 1, Low
- 1)) =
1469 Super_Slice
(Source
, 1, Low
- 1)
1471 Super_Slice
(Super_Replace_Slice
'Result,
1472 Low
, Low
- 1 + By
'Length) = By
1474 (if Integer'Max (High
, Low
- 1) < Super_Length
(Source
) then
1475 String'(Super_Slice (Super_Replace_Slice'Result,
1477 Super_Length (Super_Replace_Slice'Result))) =
1478 Super_Slice (Source,
1479 Integer'Max (High + 1, Low), Super_Length (Source))),
1481 Low - 1 > Source.Max_Length - By'Length - Integer'Max
1482 (Super_Length (Source) - Integer'Max (High, Low - 1), 0)
1483 and then Drop = Left
1485 -- Final_Super_Slice is the length of the slice of Source remaining
1486 -- after the replaced part.
1488 Final_Super_Slice : constant Natural :=
1490 (Super_Length (Source) - Integer'Max (High, Low - 1), 0);
1492 -- The result is of maximal length and ends by the last
1493 -- Final_Super_Slice characters of Source.
1495 Super_Length (Super_Replace_Slice'Result) = Source.Max_Length
1497 (if Final_Super_Slice > 0 then
1498 String'(Super_Slice
(Super_Replace_Slice
'Result,
1499 Source
.Max_Length
- Final_Super_Slice
+ 1,
1500 Source
.Max_Length
)) =
1501 Super_Slice
(Source
,
1502 Integer'Max (High
+ 1, Low
), Super_Length
(Source
)))
1504 -- Depending on when we reach Max_Length, either the first
1505 -- part of Source is fully dropped and By is partly dropped,
1506 -- or By is fully added and the first part of Source is partly
1510 (if Source
.Max_Length
- Final_Super_Slice
- By
'Length <= 0 then
1512 -- The first (possibly zero) characters of By are dropped
1514 (if Final_Super_Slice
< Source
.Max_Length
then
1515 Super_Slice
(Super_Replace_Slice
'Result,
1516 1, Source
.Max_Length
- Final_Super_Slice
) =
1517 By
(By
'Last - Source
.Max_Length
+ Final_Super_Slice
1521 else -- By is added to the result
1523 Super_Slice
(Super_Replace_Slice
'Result,
1524 Source
.Max_Length
- Final_Super_Slice
- By
'Length + 1,
1525 Source
.Max_Length
- Final_Super_Slice
) =
1528 -- The first characters of Source (1 .. Low - 1) are
1532 String'(Super_Slice (Super_Replace_Slice'Result, 1,
1533 Source.Max_Length - Final_Super_Slice - By'Length)) =
1534 Super_Slice (Source,
1535 Low - Source.Max_Length
1536 + Final_Super_Slice + By'Length,
1539 others -- Drop = Right
1541 -- The result is of maximal length and starts by the first Low - 1
1542 -- characters of Source.
1544 Super_Length (Super_Replace_Slice'Result) = Source.Max_Length
1546 String'(Super_Slice
(Super_Replace_Slice
'Result, 1, Low
- 1)) =
1547 Super_Slice
(Source
, 1, Low
- 1)
1549 -- Depending on when we reach Max_Length, either the last part
1550 -- of Source is fully dropped and By is partly dropped, or By
1551 -- is fully added and the last part of Source is partly dropped.
1554 (if Low
- 1 >= Source
.Max_Length
- By
'Length then
1556 -- The last characters of By are dropped
1558 Super_Slice
(Super_Replace_Slice
'Result,
1559 Low
, Source
.Max_Length
) =
1560 By
(By
'First .. Source
.Max_Length
- Low
+ By
'First)
1562 else -- By is fully added
1564 Super_Slice
(Super_Replace_Slice
'Result,
1565 Low
, Low
+ By
'Length - 1) = By
1567 -- Then Source starting from Natural'Max (High + 1, Low)
1568 -- is added but the last characters are dropped.
1571 String'(Super_Slice (Super_Replace_Slice'Result,
1572 Low + By'Length, Source.Max_Length)) =
1573 Super_Slice (Source, Integer'Max (High + 1, Low),
1574 Integer'Max (High + 1, Low) +
1575 (Source.Max_Length - Low - By'Length)))),
1578 procedure Super_Replace_Slice
1579 (Source : in out Super_String;
1583 Drop : Truncation := Error)
1586 Low - 1 <= Super_Length (Source)
1589 then (if High >= Low
1591 <= Source.Max_Length - By'Length
1592 - Natural'Max (Super_Length (Source) - High, 0)
1593 else Super_Length (Source) <=
1594 Source.Max_Length - By'Length)),
1596 (Low - 1 <= Source.Max_Length - By'Length - Integer'Max
1597 (Super_Length (Source) - Integer'Max (High, Low - 1), 0)
1599 -- Total length is lower than Max_Length: nothing is dropped
1601 -- Note that if High < Low, the insertion is done before Low, so in
1602 -- all cases the starting position of the slice of Source remaining
1603 -- after the replaced Slice is Integer'Max (High + 1, Low).
1605 Super_Length (Source) = Low - 1 + By'Length + Integer'Max
1606 (Super_Length (Source'Old) - Integer'Max (High, Low - 1), 0)
1608 String'(Super_Slice
(Source
, 1, Low
- 1)) =
1609 Super_Slice
(Source
'Old, 1, Low
- 1)
1610 and then Super_Slice
(Source
, Low
, Low
- 1 + By
'Length) = By
1612 (if Integer'Max (High
, Low
- 1) < Super_Length
(Source
'Old) then
1613 String'(Super_Slice (Source,
1614 Low + By'Length, Super_Length (Source))) =
1615 Super_Slice (Source'Old,
1616 Integer'Max (High + 1, Low),
1617 Super_Length (Source'Old))),
1619 Low - 1 > Source.Max_Length - By'Length - Integer'Max
1620 (Super_Length (Source) - Integer'Max (High, Low - 1), 0)
1621 and then Drop = Left
1623 -- Final_Super_Slice is the length of the slice of Source remaining
1624 -- after the replaced part.
1626 Final_Super_Slice : constant Natural :=
1628 Super_Length (Source'Old) - Integer'Max (High, Low - 1));
1630 -- The result is of maximal length and ends by the last
1631 -- Final_Super_Slice characters of Source.
1633 Super_Length (Source) = Source.Max_Length
1635 (if Final_Super_Slice > 0 then
1636 String'(Super_Slice
(Source
,
1637 Source
.Max_Length
- Final_Super_Slice
+ 1,
1638 Source
.Max_Length
)) =
1639 Super_Slice
(Source
'Old,
1640 Integer'Max (High
+ 1, Low
),
1641 Super_Length
(Source
'Old)))
1643 -- Depending on when we reach Max_Length, either the first
1644 -- part of Source is fully dropped and By is partly dropped,
1645 -- or By is fully added and the first part of Source is partly
1649 (if Source
.Max_Length
- Final_Super_Slice
- By
'Length <= 0
1651 -- The first characters of By are dropped
1653 (if Final_Super_Slice
< Source
.Max_Length
then
1654 Super_Slice
(Source
,
1655 1, Source
.Max_Length
- Final_Super_Slice
) =
1656 By
(By
'Last - Source
.Max_Length
+ Final_Super_Slice
1660 else -- By is added to the result
1662 Super_Slice
(Source
,
1663 Source
.Max_Length
- Final_Super_Slice
- By
'Length + 1,
1664 Source
.Max_Length
- Final_Super_Slice
) = By
1666 -- The first characters of Source (1 .. Low - 1) are
1670 String'(Super_Slice (Source, 1,
1671 Source.Max_Length - Final_Super_Slice - By'Length)) =
1672 Super_Slice (Source'Old,
1673 Low - Source.Max_Length + Final_Super_Slice
1677 others -- Drop = Right
1679 -- The result is of maximal length and starts by the first Low - 1
1680 -- characters of Source.
1682 Super_Length (Source) = Source.Max_Length
1684 String'(Super_Slice
(Source
, 1, Low
- 1)) =
1685 Super_Slice
(Source
'Old, 1, Low
- 1)
1687 -- Depending on when we reach Max_Length, either the last part
1688 -- of Source is fully dropped and By is partly dropped, or By
1689 -- is fully added and the last part of Source is partly dropped.
1692 (if Low
- 1 >= Source
.Max_Length
- By
'Length then
1694 -- The last characters of By are dropped
1696 Super_Slice
(Source
, Low
, Source
.Max_Length
) =
1697 By
(By
'First .. Source
.Max_Length
- Low
+ By
'First)
1699 else -- By is fully added
1701 Super_Slice
(Source
, Low
, Low
+ By
'Length - 1) = By
1703 -- Then Source starting from Natural'Max (High + 1, Low)
1704 -- is added but the last characters are dropped.
1707 String'(Super_Slice (Source,
1708 Low + By'Length, Source.Max_Length)) =
1709 Super_Slice (Source'Old, Integer'Max (High + 1, Low),
1710 Integer'Max (High + 1, Low) +
1711 (Source.Max_Length - Low - By'Length)))),
1714 function Super_Insert
1715 (Source : Super_String;
1718 Drop : Truncation := Error) return Super_String
1721 Before - 1 <= Super_Length (Source)
1723 (if New_Item'Length > Source.Max_Length - Super_Length (Source)
1724 then Drop /= Error),
1725 Post => Super_Insert'Result.Max_Length = Source.Max_Length,
1727 (Super_Length (Source) <= Source.Max_Length - New_Item'Length
1729 -- Total length is lower than Max_Length: nothing is dropped
1731 Super_Length (Super_Insert'Result) =
1732 Super_Length (Source) + New_Item'Length
1734 String'(Super_Slice
(Super_Insert
'Result, 1, Before
- 1)) =
1735 Super_Slice
(Source
, 1, Before
- 1)
1737 Super_Slice
(Super_Insert
'Result,
1738 Before
, Before
- 1 + New_Item
'Length) =
1741 (if Before
<= Super_Length
(Source
) then
1742 String'(Super_Slice (Super_Insert'Result,
1743 Before + New_Item'Length,
1744 Super_Length (Super_Insert'Result))) =
1745 Super_Slice (Source, Before, Super_Length (Source))),
1747 Super_Length (Source) > Source.Max_Length - New_Item'Length
1748 and then Drop = Left
1750 -- The result is of maximal length and ends by the last characters
1753 Super_Length (Super_Insert'Result) = Source.Max_Length
1755 (if Before <= Super_Length (Source) then
1756 String'(Super_Slice
(Super_Insert
'Result,
1757 Source
.Max_Length
- Super_Length
(Source
) + Before
,
1758 Source
.Max_Length
)) =
1759 Super_Slice
(Source
, Before
, Super_Length
(Source
)))
1761 -- Depending on when we reach Max_Length, either the first part
1762 -- of Source is fully dropped and New_Item is partly dropped, or
1763 -- New_Item is fully added and the first part of Source is partly
1767 (if Source
.Max_Length
- Super_Length
(Source
) - 1 + Before
1770 -- The first characters of New_Item are dropped
1772 (if Super_Length
(Source
) - Before
+ 1 < Source
.Max_Length
1774 Super_Slice
(Super_Insert
'Result, 1,
1775 Source
.Max_Length
- Super_Length
(Source
) - 1 + Before
) =
1777 (New_Item
'Last - Source
.Max_Length
1778 + Super_Length
(Source
) - Before
+ 2
1781 else -- New_Item is added to the result
1783 Super_Slice
(Super_Insert
'Result,
1784 Source
.Max_Length
- Super_Length
(Source
) - New_Item
'Length
1786 Source
.Max_Length
- Super_Length
(Source
) - 1 + Before
) =
1789 -- The first characters of Source (1 .. Before - 1) are
1793 String'(Super_Slice (Super_Insert'Result,
1794 1, Source.Max_Length - Super_Length (Source)
1795 - New_Item'Length - 1 + Before)) =
1796 Super_Slice (Source,
1797 Super_Length (Source) - Source.Max_Length
1798 + New_Item'Length + 1,
1801 others -- Drop = Right
1803 -- The result is of maximal length and starts by the first
1804 -- characters of Source.
1806 Super_Length (Super_Insert'Result) = Source.Max_Length
1808 String'(Super_Slice
(Super_Insert
'Result, 1, Before
- 1)) =
1809 Super_Slice
(Source
, 1, Before
- 1)
1811 -- Depending on when we reach Max_Length, either the last part
1812 -- of Source is fully dropped and New_Item is partly dropped, or
1813 -- New_Item is fully added and the last part of Source is partly
1817 (if Before
- 1 >= Source
.Max_Length
- New_Item
'Length then
1819 -- The last characters of New_Item are dropped
1821 Super_Slice
(Super_Insert
'Result, Before
, Source
.Max_Length
) =
1822 New_Item
(New_Item
'First
1823 .. Source
.Max_Length
- Before
+ New_Item
'First)
1825 else -- New_Item is fully added
1827 Super_Slice
(Super_Insert
'Result,
1828 Before
, Before
+ New_Item
'Length - 1) =
1831 -- Then Source starting from Before is added but the
1832 -- last characters are dropped.
1835 String'(Super_Slice (Super_Insert'Result,
1836 Before + New_Item'Length, Source.Max_Length)) =
1837 Super_Slice (Source,
1838 Before, Source.Max_Length - New_Item'Length))),
1841 procedure Super_Insert
1842 (Source : in out Super_String;
1845 Drop : Truncation := Error)
1848 Before - 1 <= Super_Length (Source)
1850 (if New_Item'Length > Source.Max_Length - Super_Length (Source)
1851 then Drop /= Error),
1853 (Super_Length (Source) <= Source.Max_Length - New_Item'Length
1855 -- Total length is lower than Max_Length: nothing is dropped
1857 Super_Length (Source) = Super_Length (Source'Old) + New_Item'Length
1859 String'(Super_Slice
(Source
, 1, Before
- 1)) =
1860 Super_Slice
(Source
'Old, 1, Before
- 1)
1862 Super_Slice
(Source
, Before
, Before
- 1 + New_Item
'Length) =
1865 (if Before
<= Super_Length
(Source
'Old) then
1866 String'(Super_Slice (Source,
1867 Before + New_Item'Length, Super_Length (Source))) =
1868 Super_Slice (Source'Old,
1869 Before, Super_Length (Source'Old))),
1871 Super_Length (Source) > Source.Max_Length - New_Item'Length
1872 and then Drop = Left
1874 -- The result is of maximal length and ends by the last characters
1877 Super_Length (Source) = Source.Max_Length
1879 (if Before <= Super_Length (Source'Old) then
1880 String'(Super_Slice
(Source
,
1881 Source
.Max_Length
- Super_Length
(Source
'Old) + Before
,
1882 Source
.Max_Length
)) =
1883 Super_Slice
(Source
'Old,
1884 Before
, Super_Length
(Source
'Old)))
1886 -- Depending on when we reach Max_Length, either the first part
1887 -- of Source is fully dropped and New_Item is partly dropped, or
1888 -- New_Item is fully added and the first part of Source is partly
1892 (if Source
.Max_Length
- Super_Length
(Source
'Old) - 1 + Before
1895 -- The first characters of New_Item are dropped
1897 (if Super_Length
(Source
'Old) - Before
+ 1 < Source
.Max_Length
1899 Super_Slice
(Source
,
1900 1, Source
.Max_Length
- Super_Length
(Source
'Old)
1903 (New_Item
'Last - Source
.Max_Length
1904 + Super_Length
(Source
'Old) - Before
+ 2
1907 else -- New_Item is added to the result
1909 Super_Slice
(Source
,
1910 Source
.Max_Length
- Super_Length
(Source
'Old)
1911 - New_Item
'Length + Before
,
1912 Source
.Max_Length
- Super_Length
(Source
'Old) - 1 + Before
)
1915 -- The first characters of Source (1 .. Before - 1) are
1919 String'(Super_Slice (Source, 1,
1920 Source.Max_Length - Super_Length (Source'Old)
1921 - New_Item'Length - 1 + Before)) =
1922 Super_Slice (Source'Old,
1923 Super_Length (Source'Old)
1924 - Source.Max_Length + New_Item'Length + 1,
1927 others -- Drop = Right
1929 -- The result is of maximal length and starts by the first
1930 -- characters of Source.
1932 Super_Length (Source) = Source.Max_Length
1934 String'(Super_Slice
(Source
, 1, Before
- 1)) =
1935 Super_Slice
(Source
'Old, 1, Before
- 1)
1937 -- Depending on when we reach Max_Length, either the last part
1938 -- of Source is fully dropped and New_Item is partly dropped, or
1939 -- New_Item is fully added and the last part of Source is partly
1943 (if Before
- 1 >= Source
.Max_Length
- New_Item
'Length then
1945 -- The last characters of New_Item are dropped
1947 Super_Slice
(Source
, Before
, Source
.Max_Length
) =
1948 New_Item
(New_Item
'First
1949 .. Source
.Max_Length
- Before
+ New_Item
'First)
1951 else -- New_Item is fully added
1953 Super_Slice
(Source
, Before
, Before
+ New_Item
'Length - 1) =
1956 -- Then Source starting from Before is added but the
1957 -- last characters are dropped.
1960 String'(Super_Slice (Source,
1961 Before + New_Item'Length, Source.Max_Length)) =
1962 Super_Slice (Source'Old,
1963 Before, Source.Max_Length - New_Item'Length))),
1966 function Super_Overwrite
1967 (Source : Super_String;
1968 Position : Positive;
1970 Drop : Truncation := Error) return Super_String
1973 Position - 1 <= Super_Length (Source)
1974 and then (if New_Item'Length > Source.Max_Length - (Position - 1)
1975 then Drop /= Error),
1976 Post => Super_Overwrite'Result.Max_Length = Source.Max_Length,
1978 (Position - 1 <= Source.Max_Length - New_Item'Length
1980 -- The length is unchanged, unless New_Item overwrites further than
1981 -- the end of Source. In this contract case, we suppose New_Item
1982 -- doesn't overwrite further than Max_Length.
1984 Super_Length (Super_Overwrite'Result) =
1985 Integer'Max (Super_Length (Source), Position - 1 + New_Item'Length)
1987 String'(Super_Slice
(Super_Overwrite
'Result, 1, Position
- 1)) =
1988 Super_Slice
(Source
, 1, Position
- 1)
1989 and then Super_Slice
(Super_Overwrite
'Result,
1990 Position
, Position
- 1 + New_Item
'Length) =
1993 (if Position
- 1 + New_Item
'Length < Super_Length
(Source
) then
1995 -- There are some unchanged characters of Source remaining
1998 String'(Super_Slice (Super_Overwrite'Result,
1999 Position + New_Item'Length, Super_Length (Source))) =
2000 Super_Slice (Source,
2001 Position + New_Item'Length, Super_Length (Source))),
2003 Position - 1 > Source.Max_Length - New_Item'Length and then Drop = Left
2005 Super_Length (Super_Overwrite'Result) = Source.Max_Length
2007 -- If a part of the result has to be dropped, it means New_Item is
2008 -- overwriting further than the end of Source. Thus the result is
2009 -- necessarily ending by New_Item. However, we don't know whether
2010 -- New_Item covers all Max_Length characters or some characters of
2011 -- Source are remaining at the left.
2014 (if New_Item'Length >= Source.Max_Length then
2016 -- New_Item covers all Max_Length characters
2018 Super_To_String (Super_Overwrite'Result) =
2020 (New_Item'Last - Source.Max_Length + 1 .. New_Item'Last)
2022 -- New_Item fully appears at the end
2024 Super_Slice (Super_Overwrite'Result,
2025 Source.Max_Length - New_Item'Length + 1,
2026 Source.Max_Length) =
2029 -- The left of Source is cut
2032 String'(Super_Slice
(Super_Overwrite
'Result,
2033 1, Source
.Max_Length
- New_Item
'Length)) =
2034 Super_Slice
(Source
,
2035 Position
- Source
.Max_Length
+ New_Item
'Length,
2038 others -- Drop = Right
2040 -- The result is of maximal length and starts by the first
2041 -- characters of Source.
2043 Super_Length
(Super_Overwrite
'Result) = Source
.Max_Length
2045 String'(Super_Slice (Super_Overwrite'Result, 1, Position - 1)) =
2046 Super_Slice (Source, 1, Position - 1)
2048 -- Then New_Item is written until Max_Length
2050 and then Super_Slice (Super_Overwrite'Result,
2051 Position, Source.Max_Length) =
2052 New_Item (New_Item'First
2053 .. Source.Max_Length - Position + New_Item'First)),
2056 procedure Super_Overwrite
2057 (Source : in out Super_String;
2058 Position : Positive;
2060 Drop : Truncation := Error)
2063 Position - 1 <= Super_Length (Source)
2064 and then (if New_Item'Length > Source.Max_Length - (Position - 1)
2065 then Drop /= Error),
2067 (Position - 1 <= Source.Max_Length - New_Item'Length
2069 -- The length is unchanged, unless New_Item overwrites further than
2070 -- the end of Source. In this contract case, we suppose New_Item
2071 -- doesn't overwrite further than Max_Length.
2073 Super_Length (Source) = Integer'Max
2074 (Super_Length (Source'Old), Position - 1 + New_Item'Length)
2076 String'(Super_Slice
(Source
, 1, Position
- 1)) =
2077 Super_Slice
(Source
'Old, 1, Position
- 1)
2078 and then Super_Slice
(Source
,
2079 Position
, Position
- 1 + New_Item
'Length) =
2082 (if Position
- 1 + New_Item
'Length < Super_Length
(Source
'Old)
2084 -- There are some unchanged characters of Source remaining
2087 String'(Super_Slice (Source,
2088 Position + New_Item'Length, Super_Length (Source'Old))) =
2089 Super_Slice (Source'Old,
2090 Position + New_Item'Length, Super_Length (Source'Old))),
2092 Position - 1 > Source.Max_Length - New_Item'Length and then Drop = Left
2094 Super_Length (Source) = Source.Max_Length
2096 -- If a part of the result has to be dropped, it means New_Item is
2097 -- overwriting further than the end of Source. Thus the result is
2098 -- necessarily ending by New_Item. However, we don't know whether
2099 -- New_Item covers all Max_Length characters or some characters of
2100 -- Source are remaining at the left.
2103 (if New_Item'Length >= Source.Max_Length then
2105 -- New_Item covers all Max_Length characters
2107 Super_To_String (Source) =
2109 (New_Item'Last - Source.Max_Length + 1 .. New_Item'Last)
2111 -- New_Item fully appears at the end
2113 Super_Slice (Source,
2114 Source.Max_Length - New_Item'Length + 1,
2115 Source.Max_Length) =
2118 -- The left of Source is cut
2121 String'(Super_Slice
(Source
,
2122 1, Source
.Max_Length
- New_Item
'Length)) =
2123 Super_Slice
(Source
'Old,
2124 Position
- Source
.Max_Length
+ New_Item
'Length,
2127 others -- Drop = Right
2129 -- The result is of maximal length and starts by the first
2130 -- characters of Source.
2132 Super_Length
(Source
) = Source
.Max_Length
2134 String'(Super_Slice (Source, 1, Position - 1)) =
2135 Super_Slice (Source'Old, 1, Position - 1)
2137 -- New_Item is written until Max_Length
2139 and then Super_Slice (Source, Position, Source.Max_Length) =
2140 New_Item (New_Item'First
2141 .. Source.Max_Length - Position + New_Item'First)),
2144 function Super_Delete
2145 (Source : Super_String;
2147 Through : Natural) return Super_String
2150 (if Through >= From then From - 1 <= Super_Length (Source)),
2151 Post => Super_Delete'Result.Max_Length = Source.Max_Length,
2154 Super_Length (Super_Delete'Result) =
2155 From - 1 + Natural'Max (Super_Length (Source) - Through, 0)
2157 String'(Super_Slice
(Super_Delete
'Result, 1, From
- 1)) =
2158 Super_Slice
(Source
, 1, From
- 1)
2160 (if Through
< Super_Length
(Source
) then
2161 String'(Super_Slice (Super_Delete'Result,
2162 From, Super_Length (Super_Delete'Result))) =
2163 Super_Slice (Source, Through + 1, Super_Length (Source))),
2165 Super_Delete'Result = Source),
2168 procedure Super_Delete
2169 (Source : in out Super_String;
2174 (if Through >= From then From - 1 <= Super_Length (Source)),
2177 Super_Length (Source) =
2178 From - 1 + Natural'Max (Super_Length (Source'Old) - Through, 0)
2180 String'(Super_Slice
(Source
, 1, From
- 1)) =
2181 Super_Slice
(Source
'Old, 1, From
- 1)
2183 (if Through
< Super_Length
(Source
) then
2184 String'(Super_Slice (Source, From, Super_Length (Source))) =
2185 Super_Slice (Source'Old,
2186 Through + 1, Super_Length (Source'Old))),
2188 Source = Source'Old),
2191 ---------------------------------
2192 -- String Selector Subprograms --
2193 ---------------------------------
2196 (Source : Super_String;
2197 Side : Trim_End) return Super_String
2199 Post => Super_Trim'Result.Max_Length = Source.Max_Length,
2202 -- If all characters in Source are Space, the returned string is empty
2204 ((for all C of Super_To_String (Source) => C = ' ')
2206 Super_Length (Super_Trim'Result) = 0,
2208 -- Otherwise, the returned string is a slice of Source
2213 Low : constant Positive :=
2214 (if Side = Right then 1
2215 else Super_Index_Non_Blank (Source, Forward));
2216 High : constant Positive :=
2217 (if Side = Left then Super_Length (Source)
2218 else Super_Index_Non_Blank (Source, Backward));
2220 Super_To_String (Super_Trim'Result) =
2221 Super_Slice (Source, Low, High))),
2224 procedure Super_Trim
2225 (Source : in out Super_String;
2230 -- If all characters in Source are Space, the returned string is empty
2232 ((for all C of Super_To_String (Source) => C = ' ')
2234 Super_Length (Source) = 0,
2236 -- Otherwise, the returned string is a slice of Source
2241 Low : constant Positive :=
2242 (if Side = Right then 1
2243 else Super_Index_Non_Blank (Source'Old, Forward));
2244 High : constant Positive :=
2245 (if Side = Left then Super_Length (Source'Old)
2246 else Super_Index_Non_Blank (Source'Old, Backward));
2248 Super_To_String (Source) = Super_Slice (Source'Old, Low, High))),
2252 (Source : Super_String;
2253 Left : Maps.Character_Set;
2254 Right : Maps.Character_Set) return Super_String
2256 Post => Super_Trim'Result.Max_Length = Source.Max_Length,
2259 -- If all characters in Source are contained in one of the sets Left or
2260 -- Right, then the returned string is empty.
2262 ((for all C of Super_To_String (Source) => Maps.Is_In (C, Left))
2264 (for all C of Super_To_String (Source) => Maps.Is_In (C, Right))
2266 Super_Length (Super_Trim'Result) = 0,
2268 -- Otherwise, the returned string is a slice of Source
2273 Low : constant Positive :=
2274 Super_Index (Source, Left, Outside, Forward);
2275 High : constant Positive :=
2276 Super_Index (Source, Right, Outside, Backward);
2278 Super_To_String (Super_Trim'Result) =
2279 Super_Slice (Source, Low, High))),
2282 procedure Super_Trim
2283 (Source : in out Super_String;
2284 Left : Maps.Character_Set;
2285 Right : Maps.Character_Set)
2289 -- If all characters in Source are contained in one of the sets Left or
2290 -- Right, then the returned string is empty.
2292 ((for all C of Super_To_String (Source) => Maps.Is_In (C, Left))
2294 (for all C of Super_To_String (Source) => Maps.Is_In (C, Right))
2296 Super_Length (Source) = 0,
2298 -- Otherwise, the returned string is a slice of Source
2303 Low : constant Positive :=
2304 Super_Index (Source'Old, Left, Outside, Forward);
2305 High : constant Positive :=
2306 Super_Index (Source'Old, Right, Outside, Backward);
2308 Super_To_String (Source) = Super_Slice (Source'Old, Low, High))),
2312 (Source : Super_String;
2314 Pad : Character := Space;
2315 Drop : Truncation := Error) return Super_String
2317 Pre => (if Count > Source.Max_Length then Drop /= Error),
2318 Post => Super_Head'Result.Max_Length = Source.Max_Length,
2320 (Count <= Super_Length (Source)
2324 Super_To_String (Super_Head'Result) = Super_Slice (Source, 1, Count),
2325 Count > Super_Length (Source) and then Count <= Source.Max_Length
2327 -- Source is followed by Pad characters
2329 Super_Length (Super_Head'Result) = Count
2331 Super_Slice (Super_Head'Result, 1, Super_Length (Source)) =
2332 Super_To_String (Source)
2334 String'(Super_Slice
(Super_Head
'Result,
2335 Super_Length
(Source
) + 1, Count
)) =
2336 [1 .. Count
- Super_Length
(Source
) => Pad
],
2337 Count
> Source
.Max_Length
and then Drop
= Right
2339 -- Source is followed by Pad characters
2341 Super_Length
(Super_Head
'Result) = Source
.Max_Length
2343 Super_Slice
(Super_Head
'Result, 1, Super_Length
(Source
)) =
2344 Super_To_String
(Source
)
2346 String'(Super_Slice (Super_Head'Result,
2347 Super_Length (Source) + 1, Source.Max_Length)) =
2348 [1 .. Source.Max_Length - Super_Length (Source) => Pad],
2349 Count - Super_Length (Source) > Source.Max_Length and then Drop = Left
2351 -- Source is fully dropped on the left
2353 Super_To_String (Super_Head'Result) =
2354 [1 .. Source.Max_Length => Pad],
2357 -- Source is partly dropped on the left
2359 Super_Length (Super_Head'Result) = Source.Max_Length
2361 String'(Super_Slice
(Super_Head
'Result,
2362 1, Source
.Max_Length
- Count
+ Super_Length
(Source
))) =
2363 Super_Slice
(Source
,
2364 Count
- Source
.Max_Length
+ 1, Super_Length
(Source
))
2366 String'(Super_Slice (Super_Head'Result,
2367 Source.Max_Length - Count + Super_Length (Source) + 1,
2368 Source.Max_Length)) =
2369 [1 .. Count - Super_Length (Source) => Pad]),
2372 procedure Super_Head
2373 (Source : in out Super_String;
2375 Pad : Character := Space;
2376 Drop : Truncation := Error)
2378 Pre => (if Count > Source.Max_Length then Drop /= Error),
2380 (Count <= Super_Length (Source)
2384 Super_To_String (Source) = Super_Slice (Source'Old, 1, Count),
2385 Count > Super_Length (Source) and then Count <= Source.Max_Length
2387 -- Source is followed by Pad characters
2389 Super_Length (Source) = Count
2391 Super_Slice (Source, 1, Super_Length (Source'Old)) =
2392 Super_To_String (Source'Old)
2394 String'(Super_Slice
(Source
,
2395 Super_Length
(Source
'Old) + 1, Count
)) =
2396 [1 .. Count
- Super_Length
(Source
'Old) => Pad
],
2397 Count
> Source
.Max_Length
and then Drop
= Right
2399 -- Source is followed by Pad characters
2401 Super_Length
(Source
) = Source
.Max_Length
2403 Super_Slice
(Source
, 1, Super_Length
(Source
'Old)) =
2404 Super_To_String
(Source
'Old)
2406 String'(Super_Slice (Source,
2407 Super_Length (Source'Old) + 1, Source.Max_Length)) =
2408 [1 .. Source.Max_Length - Super_Length (Source'Old) => Pad],
2409 Count - Super_Length (Source) > Source.Max_Length and then Drop = Left
2411 -- Source is fully dropped on the left
2413 Super_To_String (Source) = [1 .. Source.Max_Length => Pad],
2416 -- Source is partly dropped on the left
2418 Super_Length (Source) = Source.Max_Length
2420 String'(Super_Slice
(Source
,
2421 1, Source
.Max_Length
- Count
+ Super_Length
(Source
'Old))) =
2422 Super_Slice
(Source
'Old,
2423 Count
- Source
.Max_Length
+ 1, Super_Length
(Source
'Old))
2425 String'(Super_Slice (Source,
2426 Source.Max_Length - Count + Super_Length (Source'Old) + 1,
2427 Source.Max_Length)) =
2428 [1 .. Count - Super_Length (Source'Old) => Pad]),
2432 (Source : Super_String;
2434 Pad : Character := Space;
2435 Drop : Truncation := Error) return Super_String
2437 Pre => (if Count > Source.Max_Length then Drop /= Error),
2438 Post => Super_Tail'Result.Max_Length = Source.Max_Length,
2440 (Count < Super_Length (Source)
2445 Super_To_String (Super_Tail'Result) =
2446 Super_Slice (Source,
2447 Super_Length (Source) - Count + 1, Super_Length (Source))
2448 else Super_Length (Super_Tail'Result) = 0),
2449 Count >= Super_Length (Source) and then Count < Source.Max_Length
2451 -- Source is preceded by Pad characters
2453 Super_Length (Super_Tail'Result) = Count
2455 String'(Super_Slice
(Super_Tail
'Result,
2456 1, Count
- Super_Length
(Source
))) =
2457 [1 .. Count
- Super_Length
(Source
) => Pad
]
2459 Super_Slice
(Super_Tail
'Result,
2460 Count
- Super_Length
(Source
) + 1, Count
) =
2461 Super_To_String
(Source
),
2462 Count
>= Source
.Max_Length
and then Drop
= Left
2464 -- Source is preceded by Pad characters
2466 Super_Length
(Super_Tail
'Result) = Source
.Max_Length
2468 String'(Super_Slice (Super_Tail'Result,
2469 1, Source.Max_Length - Super_Length (Source))) =
2470 [1 .. Source.Max_Length - Super_Length (Source) => Pad]
2472 (if Super_Length (Source) > 0 then
2473 Super_Slice (Super_Tail'Result,
2474 Source.Max_Length - Super_Length (Source) + 1,
2475 Source.Max_Length) =
2476 Super_To_String (Source)),
2477 Count - Super_Length (Source) >= Source.Max_Length
2478 and then Drop /= Left
2480 -- Source is fully dropped on the right
2482 Super_To_String (Super_Tail'Result) =
2483 [1 .. Source.Max_Length => Pad],
2486 -- Source is partly dropped on the right
2488 Super_Length (Super_Tail'Result) = Source.Max_Length
2490 String'(Super_Slice
(Super_Tail
'Result,
2491 1, Count
- Super_Length
(Source
))) =
2492 [1 .. Count
- Super_Length
(Source
) => Pad
]
2494 String'(Super_Slice (Super_Tail'Result,
2495 Count - Super_Length (Source) + 1, Source.Max_Length)) =
2496 Super_Slice (Source,
2497 1, Source.Max_Length - Count + Super_Length (Source))),
2500 procedure Super_Tail
2501 (Source : in out Super_String;
2503 Pad : Character := Space;
2504 Drop : Truncation := Error)
2506 Pre => (if Count > Source.Max_Length then Drop /= Error),
2508 (Count < Super_Length (Source)
2513 Super_To_String (Source) =
2514 Super_Slice (Source'Old,
2515 Super_Length (Source'Old) - Count + 1,
2516 Super_Length (Source'Old))
2517 else Super_Length (Source) = 0),
2518 Count >= Super_Length (Source) and then Count < Source.Max_Length
2520 -- Source is preceded by Pad characters
2522 Super_Length (Source) = Count
2524 String'(Super_Slice
(Source
,
2525 1, Count
- Super_Length
(Source
'Old))) =
2526 [1 .. Count
- Super_Length
(Source
'Old) => Pad
]
2528 Super_Slice
(Source
,
2529 Count
- Super_Length
(Source
'Old) + 1, Count
) =
2530 Super_To_String
(Source
'Old),
2531 Count
>= Source
.Max_Length
and then Drop
= Left
2533 -- Source is preceded by Pad characters
2535 Super_Length
(Source
) = Source
.Max_Length
2537 String'(Super_Slice (Source,
2538 1, Source.Max_Length - Super_Length (Source'Old))) =
2539 [1 .. Source.Max_Length - Super_Length (Source'Old) => Pad]
2541 (if Super_Length (Source'Old) > 0 then
2542 Super_Slice (Source,
2543 Source.Max_Length - Super_Length (Source'Old) + 1,
2544 Source.Max_Length) =
2545 Super_To_String (Source'Old)),
2546 Count - Super_Length (Source) >= Source.Max_Length
2547 and then Drop /= Left
2549 -- Source is fully dropped on the right
2551 Super_To_String (Source) = [1 .. Source.Max_Length => Pad],
2554 -- Source is partly dropped on the right
2556 Super_Length (Source) = Source.Max_Length
2558 String'(Super_Slice
(Source
,
2559 1, Count
- Super_Length
(Source
'Old))) =
2560 [1 .. Count
- Super_Length
(Source
'Old) => Pad
]
2562 String'(Super_Slice (Source,
2563 Count - Super_Length (Source'Old) + 1, Source.Max_Length)) =
2564 Super_Slice (Source'Old,
2565 1, Source.Max_Length - Count + Super_Length (Source'Old))),
2568 ------------------------------------
2569 -- String Constructor Subprograms --
2570 ------------------------------------
2572 -- Note: in some of the following routines, there is an extra parameter
2573 -- Max_Length which specifies the value of the maximum length for the
2574 -- resulting Super_String value.
2579 Max_Length : Positive) return Super_String
2581 Pre => Left <= Max_Length,
2582 Post => Times'Result.Max_Length = Max_Length
2583 and then Super_To_String (Times'Result) = [1 .. Left => Right],
2585 -- Note the additional parameter Max_Length
2590 Max_Length : Positive) return Super_String
2592 Pre => (if Left /= 0 then Right'Length <= Max_Length / Left),
2593 Post => Times'Result.Max_Length = Max_Length
2594 and then Super_Length (Times'Result) = Left * Right'Length
2596 (if Right'Length > 0 then
2597 (for all K in 1 .. Left * Right'Length =>
2598 Super_Element (Times'Result, K) =
2599 Right (Right'First + (K - 1) mod Right'Length))),
2601 -- Note the additional parameter Max_Length
2605 Right : Super_String) return Super_String
2608 (if Left /= 0 then Super_Length (Right) <= Right.Max_Length / Left),
2609 Post => Times'Result.Max_Length = Right.Max_Length
2610 and then Super_Length (Times'Result) = Left * Super_Length (Right)
2612 (if Super_Length (Right) > 0 then
2613 (for all K in 1 .. Left * Super_Length (Right) =>
2614 Super_Element (Times'Result, K) =
2615 Super_Element (Right, 1 + (K - 1) mod Super_Length (Right)))),
2618 function Super_Replicate
2621 Drop : Truncation := Error;
2622 Max_Length : Positive) return Super_String
2624 Pre => (if Count > Max_Length then Drop /= Error),
2625 Post => Super_Replicate'Result.Max_Length = Max_Length
2626 and then Super_To_String (Super_Replicate'Result) =
2627 [1 .. Natural'Min (Max_Length, Count) => Item],
2629 -- Note the additional parameter Max_Length
2631 function Super_Replicate
2634 Drop : Truncation := Error;
2635 Max_Length : Positive) return Super_String
2638 (if Count /= 0 and then Item'Length > Max_Length / Count
2639 then Drop /= Error),
2640 Post => Super_Replicate'Result.Max_Length = Max_Length,
2642 (Count = 0 or else Item'Length <= Max_Length / Count
2644 Super_Length (Super_Replicate'Result) = Count * Item'Length
2646 (if Item'Length > 0 then
2647 (for all K in 1 .. Count * Item'Length =>
2648 Super_Element (Super_Replicate'Result, K) =
2649 Item (Item'First + (K - 1) mod Item'Length))),
2651 and then Item'Length > Max_Length / Count
2652 and then Drop = Right
2654 Super_Length (Super_Replicate'Result) = Max_Length
2656 (for all K in 1 .. Max_Length =>
2657 Super_Element (Super_Replicate'Result, K) =
2658 Item (Item'First + (K - 1) mod Item'Length)),
2659 others -- Drop = Left
2661 Super_Length (Super_Replicate'Result) = Max_Length
2663 (for all K in 1 .. Max_Length =>
2664 Super_Element (Super_Replicate'Result, K) =
2665 Item (Item'Last - (Max_Length - K) mod Item'Length))),
2667 -- Note the additional parameter Max_Length
2669 function Super_Replicate
2671 Item : Super_String;
2672 Drop : Truncation := Error) return Super_String
2676 and then Super_Length (Item) > Item.Max_Length / Count
2677 then Drop /= Error),
2678 Post => Super_Replicate'Result.Max_Length = Item.Max_Length,
2680 ((if Count /= 0 then Super_Length (Item) <= Item.Max_Length / Count)
2682 Super_Length (Super_Replicate'Result) = Count * Super_Length (Item)
2684 (if Super_Length (Item) > 0 then
2685 (for all K in 1 .. Count * Super_Length (Item) =>
2686 Super_Element (Super_Replicate'Result, K) =
2687 Super_Element (Item,
2688 1 + (K - 1) mod Super_Length (Item)))),
2690 and then Super_Length (Item) > Item.Max_Length / Count
2691 and then Drop = Right
2693 Super_Length (Super_Replicate'Result) = Item.Max_Length
2695 (for all K in 1 .. Item.Max_Length =>
2696 Super_Element (Super_Replicate'Result, K) =
2697 Super_Element (Item, 1 + (K - 1) mod Super_Length (Item))),
2698 others -- Drop = Left
2700 Super_Length (Super_Replicate'Result) = Item.Max_Length
2702 (for all K in 1 .. Item.Max_Length =>
2703 Super_Element (Super_Replicate'Result, K) =
2704 Super_Element (Item,
2706 - (Item.Max_Length - K) mod Super_Length (Item)))),
2710 (S : in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class;
2711 Source : Super_String);
2714 -- Pragma Inline declarations
2716 pragma Inline ("=");
2717 pragma Inline (Less);
2718 pragma Inline (Less_Or_Equal);
2719 pragma Inline (Greater);
2720 pragma Inline (Greater_Or_Equal);
2721 pragma Inline (Concat);
2722 pragma Inline (Super_Count);
2723 pragma Inline (Super_Element);
2724 pragma Inline (Super_Find_Token);
2725 pragma Inline (Super_Index);
2726 pragma Inline (Super_Index_Non_Blank);
2727 pragma Inline (Super_Length);
2728 pragma Inline (Super_Replace_Element);
2729 pragma Inline (Super_Slice);
2730 pragma Inline (Super_To_String);
2732 end Ada.Strings.Superbounded;