1 ------------------------------------------------------------------------------
3 -- GNAT RUN-TIME COMPONENTS --
5 -- A D A . S T R I N G S . W I D E _ W I D E _ U N B O U N D E D --
9 -- Copyright (C) 1992-2014, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
30 ------------------------------------------------------------------------------
32 with Ada
.Strings
.Wide_Wide_Search
;
33 with Ada
.Unchecked_Deallocation
;
35 package body Ada
.Strings
.Wide_Wide_Unbounded
is
37 use Ada
.Strings
.Wide_Wide_Maps
;
39 Growth_Factor
: constant := 32;
40 -- The growth factor controls how much extra space is allocated when
41 -- we have to increase the size of an allocated unbounded string. By
42 -- allocating extra space, we avoid the need to reallocate on every
43 -- append, particularly important when a string is built up by repeated
44 -- append operations of small pieces. This is expressed as a factor so
45 -- 32 means add 1/32 of the length of the string as growth space.
47 Min_Mul_Alloc
: constant := Standard
'Maximum_Alignment;
48 -- Allocation will be done by a multiple of Min_Mul_Alloc. This causes
49 -- no memory loss as most (all?) malloc implementations are obliged to
50 -- align the returned memory on the maximum alignment as malloc does not
51 -- know the target alignment.
53 function Aligned_Max_Length
(Max_Length
: Natural) return Natural;
54 -- Returns recommended length of the shared string which is greater or
55 -- equal to specified length. Calculation take in sense alignment of
56 -- the allocated memory segments to use memory effectively by
57 -- Append/Insert/etc operations.
64 (Left
: Unbounded_Wide_Wide_String
;
65 Right
: Unbounded_Wide_Wide_String
) return Unbounded_Wide_Wide_String
67 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
68 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
69 DL
: constant Natural := LR
.Last
+ RR
.Last
;
70 DR
: Shared_Wide_Wide_String_Access
;
73 -- Result is an empty string, reuse shared empty string
76 Reference
(Empty_Shared_Wide_Wide_String
'Access);
77 DR
:= Empty_Shared_Wide_Wide_String
'Access;
79 -- Left string is empty, return Rigth string
81 elsif LR
.Last
= 0 then
85 -- Right string is empty, return Left string
87 elsif RR
.Last
= 0 then
91 -- Overwise, allocate new shared string and fill data
95 DR
.Data
(1 .. LR
.Last
) := LR
.Data
(1 .. LR
.Last
);
96 DR
.Data
(LR
.Last
+ 1 .. DL
) := RR
.Data
(1 .. RR
.Last
);
100 return (AF
.Controlled
with Reference
=> DR
);
104 (Left
: Unbounded_Wide_Wide_String
;
105 Right
: Wide_Wide_String
) return Unbounded_Wide_Wide_String
107 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
108 DL
: constant Natural := LR
.Last
+ Right
'Length;
109 DR
: Shared_Wide_Wide_String_Access
;
112 -- Result is an empty string, reuse shared empty string
115 Reference
(Empty_Shared_Wide_Wide_String
'Access);
116 DR
:= Empty_Shared_Wide_Wide_String
'Access;
118 -- Right is an empty string, return Left string
120 elsif Right
'Length = 0 then
124 -- Otherwise, allocate new shared string and fill it
128 DR
.Data
(1 .. LR
.Last
) := LR
.Data
(1 .. LR
.Last
);
129 DR
.Data
(LR
.Last
+ 1 .. DL
) := Right
;
133 return (AF
.Controlled
with Reference
=> DR
);
137 (Left
: Wide_Wide_String
;
138 Right
: Unbounded_Wide_Wide_String
) return Unbounded_Wide_Wide_String
140 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
141 DL
: constant Natural := Left
'Length + RR
.Last
;
142 DR
: Shared_Wide_Wide_String_Access
;
145 -- Result is an empty string, reuse shared one
148 Reference
(Empty_Shared_Wide_Wide_String
'Access);
149 DR
:= Empty_Shared_Wide_Wide_String
'Access;
151 -- Left is empty string, return Right string
153 elsif Left
'Length = 0 then
157 -- Otherwise, allocate new shared string and fill it
161 DR
.Data
(1 .. Left
'Length) := Left
;
162 DR
.Data
(Left
'Length + 1 .. DL
) := RR
.Data
(1 .. RR
.Last
);
166 return (AF
.Controlled
with Reference
=> DR
);
170 (Left
: Unbounded_Wide_Wide_String
;
171 Right
: Wide_Wide_Character
) return Unbounded_Wide_Wide_String
173 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
174 DL
: constant Natural := LR
.Last
+ 1;
175 DR
: Shared_Wide_Wide_String_Access
;
179 DR
.Data
(1 .. LR
.Last
) := LR
.Data
(1 .. LR
.Last
);
180 DR
.Data
(DL
) := Right
;
183 return (AF
.Controlled
with Reference
=> DR
);
187 (Left
: Wide_Wide_Character
;
188 Right
: Unbounded_Wide_Wide_String
) return Unbounded_Wide_Wide_String
190 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
191 DL
: constant Natural := 1 + RR
.Last
;
192 DR
: Shared_Wide_Wide_String_Access
;
197 DR
.Data
(2 .. DL
) := RR
.Data
(1 .. RR
.Last
);
200 return (AF
.Controlled
with Reference
=> DR
);
209 Right
: Wide_Wide_Character
) return Unbounded_Wide_Wide_String
211 DR
: Shared_Wide_Wide_String_Access
;
214 -- Result is an empty string, reuse shared empty string
217 Reference
(Empty_Shared_Wide_Wide_String
'Access);
218 DR
:= Empty_Shared_Wide_Wide_String
'Access;
220 -- Otherwise, allocate new shared string and fill it
223 DR
:= Allocate
(Left
);
225 for J
in 1 .. Left
loop
226 DR
.Data
(J
) := Right
;
232 return (AF
.Controlled
with Reference
=> DR
);
237 Right
: Wide_Wide_String
) return Unbounded_Wide_Wide_String
239 DL
: constant Natural := Left
* Right
'Length;
240 DR
: Shared_Wide_Wide_String_Access
;
244 -- Result is an empty string, reuse shared empty string
247 Reference
(Empty_Shared_Wide_Wide_String
'Access);
248 DR
:= Empty_Shared_Wide_Wide_String
'Access;
250 -- Otherwise, allocate new shared string and fill it
256 for J
in 1 .. Left
loop
257 DR
.Data
(K
.. K
+ Right
'Length - 1) := Right
;
258 K
:= K
+ Right
'Length;
264 return (AF
.Controlled
with Reference
=> DR
);
269 Right
: Unbounded_Wide_Wide_String
) return Unbounded_Wide_Wide_String
271 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
272 DL
: constant Natural := Left
* RR
.Last
;
273 DR
: Shared_Wide_Wide_String_Access
;
277 -- Result is an empty string, reuse shared empty string
280 Reference
(Empty_Shared_Wide_Wide_String
'Access);
281 DR
:= Empty_Shared_Wide_Wide_String
'Access;
283 -- Coefficient is one, just return string itself
289 -- Otherwise, allocate new shared string and fill it
295 for J
in 1 .. Left
loop
296 DR
.Data
(K
.. K
+ RR
.Last
- 1) := RR
.Data
(1 .. RR
.Last
);
303 return (AF
.Controlled
with Reference
=> DR
);
311 (Left
: Unbounded_Wide_Wide_String
;
312 Right
: Unbounded_Wide_Wide_String
) return Boolean
314 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
315 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
317 return LR
.Data
(1 .. LR
.Last
) < RR
.Data
(1 .. RR
.Last
);
321 (Left
: Unbounded_Wide_Wide_String
;
322 Right
: Wide_Wide_String
) return Boolean
324 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
326 return LR
.Data
(1 .. LR
.Last
) < Right
;
330 (Left
: Wide_Wide_String
;
331 Right
: Unbounded_Wide_Wide_String
) return Boolean
333 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
335 return Left
< RR
.Data
(1 .. RR
.Last
);
343 (Left
: Unbounded_Wide_Wide_String
;
344 Right
: Unbounded_Wide_Wide_String
) return Boolean
346 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
347 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
350 -- LR = RR means two strings shares shared string, thus they are equal
352 return LR
= RR
or else LR
.Data
(1 .. LR
.Last
) <= RR
.Data
(1 .. RR
.Last
);
356 (Left
: Unbounded_Wide_Wide_String
;
357 Right
: Wide_Wide_String
) return Boolean
359 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
361 return LR
.Data
(1 .. LR
.Last
) <= Right
;
365 (Left
: Wide_Wide_String
;
366 Right
: Unbounded_Wide_Wide_String
) return Boolean
368 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
370 return Left
<= RR
.Data
(1 .. RR
.Last
);
378 (Left
: Unbounded_Wide_Wide_String
;
379 Right
: Unbounded_Wide_Wide_String
) return Boolean
381 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
382 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
385 return LR
= RR
or else LR
.Data
(1 .. LR
.Last
) = RR
.Data
(1 .. RR
.Last
);
386 -- LR = RR means two strings shares shared string, thus they are equal
390 (Left
: Unbounded_Wide_Wide_String
;
391 Right
: Wide_Wide_String
) return Boolean
393 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
395 return LR
.Data
(1 .. LR
.Last
) = Right
;
399 (Left
: Wide_Wide_String
;
400 Right
: Unbounded_Wide_Wide_String
) return Boolean
402 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
404 return Left
= RR
.Data
(1 .. RR
.Last
);
412 (Left
: Unbounded_Wide_Wide_String
;
413 Right
: Unbounded_Wide_Wide_String
) return Boolean
415 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
416 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
418 return LR
.Data
(1 .. LR
.Last
) > RR
.Data
(1 .. RR
.Last
);
422 (Left
: Unbounded_Wide_Wide_String
;
423 Right
: Wide_Wide_String
) return Boolean
425 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
427 return LR
.Data
(1 .. LR
.Last
) > Right
;
431 (Left
: Wide_Wide_String
;
432 Right
: Unbounded_Wide_Wide_String
) return Boolean
434 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
436 return Left
> RR
.Data
(1 .. RR
.Last
);
444 (Left
: Unbounded_Wide_Wide_String
;
445 Right
: Unbounded_Wide_Wide_String
) return Boolean
447 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
448 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
451 -- LR = RR means two strings shares shared string, thus they are equal
453 return LR
= RR
or else LR
.Data
(1 .. LR
.Last
) >= RR
.Data
(1 .. RR
.Last
);
457 (Left
: Unbounded_Wide_Wide_String
;
458 Right
: Wide_Wide_String
) return Boolean
460 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
462 return LR
.Data
(1 .. LR
.Last
) >= Right
;
466 (Left
: Wide_Wide_String
;
467 Right
: Unbounded_Wide_Wide_String
) return Boolean
469 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
471 return Left
>= RR
.Data
(1 .. RR
.Last
);
478 procedure Adjust
(Object
: in out Unbounded_Wide_Wide_String
) is
480 Reference
(Object
.Reference
);
483 ------------------------
484 -- Aligned_Max_Length --
485 ------------------------
487 function Aligned_Max_Length
(Max_Length
: Natural) return Natural is
488 Static_Size
: constant Natural :=
489 Empty_Shared_Wide_Wide_String
'Size / Standard
'Storage_Unit;
490 -- Total size of all static components
492 Element_Size
: constant Natural :=
493 Wide_Wide_Character
'Size / Standard
'Storage_Unit;
497 (((Static_Size
+ Max_Length
* Element_Size
- 1) / Min_Mul_Alloc
+ 2)
498 * Min_Mul_Alloc
- Static_Size
) / Element_Size
;
499 end Aligned_Max_Length
;
506 (Max_Length
: Natural) return Shared_Wide_Wide_String_Access
is
508 -- Empty string requested, return shared empty string
510 if Max_Length
= 0 then
511 Reference
(Empty_Shared_Wide_Wide_String
'Access);
512 return Empty_Shared_Wide_Wide_String
'Access;
514 -- Otherwise, allocate requested space (and probably some more room)
517 return new Shared_Wide_Wide_String
(Aligned_Max_Length
(Max_Length
));
526 (Source
: in out Unbounded_Wide_Wide_String
;
527 New_Item
: Unbounded_Wide_Wide_String
)
529 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
530 NR
: constant Shared_Wide_Wide_String_Access
:= New_Item
.Reference
;
531 DL
: constant Natural := SR
.Last
+ NR
.Last
;
532 DR
: Shared_Wide_Wide_String_Access
;
535 -- Source is an empty string, reuse New_Item data
539 Source
.Reference
:= NR
;
542 -- New_Item is empty string, nothing to do
544 elsif NR
.Last
= 0 then
547 -- Try to reuse existent shared string
549 elsif Can_Be_Reused
(SR
, DL
) then
550 SR
.Data
(SR
.Last
+ 1 .. DL
) := NR
.Data
(1 .. NR
.Last
);
553 -- Otherwise, allocate new one and fill it
556 DR
:= Allocate
(DL
+ DL
/ Growth_Factor
);
557 DR
.Data
(1 .. SR
.Last
) := SR
.Data
(1 .. SR
.Last
);
558 DR
.Data
(SR
.Last
+ 1 .. DL
) := NR
.Data
(1 .. NR
.Last
);
560 Source
.Reference
:= DR
;
566 (Source
: in out Unbounded_Wide_Wide_String
;
567 New_Item
: Wide_Wide_String
)
569 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
570 DL
: constant Natural := SR
.Last
+ New_Item
'Length;
571 DR
: Shared_Wide_Wide_String_Access
;
574 -- New_Item is an empty string, nothing to do
576 if New_Item
'Length = 0 then
579 -- Try to reuse existing shared string
581 elsif Can_Be_Reused
(SR
, DL
) then
582 SR
.Data
(SR
.Last
+ 1 .. DL
) := New_Item
;
585 -- Otherwise, allocate new one and fill it
588 DR
:= Allocate
(DL
+ DL
/ Growth_Factor
);
589 DR
.Data
(1 .. SR
.Last
) := SR
.Data
(1 .. SR
.Last
);
590 DR
.Data
(SR
.Last
+ 1 .. DL
) := New_Item
;
592 Source
.Reference
:= DR
;
598 (Source
: in out Unbounded_Wide_Wide_String
;
599 New_Item
: Wide_Wide_Character
)
601 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
602 DL
: constant Natural := SR
.Last
+ 1;
603 DR
: Shared_Wide_Wide_String_Access
;
606 -- Try to reuse existing shared string
608 if Can_Be_Reused
(SR
, SR
.Last
+ 1) then
609 SR
.Data
(SR
.Last
+ 1) := New_Item
;
610 SR
.Last
:= SR
.Last
+ 1;
612 -- Otherwise, allocate new one and fill it
615 DR
:= Allocate
(DL
+ DL
/ Growth_Factor
);
616 DR
.Data
(1 .. SR
.Last
) := SR
.Data
(1 .. SR
.Last
);
617 DR
.Data
(DL
) := New_Item
;
619 Source
.Reference
:= DR
;
628 function Can_Be_Reused
629 (Item
: Shared_Wide_Wide_String_Access
;
630 Length
: Natural) return Boolean is
633 System
.Atomic_Counters
.Is_One
(Item
.Counter
)
634 and then Item
.Max_Length
>= Length
635 and then Item
.Max_Length
<=
636 Aligned_Max_Length
(Length
+ Length
/ Growth_Factor
);
644 (Source
: Unbounded_Wide_Wide_String
;
645 Pattern
: Wide_Wide_String
;
646 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping
:=
647 Wide_Wide_Maps
.Identity
) return Natural
649 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
651 return Wide_Wide_Search
.Count
(SR
.Data
(1 .. SR
.Last
), Pattern
, Mapping
);
655 (Source
: Unbounded_Wide_Wide_String
;
656 Pattern
: Wide_Wide_String
;
657 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping_Function
)
660 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
662 return Wide_Wide_Search
.Count
(SR
.Data
(1 .. SR
.Last
), Pattern
, Mapping
);
666 (Source
: Unbounded_Wide_Wide_String
;
667 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
) return Natural
669 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
671 return Wide_Wide_Search
.Count
(SR
.Data
(1 .. SR
.Last
), Set
);
679 (Source
: Unbounded_Wide_Wide_String
;
681 Through
: Natural) return Unbounded_Wide_Wide_String
683 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
685 DR
: Shared_Wide_Wide_String_Access
;
688 -- Empty slice is deleted, use the same shared string
690 if From
> Through
then
694 -- Index is out of range
696 elsif Through
> SR
.Last
then
699 -- Compute size of the result
702 DL
:= SR
.Last
- (Through
- From
+ 1);
704 -- Result is an empty string, reuse shared empty string
707 Reference
(Empty_Shared_Wide_Wide_String
'Access);
708 DR
:= Empty_Shared_Wide_Wide_String
'Access;
710 -- Otherwise, allocate new shared string and fill it
714 DR
.Data
(1 .. From
- 1) := SR
.Data
(1 .. From
- 1);
715 DR
.Data
(From
.. DL
) := SR
.Data
(Through
+ 1 .. SR
.Last
);
720 return (AF
.Controlled
with Reference
=> DR
);
724 (Source
: in out Unbounded_Wide_Wide_String
;
728 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
730 DR
: Shared_Wide_Wide_String_Access
;
733 -- Nothing changed, return
735 if From
> Through
then
738 -- Through is outside of the range
740 elsif Through
> SR
.Last
then
744 DL
:= SR
.Last
- (Through
- From
+ 1);
746 -- Result is empty, reuse shared empty string
749 Reference
(Empty_Shared_Wide_Wide_String
'Access);
750 Source
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
753 -- Try to reuse existent shared string
755 elsif Can_Be_Reused
(SR
, DL
) then
756 SR
.Data
(From
.. DL
) := SR
.Data
(Through
+ 1 .. SR
.Last
);
759 -- Otherwise, allocate new shared string
763 DR
.Data
(1 .. From
- 1) := SR
.Data
(1 .. From
- 1);
764 DR
.Data
(From
.. DL
) := SR
.Data
(Through
+ 1 .. SR
.Last
);
766 Source
.Reference
:= DR
;
777 (Source
: Unbounded_Wide_Wide_String
;
778 Index
: Positive) return Wide_Wide_Character
780 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
782 if Index
<= SR
.Last
then
783 return SR
.Data
(Index
);
793 procedure Finalize
(Object
: in out Unbounded_Wide_Wide_String
) is
794 SR
: constant Shared_Wide_Wide_String_Access
:= Object
.Reference
;
799 -- The same controlled object can be finalized several times for
800 -- some reason. As per 7.6.1(24) this should have no ill effect,
801 -- so we need to add a guard for the case of finalizing the same
804 Object
.Reference
:= null;
814 (Source
: Unbounded_Wide_Wide_String
;
815 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
817 Test
: Strings
.Membership
;
818 First
: out Positive;
821 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
823 Wide_Wide_Search
.Find_Token
824 (SR
.Data
(From
.. SR
.Last
), Set
, Test
, First
, Last
);
828 (Source
: Unbounded_Wide_Wide_String
;
829 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
830 Test
: Strings
.Membership
;
831 First
: out Positive;
834 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
836 Wide_Wide_Search
.Find_Token
837 (SR
.Data
(1 .. SR
.Last
), Set
, Test
, First
, Last
);
844 procedure Free
(X
: in out Wide_Wide_String_Access
) is
845 procedure Deallocate
is
846 new Ada
.Unchecked_Deallocation
847 (Wide_Wide_String
, Wide_Wide_String_Access
);
857 (Source
: Unbounded_Wide_Wide_String
;
859 Pad
: Wide_Wide_Character
:= Wide_Wide_Space
)
860 return Unbounded_Wide_Wide_String
862 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
863 DR
: Shared_Wide_Wide_String_Access
;
866 -- Result is empty, reuse shared empty string
869 Reference
(Empty_Shared_Wide_Wide_String
'Access);
870 DR
:= Empty_Shared_Wide_Wide_String
'Access;
872 -- Length of the string is the same as requested, reuse source shared
875 elsif Count
= SR
.Last
then
879 -- Otherwise, allocate new shared string and fill it
882 DR
:= Allocate
(Count
);
884 -- Length of the source string is more than requested, copy
885 -- corresponding slice.
887 if Count
< SR
.Last
then
888 DR
.Data
(1 .. Count
) := SR
.Data
(1 .. Count
);
890 -- Length of the source string is less than requested, copy all
891 -- contents and fill others by Pad character.
894 DR
.Data
(1 .. SR
.Last
) := SR
.Data
(1 .. SR
.Last
);
896 for J
in SR
.Last
+ 1 .. Count
loop
904 return (AF
.Controlled
with Reference
=> DR
);
908 (Source
: in out Unbounded_Wide_Wide_String
;
910 Pad
: Wide_Wide_Character
:= Wide_Wide_Space
)
912 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
913 DR
: Shared_Wide_Wide_String_Access
;
916 -- Result is empty, reuse empty shared string
919 Reference
(Empty_Shared_Wide_Wide_String
'Access);
920 Source
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
923 -- Result is same with source string, reuse source shared string
925 elsif Count
= SR
.Last
then
928 -- Try to reuse existent shared string
930 elsif Can_Be_Reused
(SR
, Count
) then
931 if Count
> SR
.Last
then
932 for J
in SR
.Last
+ 1 .. Count
loop
939 -- Otherwise, allocate new shared string and fill it
942 DR
:= Allocate
(Count
);
944 -- Length of the source string is greater than requested, copy
945 -- corresponding slice.
947 if Count
< SR
.Last
then
948 DR
.Data
(1 .. Count
) := SR
.Data
(1 .. Count
);
950 -- Length of the source string is less than requested, copy all
951 -- exists data and fill others by Pad character.
954 DR
.Data
(1 .. SR
.Last
) := SR
.Data
(1 .. SR
.Last
);
956 for J
in SR
.Last
+ 1 .. Count
loop
962 Source
.Reference
:= DR
;
972 (Source
: Unbounded_Wide_Wide_String
;
973 Pattern
: Wide_Wide_String
;
974 Going
: Strings
.Direction
:= Strings
.Forward
;
975 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping
:=
976 Wide_Wide_Maps
.Identity
) return Natural
978 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
980 return Wide_Wide_Search
.Index
981 (SR
.Data
(1 .. SR
.Last
), Pattern
, Going
, Mapping
);
985 (Source
: Unbounded_Wide_Wide_String
;
986 Pattern
: Wide_Wide_String
;
987 Going
: Direction
:= Forward
;
988 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping_Function
)
991 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
993 return Wide_Wide_Search
.Index
994 (SR
.Data
(1 .. SR
.Last
), Pattern
, Going
, Mapping
);
998 (Source
: Unbounded_Wide_Wide_String
;
999 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
1000 Test
: Strings
.Membership
:= Strings
.Inside
;
1001 Going
: Strings
.Direction
:= Strings
.Forward
) return Natural
1003 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1005 return Wide_Wide_Search
.Index
(SR
.Data
(1 .. SR
.Last
), Set
, Test
, Going
);
1009 (Source
: Unbounded_Wide_Wide_String
;
1010 Pattern
: Wide_Wide_String
;
1012 Going
: Direction
:= Forward
;
1013 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping
:=
1014 Wide_Wide_Maps
.Identity
) return Natural
1016 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1018 return Wide_Wide_Search
.Index
1019 (SR
.Data
(1 .. SR
.Last
), Pattern
, From
, Going
, Mapping
);
1023 (Source
: Unbounded_Wide_Wide_String
;
1024 Pattern
: Wide_Wide_String
;
1026 Going
: Direction
:= Forward
;
1027 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping_Function
)
1030 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1032 return Wide_Wide_Search
.Index
1033 (SR
.Data
(1 .. SR
.Last
), Pattern
, From
, Going
, Mapping
);
1037 (Source
: Unbounded_Wide_Wide_String
;
1038 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
1040 Test
: Membership
:= Inside
;
1041 Going
: Direction
:= Forward
) return Natural
1043 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1045 return Wide_Wide_Search
.Index
1046 (SR
.Data
(1 .. SR
.Last
), Set
, From
, Test
, Going
);
1049 ---------------------
1050 -- Index_Non_Blank --
1051 ---------------------
1053 function Index_Non_Blank
1054 (Source
: Unbounded_Wide_Wide_String
;
1055 Going
: Strings
.Direction
:= Strings
.Forward
) return Natural
1057 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1059 return Wide_Wide_Search
.Index_Non_Blank
(SR
.Data
(1 .. SR
.Last
), Going
);
1060 end Index_Non_Blank
;
1062 function Index_Non_Blank
1063 (Source
: Unbounded_Wide_Wide_String
;
1065 Going
: Direction
:= Forward
) return Natural
1067 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1069 return Wide_Wide_Search
.Index_Non_Blank
1070 (SR
.Data
(1 .. SR
.Last
), From
, Going
);
1071 end Index_Non_Blank
;
1077 procedure Initialize
(Object
: in out Unbounded_Wide_Wide_String
) is
1079 Reference
(Object
.Reference
);
1087 (Source
: Unbounded_Wide_Wide_String
;
1089 New_Item
: Wide_Wide_String
) return Unbounded_Wide_Wide_String
1091 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1092 DL
: constant Natural := SR
.Last
+ New_Item
'Length;
1093 DR
: Shared_Wide_Wide_String_Access
;
1096 -- Check index first
1098 if Before
> SR
.Last
+ 1 then
1102 -- Result is empty, reuse empty shared string
1105 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1106 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1108 -- Inserted string is empty, reuse source shared string
1110 elsif New_Item
'Length = 0 then
1114 -- Otherwise, allocate new shared string and fill it
1117 DR
:= Allocate
(DL
+ DL
/ Growth_Factor
);
1118 DR
.Data
(1 .. Before
- 1) := SR
.Data
(1 .. Before
- 1);
1119 DR
.Data
(Before
.. Before
+ New_Item
'Length - 1) := New_Item
;
1120 DR
.Data
(Before
+ New_Item
'Length .. DL
) :=
1121 SR
.Data
(Before
.. SR
.Last
);
1125 return (AF
.Controlled
with Reference
=> DR
);
1129 (Source
: in out Unbounded_Wide_Wide_String
;
1131 New_Item
: Wide_Wide_String
)
1133 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1134 DL
: constant Natural := SR
.Last
+ New_Item
'Length;
1135 DR
: Shared_Wide_Wide_String_Access
;
1140 if Before
> SR
.Last
+ 1 then
1144 -- Result is empty string, reuse empty shared string
1147 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1148 Source
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
1151 -- Inserted string is empty, nothing to do
1153 elsif New_Item
'Length = 0 then
1156 -- Try to reuse existent shared string first
1158 elsif Can_Be_Reused
(SR
, DL
) then
1159 SR
.Data
(Before
+ New_Item
'Length .. DL
) :=
1160 SR
.Data
(Before
.. SR
.Last
);
1161 SR
.Data
(Before
.. Before
+ New_Item
'Length - 1) := New_Item
;
1164 -- Otherwise, allocate new shared string and fill it
1167 DR
:= Allocate
(DL
+ DL
/ Growth_Factor
);
1168 DR
.Data
(1 .. Before
- 1) := SR
.Data
(1 .. Before
- 1);
1169 DR
.Data
(Before
.. Before
+ New_Item
'Length - 1) := New_Item
;
1170 DR
.Data
(Before
+ New_Item
'Length .. DL
) :=
1171 SR
.Data
(Before
.. SR
.Last
);
1173 Source
.Reference
:= DR
;
1182 function Length
(Source
: Unbounded_Wide_Wide_String
) return Natural is
1184 return Source
.Reference
.Last
;
1192 (Source
: Unbounded_Wide_Wide_String
;
1193 Position
: Positive;
1194 New_Item
: Wide_Wide_String
) return Unbounded_Wide_Wide_String
1196 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1198 DR
: Shared_Wide_Wide_String_Access
;
1203 if Position
> SR
.Last
+ 1 then
1207 DL
:= Integer'Max (SR
.Last
, Position
+ New_Item
'Length - 1);
1209 -- Result is empty string, reuse empty shared string
1212 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1213 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1215 -- Result is same with source string, reuse source shared string
1217 elsif New_Item
'Length = 0 then
1221 -- Otherwise, allocate new shared string and fill it
1224 DR
:= Allocate
(DL
);
1225 DR
.Data
(1 .. Position
- 1) := SR
.Data
(1 .. Position
- 1);
1226 DR
.Data
(Position
.. Position
+ New_Item
'Length - 1) := New_Item
;
1227 DR
.Data
(Position
+ New_Item
'Length .. DL
) :=
1228 SR
.Data
(Position
+ New_Item
'Length .. SR
.Last
);
1232 return (AF
.Controlled
with Reference
=> DR
);
1236 (Source
: in out Unbounded_Wide_Wide_String
;
1237 Position
: Positive;
1238 New_Item
: Wide_Wide_String
)
1240 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1242 DR
: Shared_Wide_Wide_String_Access
;
1247 if Position
> SR
.Last
+ 1 then
1251 DL
:= Integer'Max (SR
.Last
, Position
+ New_Item
'Length - 1);
1253 -- Result is empty string, reuse empty shared string
1256 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1257 Source
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
1260 -- String unchanged, nothing to do
1262 elsif New_Item
'Length = 0 then
1265 -- Try to reuse existent shared string
1267 elsif Can_Be_Reused
(SR
, DL
) then
1268 SR
.Data
(Position
.. Position
+ New_Item
'Length - 1) := New_Item
;
1271 -- Otherwise allocate new shared string and fill it
1274 DR
:= Allocate
(DL
);
1275 DR
.Data
(1 .. Position
- 1) := SR
.Data
(1 .. Position
- 1);
1276 DR
.Data
(Position
.. Position
+ New_Item
'Length - 1) := New_Item
;
1277 DR
.Data
(Position
+ New_Item
'Length .. DL
) :=
1278 SR
.Data
(Position
+ New_Item
'Length .. SR
.Last
);
1280 Source
.Reference
:= DR
;
1289 procedure Reference
(Item
: not null Shared_Wide_Wide_String_Access
) is
1291 System
.Atomic_Counters
.Increment
(Item
.Counter
);
1294 ---------------------
1295 -- Replace_Element --
1296 ---------------------
1298 procedure Replace_Element
1299 (Source
: in out Unbounded_Wide_Wide_String
;
1301 By
: Wide_Wide_Character
)
1303 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1304 DR
: Shared_Wide_Wide_String_Access
;
1309 if Index
<= SR
.Last
then
1311 -- Try to reuse existent shared string
1313 if Can_Be_Reused
(SR
, SR
.Last
) then
1314 SR
.Data
(Index
) := By
;
1316 -- Otherwise allocate new shared string and fill it
1319 DR
:= Allocate
(SR
.Last
);
1320 DR
.Data
(1 .. SR
.Last
) := SR
.Data
(1 .. SR
.Last
);
1321 DR
.Data
(Index
) := By
;
1323 Source
.Reference
:= DR
;
1330 end Replace_Element
;
1336 function Replace_Slice
1337 (Source
: Unbounded_Wide_Wide_String
;
1340 By
: Wide_Wide_String
) return Unbounded_Wide_Wide_String
1342 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1344 DR
: Shared_Wide_Wide_String_Access
;
1349 if Low
> SR
.Last
+ 1 then
1353 -- Do replace operation when removed slice is not empty
1356 DL
:= By
'Length + SR
.Last
+ Low
- Integer'Min (High
, SR
.Last
) - 1;
1357 -- This is the number of characters remaining in the string after
1358 -- replacing the slice.
1360 -- Result is empty string, reuse empty shared string
1363 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1364 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1366 -- Otherwise allocate new shared string and fill it
1369 DR
:= Allocate
(DL
);
1370 DR
.Data
(1 .. Low
- 1) := SR
.Data
(1 .. Low
- 1);
1371 DR
.Data
(Low
.. Low
+ By
'Length - 1) := By
;
1372 DR
.Data
(Low
+ By
'Length .. DL
) := SR
.Data
(High
+ 1 .. SR
.Last
);
1376 return (AF
.Controlled
with Reference
=> DR
);
1378 -- Otherwise just insert string
1381 return Insert
(Source
, Low
, By
);
1385 procedure Replace_Slice
1386 (Source
: in out Unbounded_Wide_Wide_String
;
1389 By
: Wide_Wide_String
)
1391 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1393 DR
: Shared_Wide_Wide_String_Access
;
1398 if Low
> SR
.Last
+ 1 then
1402 -- Do replace operation only when replaced slice is not empty
1405 DL
:= By
'Length + SR
.Last
+ Low
- Integer'Min (High
, SR
.Last
) - 1;
1406 -- This is the number of characters remaining in the string after
1407 -- replacing the slice.
1409 -- Result is empty string, reuse empty shared string
1412 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1413 Source
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
1416 -- Try to reuse existent shared string
1418 elsif Can_Be_Reused
(SR
, DL
) then
1419 SR
.Data
(Low
+ By
'Length .. DL
) := SR
.Data
(High
+ 1 .. SR
.Last
);
1420 SR
.Data
(Low
.. Low
+ By
'Length - 1) := By
;
1423 -- Otherwise allocate new shared string and fill it
1426 DR
:= Allocate
(DL
);
1427 DR
.Data
(1 .. Low
- 1) := SR
.Data
(1 .. Low
- 1);
1428 DR
.Data
(Low
.. Low
+ By
'Length - 1) := By
;
1429 DR
.Data
(Low
+ By
'Length .. DL
) := SR
.Data
(High
+ 1 .. SR
.Last
);
1431 Source
.Reference
:= DR
;
1435 -- Otherwise just insert item
1438 Insert
(Source
, Low
, By
);
1442 -------------------------------
1443 -- Set_Unbounded_Wide_Wide_String --
1444 -------------------------------
1446 procedure Set_Unbounded_Wide_Wide_String
1447 (Target
: out Unbounded_Wide_Wide_String
;
1448 Source
: Wide_Wide_String
)
1450 TR
: constant Shared_Wide_Wide_String_Access
:= Target
.Reference
;
1451 DR
: Shared_Wide_Wide_String_Access
;
1454 -- In case of empty string, reuse empty shared string
1456 if Source
'Length = 0 then
1457 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1458 Target
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
1461 -- Try to reuse existent shared string
1463 if Can_Be_Reused
(TR
, Source
'Length) then
1467 -- Otherwise allocate new shared string
1470 DR
:= Allocate
(Source
'Length);
1471 Target
.Reference
:= DR
;
1474 DR
.Data
(1 .. Source
'Length) := Source
;
1475 DR
.Last
:= Source
'Length;
1479 end Set_Unbounded_Wide_Wide_String
;
1486 (Source
: Unbounded_Wide_Wide_String
;
1488 High
: Natural) return Wide_Wide_String
1490 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1493 -- Note: test of High > Length is in accordance with AI95-00128
1495 if Low
> SR
.Last
+ 1 or else High
> SR
.Last
then
1499 return SR
.Data
(Low
.. High
);
1508 (Source
: Unbounded_Wide_Wide_String
;
1510 Pad
: Wide_Wide_Character
:= Wide_Wide_Space
)
1511 return Unbounded_Wide_Wide_String
1513 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1514 DR
: Shared_Wide_Wide_String_Access
;
1517 -- For empty result reuse empty shared string
1520 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1521 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1523 -- Result is hole source string, reuse source shared string
1525 elsif Count
= SR
.Last
then
1529 -- Otherwise allocate new shared string and fill it
1532 DR
:= Allocate
(Count
);
1534 if Count
< SR
.Last
then
1535 DR
.Data
(1 .. Count
) := SR
.Data
(SR
.Last
- Count
+ 1 .. SR
.Last
);
1538 for J
in 1 .. Count
- SR
.Last
loop
1542 DR
.Data
(Count
- SR
.Last
+ 1 .. Count
) := SR
.Data
(1 .. SR
.Last
);
1548 return (AF
.Controlled
with Reference
=> DR
);
1552 (Source
: in out Unbounded_Wide_Wide_String
;
1554 Pad
: Wide_Wide_Character
:= Wide_Wide_Space
)
1556 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1557 DR
: Shared_Wide_Wide_String_Access
;
1560 (SR
: Shared_Wide_Wide_String_Access
;
1561 DR
: Shared_Wide_Wide_String_Access
;
1563 -- Common code of tail computation. SR/DR can point to the same object
1570 (SR
: Shared_Wide_Wide_String_Access
;
1571 DR
: Shared_Wide_Wide_String_Access
;
1574 if Count
< SR
.Last
then
1575 DR
.Data
(1 .. Count
) := SR
.Data
(SR
.Last
- Count
+ 1 .. SR
.Last
);
1578 DR
.Data
(Count
- SR
.Last
+ 1 .. Count
) := SR
.Data
(1 .. SR
.Last
);
1580 for J
in 1 .. Count
- SR
.Last
loop
1589 -- Result is empty string, reuse empty shared string
1592 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1593 Source
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
1596 -- Length of the result is the same with length of the source string,
1597 -- reuse source shared string.
1599 elsif Count
= SR
.Last
then
1602 -- Try to reuse existent shared string
1604 elsif Can_Be_Reused
(SR
, Count
) then
1605 Common
(SR
, SR
, Count
);
1607 -- Otherwise allocate new shared string and fill it
1610 DR
:= Allocate
(Count
);
1611 Common
(SR
, DR
, Count
);
1612 Source
.Reference
:= DR
;
1617 -------------------------
1618 -- To_Wide_Wide_String --
1619 -------------------------
1621 function To_Wide_Wide_String
1622 (Source
: Unbounded_Wide_Wide_String
) return Wide_Wide_String
is
1624 return Source
.Reference
.Data
(1 .. Source
.Reference
.Last
);
1625 end To_Wide_Wide_String
;
1627 -----------------------------------
1628 -- To_Unbounded_Wide_Wide_String --
1629 -----------------------------------
1631 function To_Unbounded_Wide_Wide_String
1632 (Source
: Wide_Wide_String
) return Unbounded_Wide_Wide_String
1634 DR
: Shared_Wide_Wide_String_Access
;
1637 if Source
'Length = 0 then
1638 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1639 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1642 DR
:= Allocate
(Source
'Length);
1643 DR
.Data
(1 .. Source
'Length) := Source
;
1644 DR
.Last
:= Source
'Length;
1647 return (AF
.Controlled
with Reference
=> DR
);
1648 end To_Unbounded_Wide_Wide_String
;
1650 function To_Unbounded_Wide_Wide_String
1651 (Length
: Natural) return Unbounded_Wide_Wide_String
1653 DR
: Shared_Wide_Wide_String_Access
;
1657 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1658 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1661 DR
:= Allocate
(Length
);
1665 return (AF
.Controlled
with Reference
=> DR
);
1666 end To_Unbounded_Wide_Wide_String
;
1673 (Source
: Unbounded_Wide_Wide_String
;
1674 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping
)
1675 return Unbounded_Wide_Wide_String
1677 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1678 DR
: Shared_Wide_Wide_String_Access
;
1681 -- Nothing to translate, reuse empty shared string
1684 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1685 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1687 -- Otherwise, allocate new shared string and fill it
1690 DR
:= Allocate
(SR
.Last
);
1692 for J
in 1 .. SR
.Last
loop
1693 DR
.Data
(J
) := Value
(Mapping
, SR
.Data
(J
));
1699 return (AF
.Controlled
with Reference
=> DR
);
1703 (Source
: in out Unbounded_Wide_Wide_String
;
1704 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping
)
1706 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1707 DR
: Shared_Wide_Wide_String_Access
;
1710 -- Nothing to translate
1715 -- Try to reuse shared string
1717 elsif Can_Be_Reused
(SR
, SR
.Last
) then
1718 for J
in 1 .. SR
.Last
loop
1719 SR
.Data
(J
) := Value
(Mapping
, SR
.Data
(J
));
1722 -- Otherwise, allocate new shared string
1725 DR
:= Allocate
(SR
.Last
);
1727 for J
in 1 .. SR
.Last
loop
1728 DR
.Data
(J
) := Value
(Mapping
, SR
.Data
(J
));
1732 Source
.Reference
:= DR
;
1738 (Source
: Unbounded_Wide_Wide_String
;
1739 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping_Function
)
1740 return Unbounded_Wide_Wide_String
1742 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1743 DR
: Shared_Wide_Wide_String_Access
;
1746 -- Nothing to translate, reuse empty shared string
1749 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1750 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1752 -- Otherwise, allocate new shared string and fill it
1755 DR
:= Allocate
(SR
.Last
);
1757 for J
in 1 .. SR
.Last
loop
1758 DR
.Data
(J
) := Mapping
.all (SR
.Data
(J
));
1764 return (AF
.Controlled
with Reference
=> DR
);
1774 (Source
: in out Unbounded_Wide_Wide_String
;
1775 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping_Function
)
1777 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1778 DR
: Shared_Wide_Wide_String_Access
;
1781 -- Nothing to translate
1786 -- Try to reuse shared string
1788 elsif Can_Be_Reused
(SR
, SR
.Last
) then
1789 for J
in 1 .. SR
.Last
loop
1790 SR
.Data
(J
) := Mapping
.all (SR
.Data
(J
));
1793 -- Otherwise allocate new shared string and fill it
1796 DR
:= Allocate
(SR
.Last
);
1798 for J
in 1 .. SR
.Last
loop
1799 DR
.Data
(J
) := Mapping
.all (SR
.Data
(J
));
1803 Source
.Reference
:= DR
;
1821 (Source
: Unbounded_Wide_Wide_String
;
1822 Side
: Trim_End
) return Unbounded_Wide_Wide_String
1824 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1826 DR
: Shared_Wide_Wide_String_Access
;
1831 Low
:= Index_Non_Blank
(Source
, Forward
);
1833 -- All blanks, reuse empty shared string
1836 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1837 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1843 DL
:= SR
.Last
- Low
+ 1;
1847 High
:= Index_Non_Blank
(Source
, Backward
);
1851 High
:= Index_Non_Blank
(Source
, Backward
);
1852 DL
:= High
- Low
+ 1;
1855 -- Length of the result is the same as length of the source string,
1856 -- reuse source shared string.
1858 if DL
= SR
.Last
then
1862 -- Otherwise, allocate new shared string
1865 DR
:= Allocate
(DL
);
1866 DR
.Data
(1 .. DL
) := SR
.Data
(Low
.. High
);
1871 return (AF
.Controlled
with Reference
=> DR
);
1875 (Source
: in out Unbounded_Wide_Wide_String
;
1878 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1880 DR
: Shared_Wide_Wide_String_Access
;
1885 Low
:= Index_Non_Blank
(Source
, Forward
);
1887 -- All blanks, reuse empty shared string
1890 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1891 Source
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
1898 DL
:= SR
.Last
- Low
+ 1;
1902 High
:= Index_Non_Blank
(Source
, Backward
);
1906 High
:= Index_Non_Blank
(Source
, Backward
);
1907 DL
:= High
- Low
+ 1;
1910 -- Length of the result is the same as length of the source string,
1913 if DL
= SR
.Last
then
1916 -- Try to reuse existent shared string
1918 elsif Can_Be_Reused
(SR
, DL
) then
1919 SR
.Data
(1 .. DL
) := SR
.Data
(Low
.. High
);
1922 -- Otherwise, allocate new shared string
1925 DR
:= Allocate
(DL
);
1926 DR
.Data
(1 .. DL
) := SR
.Data
(Low
.. High
);
1928 Source
.Reference
:= DR
;
1935 (Source
: Unbounded_Wide_Wide_String
;
1936 Left
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
1937 Right
: Wide_Wide_Maps
.Wide_Wide_Character_Set
)
1938 return Unbounded_Wide_Wide_String
1940 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1942 DR
: Shared_Wide_Wide_String_Access
;
1947 Low
:= Index
(Source
, Left
, Outside
, Forward
);
1949 -- Source includes only characters from Left set, reuse empty shared
1953 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1954 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1957 High
:= Index
(Source
, Right
, Outside
, Backward
);
1958 DL
:= Integer'Max (0, High
- Low
+ 1);
1960 -- Source includes only characters from Right set or result string
1961 -- is empty, reuse empty shared string.
1963 if High
= 0 or else DL
= 0 then
1964 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1965 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1967 -- Otherwise, allocate new shared string and fill it
1970 DR
:= Allocate
(DL
);
1971 DR
.Data
(1 .. DL
) := SR
.Data
(Low
.. High
);
1976 return (AF
.Controlled
with Reference
=> DR
);
1980 (Source
: in out Unbounded_Wide_Wide_String
;
1981 Left
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
1982 Right
: Wide_Wide_Maps
.Wide_Wide_Character_Set
)
1984 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1986 DR
: Shared_Wide_Wide_String_Access
;
1991 Low
:= Index
(Source
, Left
, Outside
, Forward
);
1993 -- Source includes only characters from Left set, reuse empty shared
1997 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1998 Source
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
2002 High
:= Index
(Source
, Right
, Outside
, Backward
);
2003 DL
:= Integer'Max (0, High
- Low
+ 1);
2005 -- Source includes only characters from Right set or result string
2006 -- is empty, reuse empty shared string.
2008 if High
= 0 or else DL
= 0 then
2009 Reference
(Empty_Shared_Wide_Wide_String
'Access);
2010 Source
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
2013 -- Try to reuse existent shared string
2015 elsif Can_Be_Reused
(SR
, DL
) then
2016 SR
.Data
(1 .. DL
) := SR
.Data
(Low
.. High
);
2019 -- Otherwise, allocate new shared string and fill it
2022 DR
:= Allocate
(DL
);
2023 DR
.Data
(1 .. DL
) := SR
.Data
(Low
.. High
);
2025 Source
.Reference
:= DR
;
2031 ---------------------
2032 -- Unbounded_Slice --
2033 ---------------------
2035 function Unbounded_Slice
2036 (Source
: Unbounded_Wide_Wide_String
;
2038 High
: Natural) return Unbounded_Wide_Wide_String
2040 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
2042 DR
: Shared_Wide_Wide_String_Access
;
2047 if Low
> SR
.Last
+ 1 or else High
> SR
.Last
then
2050 -- Result is empty slice, reuse empty shared string
2052 elsif Low
> High
then
2053 Reference
(Empty_Shared_Wide_Wide_String
'Access);
2054 DR
:= Empty_Shared_Wide_Wide_String
'Access;
2056 -- Otherwise, allocate new shared string and fill it
2059 DL
:= High
- Low
+ 1;
2060 DR
:= Allocate
(DL
);
2061 DR
.Data
(1 .. DL
) := SR
.Data
(Low
.. High
);
2065 return (AF
.Controlled
with Reference
=> DR
);
2066 end Unbounded_Slice
;
2068 procedure Unbounded_Slice
2069 (Source
: Unbounded_Wide_Wide_String
;
2070 Target
: out Unbounded_Wide_Wide_String
;
2074 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
2075 TR
: constant Shared_Wide_Wide_String_Access
:= Target
.Reference
;
2077 DR
: Shared_Wide_Wide_String_Access
;
2082 if Low
> SR
.Last
+ 1 or else High
> SR
.Last
then
2085 -- Result is empty slice, reuse empty shared string
2087 elsif Low
> High
then
2088 Reference
(Empty_Shared_Wide_Wide_String
'Access);
2089 Target
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
2093 DL
:= High
- Low
+ 1;
2095 -- Try to reuse existent shared string
2097 if Can_Be_Reused
(TR
, DL
) then
2098 TR
.Data
(1 .. DL
) := SR
.Data
(Low
.. High
);
2101 -- Otherwise, allocate new shared string and fill it
2104 DR
:= Allocate
(DL
);
2105 DR
.Data
(1 .. DL
) := SR
.Data
(Low
.. High
);
2107 Target
.Reference
:= DR
;
2111 end Unbounded_Slice
;
2117 procedure Unreference
(Item
: not null Shared_Wide_Wide_String_Access
) is
2120 new Ada
.Unchecked_Deallocation
2121 (Shared_Wide_Wide_String
, Shared_Wide_Wide_String_Access
);
2123 Aux
: Shared_Wide_Wide_String_Access
:= Item
;
2126 if System
.Atomic_Counters
.Decrement
(Aux
.Counter
) then
2128 -- Reference counter of Empty_Shared_Wide_Wide_String must never
2131 pragma Assert
(Aux
/= Empty_Shared_Wide_Wide_String
'Access);
2137 end Ada
.Strings
.Wide_Wide_Unbounded
;