OSDN Git Service

2012-01-10 Bob Duff <duff@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / a-stwiun.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT RUN-TIME COMPONENTS                         --
4 --                                                                          --
5 --           A D A . S T R I N G S . W I D E _ U N B O U N D E D            --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1992-2010, 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 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception,   --
20 -- version 3.1, as published by the Free Software Foundation.               --
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_Fixed;
33 with Ada.Strings.Wide_Search;
34 with Ada.Unchecked_Deallocation;
35
36 package body Ada.Strings.Wide_Unbounded is
37
38    use Ada.Finalization;
39
40    ---------
41    -- "&" --
42    ---------
43
44    function "&"
45      (Left  : Unbounded_Wide_String;
46       Right : Unbounded_Wide_String) return Unbounded_Wide_String
47    is
48       L_Length : constant Natural := Left.Last;
49       R_Length : constant Natural := Right.Last;
50       Result   : Unbounded_Wide_String;
51
52    begin
53       Result.Last := L_Length + R_Length;
54
55       Result.Reference := new Wide_String (1 .. Result.Last);
56
57       Result.Reference (1 .. L_Length) :=
58         Left.Reference (1 .. Left.Last);
59       Result.Reference (L_Length + 1 .. Result.Last) :=
60         Right.Reference (1 .. Right.Last);
61
62       return Result;
63    end "&";
64
65    function "&"
66      (Left  : Unbounded_Wide_String;
67       Right : Wide_String) return Unbounded_Wide_String
68    is
69       L_Length : constant Natural := Left.Last;
70       Result   : Unbounded_Wide_String;
71
72    begin
73       Result.Last := L_Length + Right'Length;
74
75       Result.Reference := new Wide_String (1 .. Result.Last);
76
77       Result.Reference (1 .. L_Length) := Left.Reference (1 .. Left.Last);
78       Result.Reference (L_Length + 1 .. Result.Last) := Right;
79
80       return Result;
81    end "&";
82
83    function "&"
84      (Left  : Wide_String;
85       Right : Unbounded_Wide_String) return Unbounded_Wide_String
86    is
87       R_Length : constant Natural := Right.Last;
88       Result   : Unbounded_Wide_String;
89
90    begin
91       Result.Last := Left'Length + R_Length;
92
93       Result.Reference := new Wide_String (1 .. Result.Last);
94
95       Result.Reference (1 .. Left'Length) := Left;
96       Result.Reference (Left'Length + 1 .. Result.Last) :=
97         Right.Reference (1 .. Right.Last);
98
99       return Result;
100    end "&";
101
102    function "&"
103      (Left  : Unbounded_Wide_String;
104       Right : Wide_Character) return Unbounded_Wide_String
105    is
106       Result : Unbounded_Wide_String;
107
108    begin
109       Result.Last := Left.Last + 1;
110
111       Result.Reference := new Wide_String (1 .. Result.Last);
112
113       Result.Reference (1 .. Result.Last - 1) :=
114         Left.Reference (1 .. Left.Last);
115       Result.Reference (Result.Last) := Right;
116
117       return Result;
118    end "&";
119
120    function "&"
121      (Left  : Wide_Character;
122       Right : Unbounded_Wide_String) return Unbounded_Wide_String
123    is
124       Result : Unbounded_Wide_String;
125
126    begin
127       Result.Last := Right.Last + 1;
128
129       Result.Reference := new Wide_String (1 .. Result.Last);
130       Result.Reference (1) := Left;
131       Result.Reference (2 .. Result.Last) :=
132         Right.Reference (1 .. Right.Last);
133       return Result;
134    end "&";
135
136    ---------
137    -- "*" --
138    ---------
139
140    function "*"
141      (Left  : Natural;
142       Right : Wide_Character) return Unbounded_Wide_String
143    is
144       Result : Unbounded_Wide_String;
145
146    begin
147       Result.Last   := Left;
148
149       Result.Reference := new Wide_String (1 .. Left);
150       for J in Result.Reference'Range loop
151          Result.Reference (J) := Right;
152       end loop;
153
154       return Result;
155    end "*";
156
157    function "*"
158      (Left  : Natural;
159       Right : Wide_String) return Unbounded_Wide_String
160    is
161       Len    : constant Natural := Right'Length;
162       K      : Positive;
163       Result : Unbounded_Wide_String;
164
165    begin
166       Result.Last := Left * Len;
167
168       Result.Reference := new Wide_String (1 .. Result.Last);
169
170       K := 1;
171       for J in 1 .. Left loop
172          Result.Reference (K .. K + Len - 1) := Right;
173          K := K + Len;
174       end loop;
175
176       return Result;
177    end "*";
178
179    function "*"
180      (Left  : Natural;
181       Right : Unbounded_Wide_String) return Unbounded_Wide_String
182    is
183       Len    : constant Natural := Right.Last;
184       K      : Positive;
185       Result : Unbounded_Wide_String;
186
187    begin
188       Result.Last := Left * Len;
189
190       Result.Reference := new Wide_String (1 .. Result.Last);
191
192       K := 1;
193       for J in 1 .. Left loop
194          Result.Reference (K .. K + Len - 1) :=
195            Right.Reference (1 .. Right.Last);
196          K := K + Len;
197       end loop;
198
199       return Result;
200    end "*";
201
202    ---------
203    -- "<" --
204    ---------
205
206    function "<"
207      (Left  : Unbounded_Wide_String;
208       Right : Unbounded_Wide_String) return Boolean
209    is
210    begin
211       return
212         Left.Reference (1 .. Left.Last) < Right.Reference (1 .. Right.Last);
213    end "<";
214
215    function "<"
216      (Left  : Unbounded_Wide_String;
217       Right : Wide_String) return Boolean
218    is
219    begin
220       return Left.Reference (1 .. Left.Last) < Right;
221    end "<";
222
223    function "<"
224      (Left  : Wide_String;
225       Right : Unbounded_Wide_String) return Boolean
226    is
227    begin
228       return Left < Right.Reference (1 .. Right.Last);
229    end "<";
230
231    ----------
232    -- "<=" --
233    ----------
234
235    function "<="
236      (Left  : Unbounded_Wide_String;
237       Right : Unbounded_Wide_String) return Boolean
238    is
239    begin
240       return
241         Left.Reference (1 .. Left.Last) <= Right.Reference (1 .. Right.Last);
242    end "<=";
243
244    function "<="
245      (Left  : Unbounded_Wide_String;
246       Right : Wide_String) return Boolean
247    is
248    begin
249       return Left.Reference (1 .. Left.Last) <= Right;
250    end "<=";
251
252    function "<="
253      (Left  : Wide_String;
254       Right : Unbounded_Wide_String) return Boolean
255    is
256    begin
257       return Left <= Right.Reference (1 .. Right.Last);
258    end "<=";
259
260    ---------
261    -- "=" --
262    ---------
263
264    function "="
265      (Left  : Unbounded_Wide_String;
266       Right : Unbounded_Wide_String) return Boolean
267    is
268    begin
269       return
270         Left.Reference (1 .. Left.Last) = Right.Reference (1 .. Right.Last);
271    end "=";
272
273    function "="
274      (Left  : Unbounded_Wide_String;
275       Right : Wide_String) return Boolean
276    is
277    begin
278       return Left.Reference (1 .. Left.Last) = Right;
279    end "=";
280
281    function "="
282      (Left  : Wide_String;
283       Right : Unbounded_Wide_String) return Boolean
284    is
285    begin
286       return Left = Right.Reference (1 .. Right.Last);
287    end "=";
288
289    ---------
290    -- ">" --
291    ---------
292
293    function ">"
294      (Left  : Unbounded_Wide_String;
295       Right : Unbounded_Wide_String) return Boolean
296    is
297    begin
298       return
299         Left.Reference (1 .. Left.Last) > Right.Reference (1 .. Right.Last);
300    end ">";
301
302    function ">"
303      (Left  : Unbounded_Wide_String;
304       Right : Wide_String) return Boolean
305    is
306    begin
307       return Left.Reference (1 .. Left.Last) > Right;
308    end ">";
309
310    function ">"
311      (Left  : Wide_String;
312       Right : Unbounded_Wide_String) return Boolean
313    is
314    begin
315       return Left > Right.Reference (1 .. Right.Last);
316    end ">";
317
318    ----------
319    -- ">=" --
320    ----------
321
322    function ">="
323      (Left  : Unbounded_Wide_String;
324       Right : Unbounded_Wide_String) return Boolean
325    is
326    begin
327       return
328         Left.Reference (1 .. Left.Last) >= Right.Reference (1 .. Right.Last);
329    end ">=";
330
331    function ">="
332      (Left  : Unbounded_Wide_String;
333       Right : Wide_String) return Boolean
334    is
335    begin
336       return Left.Reference (1 .. Left.Last) >= Right;
337    end ">=";
338
339    function ">="
340      (Left  : Wide_String;
341       Right : Unbounded_Wide_String) return Boolean
342    is
343    begin
344       return Left >= Right.Reference (1 .. Right.Last);
345    end ">=";
346
347    ------------
348    -- Adjust --
349    ------------
350
351    procedure Adjust (Object : in out Unbounded_Wide_String) is
352    begin
353       --  Copy string, except we do not copy the statically allocated null
354       --  string, since it can never be deallocated. Note that we do not copy
355       --  extra string room here to avoid dragging unused allocated memory.
356
357       if Object.Reference /= Null_Wide_String'Access then
358          Object.Reference :=
359            new Wide_String'(Object.Reference (1 .. Object.Last));
360       end if;
361    end Adjust;
362
363    ------------
364    -- Append --
365    ------------
366
367    procedure Append
368      (Source   : in out Unbounded_Wide_String;
369       New_Item : Unbounded_Wide_String)
370    is
371    begin
372       Realloc_For_Chunk (Source, New_Item.Last);
373       Source.Reference (Source.Last + 1 .. Source.Last + New_Item.Last) :=
374         New_Item.Reference (1 .. New_Item.Last);
375       Source.Last := Source.Last + New_Item.Last;
376    end Append;
377
378    procedure Append
379      (Source   : in out Unbounded_Wide_String;
380       New_Item : Wide_String)
381    is
382    begin
383       Realloc_For_Chunk (Source, New_Item'Length);
384       Source.Reference (Source.Last + 1 .. Source.Last + New_Item'Length) :=
385         New_Item;
386       Source.Last := Source.Last + New_Item'Length;
387    end Append;
388
389    procedure Append
390      (Source   : in out Unbounded_Wide_String;
391       New_Item : Wide_Character)
392    is
393    begin
394       Realloc_For_Chunk (Source, 1);
395       Source.Reference (Source.Last + 1) := New_Item;
396       Source.Last := Source.Last + 1;
397    end Append;
398
399    -----------
400    -- Count --
401    -----------
402
403    function Count
404      (Source  : Unbounded_Wide_String;
405       Pattern : Wide_String;
406       Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
407       return Natural
408    is
409    begin
410       return
411         Wide_Search.Count
412           (Source.Reference (1 .. Source.Last), Pattern, Mapping);
413    end Count;
414
415    function Count
416      (Source  : Unbounded_Wide_String;
417       Pattern : Wide_String;
418       Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural
419    is
420    begin
421       return
422         Wide_Search.Count
423           (Source.Reference (1 .. Source.Last), Pattern, Mapping);
424    end Count;
425
426    function Count
427      (Source : Unbounded_Wide_String;
428       Set    : Wide_Maps.Wide_Character_Set) return Natural
429    is
430    begin
431       return
432         Wide_Search.Count
433         (Source.Reference (1 .. Source.Last), Set);
434    end Count;
435
436    ------------
437    -- Delete --
438    ------------
439
440    function Delete
441      (Source  : Unbounded_Wide_String;
442       From    : Positive;
443       Through : Natural) return Unbounded_Wide_String
444    is
445    begin
446       return
447         To_Unbounded_Wide_String
448           (Wide_Fixed.Delete
449              (Source.Reference (1 .. Source.Last), From, Through));
450    end Delete;
451
452    procedure Delete
453      (Source  : in out Unbounded_Wide_String;
454       From    : Positive;
455       Through : Natural)
456    is
457    begin
458       if From > Through then
459          null;
460
461       elsif From < Source.Reference'First or else Through > Source.Last then
462          raise Index_Error;
463
464       else
465          declare
466             Len : constant Natural := Through - From + 1;
467
468          begin
469             Source.Reference (From .. Source.Last - Len) :=
470               Source.Reference (Through + 1 .. Source.Last);
471             Source.Last := Source.Last - Len;
472          end;
473       end if;
474    end Delete;
475
476    -------------
477    -- Element --
478    -------------
479
480    function Element
481      (Source : Unbounded_Wide_String;
482       Index  : Positive) return Wide_Character
483    is
484    begin
485       if Index <= Source.Last then
486          return Source.Reference (Index);
487       else
488          raise Strings.Index_Error;
489       end if;
490    end Element;
491
492    --------------
493    -- Finalize --
494    --------------
495
496    procedure Finalize (Object : in out Unbounded_Wide_String) is
497       procedure Deallocate is
498          new Ada.Unchecked_Deallocation (Wide_String, Wide_String_Access);
499
500    begin
501       --  Note: Don't try to free statically allocated null string
502
503       if Object.Reference /= Null_Wide_String'Access then
504          Deallocate (Object.Reference);
505          Object.Reference := Null_Unbounded_Wide_String.Reference;
506          Object.Last := 0;
507       end if;
508    end Finalize;
509
510    ----------------
511    -- Find_Token --
512    ----------------
513
514    procedure Find_Token
515      (Source : Unbounded_Wide_String;
516       Set    : Wide_Maps.Wide_Character_Set;
517       From   : Positive;
518       Test   : Strings.Membership;
519       First  : out Positive;
520       Last   : out Natural)
521    is
522    begin
523       Wide_Search.Find_Token
524         (Source.Reference (From .. Source.Last), Set, Test, First, Last);
525    end Find_Token;
526
527    procedure Find_Token
528      (Source : Unbounded_Wide_String;
529       Set    : Wide_Maps.Wide_Character_Set;
530       Test   : Strings.Membership;
531       First  : out Positive;
532       Last   : out Natural)
533    is
534    begin
535       Wide_Search.Find_Token
536         (Source.Reference (1 .. Source.Last), Set, Test, First, Last);
537    end Find_Token;
538
539    ----------
540    -- Free --
541    ----------
542
543    procedure Free (X : in out Wide_String_Access) is
544       procedure Deallocate is
545          new Ada.Unchecked_Deallocation (Wide_String, Wide_String_Access);
546
547    begin
548       --  Note: Do not try to free statically allocated null string
549
550       if X /= Null_Unbounded_Wide_String.Reference then
551          Deallocate (X);
552       end if;
553    end Free;
554
555    ----------
556    -- Head --
557    ----------
558
559    function Head
560      (Source : Unbounded_Wide_String;
561       Count  : Natural;
562       Pad    : Wide_Character := Wide_Space) return Unbounded_Wide_String
563    is
564    begin
565       return To_Unbounded_Wide_String
566         (Wide_Fixed.Head (Source.Reference (1 .. Source.Last), Count, Pad));
567    end Head;
568
569    procedure Head
570      (Source : in out Unbounded_Wide_String;
571       Count  : Natural;
572       Pad    : Wide_Character := Wide_Space)
573    is
574       Old : Wide_String_Access := Source.Reference;
575    begin
576       Source.Reference :=
577         new Wide_String'
578           (Wide_Fixed.Head (Source.Reference (1 .. Source.Last), Count, Pad));
579       Source.Last := Source.Reference'Length;
580       Free (Old);
581    end Head;
582
583    -----------
584    -- Index --
585    -----------
586
587    function Index
588      (Source  : Unbounded_Wide_String;
589       Pattern : Wide_String;
590       Going   : Strings.Direction := Strings.Forward;
591       Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
592       return Natural
593    is
594    begin
595       return
596         Wide_Search.Index
597           (Source.Reference (1 .. Source.Last), Pattern, Going, Mapping);
598    end Index;
599
600    function Index
601      (Source  : Unbounded_Wide_String;
602       Pattern : Wide_String;
603       Going   : Direction := Forward;
604       Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural
605    is
606    begin
607       return
608         Wide_Search.Index
609           (Source.Reference (1 .. Source.Last), Pattern, Going, Mapping);
610    end Index;
611
612    function Index
613      (Source : Unbounded_Wide_String;
614       Set    : Wide_Maps.Wide_Character_Set;
615       Test   : Strings.Membership := Strings.Inside;
616       Going  : Strings.Direction  := Strings.Forward) return Natural
617    is
618    begin
619       return Wide_Search.Index
620         (Source.Reference (1 .. Source.Last), Set, Test, Going);
621    end Index;
622
623    function Index
624      (Source  : Unbounded_Wide_String;
625       Pattern : Wide_String;
626       From    : Positive;
627       Going   : Direction := Forward;
628       Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
629       return Natural
630    is
631    begin
632       return
633         Wide_Search.Index
634           (Source.Reference (1 .. Source.Last), Pattern, From, Going, Mapping);
635    end Index;
636
637    function Index
638      (Source  : Unbounded_Wide_String;
639       Pattern : Wide_String;
640       From    : Positive;
641       Going   : Direction := Forward;
642       Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural
643    is
644    begin
645       return
646         Wide_Search.Index
647           (Source.Reference (1 .. Source.Last), Pattern, From, Going, Mapping);
648    end Index;
649
650    function Index
651      (Source  : Unbounded_Wide_String;
652       Set     : Wide_Maps.Wide_Character_Set;
653       From    : Positive;
654       Test    : Membership := Inside;
655       Going   : Direction := Forward) return Natural
656    is
657    begin
658       return
659         Wide_Search.Index
660           (Source.Reference (1 .. Source.Last), Set, From, Test, Going);
661    end Index;
662
663    function Index_Non_Blank
664      (Source : Unbounded_Wide_String;
665       Going  : Strings.Direction := Strings.Forward) return Natural
666    is
667    begin
668       return
669         Wide_Search.Index_Non_Blank
670           (Source.Reference (1 .. Source.Last), Going);
671    end Index_Non_Blank;
672
673    function Index_Non_Blank
674      (Source : Unbounded_Wide_String;
675       From   : Positive;
676       Going  : Direction := Forward) return Natural
677    is
678    begin
679       return
680         Wide_Search.Index_Non_Blank
681           (Source.Reference (1 .. Source.Last), From, Going);
682    end Index_Non_Blank;
683
684    ----------------
685    -- Initialize --
686    ----------------
687
688    procedure Initialize (Object : in out Unbounded_Wide_String) is
689    begin
690       Object.Reference := Null_Unbounded_Wide_String.Reference;
691       Object.Last      := 0;
692    end Initialize;
693
694    ------------
695    -- Insert --
696    ------------
697
698    function Insert
699      (Source   : Unbounded_Wide_String;
700       Before   : Positive;
701       New_Item : Wide_String) return Unbounded_Wide_String
702    is
703    begin
704       return
705         To_Unbounded_Wide_String
706           (Wide_Fixed.Insert
707              (Source.Reference (1 .. Source.Last), Before, New_Item));
708    end Insert;
709
710    procedure Insert
711      (Source   : in out Unbounded_Wide_String;
712       Before   : Positive;
713       New_Item : Wide_String)
714    is
715    begin
716       if Before not in Source.Reference'First .. Source.Last + 1 then
717          raise Index_Error;
718       end if;
719
720       Realloc_For_Chunk (Source, New_Item'Length);
721
722       Source.Reference
723         (Before +  New_Item'Length .. Source.Last + New_Item'Length) :=
724            Source.Reference (Before .. Source.Last);
725
726       Source.Reference (Before .. Before + New_Item'Length - 1) := New_Item;
727       Source.Last := Source.Last + New_Item'Length;
728    end Insert;
729
730    ------------
731    -- Length --
732    ------------
733
734    function Length (Source : Unbounded_Wide_String) return Natural is
735    begin
736       return Source.Last;
737    end Length;
738
739    ---------------
740    -- Overwrite --
741    ---------------
742
743    function Overwrite
744      (Source   : Unbounded_Wide_String;
745       Position : Positive;
746       New_Item : Wide_String) return Unbounded_Wide_String
747    is
748    begin
749       return
750         To_Unbounded_Wide_String
751           (Wide_Fixed.Overwrite
752             (Source.Reference (1 .. Source.Last), Position, New_Item));
753    end Overwrite;
754
755    procedure Overwrite
756      (Source    : in out Unbounded_Wide_String;
757       Position  : Positive;
758       New_Item  : Wide_String)
759    is
760       NL : constant Natural := New_Item'Length;
761    begin
762       if Position <= Source.Last - NL + 1 then
763          Source.Reference (Position .. Position + NL - 1) := New_Item;
764       else
765          declare
766             Old : Wide_String_Access := Source.Reference;
767          begin
768             Source.Reference := new Wide_String'
769               (Wide_Fixed.Overwrite
770                 (Source.Reference (1 .. Source.Last), Position, New_Item));
771             Source.Last := Source.Reference'Length;
772             Free (Old);
773          end;
774       end if;
775    end Overwrite;
776
777    -----------------------
778    -- Realloc_For_Chunk --
779    -----------------------
780
781    procedure Realloc_For_Chunk
782      (Source     : in out Unbounded_Wide_String;
783       Chunk_Size : Natural)
784    is
785       Growth_Factor : constant := 32;
786       --  The growth factor controls how much extra space is allocated when
787       --  we have to increase the size of an allocated unbounded string. By
788       --  allocating extra space, we avoid the need to reallocate on every
789       --  append, particularly important when a string is built up by repeated
790       --  append operations of small pieces. This is expressed as a factor so
791       --  32 means add 1/32 of the length of the string as growth space.
792
793       Min_Mul_Alloc : constant := Standard'Maximum_Alignment;
794       --  Allocation will be done by a multiple of Min_Mul_Alloc This causes
795       --  no memory loss as most (all?) malloc implementations are obliged to
796       --  align the returned memory on the maximum alignment as malloc does not
797       --  know the target alignment.
798
799       S_Length : constant Natural := Source.Reference'Length;
800
801    begin
802       if Chunk_Size > S_Length - Source.Last then
803          declare
804             New_Size : constant Positive :=
805                          S_Length + Chunk_Size + (S_Length / Growth_Factor);
806
807             New_Rounded_Up_Size : constant Positive :=
808                                     ((New_Size - 1) / Min_Mul_Alloc + 1) *
809                                        Min_Mul_Alloc;
810
811             Tmp : constant Wide_String_Access :=
812                     new Wide_String (1 .. New_Rounded_Up_Size);
813
814          begin
815             Tmp (1 .. Source.Last) := Source.Reference (1 .. Source.Last);
816             Free (Source.Reference);
817             Source.Reference := Tmp;
818          end;
819       end if;
820    end Realloc_For_Chunk;
821
822    ---------------------
823    -- Replace_Element --
824    ---------------------
825
826    procedure Replace_Element
827      (Source : in out Unbounded_Wide_String;
828       Index  : Positive;
829       By     : Wide_Character)
830    is
831    begin
832       if Index <= Source.Last then
833          Source.Reference (Index) := By;
834       else
835          raise Strings.Index_Error;
836       end if;
837    end Replace_Element;
838
839    -------------------
840    -- Replace_Slice --
841    -------------------
842
843    function Replace_Slice
844      (Source : Unbounded_Wide_String;
845       Low    : Positive;
846       High   : Natural;
847       By     : Wide_String) return Unbounded_Wide_String
848    is
849    begin
850       return To_Unbounded_Wide_String
851         (Wide_Fixed.Replace_Slice
852            (Source.Reference (1 .. Source.Last), Low, High, By));
853    end Replace_Slice;
854
855    procedure Replace_Slice
856      (Source : in out Unbounded_Wide_String;
857       Low    : Positive;
858       High   : Natural;
859       By     : Wide_String)
860    is
861       Old : Wide_String_Access := Source.Reference;
862    begin
863       Source.Reference := new Wide_String'
864         (Wide_Fixed.Replace_Slice
865            (Source.Reference (1 .. Source.Last), Low, High, By));
866       Source.Last := Source.Reference'Length;
867       Free (Old);
868    end Replace_Slice;
869
870    -------------------------------
871    -- Set_Unbounded_Wide_String --
872    -------------------------------
873
874    procedure Set_Unbounded_Wide_String
875      (Target : out Unbounded_Wide_String;
876       Source : Wide_String)
877    is
878    begin
879       Target.Last          := Source'Length;
880       Target.Reference     := new Wide_String (1 .. Source'Length);
881       Target.Reference.all := Source;
882    end Set_Unbounded_Wide_String;
883
884    -----------
885    -- Slice --
886    -----------
887
888    function Slice
889      (Source : Unbounded_Wide_String;
890       Low    : Positive;
891       High   : Natural) return Wide_String
892    is
893    begin
894       --  Note: test of High > Length is in accordance with AI95-00128
895
896       if Low > Source.Last + 1 or else High > Source.Last then
897          raise Index_Error;
898       else
899          return Source.Reference (Low .. High);
900       end if;
901    end Slice;
902
903    ----------
904    -- Tail --
905    ----------
906
907    function Tail
908      (Source : Unbounded_Wide_String;
909       Count  : Natural;
910       Pad    : Wide_Character := Wide_Space) return Unbounded_Wide_String is
911    begin
912       return To_Unbounded_Wide_String
913         (Wide_Fixed.Tail (Source.Reference (1 .. Source.Last), Count, Pad));
914    end Tail;
915
916    procedure Tail
917      (Source : in out Unbounded_Wide_String;
918       Count  : Natural;
919       Pad    : Wide_Character := Wide_Space)
920    is
921       Old : Wide_String_Access := Source.Reference;
922    begin
923       Source.Reference := new Wide_String'
924         (Wide_Fixed.Tail (Source.Reference (1 .. Source.Last), Count, Pad));
925       Source.Last := Source.Reference'Length;
926       Free (Old);
927    end Tail;
928
929    ------------------------------
930    -- To_Unbounded_Wide_String --
931    ------------------------------
932
933    function To_Unbounded_Wide_String
934      (Source : Wide_String)
935       return Unbounded_Wide_String
936    is
937       Result : Unbounded_Wide_String;
938    begin
939       Result.Last          := Source'Length;
940       Result.Reference     := new Wide_String (1 .. Source'Length);
941       Result.Reference.all := Source;
942       return Result;
943    end To_Unbounded_Wide_String;
944
945    function To_Unbounded_Wide_String
946      (Length : Natural) return Unbounded_Wide_String
947    is
948       Result : Unbounded_Wide_String;
949    begin
950       Result.Last      := Length;
951       Result.Reference := new Wide_String (1 .. Length);
952       return Result;
953    end To_Unbounded_Wide_String;
954
955    -------------------
956    -- To_Wide_String --
957    --------------------
958
959    function To_Wide_String
960      (Source : Unbounded_Wide_String)
961       return Wide_String
962    is
963    begin
964       return Source.Reference (1 .. Source.Last);
965    end To_Wide_String;
966
967    ---------------
968    -- Translate --
969    ---------------
970
971    function Translate
972      (Source  : Unbounded_Wide_String;
973       Mapping : Wide_Maps.Wide_Character_Mapping)
974       return Unbounded_Wide_String
975    is
976    begin
977       return
978         To_Unbounded_Wide_String
979           (Wide_Fixed.Translate
980              (Source.Reference (1 .. Source.Last), Mapping));
981    end Translate;
982
983    procedure Translate
984      (Source  : in out Unbounded_Wide_String;
985       Mapping : Wide_Maps.Wide_Character_Mapping)
986    is
987    begin
988       Wide_Fixed.Translate (Source.Reference (1 .. Source.Last), Mapping);
989    end Translate;
990
991    function Translate
992      (Source  : Unbounded_Wide_String;
993       Mapping : Wide_Maps.Wide_Character_Mapping_Function)
994       return Unbounded_Wide_String
995    is
996    begin
997       return
998         To_Unbounded_Wide_String
999           (Wide_Fixed.Translate
1000             (Source.Reference (1 .. Source.Last), Mapping));
1001    end Translate;
1002
1003    procedure Translate
1004      (Source  : in out Unbounded_Wide_String;
1005       Mapping : Wide_Maps.Wide_Character_Mapping_Function)
1006    is
1007    begin
1008       Wide_Fixed.Translate (Source.Reference (1 .. Source.Last), Mapping);
1009    end Translate;
1010
1011    ----------
1012    -- Trim --
1013    ----------
1014
1015    function Trim
1016      (Source : Unbounded_Wide_String;
1017       Side   : Trim_End) return Unbounded_Wide_String
1018    is
1019    begin
1020       return
1021         To_Unbounded_Wide_String
1022           (Wide_Fixed.Trim (Source.Reference (1 .. Source.Last), Side));
1023    end Trim;
1024
1025    procedure Trim
1026      (Source : in out Unbounded_Wide_String;
1027       Side   : Trim_End)
1028    is
1029       Old : Wide_String_Access := Source.Reference;
1030    begin
1031       Source.Reference :=
1032         new Wide_String'
1033           (Wide_Fixed.Trim (Source.Reference (1 .. Source.Last), Side));
1034       Source.Last      := Source.Reference'Length;
1035       Free (Old);
1036    end Trim;
1037
1038    function Trim
1039      (Source : Unbounded_Wide_String;
1040       Left   : Wide_Maps.Wide_Character_Set;
1041       Right  : Wide_Maps.Wide_Character_Set)
1042       return Unbounded_Wide_String
1043    is
1044    begin
1045       return
1046         To_Unbounded_Wide_String
1047           (Wide_Fixed.Trim
1048              (Source.Reference (1 .. Source.Last), Left, Right));
1049    end Trim;
1050
1051    procedure Trim
1052      (Source : in out Unbounded_Wide_String;
1053       Left   : Wide_Maps.Wide_Character_Set;
1054       Right  : Wide_Maps.Wide_Character_Set)
1055    is
1056       Old : Wide_String_Access := Source.Reference;
1057    begin
1058       Source.Reference :=
1059         new Wide_String'
1060           (Wide_Fixed.Trim
1061              (Source.Reference (1 .. Source.Last), Left, Right));
1062       Source.Last      := Source.Reference'Length;
1063       Free (Old);
1064    end Trim;
1065
1066    ---------------------
1067    -- Unbounded_Slice --
1068    ---------------------
1069
1070    function Unbounded_Slice
1071      (Source : Unbounded_Wide_String;
1072       Low    : Positive;
1073       High   : Natural) return Unbounded_Wide_String
1074    is
1075    begin
1076       if Low > Source.Last + 1 or else High > Source.Last then
1077          raise Index_Error;
1078       else
1079          return To_Unbounded_Wide_String (Source.Reference.all (Low .. High));
1080       end if;
1081    end Unbounded_Slice;
1082
1083    procedure Unbounded_Slice
1084      (Source : Unbounded_Wide_String;
1085       Target : out Unbounded_Wide_String;
1086       Low    : Positive;
1087       High   : Natural)
1088    is
1089    begin
1090       if Low > Source.Last + 1 or else High > Source.Last then
1091          raise Index_Error;
1092       else
1093          Target :=
1094            To_Unbounded_Wide_String (Source.Reference.all (Low .. High));
1095       end if;
1096    end Unbounded_Slice;
1097
1098 end Ada.Strings.Wide_Unbounded;