1------------------------------------------------------------------------------
2--                                                                          --
3--                         GNAT RUN-TIME COMPONENTS                         --
4--                                                                          --
5--                  A D A . S T R I N G S . B O U N D E D                   --
6--                                                                          --
7--                                 S p e c                                  --
8--                                                                          --
9--          Copyright (C) 1992-2019, Free Software Foundation, Inc.         --
10--                                                                          --
11-- This specification is derived from the Ada Reference Manual for use with --
12-- GNAT. The copyright notice above, and the license provisions that follow --
13-- apply solely to the  contents of the part following the private keyword. --
14--                                                                          --
15-- GNAT is free software;  you can  redistribute it  and/or modify it under --
16-- terms of the  GNU General Public License as published  by the Free Soft- --
17-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
18-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
19-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
20-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
21--                                                                          --
22-- As a special exception under Section 7 of GPL version 3, you are granted --
23-- additional permissions described in the GCC Runtime Library Exception,   --
24-- version 3.1, as published by the Free Software Foundation.               --
25--                                                                          --
26-- You should have received a copy of the GNU General Public License and    --
27-- a copy of the GCC Runtime Library Exception along with this program;     --
28-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
29-- <http://www.gnu.org/licenses/>.                                          --
30--                                                                          --
31-- GNAT was originally developed  by the GNAT team at  New York University. --
32-- Extensive contributions were provided by Ada Core Technologies Inc.      --
33--                                                                          --
34------------------------------------------------------------------------------
35
36--  Preconditions in this unit are meant for analysis only, not for run-time
37--  checking, so that the expected exceptions are raised. This is enforced by
38--  setting the corresponding assertion policy to Ignore.
39
40pragma Assertion_Policy (Pre => Ignore);
41
42with Ada.Strings.Maps;
43with Ada.Strings.Superbounded;
44
45package Ada.Strings.Bounded is
46   pragma Preelaborate;
47
48   generic
49      Max : Positive;
50      --  Maximum length of a Bounded_String
51
52   package Generic_Bounded_Length with
53     Initial_Condition => Length (Null_Bounded_String) = 0
54   is
55
56      Max_Length : constant Positive := Max;
57
58      type Bounded_String is private;
59      pragma Preelaborable_Initialization (Bounded_String);
60
61      Null_Bounded_String : constant Bounded_String;
62
63      subtype Length_Range is Natural range 0 .. Max_Length;
64
65      function Length (Source : Bounded_String) return Length_Range with
66        Global => null;
67
68      --------------------------------------------------------
69      -- Conversion, Concatenation, and Selection Functions --
70      --------------------------------------------------------
71
72      function To_Bounded_String
73        (Source : String;
74         Drop   : Truncation := Error) return Bounded_String
75      with
76        Pre    => (if Source'Length > Max_Length then Drop /= Error),
77        Post   =>
78          Length (To_Bounded_String'Result)
79        = Natural'Min (Max_Length, Source'Length),
80        Global => null;
81
82      function To_String (Source : Bounded_String) return String with
83        Post   => To_String'Result'Length = Length (Source),
84        Global => null;
85
86      procedure Set_Bounded_String
87        (Target : out Bounded_String;
88         Source : String;
89         Drop   : Truncation := Error)
90      with
91        Pre    => (if Source'Length > Max_Length then Drop /= Error),
92        Post   => Length (Target) = Natural'Min (Max_Length, Source'Length),
93        Global => null;
94      pragma Ada_05 (Set_Bounded_String);
95
96      function Append
97        (Left  : Bounded_String;
98         Right : Bounded_String;
99         Drop  : Truncation  := Error) return Bounded_String
100      with
101        Pre    =>
102          (if Length (Left) > Max_Length - Length (Right)
103           then Drop /= Error),
104        Post   =>
105          Length (Append'Result)
106        = Natural'Min (Max_Length, Length (Left) + Length (Right)),
107        Global => null;
108
109      function Append
110        (Left  : Bounded_String;
111         Right : String;
112         Drop  : Truncation := Error) return Bounded_String
113      with
114        Pre    =>
115          (if Right'Length > Max_Length - Length (Left)
116           then Drop /= Error),
117        Post   =>
118          Length (Append'Result)
119        = Natural'Min (Max_Length, Length (Left) + Right'Length),
120        Global => null;
121
122      function Append
123        (Left  : String;
124         Right : Bounded_String;
125         Drop  : Truncation := Error) return Bounded_String
126      with
127        Pre    =>
128          (if Left'Length > Max_Length - Length (Right)
129           then Drop /= Error),
130        Post   =>
131          Length (Append'Result)
132        = Natural'Min (Max_Length, Left'Length + Length (Right)),
133        Global => null;
134
135      function Append
136        (Left  : Bounded_String;
137         Right : Character;
138         Drop  : Truncation := Error) return Bounded_String
139      with
140        Pre    => (if Length (Left) = Max_Length then Drop /= Error),
141        Post   =>
142          Length (Append'Result)
143        = Natural'Min (Max_Length, Length (Left) + 1),
144        Global => null;
145
146      function Append
147        (Left  : Character;
148         Right : Bounded_String;
149         Drop  : Truncation := Error) return Bounded_String
150      with
151        Pre    => (if Length (Right) = Max_Length then Drop /= Error),
152        Post   =>
153          Length (Append'Result)
154        = Natural'Min (Max_Length, 1 + Length (Right)),
155        Global => null;
156
157      procedure Append
158        (Source   : in out Bounded_String;
159         New_Item : Bounded_String;
160         Drop     : Truncation  := Error)
161      with
162        Pre    =>
163          (if Length (Source) > Max_Length - Length (New_Item)
164           then Drop /= Error),
165        Post   =>
166          Length (Source)
167        = Natural'Min (Max_Length, Length (Source)'Old + Length (New_Item)),
168        Global => null;
169
170      procedure Append
171        (Source   : in out Bounded_String;
172         New_Item : String;
173         Drop     : Truncation  := Error)
174      with
175        Pre    =>
176          (if New_Item'Length > Max_Length - Length (Source)
177           then Drop /= Error),
178        Post   =>
179          Length (Source)
180        = Natural'Min (Max_Length, Length (Source)'Old + New_Item'Length),
181        Global => null;
182
183      procedure Append
184        (Source   : in out Bounded_String;
185         New_Item : Character;
186         Drop     : Truncation  := Error)
187      with
188        Pre    => (if Length (Source) = Max_Length then Drop /= Error),
189        Post   =>
190          Length (Source)
191        = Natural'Min (Max_Length, Length (Source)'Old + 1),
192        Global => null;
193
194      function "&"
195        (Left  : Bounded_String;
196         Right : Bounded_String) return Bounded_String
197      with
198        Pre    => Length (Left) <= Max_Length - Length (Right),
199        Post   => Length ("&"'Result) = Length (Left) + Length (Right),
200        Global => null;
201
202      function "&"
203        (Left  : Bounded_String;
204         Right : String) return Bounded_String
205      with
206        Pre    => Right'Length <= Max_Length - Length (Left),
207        Post   => Length ("&"'Result) = Length (Left) + Right'Length,
208        Global => null;
209
210      function "&"
211        (Left  : String;
212         Right : Bounded_String) return Bounded_String
213      with
214        Pre    => Left'Length <= Max_Length - Length (Right),
215        Post   => Length ("&"'Result) = Left'Length + Length (Right),
216        Global => null;
217
218      function "&"
219        (Left  : Bounded_String;
220         Right : Character) return Bounded_String
221      with
222        Pre    => Length (Left) < Max_Length,
223        Post   => Length ("&"'Result) = Length (Left) + 1,
224        Global => null;
225
226      function "&"
227        (Left  : Character;
228         Right : Bounded_String) return Bounded_String
229      with
230        Pre    => Length (Right) < Max_Length,
231        Post   => Length ("&"'Result) = 1 + Length (Right),
232        Global => null;
233
234      function Element
235        (Source : Bounded_String;
236         Index  : Positive) return Character
237      with
238        Pre    => Index <= Length (Source),
239        Global => null;
240
241      procedure Replace_Element
242        (Source : in out Bounded_String;
243         Index  : Positive;
244         By     : Character)
245      with
246        Pre    => Index <= Length (Source),
247        Post   => Length (Source) = Length (Source)'Old,
248        Global => null;
249
250      function Slice
251        (Source : Bounded_String;
252         Low    : Positive;
253         High   : Natural) return String
254      with
255        Pre    => Low - 1 <= Length (Source) and then High <= Length (Source),
256        Post   => Slice'Result'Length = Natural'Max (0, High - Low + 1),
257        Global => null;
258
259      function Bounded_Slice
260        (Source : Bounded_String;
261         Low    : Positive;
262         High   : Natural) return Bounded_String
263       with
264        Pre    => Low - 1 <= Length (Source) and then High <= Length (Source),
265        Post   =>
266          Length (Bounded_Slice'Result) = Natural'Max (0, High - Low + 1),
267        Global => null;
268      pragma Ada_05 (Bounded_Slice);
269
270      procedure Bounded_Slice
271        (Source : Bounded_String;
272         Target : out Bounded_String;
273         Low    : Positive;
274         High   : Natural)
275      with
276        Pre    => Low - 1 <= Length (Source) and then High <= Length (Source),
277        Post   => Length (Target) = Natural'Max (0, High - Low + 1),
278        Global => null;
279      pragma Ada_05 (Bounded_Slice);
280
281      function "="
282        (Left  : Bounded_String;
283         Right : Bounded_String) return Boolean
284      with
285        Global => null;
286
287      function "="
288        (Left  : Bounded_String;
289         Right : String) return Boolean
290      with
291        Global => null;
292
293      function "="
294        (Left  : String;
295         Right : Bounded_String) return Boolean
296      with
297        Global => null;
298
299      function "<"
300        (Left  : Bounded_String;
301         Right : Bounded_String) return Boolean
302      with
303        Global => null;
304
305      function "<"
306        (Left  : Bounded_String;
307         Right : String) return Boolean
308      with
309        Global => null;
310
311      function "<"
312        (Left  : String;
313         Right : Bounded_String) return Boolean
314      with
315        Global => null;
316
317      function "<="
318        (Left  : Bounded_String;
319         Right : Bounded_String) return Boolean
320      with
321        Global => null;
322
323      function "<="
324        (Left  : Bounded_String;
325         Right : String) return Boolean
326      with
327        Global => null;
328
329      function "<="
330        (Left  : String;
331         Right : Bounded_String) return Boolean
332      with
333        Global => null;
334
335      function ">"
336        (Left  : Bounded_String;
337         Right : Bounded_String) return Boolean
338      with
339        Global => null;
340
341      function ">"
342        (Left  : Bounded_String;
343         Right : String) return Boolean
344      with
345        Global => null;
346
347      function ">"
348        (Left  : String;
349         Right : Bounded_String) return Boolean
350      with
351        Global => null;
352
353      function ">="
354        (Left  : Bounded_String;
355         Right : Bounded_String) return Boolean
356      with
357        Global => null;
358
359      function ">="
360        (Left  : Bounded_String;
361         Right : String) return Boolean
362      with
363        Global => null;
364
365      function ">="
366        (Left  : String;
367         Right : Bounded_String) return Boolean
368      with
369        Global => null;
370
371      ----------------------
372      -- Search Functions --
373      ----------------------
374
375      function Index
376        (Source  : Bounded_String;
377         Pattern : String;
378         Going   : Direction := Forward;
379         Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
380      with
381        Pre    => Pattern'Length /= 0,
382        Global => null;
383
384      function Index
385        (Source  : Bounded_String;
386         Pattern : String;
387         Going   : Direction := Forward;
388         Mapping : Maps.Character_Mapping_Function) return Natural
389      with
390        Pre    => Pattern'Length /= 0,
391        Global => null;
392
393      function Index
394        (Source : Bounded_String;
395         Set    : Maps.Character_Set;
396         Test   : Membership := Inside;
397         Going  : Direction  := Forward) return Natural
398      with
399        Global => null;
400
401      function Index
402        (Source  : Bounded_String;
403         Pattern : String;
404         From    : Positive;
405         Going   : Direction := Forward;
406         Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
407      with
408        Pre    =>
409          (if Length (Source) /= 0
410           then From <= Length (Source))
411                  and then Pattern'Length /= 0,
412        Global => null;
413      pragma Ada_05 (Index);
414
415      function Index
416        (Source  : Bounded_String;
417         Pattern : String;
418         From    : Positive;
419         Going   : Direction := Forward;
420         Mapping : Maps.Character_Mapping_Function) return Natural
421      with
422        Pre    =>
423          (if Length (Source) /= 0
424           then From <= Length (Source))
425                  and then Pattern'Length /= 0,
426        Global => null;
427      pragma Ada_05 (Index);
428
429      function Index
430        (Source  : Bounded_String;
431         Set     : Maps.Character_Set;
432         From    : Positive;
433         Test    : Membership := Inside;
434         Going   : Direction := Forward) return Natural
435      with
436        Pre    => (if Length (Source) /= 0 then From <= Length (Source)),
437        Global => null;
438      pragma Ada_05 (Index);
439
440      function Index_Non_Blank
441        (Source : Bounded_String;
442         Going  : Direction := Forward) return Natural
443      with
444        Global => null;
445
446      function Index_Non_Blank
447        (Source : Bounded_String;
448         From   : Positive;
449         Going  : Direction := Forward) return Natural
450      with
451        Pre    => (if Length (Source) /= 0 then From <= Length (Source)),
452        Global => null;
453      pragma Ada_05 (Index_Non_Blank);
454
455      function Count
456        (Source  : Bounded_String;
457         Pattern : String;
458         Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
459      with
460        Pre    => Pattern'Length /= 0,
461        Global => null;
462
463      function Count
464        (Source  : Bounded_String;
465         Pattern : String;
466         Mapping : Maps.Character_Mapping_Function) return Natural
467      with
468        Pre    => Pattern'Length /= 0,
469        Global => null;
470
471      function Count
472        (Source : Bounded_String;
473         Set    : Maps.Character_Set) return Natural
474      with
475        Global => null;
476
477      procedure Find_Token
478        (Source : Bounded_String;
479         Set    : Maps.Character_Set;
480         From   : Positive;
481         Test   : Membership;
482         First  : out Positive;
483         Last   : out Natural)
484      with
485        Pre    => (if Length (Source) /= 0 then From <= Length (Source)),
486        Global => null;
487      pragma Ada_2012 (Find_Token);
488
489      procedure Find_Token
490        (Source : Bounded_String;
491         Set    : Maps.Character_Set;
492         Test   : Membership;
493         First  : out Positive;
494         Last   : out Natural)
495      with
496        Global => null;
497
498      ------------------------------------
499      -- String Translation Subprograms --
500      ------------------------------------
501
502      function Translate
503        (Source  : Bounded_String;
504         Mapping : Maps.Character_Mapping) return Bounded_String
505      with
506        Post   => Length (Translate'Result) = Length (Source),
507        Global => null;
508
509      procedure Translate
510        (Source   : in out Bounded_String;
511         Mapping  : Maps.Character_Mapping)
512      with
513        Post   => Length (Source) = Length (Source)'Old,
514        Global => null;
515
516      function Translate
517        (Source  : Bounded_String;
518         Mapping : Maps.Character_Mapping_Function) return Bounded_String
519      with
520        Post   => Length (Translate'Result) = Length (Source),
521        Global => null;
522
523      procedure Translate
524        (Source  : in out Bounded_String;
525         Mapping : Maps.Character_Mapping_Function)
526      with
527        Post   => Length (Source) = Length (Source)'Old,
528        Global => null;
529
530      ---------------------------------------
531      -- String Transformation Subprograms --
532      ---------------------------------------
533
534      function Replace_Slice
535        (Source : Bounded_String;
536         Low    : Positive;
537         High   : Natural;
538         By     : String;
539         Drop   : Truncation := Error) return Bounded_String
540      with
541        Pre            =>
542          Low - 1 <= Length (Source)
543            and then
544          (if Drop = Error
545           then (if High >= Low
546                 then Low - 1
547                   <= Max_Length - By'Length
548                    - Natural'Max (Length (Source) - High, 0)
549                 else Length (Source) <= Max_Length - By'Length)),
550        Contract_Cases =>
551          (High >= Low =>
552             Length (Replace_Slice'Result)
553           = Natural'Min
554             (Max_Length,
555              Low - 1 + By'Length + Natural'Max (Length (Source) - High,
556                                                  0)),
557           others      =>
558             Length (Replace_Slice'Result)
559           = Natural'Min (Max_Length, Length (Source) + By'Length)),
560        Global         => null;
561
562      procedure Replace_Slice
563        (Source   : in out Bounded_String;
564         Low      : Positive;
565         High     : Natural;
566         By       : String;
567         Drop     : Truncation := Error)
568      with
569        Pre            =>
570          Low - 1 <= Length (Source)
571            and then
572          (if Drop = Error
573           then (if High >= Low
574                 then Low - 1
575                   <= Max_Length - By'Length
576                    - Natural'Max (Length (Source) - High, 0)
577                 else Length (Source) <= Max_Length - By'Length)),
578        Contract_Cases =>
579          (High >= Low =>
580            Length (Source)
581          = Natural'Min
582              (Max_Length,
583               Low - 1 + By'Length + Natural'Max (Length (Source)'Old - High,
584                                                  0)),
585           others      =>
586             Length (Source)
587           = Natural'Min (Max_Length, Length (Source)'Old + By'Length)),
588        Global         => null;
589
590      function Insert
591        (Source   : Bounded_String;
592         Before   : Positive;
593         New_Item : String;
594         Drop     : Truncation := Error) return Bounded_String
595      with
596        Pre    =>
597          Before - 1 <= Length (Source)
598            and then (if New_Item'Length > Max_Length - Length (Source)
599                      then Drop /= Error),
600        Post   =>
601          Length (Insert'Result)
602        = Natural'Min (Max_Length, Length (Source) + New_Item'Length),
603        Global => null;
604
605      procedure Insert
606        (Source   : in out Bounded_String;
607         Before   : Positive;
608         New_Item : String;
609         Drop     : Truncation := Error)
610      with
611        Pre    =>
612          Before - 1 <= Length (Source)
613            and then (if New_Item'Length > Max_Length - Length (Source)
614                      then Drop /= Error),
615        Post   =>
616          Length (Source)
617        = Natural'Min (Max_Length, Length (Source)'Old + New_Item'Length),
618        Global => null;
619
620      function Overwrite
621        (Source   : Bounded_String;
622         Position : Positive;
623         New_Item : String;
624         Drop     : Truncation := Error) return Bounded_String
625      with
626        Pre    =>
627          Position - 1 <= Length (Source)
628            and then (if New_Item'Length > Max_Length - (Position - 1)
629                      then Drop /= Error),
630        Post   =>
631          Length (Overwrite'Result)
632        = Natural'Max
633            (Length (Source),
634             Natural'Min (Max_Length, Position - 1 + New_Item'Length)),
635        Global => null;
636
637      procedure Overwrite
638        (Source    : in out Bounded_String;
639         Position  : Positive;
640         New_Item  : String;
641         Drop      : Truncation := Error)
642      with
643        Pre    =>
644          Position - 1 <= Length (Source)
645            and then (if New_Item'Length > Max_Length - (Position - 1)
646                      then Drop /= Error),
647        Post   =>
648          Length (Source)
649        = Natural'Max
650            (Length (Source)'Old,
651             Natural'Min (Max_Length, Position - 1 + New_Item'Length)),
652        Global => null;
653
654      function Delete
655        (Source  : Bounded_String;
656         From    : Positive;
657         Through : Natural) return Bounded_String
658      with
659        Pre            =>
660          (if Through <= From then From - 1 <= Length (Source)),
661        Contract_Cases =>
662          (Through >= From =>
663             Length (Delete'Result) = Length (Source) - (Through - From + 1),
664           others          =>
665             Length (Delete'Result) = Length (Source)),
666
667        Global         => null;
668
669      procedure Delete
670        (Source  : in out Bounded_String;
671         From    : Positive;
672         Through : Natural)
673      with
674        Pre            =>
675          (if Through <= From then From - 1 <= Length (Source)),
676        Contract_Cases =>
677          (Through >= From =>
678             Length (Source) = Length (Source)'Old - (Through - From + 1),
679           others          =>
680             Length (Source) = Length (Source)'Old),
681        Global         => null;
682
683      ---------------------------------
684      -- String Selector Subprograms --
685      ---------------------------------
686
687      function Trim
688        (Source : Bounded_String;
689         Side   : Trim_End) return Bounded_String
690      with
691        Post   => Length (Trim'Result) <= Length (Source),
692        Global => null;
693
694      procedure Trim
695        (Source : in out Bounded_String;
696         Side   : Trim_End)
697      with
698        Post   => Length (Source) <= Length (Source)'Old,
699        Global => null;
700
701      function Trim
702        (Source : Bounded_String;
703         Left   : Maps.Character_Set;
704         Right  : Maps.Character_Set) return Bounded_String
705      with
706        Post   => Length (Trim'Result) <= Length (Source),
707        Global => null;
708
709      procedure Trim
710        (Source : in out Bounded_String;
711         Left   : Maps.Character_Set;
712         Right  : Maps.Character_Set)
713      with
714        Post   => Length (Source) <= Length (Source)'Old,
715        Global => null;
716
717      function Head
718        (Source : Bounded_String;
719         Count  : Natural;
720         Pad    : Character := Space;
721         Drop   : Truncation := Error) return Bounded_String
722      with
723        Pre    => (if Count > Max_Length then Drop /= Error),
724        Post   => Length (Head'Result) = Natural'Min (Max_Length, Count),
725        Global => null;
726
727      procedure Head
728        (Source : in out Bounded_String;
729         Count  : Natural;
730         Pad    : Character  := Space;
731         Drop   : Truncation := Error)
732      with
733        Pre    => (if Count > Max_Length then Drop /= Error),
734        Post   => Length (Source) = Natural'Min (Max_Length, Count),
735        Global => null;
736
737      function Tail
738        (Source : Bounded_String;
739         Count  : Natural;
740         Pad    : Character  := Space;
741         Drop   : Truncation := Error) return Bounded_String
742      with
743        Pre    => (if Count > Max_Length then Drop /= Error),
744        Post   => Length (Tail'Result) = Natural'Min (Max_Length, Count),
745        Global => null;
746
747      procedure Tail
748        (Source : in out Bounded_String;
749         Count  : Natural;
750         Pad    : Character  := Space;
751         Drop   : Truncation := Error)
752      with
753        Pre    => (if Count > Max_Length then Drop /= Error),
754        Post   => Length (Source) = Natural'Min (Max_Length, Count),
755        Global => null;
756
757      ------------------------------------
758      -- String Constructor Subprograms --
759      ------------------------------------
760
761      function "*"
762        (Left  : Natural;
763         Right : Character) return Bounded_String
764      with
765        Pre    => Left <= Max_Length,
766        Post   => Length ("*"'Result) = Left,
767        Global => null;
768
769      function "*"
770        (Left  : Natural;
771         Right : String) return Bounded_String
772      with
773        Pre    => (if Left /= 0 then Right'Length <= Max_Length / Left),
774        Post   => Length ("*"'Result) = Left * Right'Length,
775        Global => null;
776
777      function "*"
778        (Left  : Natural;
779         Right : Bounded_String) return Bounded_String
780      with
781        Pre    => (if Left /= 0 then Length (Right) <= Max_Length / Left),
782        Post   => Length ("*"'Result) = Left * Length (Right),
783        Global => null;
784
785      function Replicate
786        (Count : Natural;
787         Item  : Character;
788         Drop  : Truncation := Error) return Bounded_String
789      with
790        Pre    => (if Count > Max_Length then Drop /= Error),
791        Post   =>
792          Length (Replicate'Result)
793        = Natural'Min (Max_Length, Count),
794        Global => null;
795
796      function Replicate
797        (Count : Natural;
798         Item  : String;
799         Drop  : Truncation := Error) return Bounded_String
800      with
801        Pre    =>
802          (if Item'Length /= 0
803             and then Count > Max_Length / Item'Length
804           then Drop /= Error),
805        Post   =>
806          Length (Replicate'Result)
807        = Natural'Min (Max_Length, Count * Item'Length),
808        Global => null;
809
810      function Replicate
811        (Count : Natural;
812         Item  : Bounded_String;
813         Drop  : Truncation := Error) return Bounded_String
814      with
815        Pre    =>
816          (if Length (Item) /= 0
817             and then Count > Max_Length / Length (Item)
818           then Drop /= Error),
819        Post   =>
820          Length (Replicate'Result)
821        = Natural'Min (Max_Length, Count * Length (Item)),
822        Global => null;
823
824   private
825      --  Most of the implementation is in the separate non generic package
826      --  Ada.Strings.Superbounded. Type Bounded_String is derived from type
827      --  Superbounded.Super_String with the maximum length constraint. In
828      --  almost all cases, the routines in Superbounded can be called with
829      --  no requirement to pass the maximum length explicitly, since there
830      --  is at least one Bounded_String argument from which the maximum
831      --  length can be obtained. For all such routines, the implementation
832      --  in this private part is simply a renaming of the corresponding
833      --  routine in the superbounded package.
834
835      --  The five exceptions are the * and Replicate routines operating on
836      --  character values. For these cases, we have a routine in the body
837      --  that calls the superbounded routine passing the maximum length
838      --  explicitly as an extra parameter.
839
840      type Bounded_String is new Superbounded.Super_String (Max_Length);
841      --  Deriving Bounded_String from Superbounded.Super_String is the
842      --  real trick, it ensures that the type Bounded_String declared in
843      --  the generic instantiation is compatible with the Super_String
844      --  type declared in the Superbounded package.
845
846      function From_String (Source : String) return Bounded_String;
847      --  Private routine used only by Stream_Convert
848
849      pragma Stream_Convert (Bounded_String, From_String, To_String);
850      --  Provide stream routines without dragging in Ada.Streams
851
852      Null_Bounded_String : constant Bounded_String :=
853                              (Max_Length     => Max_Length,
854                               Current_Length => 0,
855                               Data           =>
856                                 (1 .. Max_Length => ASCII.NUL));
857
858      pragma Inline (To_Bounded_String);
859
860      procedure Set_Bounded_String
861        (Target : out Bounded_String;
862         Source : String;
863         Drop   : Truncation := Error)
864         renames Set_Super_String;
865
866      function Length
867        (Source : Bounded_String) return Length_Range
868         renames Super_Length;
869
870      function To_String
871        (Source : Bounded_String) return String
872         renames Super_To_String;
873
874      function Append
875        (Left  : Bounded_String;
876         Right : Bounded_String;
877         Drop  : Truncation  := Error) return Bounded_String
878         renames Super_Append;
879
880      function Append
881        (Left  : Bounded_String;
882         Right : String;
883         Drop  : Truncation := Error) return Bounded_String
884         renames Super_Append;
885
886      function Append
887        (Left  : String;
888         Right : Bounded_String;
889         Drop  : Truncation := Error) return Bounded_String
890         renames Super_Append;
891
892      function Append
893        (Left  : Bounded_String;
894         Right : Character;
895         Drop  : Truncation := Error) return Bounded_String
896         renames Super_Append;
897
898      function Append
899        (Left  : Character;
900         Right : Bounded_String;
901         Drop  : Truncation := Error) return Bounded_String
902         renames Super_Append;
903
904      procedure Append
905        (Source   : in out Bounded_String;
906         New_Item : Bounded_String;
907         Drop     : Truncation  := Error)
908         renames Super_Append;
909
910      procedure Append
911        (Source   : in out Bounded_String;
912         New_Item : String;
913         Drop     : Truncation  := Error)
914         renames Super_Append;
915
916      procedure Append
917        (Source   : in out Bounded_String;
918         New_Item : Character;
919         Drop     : Truncation  := Error)
920         renames Super_Append;
921
922      function "&"
923        (Left  : Bounded_String;
924         Right : Bounded_String) return Bounded_String
925         renames Concat;
926
927      function "&"
928        (Left  : Bounded_String;
929         Right : String) return Bounded_String
930         renames Concat;
931
932      function "&"
933        (Left  : String;
934         Right : Bounded_String) return Bounded_String
935         renames Concat;
936
937      function "&"
938        (Left  : Bounded_String;
939         Right : Character) return Bounded_String
940         renames Concat;
941
942      function "&"
943        (Left  : Character;
944         Right : Bounded_String) return Bounded_String
945         renames Concat;
946
947      function Element
948        (Source : Bounded_String;
949         Index  : Positive) return Character
950         renames Super_Element;
951
952      procedure Replace_Element
953        (Source : in out Bounded_String;
954         Index  : Positive;
955         By     : Character)
956         renames Super_Replace_Element;
957
958      function Slice
959        (Source : Bounded_String;
960         Low    : Positive;
961         High   : Natural) return String
962         renames Super_Slice;
963
964      function Bounded_Slice
965        (Source : Bounded_String;
966         Low    : Positive;
967         High   : Natural) return Bounded_String
968         renames Super_Slice;
969
970      procedure Bounded_Slice
971        (Source : Bounded_String;
972         Target : out Bounded_String;
973         Low    : Positive;
974         High   : Natural)
975         renames Super_Slice;
976
977      overriding function "="
978        (Left  : Bounded_String;
979         Right : Bounded_String) return Boolean
980         renames Equal;
981
982      function "="
983        (Left  : Bounded_String;
984         Right : String) return Boolean
985         renames Equal;
986
987      function "="
988        (Left  : String;
989         Right : Bounded_String) return Boolean
990         renames Equal;
991
992      function "<"
993        (Left  : Bounded_String;
994         Right : Bounded_String) return Boolean
995         renames Less;
996
997      function "<"
998        (Left  : Bounded_String;
999         Right : String) return Boolean
1000         renames Less;
1001
1002      function "<"
1003        (Left  : String;
1004         Right : Bounded_String) return Boolean
1005         renames Less;
1006
1007      function "<="
1008        (Left  : Bounded_String;
1009         Right : Bounded_String) return Boolean
1010         renames Less_Or_Equal;
1011
1012      function "<="
1013        (Left  : Bounded_String;
1014         Right : String) return Boolean
1015         renames Less_Or_Equal;
1016
1017      function "<="
1018        (Left  : String;
1019         Right : Bounded_String) return Boolean
1020         renames Less_Or_Equal;
1021
1022      function ">"
1023        (Left  : Bounded_String;
1024         Right : Bounded_String) return Boolean
1025         renames Greater;
1026
1027      function ">"
1028        (Left  : Bounded_String;
1029         Right : String) return Boolean
1030         renames Greater;
1031
1032      function ">"
1033        (Left  : String;
1034         Right : Bounded_String) return Boolean
1035         renames Greater;
1036
1037      function ">="
1038        (Left  : Bounded_String;
1039         Right : Bounded_String) return Boolean
1040         renames Greater_Or_Equal;
1041
1042      function ">="
1043        (Left  : Bounded_String;
1044         Right : String) return Boolean
1045         renames Greater_Or_Equal;
1046
1047      function ">="
1048        (Left  : String;
1049         Right : Bounded_String) return Boolean
1050         renames Greater_Or_Equal;
1051
1052      function Index
1053        (Source  : Bounded_String;
1054         Pattern : String;
1055         Going   : Direction := Forward;
1056         Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
1057         renames Super_Index;
1058
1059      function Index
1060        (Source  : Bounded_String;
1061         Pattern : String;
1062         Going   : Direction := Forward;
1063         Mapping : Maps.Character_Mapping_Function) return Natural
1064         renames Super_Index;
1065
1066      function Index
1067        (Source : Bounded_String;
1068         Set    : Maps.Character_Set;
1069         Test   : Membership := Inside;
1070         Going  : Direction  := Forward) return Natural
1071         renames Super_Index;
1072
1073      function Index
1074        (Source  : Bounded_String;
1075         Pattern : String;
1076         From    : Positive;
1077         Going   : Direction := Forward;
1078         Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
1079         renames Super_Index;
1080
1081      function Index
1082        (Source  : Bounded_String;
1083         Pattern : String;
1084         From    : Positive;
1085         Going   : Direction := Forward;
1086         Mapping : Maps.Character_Mapping_Function) return Natural
1087      renames Super_Index;
1088
1089      function Index
1090        (Source  : Bounded_String;
1091         Set     : Maps.Character_Set;
1092         From    : Positive;
1093         Test    : Membership := Inside;
1094         Going   : Direction := Forward) return Natural
1095      renames Super_Index;
1096
1097      function Index_Non_Blank
1098        (Source : Bounded_String;
1099         Going  : Direction := Forward) return Natural
1100         renames Super_Index_Non_Blank;
1101
1102      function Index_Non_Blank
1103        (Source : Bounded_String;
1104         From   : Positive;
1105         Going  : Direction := Forward) return Natural
1106         renames Super_Index_Non_Blank;
1107
1108      function Count
1109        (Source  : Bounded_String;
1110         Pattern : String;
1111         Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
1112         renames Super_Count;
1113
1114      function Count
1115        (Source  : Bounded_String;
1116         Pattern : String;
1117         Mapping : Maps.Character_Mapping_Function) return Natural
1118         renames Super_Count;
1119
1120      function Count
1121        (Source : Bounded_String;
1122         Set    : Maps.Character_Set) return Natural
1123         renames Super_Count;
1124
1125      procedure Find_Token
1126        (Source : Bounded_String;
1127         Set    : Maps.Character_Set;
1128         From   : Positive;
1129         Test   : Membership;
1130         First  : out Positive;
1131         Last   : out Natural)
1132         renames Super_Find_Token;
1133
1134      procedure Find_Token
1135        (Source : Bounded_String;
1136         Set    : Maps.Character_Set;
1137         Test   : Membership;
1138         First  : out Positive;
1139         Last   : out Natural)
1140         renames Super_Find_Token;
1141
1142      function Translate
1143        (Source  : Bounded_String;
1144         Mapping : Maps.Character_Mapping) return Bounded_String
1145         renames Super_Translate;
1146
1147      procedure Translate
1148        (Source   : in out Bounded_String;
1149         Mapping  : Maps.Character_Mapping)
1150         renames Super_Translate;
1151
1152      function Translate
1153        (Source  : Bounded_String;
1154         Mapping : Maps.Character_Mapping_Function) return Bounded_String
1155         renames Super_Translate;
1156
1157      procedure Translate
1158        (Source  : in out Bounded_String;
1159         Mapping : Maps.Character_Mapping_Function)
1160         renames Super_Translate;
1161
1162      function Replace_Slice
1163        (Source : Bounded_String;
1164         Low    : Positive;
1165         High   : Natural;
1166         By     : String;
1167         Drop   : Truncation := Error) return Bounded_String
1168         renames Super_Replace_Slice;
1169
1170      procedure Replace_Slice
1171        (Source   : in out Bounded_String;
1172         Low      : Positive;
1173         High     : Natural;
1174         By       : String;
1175         Drop     : Truncation := Error)
1176         renames Super_Replace_Slice;
1177
1178      function Insert
1179        (Source   : Bounded_String;
1180         Before   : Positive;
1181         New_Item : String;
1182         Drop     : Truncation := Error) return Bounded_String
1183         renames Super_Insert;
1184
1185      procedure Insert
1186        (Source   : in out Bounded_String;
1187         Before   : Positive;
1188         New_Item : String;
1189         Drop     : Truncation := Error)
1190         renames Super_Insert;
1191
1192      function Overwrite
1193        (Source   : Bounded_String;
1194         Position : Positive;
1195         New_Item : String;
1196         Drop     : Truncation := Error) return Bounded_String
1197         renames Super_Overwrite;
1198
1199      procedure Overwrite
1200        (Source    : in out Bounded_String;
1201         Position  : Positive;
1202         New_Item  : String;
1203         Drop      : Truncation := Error)
1204         renames Super_Overwrite;
1205
1206      function Delete
1207        (Source  : Bounded_String;
1208         From    : Positive;
1209         Through : Natural) return Bounded_String
1210         renames Super_Delete;
1211
1212      procedure Delete
1213        (Source  : in out Bounded_String;
1214         From    : Positive;
1215         Through : Natural)
1216         renames Super_Delete;
1217
1218      function Trim
1219        (Source : Bounded_String;
1220         Side   : Trim_End) return Bounded_String
1221         renames Super_Trim;
1222
1223      procedure Trim
1224        (Source : in out Bounded_String;
1225         Side   : Trim_End)
1226         renames Super_Trim;
1227
1228      function Trim
1229        (Source : Bounded_String;
1230         Left   : Maps.Character_Set;
1231         Right  : Maps.Character_Set) return Bounded_String
1232         renames Super_Trim;
1233
1234      procedure Trim
1235        (Source : in out Bounded_String;
1236         Left   : Maps.Character_Set;
1237         Right  : Maps.Character_Set)
1238         renames Super_Trim;
1239
1240      function Head
1241        (Source : Bounded_String;
1242         Count  : Natural;
1243         Pad    : Character := Space;
1244         Drop   : Truncation := Error) return Bounded_String
1245         renames Super_Head;
1246
1247      procedure Head
1248        (Source : in out Bounded_String;
1249         Count  : Natural;
1250         Pad    : Character  := Space;
1251         Drop   : Truncation := Error)
1252         renames Super_Head;
1253
1254      function Tail
1255        (Source : Bounded_String;
1256         Count  : Natural;
1257         Pad    : Character  := Space;
1258         Drop   : Truncation := Error) return Bounded_String
1259         renames Super_Tail;
1260
1261      procedure Tail
1262        (Source : in out Bounded_String;
1263         Count  : Natural;
1264         Pad    : Character  := Space;
1265         Drop   : Truncation := Error)
1266         renames Super_Tail;
1267
1268      function "*"
1269        (Left  : Natural;
1270         Right : Bounded_String) return Bounded_String
1271         renames Times;
1272
1273      function Replicate
1274        (Count : Natural;
1275         Item  : Bounded_String;
1276         Drop  : Truncation := Error) return Bounded_String
1277         renames Super_Replicate;
1278
1279   end Generic_Bounded_Length;
1280
1281end Ada.Strings.Bounded;
1282