File : a-stwisu.adb


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                         GNAT RUN-TIME COMPONENTS                         --
   4 --                                                                          --
   5 --        A D A . S T R I N G S . W I D E _ S U P E R B O U N D E D         --
   6 --                                                                          --
   7 --                                 B o d y                                  --
   8 --                                                                          --
   9 --          Copyright (C) 2003-2012, Free Software Foundation, Inc.         --
  10 --                                                                          --
  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.                                     --
  17 --                                                                          --
  18 --                                                                          --
  19 --                                                                          --
  20 --                                                                          --
  21 --                                                                          --
  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/>.                                          --
  26 --                                                                          --
  27 -- GNAT was originally developed  by the GNAT team at  New York University. --
  28 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
  29 --                                                                          --
  30 ------------------------------------------------------------------------------
  31 
  32 with Ada.Strings.Wide_Maps;   use Ada.Strings.Wide_Maps;
  33 with Ada.Strings.Wide_Search;
  34 
  35 package body Ada.Strings.Wide_Superbounded is
  36 
  37    ------------
  38    -- Concat --
  39    ------------
  40 
  41    function Concat
  42      (Left  : Super_String;
  43       Right : Super_String) return Super_String
  44    is
  45    begin
  46       return Result : Super_String (Left.Max_Length) do
  47          declare
  48             Llen : constant Natural := Left.Current_Length;
  49             Rlen : constant Natural := Right.Current_Length;
  50             Nlen : constant Natural := Llen + Rlen;
  51 
  52          begin
  53             if Nlen > Left.Max_Length then
  54                raise Ada.Strings.Length_Error;
  55             else
  56                Result.Current_Length := Nlen;
  57                Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
  58                Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
  59             end if;
  60          end;
  61       end return;
  62    end Concat;
  63 
  64    function Concat
  65      (Left  : Super_String;
  66       Right : Wide_String) return Super_String
  67    is
  68    begin
  69       return Result : Super_String (Left.Max_Length) do
  70          declare
  71             Llen : constant Natural := Left.Current_Length;
  72             Nlen : constant Natural := Llen + Right'Length;
  73 
  74          begin
  75             if Nlen > Left.Max_Length then
  76                raise Ada.Strings.Length_Error;
  77             else
  78                Result.Current_Length := Nlen;
  79                Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
  80                Result.Data (Llen + 1 .. Nlen) := Right;
  81             end if;
  82          end;
  83       end return;
  84    end Concat;
  85 
  86    function Concat
  87      (Left  : Wide_String;
  88       Right : Super_String) return Super_String
  89    is
  90    begin
  91       return Result : Super_String (Right.Max_Length) do
  92          declare
  93             Llen : constant Natural := Left'Length;
  94             Rlen : constant Natural := Right.Current_Length;
  95             Nlen : constant Natural := Llen + Rlen;
  96 
  97          begin
  98             if Nlen > Right.Max_Length then
  99                raise Ada.Strings.Length_Error;
 100             else
 101                Result.Current_Length := Nlen;
 102                Result.Data (1 .. Llen) := Left;
 103                Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
 104             end if;
 105          end;
 106       end return;
 107    end Concat;
 108 
 109    function Concat
 110      (Left  : Super_String;
 111       Right : Wide_Character) return Super_String
 112    is
 113    begin
 114       return Result : Super_String (Left.Max_Length) do
 115          declare
 116             Llen : constant Natural := Left.Current_Length;
 117 
 118          begin
 119             if Llen = Left.Max_Length then
 120                raise Ada.Strings.Length_Error;
 121             else
 122                Result.Current_Length := Llen + 1;
 123                Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
 124                Result.Data (Result.Current_Length) := Right;
 125             end if;
 126          end;
 127       end return;
 128    end Concat;
 129 
 130    function Concat
 131      (Left  : Wide_Character;
 132       Right : Super_String) return Super_String
 133    is
 134    begin
 135       return Result : Super_String (Right.Max_Length) do
 136          declare
 137             Rlen : constant Natural := Right.Current_Length;
 138 
 139          begin
 140             if Rlen = Right.Max_Length then
 141                raise Ada.Strings.Length_Error;
 142             else
 143                Result.Current_Length := Rlen + 1;
 144                Result.Data (1) := Left;
 145                Result.Data (2 .. Result.Current_Length) :=
 146                  Right.Data (1 .. Rlen);
 147             end if;
 148          end;
 149       end return;
 150    end Concat;
 151 
 152    -----------
 153    -- Equal --
 154    -----------
 155 
 156    function "="
 157      (Left  : Super_String;
 158       Right : Super_String) return Boolean
 159    is
 160    begin
 161       return Left.Current_Length = Right.Current_Length
 162         and then Left.Data (1 .. Left.Current_Length) =
 163                    Right.Data (1 .. Right.Current_Length);
 164    end "=";
 165 
 166    function Equal
 167      (Left  : Super_String;
 168       Right : Wide_String) return Boolean
 169    is
 170    begin
 171       return Left.Current_Length = Right'Length
 172         and then Left.Data (1 .. Left.Current_Length) = Right;
 173    end Equal;
 174 
 175    function Equal
 176      (Left  : Wide_String;
 177       Right : Super_String) return Boolean
 178    is
 179    begin
 180       return Left'Length = Right.Current_Length
 181         and then Left = Right.Data (1 .. Right.Current_Length);
 182    end Equal;
 183 
 184    -------------
 185    -- Greater --
 186    -------------
 187 
 188    function Greater
 189      (Left  : Super_String;
 190       Right : Super_String) return Boolean
 191    is
 192    begin
 193       return Left.Data (1 .. Left.Current_Length) >
 194                Right.Data (1 .. Right.Current_Length);
 195    end Greater;
 196 
 197    function Greater
 198      (Left  : Super_String;
 199       Right : Wide_String) return Boolean
 200    is
 201    begin
 202       return Left.Data (1 .. Left.Current_Length) > Right;
 203    end Greater;
 204 
 205    function Greater
 206      (Left  : Wide_String;
 207       Right : Super_String) return Boolean
 208    is
 209    begin
 210       return Left > Right.Data (1 .. Right.Current_Length);
 211    end Greater;
 212 
 213    ----------------------
 214    -- Greater_Or_Equal --
 215    ----------------------
 216 
 217    function Greater_Or_Equal
 218      (Left  : Super_String;
 219       Right : Super_String) return Boolean
 220    is
 221    begin
 222       return Left.Data (1 .. Left.Current_Length) >=
 223                Right.Data (1 .. Right.Current_Length);
 224    end Greater_Or_Equal;
 225 
 226    function Greater_Or_Equal
 227      (Left  : Super_String;
 228       Right : Wide_String) return Boolean
 229    is
 230    begin
 231       return Left.Data (1 .. Left.Current_Length) >= Right;
 232    end Greater_Or_Equal;
 233 
 234    function Greater_Or_Equal
 235      (Left  : Wide_String;
 236       Right : Super_String) return Boolean
 237    is
 238    begin
 239       return Left >= Right.Data (1 .. Right.Current_Length);
 240    end Greater_Or_Equal;
 241 
 242    ----------
 243    -- Less --
 244    ----------
 245 
 246    function Less
 247      (Left  : Super_String;
 248       Right : Super_String) return Boolean
 249    is
 250    begin
 251       return Left.Data (1 .. Left.Current_Length) <
 252                Right.Data (1 .. Right.Current_Length);
 253    end Less;
 254 
 255    function Less
 256      (Left  : Super_String;
 257       Right : Wide_String) return Boolean
 258    is
 259    begin
 260       return Left.Data (1 .. Left.Current_Length) < Right;
 261    end Less;
 262 
 263    function Less
 264      (Left  : Wide_String;
 265       Right : Super_String) return Boolean
 266    is
 267    begin
 268       return Left < Right.Data (1 .. Right.Current_Length);
 269    end Less;
 270 
 271    -------------------
 272    -- Less_Or_Equal --
 273    -------------------
 274 
 275    function Less_Or_Equal
 276      (Left  : Super_String;
 277       Right : Super_String) return Boolean
 278    is
 279    begin
 280       return Left.Data (1 .. Left.Current_Length) <=
 281                Right.Data (1 .. Right.Current_Length);
 282    end Less_Or_Equal;
 283 
 284    function Less_Or_Equal
 285      (Left  : Super_String;
 286       Right : Wide_String) return Boolean
 287    is
 288    begin
 289       return Left.Data (1 .. Left.Current_Length) <= Right;
 290    end Less_Or_Equal;
 291 
 292    function Less_Or_Equal
 293      (Left  : Wide_String;
 294       Right : Super_String) return Boolean
 295    is
 296    begin
 297       return Left <= Right.Data (1 .. Right.Current_Length);
 298    end Less_Or_Equal;
 299 
 300    ----------------------
 301    -- Set_Super_String --
 302    ----------------------
 303 
 304    procedure Set_Super_String
 305      (Target : out Super_String;
 306       Source : Wide_String;
 307       Drop   : Truncation := Error)
 308    is
 309       Slen       : constant Natural := Source'Length;
 310       Max_Length : constant Positive := Target.Max_Length;
 311 
 312    begin
 313       if Slen <= Max_Length then
 314          Target.Current_Length := Slen;
 315          Target.Data (1 .. Slen) := Source;
 316 
 317       else
 318          case Drop is
 319             when Strings.Right =>
 320                Target.Current_Length := Max_Length;
 321                Target.Data (1 .. Max_Length) :=
 322                  Source (Source'First .. Source'First - 1 + Max_Length);
 323 
 324             when Strings.Left =>
 325                Target.Current_Length := Max_Length;
 326                Target.Data (1 .. Max_Length) :=
 327                  Source (Source'Last - (Max_Length - 1) .. Source'Last);
 328 
 329             when Strings.Error =>
 330                raise Ada.Strings.Length_Error;
 331          end case;
 332       end if;
 333    end Set_Super_String;
 334 
 335    ------------------
 336    -- Super_Append --
 337    ------------------
 338 
 339    --  Case of Super_String and Super_String
 340 
 341    function Super_Append
 342      (Left  : Super_String;
 343       Right : Super_String;
 344       Drop  : Strings.Truncation  := Strings.Error) return Super_String
 345    is
 346       Max_Length : constant Positive := Left.Max_Length;
 347       Result : Super_String (Max_Length);
 348       Llen   : constant Natural := Left.Current_Length;
 349       Rlen   : constant Natural := Right.Current_Length;
 350       Nlen   : constant Natural := Llen + Rlen;
 351 
 352    begin
 353       if Nlen <= Max_Length then
 354          Result.Current_Length := Nlen;
 355          Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
 356          Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
 357 
 358       else
 359          Result.Current_Length := Max_Length;
 360 
 361          case Drop is
 362             when Strings.Right =>
 363                if Llen >= Max_Length then -- only case is Llen = Max_Length
 364                   Result.Data := Left.Data;
 365 
 366                else
 367                   Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
 368                   Result.Data (Llen + 1 .. Max_Length) :=
 369                     Right.Data (1 .. Max_Length - Llen);
 370                end if;
 371 
 372             when Strings.Left =>
 373                if Rlen >= Max_Length then -- only case is Rlen = Max_Length
 374                   Result.Data := Right.Data;
 375 
 376                else
 377                   Result.Data (1 .. Max_Length - Rlen) :=
 378                     Left.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
 379                   Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
 380                     Right.Data (1 .. Rlen);
 381                end if;
 382 
 383             when Strings.Error =>
 384                raise Ada.Strings.Length_Error;
 385          end case;
 386       end if;
 387 
 388       return Result;
 389    end Super_Append;
 390 
 391    procedure Super_Append
 392      (Source   : in out Super_String;
 393       New_Item : Super_String;
 394       Drop     : Truncation  := Error)
 395    is
 396       Max_Length : constant Positive := Source.Max_Length;
 397       Llen       : constant Natural := Source.Current_Length;
 398       Rlen       : constant Natural := New_Item.Current_Length;
 399       Nlen       : constant Natural := Llen + Rlen;
 400 
 401    begin
 402       if Nlen <= Max_Length then
 403          Source.Current_Length := Nlen;
 404          Source.Data (Llen + 1 .. Nlen) := New_Item.Data (1 .. Rlen);
 405 
 406       else
 407          Source.Current_Length := Max_Length;
 408 
 409          case Drop is
 410             when Strings.Right =>
 411                if Llen < Max_Length then
 412                   Source.Data (Llen + 1 .. Max_Length) :=
 413                     New_Item.Data (1 .. Max_Length - Llen);
 414                end if;
 415 
 416             when Strings.Left =>
 417                if Rlen >= Max_Length then -- only case is Rlen = Max_Length
 418                   Source.Data := New_Item.Data;
 419 
 420                else
 421                   Source.Data (1 .. Max_Length - Rlen) :=
 422                     Source.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
 423                   Source.Data (Max_Length - Rlen + 1 .. Max_Length) :=
 424                     New_Item.Data (1 .. Rlen);
 425                end if;
 426 
 427             when Strings.Error =>
 428                raise Ada.Strings.Length_Error;
 429          end case;
 430       end if;
 431 
 432    end Super_Append;
 433 
 434    --  Case of Super_String and Wide_String
 435 
 436    function Super_Append
 437      (Left  : Super_String;
 438       Right : Wide_String;
 439       Drop  : Strings.Truncation := Strings.Error) return Super_String
 440    is
 441       Max_Length : constant Positive := Left.Max_Length;
 442       Result : Super_String (Max_Length);
 443       Llen   : constant Natural := Left.Current_Length;
 444       Rlen   : constant Natural := Right'Length;
 445       Nlen   : constant Natural := Llen + Rlen;
 446 
 447    begin
 448       if Nlen <= Max_Length then
 449          Result.Current_Length := Nlen;
 450          Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
 451          Result.Data (Llen + 1 .. Nlen) := Right;
 452 
 453       else
 454          Result.Current_Length := Max_Length;
 455 
 456          case Drop is
 457             when Strings.Right =>
 458                if Llen >= Max_Length then -- only case is Llen = Max_Length
 459                   Result.Data := Left.Data;
 460 
 461                else
 462                   Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
 463                   Result.Data (Llen + 1 .. Max_Length) :=
 464                     Right (Right'First .. Right'First - 1 +
 465                              Max_Length - Llen);
 466 
 467                end if;
 468 
 469             when Strings.Left =>
 470                if Rlen >= Max_Length then
 471                   Result.Data (1 .. Max_Length) :=
 472                     Right (Right'Last - (Max_Length - 1) .. Right'Last);
 473 
 474                else
 475                   Result.Data (1 .. Max_Length - Rlen) :=
 476                     Left.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
 477                   Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
 478                     Right;
 479                end if;
 480 
 481             when Strings.Error =>
 482                raise Ada.Strings.Length_Error;
 483          end case;
 484       end if;
 485 
 486       return Result;
 487    end Super_Append;
 488 
 489    procedure Super_Append
 490      (Source   : in out Super_String;
 491       New_Item : Wide_String;
 492       Drop     : Truncation  := Error)
 493    is
 494       Max_Length : constant Positive := Source.Max_Length;
 495       Llen   : constant Natural := Source.Current_Length;
 496       Rlen   : constant Natural := New_Item'Length;
 497       Nlen   : constant Natural := Llen + Rlen;
 498 
 499    begin
 500       if Nlen <= Max_Length then
 501          Source.Current_Length := Nlen;
 502          Source.Data (Llen + 1 .. Nlen) := New_Item;
 503 
 504       else
 505          Source.Current_Length := Max_Length;
 506 
 507          case Drop is
 508             when Strings.Right =>
 509                if Llen < Max_Length then
 510                   Source.Data (Llen + 1 .. Max_Length) :=
 511                     New_Item (New_Item'First ..
 512                                 New_Item'First - 1 + Max_Length - Llen);
 513                end if;
 514 
 515             when Strings.Left =>
 516                if Rlen >= Max_Length then
 517                   Source.Data (1 .. Max_Length) :=
 518                     New_Item (New_Item'Last - (Max_Length - 1) ..
 519                                 New_Item'Last);
 520 
 521                else
 522                   Source.Data (1 .. Max_Length - Rlen) :=
 523                     Source.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
 524                   Source.Data (Max_Length - Rlen + 1 .. Max_Length) :=
 525                     New_Item;
 526                end if;
 527 
 528             when Strings.Error =>
 529                raise Ada.Strings.Length_Error;
 530          end case;
 531       end if;
 532 
 533    end Super_Append;
 534 
 535    --  Case of Wide_String and Super_String
 536 
 537    function Super_Append
 538      (Left  : Wide_String;
 539       Right : Super_String;
 540       Drop  : Strings.Truncation := Strings.Error) return Super_String
 541    is
 542       Max_Length : constant Positive := Right.Max_Length;
 543       Result     : Super_String (Max_Length);
 544       Llen       : constant Natural := Left'Length;
 545       Rlen       : constant Natural := Right.Current_Length;
 546       Nlen       : constant Natural := Llen + Rlen;
 547 
 548    begin
 549       if Nlen <= Max_Length then
 550          Result.Current_Length := Nlen;
 551          Result.Data (1 .. Llen) := Left;
 552          Result.Data (Llen + 1 .. Llen + Rlen) := Right.Data (1 .. Rlen);
 553 
 554       else
 555          Result.Current_Length := Max_Length;
 556 
 557          case Drop is
 558             when Strings.Right =>
 559                if Llen >= Max_Length then
 560                   Result.Data (1 .. Max_Length) :=
 561                     Left (Left'First .. Left'First + (Max_Length - 1));
 562 
 563                else
 564                   Result.Data (1 .. Llen) := Left;
 565                   Result.Data (Llen + 1 .. Max_Length) :=
 566                     Right.Data (1 .. Max_Length - Llen);
 567                end if;
 568 
 569             when Strings.Left =>
 570                if Rlen >= Max_Length then
 571                   Result.Data (1 .. Max_Length) :=
 572                     Right.Data (Rlen - (Max_Length - 1) .. Rlen);
 573 
 574                else
 575                   Result.Data (1 .. Max_Length - Rlen) :=
 576                     Left (Left'Last - (Max_Length - Rlen - 1) .. Left'Last);
 577                   Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
 578                     Right.Data (1 .. Rlen);
 579                end if;
 580 
 581             when Strings.Error =>
 582                raise Ada.Strings.Length_Error;
 583          end case;
 584       end if;
 585 
 586       return Result;
 587    end Super_Append;
 588 
 589    --  Case of Super_String and Wide_Character
 590 
 591    function Super_Append
 592      (Left  : Super_String;
 593       Right : Wide_Character;
 594       Drop  : Strings.Truncation := Strings.Error) return Super_String
 595    is
 596       Max_Length : constant Positive := Left.Max_Length;
 597       Result     : Super_String (Max_Length);
 598       Llen       : constant Natural := Left.Current_Length;
 599 
 600    begin
 601       if Llen  < Max_Length then
 602          Result.Current_Length := Llen + 1;
 603          Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
 604          Result.Data (Llen + 1) := Right;
 605          return Result;
 606 
 607       else
 608          case Drop is
 609             when Strings.Right =>
 610                return Left;
 611 
 612             when Strings.Left =>
 613                Result.Current_Length := Max_Length;
 614                Result.Data (1 .. Max_Length - 1) :=
 615                  Left.Data (2 .. Max_Length);
 616                Result.Data (Max_Length) := Right;
 617                return Result;
 618 
 619             when Strings.Error =>
 620                raise Ada.Strings.Length_Error;
 621          end case;
 622       end if;
 623    end Super_Append;
 624 
 625    procedure Super_Append
 626      (Source   : in out Super_String;
 627       New_Item : Wide_Character;
 628       Drop     : Truncation  := Error)
 629    is
 630       Max_Length : constant Positive := Source.Max_Length;
 631       Llen       : constant Natural  := Source.Current_Length;
 632 
 633    begin
 634       if Llen  < Max_Length then
 635          Source.Current_Length := Llen + 1;
 636          Source.Data (Llen + 1) := New_Item;
 637 
 638       else
 639          Source.Current_Length := Max_Length;
 640 
 641          case Drop is
 642             when Strings.Right =>
 643                null;
 644 
 645             when Strings.Left =>
 646                Source.Data (1 .. Max_Length - 1) :=
 647                  Source.Data (2 .. Max_Length);
 648                Source.Data (Max_Length) := New_Item;
 649 
 650             when Strings.Error =>
 651                raise Ada.Strings.Length_Error;
 652          end case;
 653       end if;
 654 
 655    end Super_Append;
 656 
 657    --  Case of Wide_Character and Super_String
 658 
 659    function Super_Append
 660      (Left  : Wide_Character;
 661       Right : Super_String;
 662       Drop  : Strings.Truncation := Strings.Error) return Super_String
 663    is
 664       Max_Length : constant Positive := Right.Max_Length;
 665       Result : Super_String (Max_Length);
 666       Rlen   : constant Natural := Right.Current_Length;
 667 
 668    begin
 669       if Rlen < Max_Length then
 670          Result.Current_Length := Rlen + 1;
 671          Result.Data (1) := Left;
 672          Result.Data (2 .. Rlen + 1) := Right.Data (1 .. Rlen);
 673          return Result;
 674 
 675       else
 676          case Drop is
 677             when Strings.Right =>
 678                Result.Current_Length := Max_Length;
 679                Result.Data (1) := Left;
 680                Result.Data (2 .. Max_Length) :=
 681                  Right.Data (1 .. Max_Length - 1);
 682                return Result;
 683 
 684             when Strings.Left =>
 685                return Right;
 686 
 687             when Strings.Error =>
 688                raise Ada.Strings.Length_Error;
 689          end case;
 690       end if;
 691    end Super_Append;
 692 
 693    -----------------
 694    -- Super_Count --
 695    -----------------
 696 
 697    function Super_Count
 698      (Source  : Super_String;
 699       Pattern : Wide_String;
 700       Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
 701       return Natural
 702    is
 703    begin
 704       return
 705         Wide_Search.Count
 706           (Source.Data (1 .. Source.Current_Length), Pattern, Mapping);
 707    end Super_Count;
 708 
 709    function Super_Count
 710      (Source  : Super_String;
 711       Pattern : Wide_String;
 712       Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural
 713    is
 714    begin
 715       return
 716         Wide_Search.Count
 717           (Source.Data (1 .. Source.Current_Length), Pattern, Mapping);
 718    end Super_Count;
 719 
 720    function Super_Count
 721      (Source : Super_String;
 722       Set    : Wide_Maps.Wide_Character_Set) return Natural
 723    is
 724    begin
 725       return Wide_Search.Count (Source.Data (1 .. Source.Current_Length), Set);
 726    end Super_Count;
 727 
 728    ------------------
 729    -- Super_Delete --
 730    ------------------
 731 
 732    function Super_Delete
 733      (Source  : Super_String;
 734       From    : Positive;
 735       Through : Natural) return Super_String
 736    is
 737       Result     : Super_String (Source.Max_Length);
 738       Slen       : constant Natural := Source.Current_Length;
 739       Num_Delete : constant Integer := Through - From + 1;
 740 
 741    begin
 742       if Num_Delete <= 0 then
 743          return Source;
 744 
 745       elsif From > Slen + 1 then
 746          raise Ada.Strings.Index_Error;
 747 
 748       elsif Through >= Slen then
 749          Result.Current_Length := From - 1;
 750          Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
 751          return Result;
 752 
 753       else
 754          Result.Current_Length := Slen - Num_Delete;
 755          Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
 756          Result.Data (From .. Result.Current_Length) :=
 757            Source.Data (Through + 1 .. Slen);
 758          return Result;
 759       end if;
 760    end Super_Delete;
 761 
 762    procedure Super_Delete
 763      (Source  : in out Super_String;
 764       From    : Positive;
 765       Through : Natural)
 766    is
 767       Slen       : constant Natural := Source.Current_Length;
 768       Num_Delete : constant Integer := Through - From + 1;
 769 
 770    begin
 771       if Num_Delete <= 0 then
 772          return;
 773 
 774       elsif From > Slen + 1 then
 775          raise Ada.Strings.Index_Error;
 776 
 777       elsif Through >= Slen then
 778          Source.Current_Length := From - 1;
 779 
 780       else
 781          Source.Current_Length := Slen - Num_Delete;
 782          Source.Data (From .. Source.Current_Length) :=
 783            Source.Data (Through + 1 .. Slen);
 784       end if;
 785    end Super_Delete;
 786 
 787    -------------------
 788    -- Super_Element --
 789    -------------------
 790 
 791    function Super_Element
 792      (Source : Super_String;
 793       Index  : Positive) return Wide_Character
 794    is
 795    begin
 796       if Index <= Source.Current_Length then
 797          return Source.Data (Index);
 798       else
 799          raise Strings.Index_Error;
 800       end if;
 801    end Super_Element;
 802 
 803    ----------------------
 804    -- Super_Find_Token --
 805    ----------------------
 806 
 807    procedure Super_Find_Token
 808      (Source : Super_String;
 809       Set    : Wide_Maps.Wide_Character_Set;
 810       From   : Positive;
 811       Test   : Strings.Membership;
 812       First  : out Positive;
 813       Last   : out Natural)
 814    is
 815    begin
 816       Wide_Search.Find_Token
 817         (Source.Data (From .. Source.Current_Length), Set, Test, First, Last);
 818    end Super_Find_Token;
 819 
 820    procedure Super_Find_Token
 821      (Source : Super_String;
 822       Set    : Wide_Maps.Wide_Character_Set;
 823       Test   : Strings.Membership;
 824       First  : out Positive;
 825       Last   : out Natural)
 826    is
 827    begin
 828       Wide_Search.Find_Token
 829         (Source.Data (1 .. Source.Current_Length), Set, Test, First, Last);
 830    end Super_Find_Token;
 831 
 832    ----------------
 833    -- Super_Head --
 834    ----------------
 835 
 836    function Super_Head
 837      (Source : Super_String;
 838       Count  : Natural;
 839       Pad    : Wide_Character := Wide_Space;
 840       Drop   : Strings.Truncation := Strings.Error) return Super_String
 841    is
 842       Max_Length : constant Positive := Source.Max_Length;
 843       Result     : Super_String (Max_Length);
 844       Slen       : constant Natural := Source.Current_Length;
 845       Npad       : constant Integer := Count - Slen;
 846 
 847    begin
 848       if Npad <= 0 then
 849          Result.Current_Length := Count;
 850          Result.Data (1 .. Count) := Source.Data (1 .. Count);
 851 
 852       elsif Count <= Max_Length then
 853          Result.Current_Length := Count;
 854          Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
 855          Result.Data (Slen + 1 .. Count) := (others => Pad);
 856 
 857       else
 858          Result.Current_Length := Max_Length;
 859 
 860          case Drop is
 861             when Strings.Right =>
 862                Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
 863                Result.Data (Slen + 1 .. Max_Length) := (others => Pad);
 864 
 865             when Strings.Left =>
 866                if Npad >= Max_Length then
 867                   Result.Data := (others => Pad);
 868 
 869                else
 870                   Result.Data (1 .. Max_Length - Npad) :=
 871                     Source.Data (Count - Max_Length + 1 .. Slen);
 872                   Result.Data (Max_Length - Npad + 1 .. Max_Length) :=
 873                     (others => Pad);
 874                end if;
 875 
 876             when Strings.Error =>
 877                raise Ada.Strings.Length_Error;
 878          end case;
 879       end if;
 880 
 881       return Result;
 882    end Super_Head;
 883 
 884    procedure Super_Head
 885      (Source : in out Super_String;
 886       Count  : Natural;
 887       Pad    : Wide_Character := Wide_Space;
 888       Drop   : Truncation := Error)
 889    is
 890       Max_Length : constant Positive := Source.Max_Length;
 891       Slen       : constant Natural  := Source.Current_Length;
 892       Npad       : constant Integer  := Count - Slen;
 893       Temp       : Wide_String (1 .. Max_Length);
 894 
 895    begin
 896       if Npad <= 0 then
 897          Source.Current_Length := Count;
 898 
 899       elsif Count <= Max_Length then
 900          Source.Current_Length := Count;
 901          Source.Data (Slen + 1 .. Count) := (others => Pad);
 902 
 903       else
 904          Source.Current_Length := Max_Length;
 905 
 906          case Drop is
 907             when Strings.Right =>
 908                Source.Data (Slen + 1 .. Max_Length) := (others => Pad);
 909 
 910             when Strings.Left =>
 911                if Npad > Max_Length then
 912                   Source.Data := (others => Pad);
 913 
 914                else
 915                   Temp := Source.Data;
 916                   Source.Data (1 .. Max_Length - Npad) :=
 917                     Temp (Count - Max_Length + 1 .. Slen);
 918 
 919                   for J in Max_Length - Npad + 1 .. Max_Length loop
 920                      Source.Data (J) := Pad;
 921                   end loop;
 922                end if;
 923 
 924             when Strings.Error =>
 925                raise Ada.Strings.Length_Error;
 926          end case;
 927       end if;
 928    end Super_Head;
 929 
 930    -----------------
 931    -- Super_Index --
 932    -----------------
 933 
 934    function Super_Index
 935      (Source  : Super_String;
 936       Pattern : Wide_String;
 937       Going   : Strings.Direction := Strings.Forward;
 938       Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
 939       return Natural
 940    is
 941    begin
 942       return Wide_Search.Index
 943         (Source.Data (1 .. Source.Current_Length), Pattern, Going, Mapping);
 944    end Super_Index;
 945 
 946    function Super_Index
 947      (Source  : Super_String;
 948       Pattern : Wide_String;
 949       Going   : Direction := Forward;
 950       Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural
 951    is
 952    begin
 953       return Wide_Search.Index
 954         (Source.Data (1 .. Source.Current_Length), Pattern, Going, Mapping);
 955    end Super_Index;
 956 
 957    function Super_Index
 958      (Source : Super_String;
 959       Set    : Wide_Maps.Wide_Character_Set;
 960       Test   : Strings.Membership := Strings.Inside;
 961       Going  : Strings.Direction  := Strings.Forward) return Natural
 962    is
 963    begin
 964       return Wide_Search.Index
 965         (Source.Data (1 .. Source.Current_Length), Set, Test, Going);
 966    end Super_Index;
 967 
 968    function Super_Index
 969      (Source  : Super_String;
 970       Pattern : Wide_String;
 971       From    : Positive;
 972       Going   : Direction := Forward;
 973       Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
 974       return Natural
 975    is
 976    begin
 977       return Wide_Search.Index
 978         (Source.Data (1 .. Source.Current_Length),
 979          Pattern, From, Going, Mapping);
 980    end Super_Index;
 981 
 982    function Super_Index
 983      (Source  : Super_String;
 984       Pattern : Wide_String;
 985       From    : Positive;
 986       Going   : Direction := Forward;
 987       Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural
 988    is
 989    begin
 990       return Wide_Search.Index
 991         (Source.Data (1 .. Source.Current_Length),
 992          Pattern, From, Going, Mapping);
 993    end Super_Index;
 994 
 995    function Super_Index
 996      (Source : Super_String;
 997       Set    : Wide_Maps.Wide_Character_Set;
 998       From   : Positive;
 999       Test   : Membership := Inside;
1000       Going  : Direction := Forward) return Natural
1001    is
1002    begin
1003       return Wide_Search.Index
1004         (Source.Data (1 .. Source.Current_Length), Set, From, Test, Going);
1005    end Super_Index;
1006 
1007    ---------------------------
1008    -- Super_Index_Non_Blank --
1009    ---------------------------
1010 
1011    function Super_Index_Non_Blank
1012      (Source : Super_String;
1013       Going  : Strings.Direction := Strings.Forward) return Natural
1014    is
1015    begin
1016       return
1017         Wide_Search.Index_Non_Blank
1018           (Source.Data (1 .. Source.Current_Length), Going);
1019    end Super_Index_Non_Blank;
1020 
1021    function Super_Index_Non_Blank
1022      (Source : Super_String;
1023       From   : Positive;
1024       Going  : Direction := Forward) return Natural
1025    is
1026    begin
1027       return
1028         Wide_Search.Index_Non_Blank
1029           (Source.Data (1 .. Source.Current_Length), From, Going);
1030    end Super_Index_Non_Blank;
1031 
1032    ------------------
1033    -- Super_Insert --
1034    ------------------
1035 
1036    function Super_Insert
1037      (Source   : Super_String;
1038       Before   : Positive;
1039       New_Item : Wide_String;
1040       Drop     : Strings.Truncation := Strings.Error) return Super_String
1041    is
1042       Max_Length : constant Positive := Source.Max_Length;
1043       Result     : Super_String (Max_Length);
1044       Slen       : constant Natural := Source.Current_Length;
1045       Nlen       : constant Natural := New_Item'Length;
1046       Tlen       : constant Natural := Slen + Nlen;
1047       Blen       : constant Natural := Before - 1;
1048       Alen       : constant Integer := Slen - Blen;
1049       Droplen    : constant Integer := Tlen - Max_Length;
1050 
1051       --  Tlen is the length of the total string before possible truncation.
1052       --  Blen, Alen are the lengths of the before and after pieces of the
1053       --  source string.
1054 
1055    begin
1056       if Alen < 0 then
1057          raise Ada.Strings.Index_Error;
1058 
1059       elsif Droplen <= 0 then
1060          Result.Current_Length := Tlen;
1061          Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1062          Result.Data (Before .. Before + Nlen - 1) := New_Item;
1063          Result.Data (Before + Nlen .. Tlen) :=
1064            Source.Data (Before .. Slen);
1065 
1066       else
1067          Result.Current_Length := Max_Length;
1068 
1069          case Drop is
1070             when Strings.Right =>
1071                Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1072 
1073                if Droplen > Alen then
1074                   Result.Data (Before .. Max_Length) :=
1075                     New_Item (New_Item'First
1076                                 .. New_Item'First + Max_Length - Before);
1077                else
1078                   Result.Data (Before .. Before + Nlen - 1) := New_Item;
1079                   Result.Data (Before + Nlen .. Max_Length) :=
1080                     Source.Data (Before .. Slen - Droplen);
1081                end if;
1082 
1083             when Strings.Left =>
1084                Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
1085                  Source.Data (Before .. Slen);
1086 
1087                if Droplen >= Blen then
1088                   Result.Data (1 .. Max_Length - Alen) :=
1089                     New_Item (New_Item'Last - (Max_Length - Alen) + 1
1090                                 .. New_Item'Last);
1091                else
1092                   Result.Data
1093                     (Blen - Droplen + 1 .. Max_Length - Alen) :=
1094                     New_Item;
1095                   Result.Data (1 .. Blen - Droplen) :=
1096                     Source.Data (Droplen + 1 .. Blen);
1097                end if;
1098 
1099             when Strings.Error =>
1100                raise Ada.Strings.Length_Error;
1101          end case;
1102       end if;
1103 
1104       return Result;
1105    end Super_Insert;
1106 
1107    procedure Super_Insert
1108      (Source   : in out Super_String;
1109       Before   : Positive;
1110       New_Item : Wide_String;
1111       Drop     : Strings.Truncation := Strings.Error)
1112    is
1113    begin
1114       --  We do a double copy here because this is one of the situations
1115       --  in which we move data to the right, and at least at the moment,
1116       --  GNAT is not handling such cases correctly ???
1117 
1118       Source := Super_Insert (Source, Before, New_Item, Drop);
1119    end Super_Insert;
1120 
1121    ------------------
1122    -- Super_Length --
1123    ------------------
1124 
1125    function Super_Length (Source : Super_String) return Natural is
1126    begin
1127       return Source.Current_Length;
1128    end Super_Length;
1129 
1130    ---------------------
1131    -- Super_Overwrite --
1132    ---------------------
1133 
1134    function Super_Overwrite
1135      (Source   : Super_String;
1136       Position : Positive;
1137       New_Item : Wide_String;
1138       Drop     : Strings.Truncation := Strings.Error) return Super_String
1139    is
1140       Max_Length : constant Positive := Source.Max_Length;
1141       Result     : Super_String (Max_Length);
1142       Endpos     : constant Natural  := Position + New_Item'Length - 1;
1143       Slen       : constant Natural  := Source.Current_Length;
1144       Droplen    : Natural;
1145 
1146    begin
1147       if Position > Slen + 1 then
1148          raise Ada.Strings.Index_Error;
1149 
1150       elsif New_Item'Length = 0 then
1151          return Source;
1152 
1153       elsif Endpos <= Slen then
1154          Result.Current_Length := Source.Current_Length;
1155          Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
1156          Result.Data (Position .. Endpos) := New_Item;
1157          return Result;
1158 
1159       elsif Endpos <= Max_Length then
1160          Result.Current_Length := Endpos;
1161          Result.Data (1 .. Position - 1) := Source.Data (1 .. Position - 1);
1162          Result.Data (Position .. Endpos) := New_Item;
1163          return Result;
1164 
1165       else
1166          Result.Current_Length := Max_Length;
1167          Droplen := Endpos - Max_Length;
1168 
1169          case Drop is
1170             when Strings.Right =>
1171                Result.Data (1 .. Position - 1) :=
1172                  Source.Data (1 .. Position - 1);
1173 
1174                Result.Data (Position .. Max_Length) :=
1175                  New_Item (New_Item'First .. New_Item'Last - Droplen);
1176                return Result;
1177 
1178             when Strings.Left =>
1179                if New_Item'Length >= Max_Length then
1180                   Result.Data (1 .. Max_Length) :=
1181                     New_Item (New_Item'Last - Max_Length + 1 ..
1182                                 New_Item'Last);
1183                   return Result;
1184 
1185                else
1186                   Result.Data (1 .. Max_Length - New_Item'Length) :=
1187                     Source.Data (Droplen + 1 .. Position - 1);
1188                   Result.Data
1189                     (Max_Length - New_Item'Length + 1 .. Max_Length) :=
1190                     New_Item;
1191                   return Result;
1192                end if;
1193 
1194             when Strings.Error =>
1195                raise Ada.Strings.Length_Error;
1196          end case;
1197       end if;
1198    end Super_Overwrite;
1199 
1200    procedure Super_Overwrite
1201      (Source    : in out Super_String;
1202       Position  : Positive;
1203       New_Item  : Wide_String;
1204       Drop      : Strings.Truncation := Strings.Error)
1205    is
1206       Max_Length : constant Positive := Source.Max_Length;
1207       Endpos     : constant Positive := Position + New_Item'Length - 1;
1208       Slen       : constant Natural  := Source.Current_Length;
1209       Droplen    : Natural;
1210 
1211    begin
1212       if Position > Slen + 1 then
1213          raise Ada.Strings.Index_Error;
1214 
1215       elsif Endpos <= Slen then
1216          Source.Data (Position .. Endpos) := New_Item;
1217 
1218       elsif Endpos <= Max_Length then
1219          Source.Data (Position .. Endpos) := New_Item;
1220          Source.Current_Length := Endpos;
1221 
1222       else
1223          Source.Current_Length := Max_Length;
1224          Droplen := Endpos - Max_Length;
1225 
1226          case Drop is
1227             when Strings.Right =>
1228                Source.Data (Position .. Max_Length) :=
1229                  New_Item (New_Item'First .. New_Item'Last - Droplen);
1230 
1231             when Strings.Left =>
1232                if New_Item'Length > Max_Length then
1233                   Source.Data (1 .. Max_Length) :=
1234                     New_Item (New_Item'Last - Max_Length + 1 ..
1235                                 New_Item'Last);
1236 
1237                else
1238                   Source.Data (1 .. Max_Length - New_Item'Length) :=
1239                     Source.Data (Droplen + 1 .. Position - 1);
1240 
1241                   Source.Data
1242                     (Max_Length - New_Item'Length + 1 .. Max_Length) :=
1243                     New_Item;
1244                end if;
1245 
1246             when Strings.Error =>
1247                raise Ada.Strings.Length_Error;
1248          end case;
1249       end if;
1250    end Super_Overwrite;
1251 
1252    ---------------------------
1253    -- Super_Replace_Element --
1254    ---------------------------
1255 
1256    procedure Super_Replace_Element
1257      (Source : in out Super_String;
1258       Index  : Positive;
1259       By     : Wide_Character)
1260    is
1261    begin
1262       if Index <= Source.Current_Length then
1263          Source.Data (Index) := By;
1264       else
1265          raise Ada.Strings.Index_Error;
1266       end if;
1267    end Super_Replace_Element;
1268 
1269    -------------------------
1270    -- Super_Replace_Slice --
1271    -------------------------
1272 
1273    function Super_Replace_Slice
1274      (Source : Super_String;
1275       Low    : Positive;
1276       High   : Natural;
1277       By     : Wide_String;
1278       Drop   : Strings.Truncation := Strings.Error) return Super_String
1279    is
1280       Max_Length : constant Positive := Source.Max_Length;
1281       Slen       : constant Natural  := Source.Current_Length;
1282 
1283    begin
1284       if Low > Slen + 1 then
1285          raise Strings.Index_Error;
1286 
1287       elsif High < Low then
1288          return Super_Insert (Source, Low, By, Drop);
1289 
1290       else
1291          declare
1292             Blen    : constant Natural := Natural'Max (0, Low - 1);
1293             Alen    : constant Natural := Natural'Max (0, Slen - High);
1294             Tlen    : constant Natural := Blen + By'Length + Alen;
1295             Droplen : constant Integer := Tlen - Max_Length;
1296             Result  : Super_String (Max_Length);
1297 
1298             --  Tlen is the total length of the result string before any
1299             --  truncation. Blen and Alen are the lengths of the pieces
1300             --  of the original string that end up in the result string
1301             --  before and after the replaced slice.
1302 
1303          begin
1304             if Droplen <= 0 then
1305                Result.Current_Length := Tlen;
1306                Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1307                Result.Data (Low .. Low + By'Length - 1) := By;
1308                Result.Data (Low + By'Length .. Tlen) :=
1309                  Source.Data (High + 1 .. Slen);
1310 
1311             else
1312                Result.Current_Length := Max_Length;
1313 
1314                case Drop is
1315                   when Strings.Right =>
1316                      Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1317 
1318                      if Droplen > Alen then
1319                         Result.Data (Low .. Max_Length) :=
1320                           By (By'First .. By'First + Max_Length - Low);
1321                      else
1322                         Result.Data (Low .. Low + By'Length - 1) := By;
1323                         Result.Data (Low + By'Length .. Max_Length) :=
1324                           Source.Data (High + 1 .. Slen - Droplen);
1325                      end if;
1326 
1327                   when Strings.Left =>
1328                      Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
1329                        Source.Data (High + 1 .. Slen);
1330 
1331                      if Droplen >= Blen then
1332                         Result.Data (1 .. Max_Length - Alen) :=
1333                           By (By'Last - (Max_Length - Alen) + 1 .. By'Last);
1334                      else
1335                         Result.Data
1336                           (Blen - Droplen + 1 .. Max_Length - Alen) := By;
1337                         Result.Data (1 .. Blen - Droplen) :=
1338                           Source.Data (Droplen + 1 .. Blen);
1339                      end if;
1340 
1341                   when Strings.Error =>
1342                      raise Ada.Strings.Length_Error;
1343                end case;
1344             end if;
1345 
1346             return Result;
1347          end;
1348       end if;
1349    end Super_Replace_Slice;
1350 
1351    procedure Super_Replace_Slice
1352      (Source   : in out Super_String;
1353       Low      : Positive;
1354       High     : Natural;
1355       By       : Wide_String;
1356       Drop     : Strings.Truncation := Strings.Error)
1357    is
1358    begin
1359       --  We do a double copy here because this is one of the situations
1360       --  in which we move data to the right, and at least at the moment,
1361       --  GNAT is not handling such cases correctly ???
1362 
1363       Source := Super_Replace_Slice (Source, Low, High, By, Drop);
1364    end Super_Replace_Slice;
1365 
1366    ---------------------
1367    -- Super_Replicate --
1368    ---------------------
1369 
1370    function Super_Replicate
1371      (Count      : Natural;
1372       Item       : Wide_Character;
1373       Drop       : Truncation := Error;
1374       Max_Length : Positive) return Super_String
1375    is
1376       Result : Super_String (Max_Length);
1377 
1378    begin
1379       if Count <= Max_Length then
1380          Result.Current_Length := Count;
1381 
1382       elsif Drop = Strings.Error then
1383          raise Ada.Strings.Length_Error;
1384 
1385       else
1386          Result.Current_Length := Max_Length;
1387       end if;
1388 
1389       Result.Data (1 .. Result.Current_Length) := (others => Item);
1390       return Result;
1391    end Super_Replicate;
1392 
1393    function Super_Replicate
1394      (Count      : Natural;
1395       Item       : Wide_String;
1396       Drop       : Truncation := Error;
1397       Max_Length : Positive) return Super_String
1398    is
1399       Length : constant Integer := Count * Item'Length;
1400       Result : Super_String (Max_Length);
1401       Indx   : Positive;
1402 
1403    begin
1404       if Length <= Max_Length then
1405          Result.Current_Length := Length;
1406 
1407          if Length > 0 then
1408             Indx := 1;
1409 
1410             for J in 1 .. Count loop
1411                Result.Data (Indx .. Indx + Item'Length - 1) := Item;
1412                Indx := Indx + Item'Length;
1413             end loop;
1414          end if;
1415 
1416       else
1417          Result.Current_Length := Max_Length;
1418 
1419          case Drop is
1420             when Strings.Right =>
1421                Indx := 1;
1422 
1423                while Indx + Item'Length <= Max_Length + 1 loop
1424                   Result.Data (Indx .. Indx + Item'Length - 1) := Item;
1425                   Indx := Indx + Item'Length;
1426                end loop;
1427 
1428                Result.Data (Indx .. Max_Length) :=
1429                  Item (Item'First .. Item'First + Max_Length - Indx);
1430 
1431             when Strings.Left =>
1432                Indx := Max_Length;
1433 
1434                while Indx - Item'Length >= 1 loop
1435                   Result.Data (Indx - (Item'Length - 1) .. Indx) := Item;
1436                   Indx := Indx - Item'Length;
1437                end loop;
1438 
1439                Result.Data (1 .. Indx) :=
1440                  Item (Item'Last - Indx + 1 .. Item'Last);
1441 
1442             when Strings.Error =>
1443                raise Ada.Strings.Length_Error;
1444          end case;
1445       end if;
1446 
1447       return Result;
1448    end Super_Replicate;
1449 
1450    function Super_Replicate
1451      (Count : Natural;
1452       Item  : Super_String;
1453       Drop  : Strings.Truncation := Strings.Error) return Super_String
1454    is
1455    begin
1456       return
1457         Super_Replicate
1458           (Count,
1459            Item.Data (1 .. Item.Current_Length),
1460            Drop,
1461            Item.Max_Length);
1462    end Super_Replicate;
1463 
1464    -----------------
1465    -- Super_Slice --
1466    -----------------
1467 
1468    function Super_Slice
1469      (Source : Super_String;
1470       Low    : Positive;
1471       High   : Natural) return Wide_String
1472    is
1473    begin
1474       --  Note: test of High > Length is in accordance with AI95-00128
1475 
1476       return R : Wide_String (Low .. High) do
1477          if Low > Source.Current_Length + 1
1478            or else High > Source.Current_Length
1479          then
1480             raise Index_Error;
1481          end if;
1482 
1483          R := Source.Data (Low .. High);
1484       end return;
1485    end Super_Slice;
1486 
1487    function Super_Slice
1488      (Source : Super_String;
1489       Low    : Positive;
1490       High   : Natural) return Super_String
1491    is
1492    begin
1493       return Result : Super_String (Source.Max_Length) do
1494          if Low > Source.Current_Length + 1
1495            or else High > Source.Current_Length
1496          then
1497             raise Index_Error;
1498          end if;
1499 
1500          Result.Current_Length := High - Low + 1;
1501          Result.Data (1 .. Result.Current_Length) := Source.Data (Low .. High);
1502       end return;
1503    end Super_Slice;
1504 
1505    procedure Super_Slice
1506      (Source : Super_String;
1507       Target : out Super_String;
1508       Low    : Positive;
1509       High   : Natural)
1510    is
1511    begin
1512       if Low > Source.Current_Length + 1
1513         or else High > Source.Current_Length
1514       then
1515          raise Index_Error;
1516       else
1517          Target.Current_Length := High - Low + 1;
1518          Target.Data (1 .. Target.Current_Length) := Source.Data (Low .. High);
1519       end if;
1520    end Super_Slice;
1521 
1522    ----------------
1523    -- Super_Tail --
1524    ----------------
1525 
1526    function Super_Tail
1527      (Source : Super_String;
1528       Count  : Natural;
1529       Pad    : Wide_Character := Wide_Space;
1530       Drop   : Strings.Truncation := Strings.Error) return Super_String
1531    is
1532       Max_Length : constant Positive := Source.Max_Length;
1533       Result     : Super_String (Max_Length);
1534       Slen       : constant Natural := Source.Current_Length;
1535       Npad       : constant Integer := Count - Slen;
1536 
1537    begin
1538       if Npad <= 0 then
1539          Result.Current_Length := Count;
1540          Result.Data (1 .. Count) :=
1541            Source.Data (Slen - (Count - 1) .. Slen);
1542 
1543       elsif Count <= Max_Length then
1544          Result.Current_Length := Count;
1545          Result.Data (1 .. Npad) := (others => Pad);
1546          Result.Data (Npad + 1 .. Count) := Source.Data (1 .. Slen);
1547 
1548       else
1549          Result.Current_Length := Max_Length;
1550 
1551          case Drop is
1552             when Strings.Right =>
1553                if Npad >= Max_Length then
1554                   Result.Data := (others => Pad);
1555 
1556                else
1557                   Result.Data (1 .. Npad) := (others => Pad);
1558                   Result.Data (Npad + 1 .. Max_Length) :=
1559                     Source.Data (1 .. Max_Length - Npad);
1560                end if;
1561 
1562             when Strings.Left =>
1563                Result.Data (1 .. Max_Length - Slen) := (others => Pad);
1564                Result.Data (Max_Length - Slen + 1 .. Max_Length) :=
1565                  Source.Data (1 .. Slen);
1566 
1567             when Strings.Error =>
1568                raise Ada.Strings.Length_Error;
1569          end case;
1570       end if;
1571 
1572       return Result;
1573    end Super_Tail;
1574 
1575    procedure Super_Tail
1576      (Source : in out Super_String;
1577       Count  : Natural;
1578       Pad    : Wide_Character := Wide_Space;
1579       Drop   : Truncation := Error)
1580    is
1581       Max_Length : constant Positive := Source.Max_Length;
1582       Slen       : constant Natural  := Source.Current_Length;
1583       Npad       : constant Integer  := Count - Slen;
1584 
1585       Temp : constant Wide_String (1 .. Max_Length) := Source.Data;
1586 
1587    begin
1588       if Npad <= 0 then
1589          Source.Current_Length := Count;
1590          Source.Data (1 .. Count) :=
1591            Temp (Slen - (Count - 1) .. Slen);
1592 
1593       elsif Count <= Max_Length then
1594          Source.Current_Length := Count;
1595          Source.Data (1 .. Npad) := (others => Pad);
1596          Source.Data (Npad + 1 .. Count) := Temp (1 .. Slen);
1597 
1598       else
1599          Source.Current_Length := Max_Length;
1600 
1601          case Drop is
1602             when Strings.Right =>
1603                if Npad >= Max_Length then
1604                   Source.Data := (others => Pad);
1605 
1606                else
1607                   Source.Data (1 .. Npad) := (others => Pad);
1608                   Source.Data (Npad + 1 .. Max_Length) :=
1609                     Temp (1 .. Max_Length - Npad);
1610                end if;
1611 
1612             when Strings.Left =>
1613                for J in 1 .. Max_Length - Slen loop
1614                   Source.Data (J) := Pad;
1615                end loop;
1616 
1617                Source.Data (Max_Length - Slen + 1 .. Max_Length) :=
1618                  Temp (1 .. Slen);
1619 
1620             when Strings.Error =>
1621                raise Ada.Strings.Length_Error;
1622          end case;
1623       end if;
1624    end Super_Tail;
1625 
1626    ---------------------
1627    -- Super_To_String --
1628    ---------------------
1629 
1630    function Super_To_String (Source : Super_String) return Wide_String is
1631    begin
1632       return R : Wide_String (1 .. Source.Current_Length) do
1633          R := Source.Data (1 .. Source.Current_Length);
1634       end return;
1635    end Super_To_String;
1636 
1637    ---------------------
1638    -- Super_Translate --
1639    ---------------------
1640 
1641    function Super_Translate
1642      (Source  : Super_String;
1643       Mapping : Wide_Maps.Wide_Character_Mapping) return Super_String
1644    is
1645       Result : Super_String (Source.Max_Length);
1646 
1647    begin
1648       Result.Current_Length := Source.Current_Length;
1649 
1650       for J in 1 .. Source.Current_Length loop
1651          Result.Data (J) := Value (Mapping, Source.Data (J));
1652       end loop;
1653 
1654       return Result;
1655    end Super_Translate;
1656 
1657    procedure Super_Translate
1658      (Source  : in out Super_String;
1659       Mapping : Wide_Maps.Wide_Character_Mapping)
1660    is
1661    begin
1662       for J in 1 .. Source.Current_Length loop
1663          Source.Data (J) := Value (Mapping, Source.Data (J));
1664       end loop;
1665    end Super_Translate;
1666 
1667    function Super_Translate
1668      (Source  : Super_String;
1669       Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Super_String
1670    is
1671       Result : Super_String (Source.Max_Length);
1672 
1673    begin
1674       Result.Current_Length := Source.Current_Length;
1675 
1676       for J in 1 .. Source.Current_Length loop
1677          Result.Data (J) := Mapping.all (Source.Data (J));
1678       end loop;
1679 
1680       return Result;
1681    end Super_Translate;
1682 
1683    procedure Super_Translate
1684      (Source  : in out Super_String;
1685       Mapping : Wide_Maps.Wide_Character_Mapping_Function)
1686    is
1687    begin
1688       for J in 1 .. Source.Current_Length loop
1689          Source.Data (J) := Mapping.all (Source.Data (J));
1690       end loop;
1691    end Super_Translate;
1692 
1693    ----------------
1694    -- Super_Trim --
1695    ----------------
1696 
1697    function Super_Trim
1698      (Source : Super_String;
1699       Side   : Trim_End) return Super_String
1700    is
1701       Result : Super_String (Source.Max_Length);
1702       Last   : Natural := Source.Current_Length;
1703       First  : Positive := 1;
1704 
1705    begin
1706       if Side = Left or else Side = Both then
1707          while First <= Last and then Source.Data (First) = ' ' loop
1708             First := First + 1;
1709          end loop;
1710       end if;
1711 
1712       if Side = Right or else Side = Both then
1713          while Last >= First and then Source.Data (Last) = ' ' loop
1714             Last := Last - 1;
1715          end loop;
1716       end if;
1717 
1718       Result.Current_Length := Last - First + 1;
1719       Result.Data (1 .. Result.Current_Length) := Source.Data (First .. Last);
1720       return Result;
1721    end Super_Trim;
1722 
1723    procedure Super_Trim
1724      (Source : in out Super_String;
1725       Side   : Trim_End)
1726    is
1727       Max_Length : constant Positive := Source.Max_Length;
1728       Last       : Natural           := Source.Current_Length;
1729       First      : Positive          := 1;
1730       Temp       : Wide_String (1 .. Max_Length);
1731 
1732    begin
1733       Temp (1 .. Last) := Source.Data (1 .. Last);
1734 
1735       if Side = Left or else Side = Both then
1736          while First <= Last and then Temp (First) = ' ' loop
1737             First := First + 1;
1738          end loop;
1739       end if;
1740 
1741       if Side = Right or else Side = Both then
1742          while Last >= First and then Temp (Last) = ' ' loop
1743             Last := Last - 1;
1744          end loop;
1745       end if;
1746 
1747       Source.Data := (others => Wide_NUL);
1748       Source.Current_Length := Last - First + 1;
1749       Source.Data (1 .. Source.Current_Length) := Temp (First .. Last);
1750    end Super_Trim;
1751 
1752    function Super_Trim
1753      (Source : Super_String;
1754       Left   : Wide_Maps.Wide_Character_Set;
1755       Right  : Wide_Maps.Wide_Character_Set) return Super_String
1756    is
1757       Result : Super_String (Source.Max_Length);
1758 
1759    begin
1760       for First in 1 .. Source.Current_Length loop
1761          if not Is_In (Source.Data (First), Left) then
1762             for Last in reverse First .. Source.Current_Length loop
1763                if not Is_In (Source.Data (Last), Right) then
1764                   Result.Current_Length := Last - First + 1;
1765                   Result.Data (1 .. Result.Current_Length) :=
1766                     Source.Data (First .. Last);
1767                   return Result;
1768                end if;
1769             end loop;
1770          end if;
1771       end loop;
1772 
1773       Result.Current_Length := 0;
1774       return Result;
1775    end Super_Trim;
1776 
1777    procedure Super_Trim
1778      (Source : in out Super_String;
1779       Left   : Wide_Maps.Wide_Character_Set;
1780       Right  : Wide_Maps.Wide_Character_Set)
1781    is
1782    begin
1783       for First in 1 .. Source.Current_Length loop
1784          if not Is_In (Source.Data (First), Left) then
1785             for Last in reverse First .. Source.Current_Length loop
1786                if not Is_In (Source.Data (Last), Right) then
1787                   if First = 1 then
1788                      Source.Current_Length := Last;
1789                      return;
1790                   else
1791                      Source.Current_Length := Last - First + 1;
1792                      Source.Data (1 .. Source.Current_Length) :=
1793                        Source.Data (First .. Last);
1794 
1795                      for J in Source.Current_Length + 1 ..
1796                                 Source.Max_Length
1797                      loop
1798                         Source.Data (J) := Wide_NUL;
1799                      end loop;
1800 
1801                      return;
1802                   end if;
1803                end if;
1804             end loop;
1805 
1806             Source.Current_Length := 0;
1807             return;
1808          end if;
1809       end loop;
1810 
1811       Source.Current_Length := 0;
1812    end Super_Trim;
1813 
1814    -----------
1815    -- Times --
1816    -----------
1817 
1818    function Times
1819      (Left       : Natural;
1820       Right      : Wide_Character;
1821       Max_Length : Positive) return Super_String
1822    is
1823       Result : Super_String (Max_Length);
1824 
1825    begin
1826       if Left > Max_Length then
1827          raise Ada.Strings.Length_Error;
1828 
1829       else
1830          Result.Current_Length := Left;
1831 
1832          for J in 1 .. Left loop
1833             Result.Data (J) := Right;
1834          end loop;
1835       end if;
1836 
1837       return Result;
1838    end Times;
1839 
1840    function Times
1841      (Left       : Natural;
1842       Right      : Wide_String;
1843       Max_Length : Positive) return Super_String
1844    is
1845       Result : Super_String (Max_Length);
1846       Pos    : Positive         := 1;
1847       Rlen   : constant Natural := Right'Length;
1848       Nlen   : constant Natural := Left * Rlen;
1849 
1850    begin
1851       if Nlen > Max_Length then
1852          raise Ada.Strings.Index_Error;
1853 
1854       else
1855          Result.Current_Length := Nlen;
1856 
1857          if Nlen > 0 then
1858             for J in 1 .. Left loop
1859                Result.Data (Pos .. Pos + Rlen - 1) := Right;
1860                Pos := Pos + Rlen;
1861             end loop;
1862          end if;
1863       end if;
1864 
1865       return Result;
1866    end Times;
1867 
1868    function Times
1869      (Left  : Natural;
1870       Right : Super_String) return Super_String
1871    is
1872       Result : Super_String (Right.Max_Length);
1873       Pos    : Positive := 1;
1874       Rlen   : constant Natural := Right.Current_Length;
1875       Nlen   : constant Natural := Left * Rlen;
1876 
1877    begin
1878       if Nlen > Right.Max_Length then
1879          raise Ada.Strings.Length_Error;
1880 
1881       else
1882          Result.Current_Length := Nlen;
1883 
1884          if Nlen > 0 then
1885             for J in 1 .. Left loop
1886                Result.Data (Pos .. Pos + Rlen - 1) :=
1887                  Right.Data (1 .. Rlen);
1888                Pos := Pos + Rlen;
1889             end loop;
1890          end if;
1891       end if;
1892 
1893       return Result;
1894    end Times;
1895 
1896    ---------------------
1897    -- To_Super_String --
1898    ---------------------
1899 
1900    function To_Super_String
1901      (Source     : Wide_String;
1902       Max_Length : Natural;
1903       Drop       : Truncation := Error) return Super_String
1904    is
1905       Result : Super_String (Max_Length);
1906       Slen   : constant Natural := Source'Length;
1907 
1908    begin
1909       if Slen <= Max_Length then
1910          Result.Current_Length := Slen;
1911          Result.Data (1 .. Slen) := Source;
1912 
1913       else
1914          case Drop is
1915             when Strings.Right =>
1916                Result.Current_Length := Max_Length;
1917                Result.Data (1 .. Max_Length) :=
1918                  Source (Source'First .. Source'First - 1 + Max_Length);
1919 
1920             when Strings.Left =>
1921                Result.Current_Length := Max_Length;
1922                Result.Data (1 .. Max_Length) :=
1923                  Source (Source'Last - (Max_Length - 1) .. Source'Last);
1924 
1925             when Strings.Error =>
1926                raise Ada.Strings.Length_Error;
1927          end case;
1928       end if;
1929 
1930       return Result;
1931    end To_Super_String;
1932 
1933 end Ada.Strings.Wide_Superbounded;