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-2010, 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 procedure Sync_Add_And_Fetch
54 (Ptr
: access Interfaces
.Unsigned_32
;
55 Value
: Interfaces
.Unsigned_32
);
56 pragma Import
(Intrinsic
, Sync_Add_And_Fetch
, "__sync_add_and_fetch_4");
58 function Sync_Sub_And_Fetch
59 (Ptr
: access Interfaces
.Unsigned_32
;
60 Value
: Interfaces
.Unsigned_32
) return Interfaces
.Unsigned_32
;
61 pragma Import
(Intrinsic
, Sync_Sub_And_Fetch
, "__sync_sub_and_fetch_4");
63 function Aligned_Max_Length
(Max_Length
: Natural) return Natural;
64 -- Returns recommended length of the shared string which is greater or
65 -- equal to specified length. Calculation take in sense alignment of
66 -- the allocated memory segments to use memory effectively by
67 -- Append/Insert/etc operations.
74 (Left
: Unbounded_Wide_Wide_String
;
75 Right
: Unbounded_Wide_Wide_String
) return Unbounded_Wide_Wide_String
77 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
78 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
79 DL
: constant Natural := LR
.Last
+ RR
.Last
;
80 DR
: Shared_Wide_Wide_String_Access
;
83 -- Result is an empty string, reuse shared empty string.
86 Reference
(Empty_Shared_Wide_Wide_String
'Access);
87 DR
:= Empty_Shared_Wide_Wide_String
'Access;
89 -- Left string is empty, return Rigth string.
91 elsif LR
.Last
= 0 then
95 -- Right string is empty, return Left string.
97 elsif RR
.Last
= 0 then
101 -- Overwise, allocate new shared string and fill data.
104 DR
:= Allocate
(LR
.Last
+ RR
.Last
);
105 DR
.Data
(1 .. LR
.Last
) := LR
.Data
(1 .. LR
.Last
);
106 DR
.Data
(LR
.Last
+ 1 .. DL
) := RR
.Data
(1 .. RR
.Last
);
110 return (AF
.Controlled
with Reference
=> DR
);
114 (Left
: Unbounded_Wide_Wide_String
;
115 Right
: Wide_Wide_String
) return Unbounded_Wide_Wide_String
117 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
118 DL
: constant Natural := LR
.Last
+ Right
'Length;
119 DR
: Shared_Wide_Wide_String_Access
;
122 -- Result is an empty string, reuse shared empty string.
125 Reference
(Empty_Shared_Wide_Wide_String
'Access);
126 DR
:= Empty_Shared_Wide_Wide_String
'Access;
128 -- Right is an empty string, return Left string.
130 elsif Right
'Length = 0 then
134 -- Otherwise, allocate new shared string and fill it.
138 DR
.Data
(1 .. LR
.Last
) := LR
.Data
(1 .. LR
.Last
);
139 DR
.Data
(LR
.Last
+ 1 .. DL
) := Right
;
143 return (AF
.Controlled
with Reference
=> DR
);
147 (Left
: Wide_Wide_String
;
148 Right
: Unbounded_Wide_Wide_String
) return Unbounded_Wide_Wide_String
150 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
151 DL
: constant Natural := Left
'Length + RR
.Last
;
152 DR
: Shared_Wide_Wide_String_Access
;
155 -- Result is an empty string, reuse shared one.
158 Reference
(Empty_Shared_Wide_Wide_String
'Access);
159 DR
:= Empty_Shared_Wide_Wide_String
'Access;
161 -- Left is empty string, return Right string.
163 elsif Left
'Length = 0 then
167 -- Otherwise, allocate new shared string and fill it.
171 DR
.Data
(1 .. Left
'Length) := Left
;
172 DR
.Data
(Left
'Length + 1 .. DL
) := RR
.Data
(1 .. RR
.Last
);
176 return (AF
.Controlled
with Reference
=> DR
);
180 (Left
: Unbounded_Wide_Wide_String
;
181 Right
: Wide_Wide_Character
) return Unbounded_Wide_Wide_String
183 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
184 DL
: constant Natural := LR
.Last
+ 1;
185 DR
: Shared_Wide_Wide_String_Access
;
189 DR
.Data
(1 .. LR
.Last
) := LR
.Data
(1 .. LR
.Last
);
190 DR
.Data
(DL
) := Right
;
193 return (AF
.Controlled
with Reference
=> DR
);
197 (Left
: Wide_Wide_Character
;
198 Right
: Unbounded_Wide_Wide_String
) return Unbounded_Wide_Wide_String
200 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
201 DL
: constant Natural := 1 + RR
.Last
;
202 DR
: Shared_Wide_Wide_String_Access
;
207 DR
.Data
(2 .. DL
) := RR
.Data
(1 .. RR
.Last
);
210 return (AF
.Controlled
with Reference
=> DR
);
219 Right
: Wide_Wide_Character
) return Unbounded_Wide_Wide_String
221 DR
: Shared_Wide_Wide_String_Access
;
224 -- Result is an empty string, reuse shared empty string.
227 Reference
(Empty_Shared_Wide_Wide_String
'Access);
228 DR
:= Empty_Shared_Wide_Wide_String
'Access;
230 -- Otherwise, allocate new shared string and fill it.
233 DR
:= Allocate
(Left
);
235 for J
in 1 .. Left
loop
236 DR
.Data
(J
) := Right
;
242 return (AF
.Controlled
with Reference
=> DR
);
247 Right
: Wide_Wide_String
) return Unbounded_Wide_Wide_String
249 DL
: constant Natural := Left
* Right
'Length;
250 DR
: Shared_Wide_Wide_String_Access
;
254 -- Result is an empty string, reuse shared empty string.
257 Reference
(Empty_Shared_Wide_Wide_String
'Access);
258 DR
:= Empty_Shared_Wide_Wide_String
'Access;
260 -- Otherwise, allocate new shared string and fill it.
266 for J
in 1 .. Left
loop
267 DR
.Data
(K
.. K
+ Right
'Length - 1) := Right
;
268 K
:= K
+ Right
'Length;
274 return (AF
.Controlled
with Reference
=> DR
);
279 Right
: Unbounded_Wide_Wide_String
) return Unbounded_Wide_Wide_String
281 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
282 DL
: constant Natural := Left
* RR
.Last
;
283 DR
: Shared_Wide_Wide_String_Access
;
287 -- Result is an empty string, reuse shared empty string.
290 Reference
(Empty_Shared_Wide_Wide_String
'Access);
291 DR
:= Empty_Shared_Wide_Wide_String
'Access;
293 -- Coefficient is one, just return string itself.
299 -- Otherwise, allocate new shared string and fill it.
305 for J
in 1 .. Left
loop
306 DR
.Data
(K
.. K
+ RR
.Last
- 1) := RR
.Data
(1 .. RR
.Last
);
313 return (AF
.Controlled
with Reference
=> DR
);
321 (Left
: Unbounded_Wide_Wide_String
;
322 Right
: Unbounded_Wide_Wide_String
) return Boolean
324 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
325 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
327 return LR
.Data
(1 .. LR
.Last
) < RR
.Data
(1 .. RR
.Last
);
331 (Left
: Unbounded_Wide_Wide_String
;
332 Right
: Wide_Wide_String
) return Boolean
334 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
336 return LR
.Data
(1 .. LR
.Last
) < Right
;
340 (Left
: Wide_Wide_String
;
341 Right
: Unbounded_Wide_Wide_String
) return Boolean
343 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
345 return Left
< RR
.Data
(1 .. RR
.Last
);
353 (Left
: Unbounded_Wide_Wide_String
;
354 Right
: Unbounded_Wide_Wide_String
) return Boolean
356 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
357 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
360 -- LR = RR means two strings shares shared string, thus they are equal
362 return LR
= RR
or else LR
.Data
(1 .. LR
.Last
) <= RR
.Data
(1 .. RR
.Last
);
366 (Left
: Unbounded_Wide_Wide_String
;
367 Right
: Wide_Wide_String
) return Boolean
369 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
371 return LR
.Data
(1 .. LR
.Last
) <= Right
;
375 (Left
: Wide_Wide_String
;
376 Right
: Unbounded_Wide_Wide_String
) return Boolean
378 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
380 return Left
<= RR
.Data
(1 .. RR
.Last
);
388 (Left
: Unbounded_Wide_Wide_String
;
389 Right
: Unbounded_Wide_Wide_String
) return Boolean
391 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
392 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
395 return LR
= RR
or else LR
.Data
(1 .. LR
.Last
) = RR
.Data
(1 .. RR
.Last
);
396 -- LR = RR means two strings shares shared string, thus they are equal.
400 (Left
: Unbounded_Wide_Wide_String
;
401 Right
: Wide_Wide_String
) return Boolean
403 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
405 return LR
.Data
(1 .. LR
.Last
) = Right
;
409 (Left
: Wide_Wide_String
;
410 Right
: Unbounded_Wide_Wide_String
) return Boolean
412 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
414 return Left
= RR
.Data
(1 .. RR
.Last
);
422 (Left
: Unbounded_Wide_Wide_String
;
423 Right
: Unbounded_Wide_Wide_String
) return Boolean
425 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
426 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
428 return LR
.Data
(1 .. LR
.Last
) > RR
.Data
(1 .. RR
.Last
);
432 (Left
: Unbounded_Wide_Wide_String
;
433 Right
: Wide_Wide_String
) return Boolean
435 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
437 return LR
.Data
(1 .. LR
.Last
) > Right
;
441 (Left
: Wide_Wide_String
;
442 Right
: Unbounded_Wide_Wide_String
) return Boolean
444 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
446 return Left
> RR
.Data
(1 .. RR
.Last
);
454 (Left
: Unbounded_Wide_Wide_String
;
455 Right
: Unbounded_Wide_Wide_String
) return Boolean
457 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
458 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
461 -- LR = RR means two strings shares shared string, thus they are equal
463 return LR
= RR
or else LR
.Data
(1 .. LR
.Last
) >= RR
.Data
(1 .. RR
.Last
);
467 (Left
: Unbounded_Wide_Wide_String
;
468 Right
: Wide_Wide_String
) return Boolean
470 LR
: constant Shared_Wide_Wide_String_Access
:= Left
.Reference
;
472 return LR
.Data
(1 .. LR
.Last
) >= Right
;
476 (Left
: Wide_Wide_String
;
477 Right
: Unbounded_Wide_Wide_String
) return Boolean
479 RR
: constant Shared_Wide_Wide_String_Access
:= Right
.Reference
;
481 return Left
>= RR
.Data
(1 .. RR
.Last
);
488 procedure Adjust
(Object
: in out Unbounded_Wide_Wide_String
) is
490 Reference
(Object
.Reference
);
493 ------------------------
494 -- Aligned_Max_Length --
495 ------------------------
497 function Aligned_Max_Length
(Max_Length
: Natural) return Natural is
498 Static_Size
: constant Natural :=
499 Empty_Shared_Wide_Wide_String
'Size
500 / Standard
'Storage_Unit;
501 -- Total size of all static components
503 Element_Size
: constant Natural :=
504 Wide_Wide_Character
'Size / Standard
'Storage_Unit;
508 (((Static_Size
+ Max_Length
* Element_Size
- 1) / Min_Mul_Alloc
+ 2)
509 * Min_Mul_Alloc
- Static_Size
) / Element_Size
;
510 end Aligned_Max_Length
;
517 (Max_Length
: Natural) return Shared_Wide_Wide_String_Access
is
519 -- Empty string requested, return shared empty string
521 if Max_Length
= 0 then
522 Reference
(Empty_Shared_Wide_Wide_String
'Access);
523 return Empty_Shared_Wide_Wide_String
'Access;
525 -- Otherwise, allocate requested space (and probably some more room)
528 return new Shared_Wide_Wide_String
(Aligned_Max_Length
(Max_Length
));
537 (Source
: in out Unbounded_Wide_Wide_String
;
538 New_Item
: Unbounded_Wide_Wide_String
)
540 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
541 NR
: constant Shared_Wide_Wide_String_Access
:= New_Item
.Reference
;
542 DL
: constant Natural := SR
.Last
+ NR
.Last
;
543 DR
: Shared_Wide_Wide_String_Access
;
546 -- Source is an empty string, reuse New_Item data
550 Source
.Reference
:= NR
;
553 -- New_Item is empty string, nothing to do
555 elsif NR
.Last
= 0 then
558 -- Try to reuse existent shared string
560 elsif Can_Be_Reused
(SR
, DL
) then
561 SR
.Data
(SR
.Last
+ 1 .. DL
) := NR
.Data
(1 .. NR
.Last
);
564 -- Otherwise, allocate new one and fill it
567 DR
:= Allocate
(DL
+ DL
/ Growth_Factor
);
568 DR
.Data
(1 .. SR
.Last
) := SR
.Data
(1 .. SR
.Last
);
569 DR
.Data
(SR
.Last
+ 1 .. DL
) := NR
.Data
(1 .. NR
.Last
);
571 Source
.Reference
:= DR
;
577 (Source
: in out Unbounded_Wide_Wide_String
;
578 New_Item
: Wide_Wide_String
)
580 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
581 DL
: constant Natural := SR
.Last
+ New_Item
'Length;
582 DR
: Shared_Wide_Wide_String_Access
;
585 -- New_Item is an empty string, nothing to do
587 if New_Item
'Length = 0 then
590 -- Try to reuse existing shared string
592 elsif Can_Be_Reused
(SR
, DL
) then
593 SR
.Data
(SR
.Last
+ 1 .. DL
) := New_Item
;
596 -- Otherwise, allocate new one and fill it
599 DR
:= Allocate
(DL
+ DL
/ Growth_Factor
);
600 DR
.Data
(1 .. SR
.Last
) := SR
.Data
(1 .. SR
.Last
);
601 DR
.Data
(SR
.Last
+ 1 .. DL
) := New_Item
;
603 Source
.Reference
:= DR
;
609 (Source
: in out Unbounded_Wide_Wide_String
;
610 New_Item
: Wide_Wide_Character
)
612 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
613 DL
: constant Natural := SR
.Last
+ 1;
614 DR
: Shared_Wide_Wide_String_Access
;
617 -- Try to reuse existing shared string
619 if Can_Be_Reused
(SR
, SR
.Last
+ 1) then
620 SR
.Data
(SR
.Last
+ 1) := New_Item
;
621 SR
.Last
:= SR
.Last
+ 1;
623 -- Otherwise, allocate new one and fill it
626 DR
:= Allocate
(DL
+ DL
/ Growth_Factor
);
627 DR
.Data
(1 .. SR
.Last
) := SR
.Data
(1 .. SR
.Last
);
628 DR
.Data
(DL
) := New_Item
;
630 Source
.Reference
:= DR
;
639 function Can_Be_Reused
640 (Item
: Shared_Wide_Wide_String_Access
;
641 Length
: Natural) return Boolean
647 and then Item
.Max_Length
>= Length
648 and then Item
.Max_Length
<=
649 Aligned_Max_Length
(Length
+ Length
/ Growth_Factor
);
657 (Source
: Unbounded_Wide_Wide_String
;
658 Pattern
: Wide_Wide_String
;
659 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping
:=
660 Wide_Wide_Maps
.Identity
)
663 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
665 return Wide_Wide_Search
.Count
(SR
.Data
(1 .. SR
.Last
), Pattern
, Mapping
);
669 (Source
: Unbounded_Wide_Wide_String
;
670 Pattern
: Wide_Wide_String
;
671 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping_Function
)
674 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
676 return Wide_Wide_Search
.Count
(SR
.Data
(1 .. SR
.Last
), Pattern
, Mapping
);
680 (Source
: Unbounded_Wide_Wide_String
;
681 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
) return Natural
683 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
685 return Wide_Wide_Search
.Count
(SR
.Data
(1 .. SR
.Last
), Set
);
693 (Source
: Unbounded_Wide_Wide_String
;
695 Through
: Natural) return Unbounded_Wide_Wide_String
697 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
699 DR
: Shared_Wide_Wide_String_Access
;
702 -- Empty slice is deleted, use the same shared string
704 if From
> Through
then
708 -- Index is out of range
710 elsif Through
> SR
.Last
then
713 -- Compute size of the result
716 DL
:= SR
.Last
- (Through
- From
+ 1);
718 -- Result is an empty string, reuse shared empty string
721 Reference
(Empty_Shared_Wide_Wide_String
'Access);
722 DR
:= Empty_Shared_Wide_Wide_String
'Access;
724 -- Otherwise, allocate new shared string and fill it
728 DR
.Data
(1 .. From
- 1) := SR
.Data
(1 .. From
- 1);
729 DR
.Data
(From
.. DL
) := SR
.Data
(Through
+ 1 .. SR
.Last
);
734 return (AF
.Controlled
with Reference
=> DR
);
738 (Source
: in out Unbounded_Wide_Wide_String
;
742 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
744 DR
: Shared_Wide_Wide_String_Access
;
747 -- Nothing changed, return
749 if From
> Through
then
752 -- Through is outside of the range
754 elsif Through
> SR
.Last
then
758 DL
:= SR
.Last
- (Through
- From
+ 1);
760 -- Result is empty, reuse shared empty string
763 Reference
(Empty_Shared_Wide_Wide_String
'Access);
764 Source
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
767 -- Try to reuse existent shared string
769 elsif Can_Be_Reused
(SR
, DL
) then
770 SR
.Data
(From
.. DL
) := SR
.Data
(Through
+ 1 .. SR
.Last
);
773 -- Otherwise, allocate new shared string
777 DR
.Data
(1 .. From
- 1) := SR
.Data
(1 .. From
- 1);
778 DR
.Data
(From
.. DL
) := SR
.Data
(Through
+ 1 .. SR
.Last
);
780 Source
.Reference
:= DR
;
791 (Source
: Unbounded_Wide_Wide_String
;
792 Index
: Positive) return Wide_Wide_Character
794 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
796 if Index
<= SR
.Last
then
797 return SR
.Data
(Index
);
807 procedure Finalize
(Object
: in out Unbounded_Wide_Wide_String
) is
808 SR
: constant Shared_Wide_Wide_String_Access
:= Object
.Reference
;
813 -- The same controlled object can be finalized several times for
814 -- some reason. As per 7.6.1(24) this should have no ill effect,
815 -- so we need to add a guard for the case of finalizing the same
818 Object
.Reference
:= null;
828 (Source
: Unbounded_Wide_Wide_String
;
829 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
831 Test
: Strings
.Membership
;
832 First
: out Positive;
835 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
837 Wide_Wide_Search
.Find_Token
838 (SR
.Data
(From
.. SR
.Last
), Set
, Test
, First
, Last
);
842 (Source
: Unbounded_Wide_Wide_String
;
843 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
844 Test
: Strings
.Membership
;
845 First
: out Positive;
848 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
850 Wide_Wide_Search
.Find_Token
851 (SR
.Data
(1 .. SR
.Last
), Set
, Test
, First
, Last
);
858 procedure Free
(X
: in out Wide_Wide_String_Access
) is
859 procedure Deallocate
is
860 new Ada
.Unchecked_Deallocation
861 (Wide_Wide_String
, Wide_Wide_String_Access
);
871 (Source
: Unbounded_Wide_Wide_String
;
873 Pad
: Wide_Wide_Character
:= Wide_Wide_Space
)
874 return Unbounded_Wide_Wide_String
876 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
877 DR
: Shared_Wide_Wide_String_Access
;
880 -- Result is empty, reuse shared empty string
883 Reference
(Empty_Shared_Wide_Wide_String
'Access);
884 DR
:= Empty_Shared_Wide_Wide_String
'Access;
886 -- Length of the string is the same as requested, reuse source shared
889 elsif Count
= SR
.Last
then
893 -- Otherwise, allocate new shared string and fill it
896 DR
:= Allocate
(Count
);
898 -- Length of the source string is more than requested, copy
899 -- corresponding slice.
901 if Count
< SR
.Last
then
902 DR
.Data
(1 .. Count
) := SR
.Data
(1 .. Count
);
904 -- Length of the source string is less then requested, copy all
905 -- contents and fill others by Pad character.
908 DR
.Data
(1 .. SR
.Last
) := SR
.Data
(1 .. SR
.Last
);
910 for J
in SR
.Last
+ 1 .. Count
loop
918 return (AF
.Controlled
with Reference
=> DR
);
922 (Source
: in out Unbounded_Wide_Wide_String
;
924 Pad
: Wide_Wide_Character
:= Wide_Wide_Space
)
926 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
927 DR
: Shared_Wide_Wide_String_Access
;
930 -- Result is empty, reuse empty shared string
933 Reference
(Empty_Shared_Wide_Wide_String
'Access);
934 Source
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
937 -- Result is same with source string, reuse source shared string
939 elsif Count
= SR
.Last
then
942 -- Try to reuse existent shared string
944 elsif Can_Be_Reused
(SR
, Count
) then
945 if Count
> SR
.Last
then
946 for J
in SR
.Last
+ 1 .. Count
loop
953 -- Otherwise, allocate new shared string and fill it
956 DR
:= Allocate
(Count
);
958 -- Length of the source string is greater then requested, copy
959 -- corresponding slice.
961 if Count
< SR
.Last
then
962 DR
.Data
(1 .. Count
) := SR
.Data
(1 .. Count
);
964 -- Length of the source string is less the requested, copy all
965 -- exists data and fill others by Pad character.
968 DR
.Data
(1 .. SR
.Last
) := SR
.Data
(1 .. SR
.Last
);
970 for J
in SR
.Last
+ 1 .. Count
loop
976 Source
.Reference
:= DR
;
986 (Source
: Unbounded_Wide_Wide_String
;
987 Pattern
: Wide_Wide_String
;
988 Going
: Strings
.Direction
:= Strings
.Forward
;
989 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping
:=
990 Wide_Wide_Maps
.Identity
)
993 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
995 return Wide_Wide_Search
.Index
996 (SR
.Data
(1 .. SR
.Last
), Pattern
, Going
, Mapping
);
1000 (Source
: Unbounded_Wide_Wide_String
;
1001 Pattern
: Wide_Wide_String
;
1002 Going
: Direction
:= Forward
;
1003 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping_Function
)
1006 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1008 return Wide_Wide_Search
.Index
1009 (SR
.Data
(1 .. SR
.Last
), Pattern
, Going
, Mapping
);
1013 (Source
: Unbounded_Wide_Wide_String
;
1014 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
1015 Test
: Strings
.Membership
:= Strings
.Inside
;
1016 Going
: Strings
.Direction
:= Strings
.Forward
) return Natural
1018 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1020 return Wide_Wide_Search
.Index
(SR
.Data
(1 .. SR
.Last
), Set
, Test
, Going
);
1024 (Source
: Unbounded_Wide_Wide_String
;
1025 Pattern
: Wide_Wide_String
;
1027 Going
: Direction
:= Forward
;
1028 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping
:=
1029 Wide_Wide_Maps
.Identity
)
1032 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1034 return Wide_Wide_Search
.Index
1035 (SR
.Data
(1 .. SR
.Last
), Pattern
, From
, Going
, Mapping
);
1039 (Source
: Unbounded_Wide_Wide_String
;
1040 Pattern
: Wide_Wide_String
;
1042 Going
: Direction
:= Forward
;
1043 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping_Function
)
1046 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1048 return Wide_Wide_Search
.Index
1049 (SR
.Data
(1 .. SR
.Last
), Pattern
, From
, Going
, Mapping
);
1053 (Source
: Unbounded_Wide_Wide_String
;
1054 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
1056 Test
: Membership
:= Inside
;
1057 Going
: Direction
:= Forward
) return Natural
1059 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1061 return Wide_Wide_Search
.Index
1062 (SR
.Data
(1 .. SR
.Last
), Set
, From
, Test
, Going
);
1065 ---------------------
1066 -- Index_Non_Blank --
1067 ---------------------
1069 function Index_Non_Blank
1070 (Source
: Unbounded_Wide_Wide_String
;
1071 Going
: Strings
.Direction
:= Strings
.Forward
) return Natural
1073 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1075 return Wide_Wide_Search
.Index_Non_Blank
(SR
.Data
(1 .. SR
.Last
), Going
);
1076 end Index_Non_Blank
;
1078 function Index_Non_Blank
1079 (Source
: Unbounded_Wide_Wide_String
;
1081 Going
: Direction
:= Forward
) return Natural
1083 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1085 return Wide_Wide_Search
.Index_Non_Blank
1086 (SR
.Data
(1 .. SR
.Last
), From
, Going
);
1087 end Index_Non_Blank
;
1093 procedure Initialize
(Object
: in out Unbounded_Wide_Wide_String
) is
1095 Reference
(Object
.Reference
);
1103 (Source
: Unbounded_Wide_Wide_String
;
1105 New_Item
: Wide_Wide_String
) return Unbounded_Wide_Wide_String
1107 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1108 DL
: constant Natural := SR
.Last
+ New_Item
'Length;
1109 DR
: Shared_Wide_Wide_String_Access
;
1112 -- Check index first
1114 if Before
> SR
.Last
+ 1 then
1118 -- Result is empty, reuse empty shared string
1121 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1122 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1124 -- Inserted string is empty, reuse source shared string
1126 elsif New_Item
'Length = 0 then
1130 -- Otherwise, allocate new shared string and fill it
1133 DR
:= Allocate
(DL
+ DL
/ Growth_Factor
);
1134 DR
.Data
(1 .. Before
- 1) := SR
.Data
(1 .. Before
- 1);
1135 DR
.Data
(Before
.. Before
+ New_Item
'Length - 1) := New_Item
;
1136 DR
.Data
(Before
+ New_Item
'Length .. DL
) :=
1137 SR
.Data
(Before
.. SR
.Last
);
1141 return (AF
.Controlled
with Reference
=> DR
);
1145 (Source
: in out Unbounded_Wide_Wide_String
;
1147 New_Item
: Wide_Wide_String
)
1149 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1150 DL
: constant Natural := SR
.Last
+ New_Item
'Length;
1151 DR
: Shared_Wide_Wide_String_Access
;
1156 if Before
> SR
.Last
+ 1 then
1160 -- Result is empty string, reuse empty shared string
1163 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1164 Source
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
1167 -- Inserted string is empty, nothing to do
1169 elsif New_Item
'Length = 0 then
1172 -- Try to reuse existent shared string first
1174 elsif Can_Be_Reused
(SR
, DL
) then
1175 SR
.Data
(Before
+ New_Item
'Length .. DL
) :=
1176 SR
.Data
(Before
.. SR
.Last
);
1177 SR
.Data
(Before
.. Before
+ New_Item
'Length - 1) := New_Item
;
1180 -- Otherwise, allocate new shared string and fill it
1183 DR
:= Allocate
(DL
+ DL
/ Growth_Factor
);
1184 DR
.Data
(1 .. Before
- 1) := SR
.Data
(1 .. Before
- 1);
1185 DR
.Data
(Before
.. Before
+ New_Item
'Length - 1) := New_Item
;
1186 DR
.Data
(Before
+ New_Item
'Length .. DL
) :=
1187 SR
.Data
(Before
.. SR
.Last
);
1189 Source
.Reference
:= DR
;
1198 function Length
(Source
: Unbounded_Wide_Wide_String
) return Natural is
1200 return Source
.Reference
.Last
;
1208 (Source
: Unbounded_Wide_Wide_String
;
1209 Position
: Positive;
1210 New_Item
: Wide_Wide_String
) return Unbounded_Wide_Wide_String
1212 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1214 DR
: Shared_Wide_Wide_String_Access
;
1219 if Position
> SR
.Last
+ 1 then
1223 DL
:= Integer'Max (SR
.Last
, Position
+ New_Item
'Length - 1);
1225 -- Result is empty string, reuse empty shared string
1228 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1229 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1231 -- Result is same with source string, reuse source shared string
1233 elsif New_Item
'Length = 0 then
1237 -- Otherwise, allocate new shared string and fill it
1240 DR
:= Allocate
(DL
);
1241 DR
.Data
(1 .. Position
- 1) := SR
.Data
(1 .. Position
- 1);
1242 DR
.Data
(Position
.. Position
+ New_Item
'Length - 1) := New_Item
;
1243 DR
.Data
(Position
+ New_Item
'Length .. DL
) :=
1244 SR
.Data
(Position
+ New_Item
'Length .. SR
.Last
);
1248 return (AF
.Controlled
with Reference
=> DR
);
1252 (Source
: in out Unbounded_Wide_Wide_String
;
1253 Position
: Positive;
1254 New_Item
: Wide_Wide_String
)
1256 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1258 DR
: Shared_Wide_Wide_String_Access
;
1263 if Position
> SR
.Last
+ 1 then
1267 DL
:= Integer'Max (SR
.Last
, Position
+ New_Item
'Length - 1);
1269 -- Result is empty string, reuse empty shared string
1272 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1273 Source
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
1276 -- String unchanged, nothing to do
1278 elsif New_Item
'Length = 0 then
1281 -- Try to reuse existent shared string
1283 elsif Can_Be_Reused
(SR
, DL
) then
1284 SR
.Data
(Position
.. Position
+ New_Item
'Length - 1) := New_Item
;
1287 -- Otherwise allocate new shared string and fill it
1290 DR
:= Allocate
(DL
);
1291 DR
.Data
(1 .. Position
- 1) := SR
.Data
(1 .. Position
- 1);
1292 DR
.Data
(Position
.. Position
+ New_Item
'Length - 1) := New_Item
;
1293 DR
.Data
(Position
+ New_Item
'Length .. DL
) :=
1294 SR
.Data
(Position
+ New_Item
'Length .. SR
.Last
);
1296 Source
.Reference
:= DR
;
1305 procedure Reference
(Item
: not null Shared_Wide_Wide_String_Access
) is
1307 Sync_Add_And_Fetch
(Item
.Counter
'Access, 1);
1310 ---------------------
1311 -- Replace_Element --
1312 ---------------------
1314 procedure Replace_Element
1315 (Source
: in out Unbounded_Wide_Wide_String
;
1317 By
: Wide_Wide_Character
)
1319 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1320 DR
: Shared_Wide_Wide_String_Access
;
1325 if Index
<= SR
.Last
then
1327 -- Try to reuse existent shared string
1329 if Can_Be_Reused
(SR
, SR
.Last
) then
1330 SR
.Data
(Index
) := By
;
1332 -- Otherwise allocate new shared string and fill it
1335 DR
:= Allocate
(SR
.Last
);
1336 DR
.Data
(1 .. SR
.Last
) := SR
.Data
(1 .. SR
.Last
);
1337 DR
.Data
(Index
) := By
;
1339 Source
.Reference
:= DR
;
1346 end Replace_Element
;
1352 function Replace_Slice
1353 (Source
: Unbounded_Wide_Wide_String
;
1356 By
: Wide_Wide_String
) return Unbounded_Wide_Wide_String
1358 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1360 DR
: Shared_Wide_Wide_String_Access
;
1365 if Low
> SR
.Last
+ 1 then
1369 -- Do replace operation when removed slice is not empty
1372 DL
:= By
'Length + SR
.Last
+ Low
- High
- 1;
1374 -- Result is empty string, reuse empty shared string
1377 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1378 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1380 -- Otherwise allocate new shared string and fill it
1383 DR
:= Allocate
(DL
);
1384 DR
.Data
(1 .. Low
- 1) := SR
.Data
(1 .. Low
- 1);
1385 DR
.Data
(Low
.. Low
+ By
'Length - 1) := By
;
1386 DR
.Data
(Low
+ By
'Length .. DL
) := SR
.Data
(High
+ 1 .. SR
.Last
);
1390 return (AF
.Controlled
with Reference
=> DR
);
1392 -- Otherwise just insert string
1395 return Insert
(Source
, Low
, By
);
1399 procedure Replace_Slice
1400 (Source
: in out Unbounded_Wide_Wide_String
;
1403 By
: Wide_Wide_String
)
1405 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1407 DR
: Shared_Wide_Wide_String_Access
;
1412 if Low
> SR
.Last
+ 1 then
1416 -- Do replace operation only when replaced slice is not empty
1419 DL
:= By
'Length + SR
.Last
+ Low
- High
- 1;
1421 -- Result is empty string, reuse empty shared string
1424 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1425 Source
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
1428 -- Try to reuse existent shared string
1430 elsif Can_Be_Reused
(SR
, DL
) then
1431 SR
.Data
(Low
+ By
'Length .. DL
) := SR
.Data
(High
+ 1 .. SR
.Last
);
1432 SR
.Data
(Low
.. Low
+ By
'Length - 1) := By
;
1435 -- Otherwise allocate new shared string and fill it
1438 DR
:= Allocate
(DL
);
1439 DR
.Data
(1 .. Low
- 1) := SR
.Data
(1 .. Low
- 1);
1440 DR
.Data
(Low
.. Low
+ By
'Length - 1) := By
;
1441 DR
.Data
(Low
+ By
'Length .. DL
) := SR
.Data
(High
+ 1 .. SR
.Last
);
1443 Source
.Reference
:= DR
;
1447 -- Otherwise just insert item
1450 Insert
(Source
, Low
, By
);
1454 -------------------------------
1455 -- Set_Unbounded_Wide_Wide_String --
1456 -------------------------------
1458 procedure Set_Unbounded_Wide_Wide_String
1459 (Target
: out Unbounded_Wide_Wide_String
;
1460 Source
: Wide_Wide_String
)
1462 TR
: constant Shared_Wide_Wide_String_Access
:= Target
.Reference
;
1463 DR
: Shared_Wide_Wide_String_Access
;
1466 -- In case of empty string, reuse empty shared string
1468 if Source
'Length = 0 then
1469 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1470 Target
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
1473 -- Try to reuse existent shared string
1475 if Can_Be_Reused
(TR
, Source
'Length) then
1479 -- Otherwise allocate new shared string
1482 DR
:= Allocate
(Source
'Length);
1483 Target
.Reference
:= DR
;
1486 DR
.Data
(1 .. Source
'Length) := Source
;
1487 DR
.Last
:= Source
'Length;
1491 end Set_Unbounded_Wide_Wide_String
;
1498 (Source
: Unbounded_Wide_Wide_String
;
1500 High
: Natural) return Wide_Wide_String
1502 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1505 -- Note: test of High > Length is in accordance with AI95-00128
1507 if Low
> SR
.Last
+ 1 or else High
> SR
.Last
then
1511 return SR
.Data
(Low
.. High
);
1520 (Source
: Unbounded_Wide_Wide_String
;
1522 Pad
: Wide_Wide_Character
:= Wide_Wide_Space
)
1523 return Unbounded_Wide_Wide_String
1525 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1526 DR
: Shared_Wide_Wide_String_Access
;
1529 -- For empty result reuse empty shared string
1532 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1533 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1535 -- Result is hole source string, reuse source shared string
1537 elsif Count
= SR
.Last
then
1541 -- Otherwise allocate new shared string and fill it
1544 DR
:= Allocate
(Count
);
1546 if Count
< SR
.Last
then
1547 DR
.Data
(1 .. Count
) := SR
.Data
(SR
.Last
- Count
+ 1 .. SR
.Last
);
1550 for J
in 1 .. Count
- SR
.Last
loop
1554 DR
.Data
(Count
- SR
.Last
+ 1 .. Count
) := SR
.Data
(1 .. SR
.Last
);
1560 return (AF
.Controlled
with Reference
=> DR
);
1564 (Source
: in out Unbounded_Wide_Wide_String
;
1566 Pad
: Wide_Wide_Character
:= Wide_Wide_Space
)
1568 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1569 DR
: Shared_Wide_Wide_String_Access
;
1572 (SR
: Shared_Wide_Wide_String_Access
;
1573 DR
: Shared_Wide_Wide_String_Access
;
1575 -- Common code of tail computation. SR/DR can point to the same object
1582 (SR
: Shared_Wide_Wide_String_Access
;
1583 DR
: Shared_Wide_Wide_String_Access
;
1586 if Count
< SR
.Last
then
1587 DR
.Data
(1 .. Count
) := SR
.Data
(SR
.Last
- Count
+ 1 .. SR
.Last
);
1590 DR
.Data
(Count
- SR
.Last
+ 1 .. Count
) := SR
.Data
(1 .. SR
.Last
);
1592 for J
in 1 .. Count
- SR
.Last
loop
1601 -- Result is empty string, reuse empty shared string
1604 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1605 Source
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
1608 -- Length of the result is the same with length of the source string,
1609 -- reuse source shared string.
1611 elsif Count
= SR
.Last
then
1614 -- Try to reuse existent shared string
1616 elsif Can_Be_Reused
(SR
, Count
) then
1617 Common
(SR
, SR
, Count
);
1619 -- Otherwise allocate new shared string and fill it
1622 DR
:= Allocate
(Count
);
1623 Common
(SR
, DR
, Count
);
1624 Source
.Reference
:= DR
;
1629 --------------------
1630 -- To_Wide_Wide_String --
1631 --------------------
1633 function To_Wide_Wide_String
1634 (Source
: Unbounded_Wide_Wide_String
) return Wide_Wide_String
is
1636 return Source
.Reference
.Data
(1 .. Source
.Reference
.Last
);
1637 end To_Wide_Wide_String
;
1639 ------------------------------
1640 -- To_Unbounded_Wide_Wide_String --
1641 ------------------------------
1643 function To_Unbounded_Wide_Wide_String
1644 (Source
: Wide_Wide_String
) return Unbounded_Wide_Wide_String
1646 DR
: constant Shared_Wide_Wide_String_Access
:= Allocate
(Source
'Length);
1648 DR
.Data
(1 .. Source
'Length) := Source
;
1649 DR
.Last
:= Source
'Length;
1650 return (AF
.Controlled
with Reference
=> DR
);
1651 end To_Unbounded_Wide_Wide_String
;
1653 function To_Unbounded_Wide_Wide_String
1654 (Length
: Natural) return Unbounded_Wide_Wide_String
1656 DR
: constant Shared_Wide_Wide_String_Access
:= Allocate
(Length
);
1659 return (AF
.Controlled
with Reference
=> DR
);
1660 end To_Unbounded_Wide_Wide_String
;
1667 (Source
: Unbounded_Wide_Wide_String
;
1668 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping
)
1669 return Unbounded_Wide_Wide_String
1671 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1672 DR
: Shared_Wide_Wide_String_Access
;
1675 -- Nothing to translate, reuse empty shared string
1678 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1679 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1681 -- Otherwise, allocate new shared string and fill it
1684 DR
:= Allocate
(SR
.Last
);
1686 for J
in 1 .. SR
.Last
loop
1687 DR
.Data
(J
) := Value
(Mapping
, SR
.Data
(J
));
1693 return (AF
.Controlled
with Reference
=> DR
);
1697 (Source
: in out Unbounded_Wide_Wide_String
;
1698 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping
)
1700 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1701 DR
: Shared_Wide_Wide_String_Access
;
1704 -- Nothing to translate
1709 -- Try to reuse shared string
1711 elsif Can_Be_Reused
(SR
, SR
.Last
) then
1712 for J
in 1 .. SR
.Last
loop
1713 SR
.Data
(J
) := Value
(Mapping
, SR
.Data
(J
));
1716 -- Otherwise, allocate new shared string
1719 DR
:= Allocate
(SR
.Last
);
1721 for J
in 1 .. SR
.Last
loop
1722 DR
.Data
(J
) := Value
(Mapping
, SR
.Data
(J
));
1726 Source
.Reference
:= DR
;
1732 (Source
: Unbounded_Wide_Wide_String
;
1733 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping_Function
)
1734 return Unbounded_Wide_Wide_String
1736 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1737 DR
: Shared_Wide_Wide_String_Access
;
1740 -- Nothing to translate, reuse empty shared string
1743 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1744 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1746 -- Otherwise, allocate new shared string and fill it
1749 DR
:= Allocate
(SR
.Last
);
1751 for J
in 1 .. SR
.Last
loop
1752 DR
.Data
(J
) := Mapping
.all (SR
.Data
(J
));
1758 return (AF
.Controlled
with Reference
=> DR
);
1768 (Source
: in out Unbounded_Wide_Wide_String
;
1769 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping_Function
)
1771 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1772 DR
: Shared_Wide_Wide_String_Access
;
1775 -- Nothing to translate
1780 -- Try to reuse shared string
1782 elsif Can_Be_Reused
(SR
, SR
.Last
) then
1783 for J
in 1 .. SR
.Last
loop
1784 SR
.Data
(J
) := Mapping
.all (SR
.Data
(J
));
1787 -- Otherwise allocate new shared string and fill it
1790 DR
:= Allocate
(SR
.Last
);
1792 for J
in 1 .. SR
.Last
loop
1793 DR
.Data
(J
) := Mapping
.all (SR
.Data
(J
));
1797 Source
.Reference
:= DR
;
1815 (Source
: Unbounded_Wide_Wide_String
;
1816 Side
: Trim_End
) return Unbounded_Wide_Wide_String
1818 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1820 DR
: Shared_Wide_Wide_String_Access
;
1825 Low
:= Index_Non_Blank
(Source
, Forward
);
1827 -- All blanks, reuse empty shared string
1830 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1831 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1837 DL
:= SR
.Last
- Low
+ 1;
1841 High
:= Index_Non_Blank
(Source
, Backward
);
1845 High
:= Index_Non_Blank
(Source
, Backward
);
1846 DL
:= High
- Low
+ 1;
1849 -- Length of the result is the same as length of the source string,
1850 -- reuse source shared string.
1852 if DL
= SR
.Last
then
1856 -- Otherwise, allocate new shared string
1859 DR
:= Allocate
(DL
);
1860 DR
.Data
(1 .. DL
) := SR
.Data
(Low
.. High
);
1865 return (AF
.Controlled
with Reference
=> DR
);
1869 (Source
: in out Unbounded_Wide_Wide_String
;
1872 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1874 DR
: Shared_Wide_Wide_String_Access
;
1879 Low
:= Index_Non_Blank
(Source
, Forward
);
1881 -- All blanks, reuse empty shared string
1884 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1885 Source
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
1892 DL
:= SR
.Last
- Low
+ 1;
1896 High
:= Index_Non_Blank
(Source
, Backward
);
1900 High
:= Index_Non_Blank
(Source
, Backward
);
1901 DL
:= High
- Low
+ 1;
1904 -- Length of the result is the same as length of the source string,
1907 if DL
= SR
.Last
then
1910 -- Try to reuse existent shared string
1912 elsif Can_Be_Reused
(SR
, DL
) then
1913 SR
.Data
(1 .. DL
) := SR
.Data
(Low
.. High
);
1916 -- Otherwise, allocate new shared string
1919 DR
:= Allocate
(DL
);
1920 DR
.Data
(1 .. DL
) := SR
.Data
(Low
.. High
);
1922 Source
.Reference
:= DR
;
1929 (Source
: Unbounded_Wide_Wide_String
;
1930 Left
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
1931 Right
: Wide_Wide_Maps
.Wide_Wide_Character_Set
)
1932 return Unbounded_Wide_Wide_String
1934 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1936 DR
: Shared_Wide_Wide_String_Access
;
1941 Low
:= Index
(Source
, Left
, Outside
, Forward
);
1943 -- Source includes only characters from Left set, reuse empty shared
1947 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1948 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1951 High
:= Index
(Source
, Right
, Outside
, Backward
);
1952 DL
:= Integer'Max (0, High
- Low
+ 1);
1954 -- Source includes only characters from Right set or result string
1955 -- is empty, reuse empty shared string.
1957 if High
= 0 or else DL
= 0 then
1958 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1959 DR
:= Empty_Shared_Wide_Wide_String
'Access;
1961 -- Otherwise, allocate new shared string and fill it
1964 DR
:= Allocate
(DL
);
1965 DR
.Data
(1 .. DL
) := SR
.Data
(Low
.. High
);
1970 return (AF
.Controlled
with Reference
=> DR
);
1974 (Source
: in out Unbounded_Wide_Wide_String
;
1975 Left
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
1976 Right
: Wide_Wide_Maps
.Wide_Wide_Character_Set
)
1978 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
1980 DR
: Shared_Wide_Wide_String_Access
;
1985 Low
:= Index
(Source
, Left
, Outside
, Forward
);
1987 -- Source includes only characters from Left set, reuse empty shared
1991 Reference
(Empty_Shared_Wide_Wide_String
'Access);
1992 Source
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
1996 High
:= Index
(Source
, Right
, Outside
, Backward
);
1997 DL
:= Integer'Max (0, High
- Low
+ 1);
1999 -- Source includes only characters from Right set or result string
2000 -- is empty, reuse empty shared string.
2002 if High
= 0 or else DL
= 0 then
2003 Reference
(Empty_Shared_Wide_Wide_String
'Access);
2004 Source
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
2007 -- Try to reuse existent shared string
2009 elsif Can_Be_Reused
(SR
, DL
) then
2010 SR
.Data
(1 .. DL
) := SR
.Data
(Low
.. High
);
2013 -- Otherwise, allocate new shared string and fill it
2016 DR
:= Allocate
(DL
);
2017 DR
.Data
(1 .. DL
) := SR
.Data
(Low
.. High
);
2019 Source
.Reference
:= DR
;
2025 ---------------------
2026 -- Unbounded_Slice --
2027 ---------------------
2029 function Unbounded_Slice
2030 (Source
: Unbounded_Wide_Wide_String
;
2032 High
: Natural) return Unbounded_Wide_Wide_String
2034 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
2036 DR
: Shared_Wide_Wide_String_Access
;
2041 if Low
> SR
.Last
+ 1 or else High
> SR
.Last
then
2044 -- Result is empty slice, reuse empty shared string
2046 elsif Low
> High
then
2047 Reference
(Empty_Shared_Wide_Wide_String
'Access);
2048 DR
:= Empty_Shared_Wide_Wide_String
'Access;
2050 -- Otherwise, allocate new shared string and fill it
2053 DL
:= High
- Low
+ 1;
2054 DR
:= Allocate
(DL
);
2055 DR
.Data
(1 .. DL
) := SR
.Data
(Low
.. High
);
2059 return (AF
.Controlled
with Reference
=> DR
);
2060 end Unbounded_Slice
;
2062 procedure Unbounded_Slice
2063 (Source
: Unbounded_Wide_Wide_String
;
2064 Target
: out Unbounded_Wide_Wide_String
;
2068 SR
: constant Shared_Wide_Wide_String_Access
:= Source
.Reference
;
2069 TR
: constant Shared_Wide_Wide_String_Access
:= Target
.Reference
;
2071 DR
: Shared_Wide_Wide_String_Access
;
2076 if Low
> SR
.Last
+ 1 or else High
> SR
.Last
then
2079 -- Result is empty slice, reuse empty shared string
2081 elsif Low
> High
then
2082 Reference
(Empty_Shared_Wide_Wide_String
'Access);
2083 Target
.Reference
:= Empty_Shared_Wide_Wide_String
'Access;
2087 DL
:= High
- Low
+ 1;
2089 -- Try to reuse existent shared string
2091 if Can_Be_Reused
(TR
, DL
) then
2092 TR
.Data
(1 .. DL
) := SR
.Data
(Low
.. High
);
2095 -- Otherwise, allocate new shared string and fill it
2098 DR
:= Allocate
(DL
);
2099 DR
.Data
(1 .. DL
) := SR
.Data
(Low
.. High
);
2101 Target
.Reference
:= DR
;
2105 end Unbounded_Slice
;
2111 procedure Unreference
(Item
: not null Shared_Wide_Wide_String_Access
) is
2115 new Ada
.Unchecked_Deallocation
2116 (Shared_Wide_Wide_String
, Shared_Wide_Wide_String_Access
);
2118 Aux
: Shared_Wide_Wide_String_Access
:= Item
;
2121 if Sync_Sub_And_Fetch
(Aux
.Counter
'Access, 1) = 0 then
2123 -- Reference counter of Empty_Shared_Wide_Wide_String must never
2126 pragma Assert
(Aux
/= Empty_Shared_Wide_Wide_String
'Access);
2132 end Ada
.Strings
.Wide_Wide_Unbounded
;