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--                                 S p e c                                  --
8--                                                                          --
9--          Copyright (C) 1992-2019, Free Software Foundation, Inc.         --
10--                                                                          --
11-- This specification is derived from the Ada Reference Manual for use with --
12-- GNAT. The copyright notice above, and the license provisions that follow --
13-- apply solely to the  contents of the part following the private keyword. --
14--                                                                          --
15-- GNAT is free software;  you can  redistribute it  and/or modify it under --
16-- terms of the  GNU General Public License as published  by the Free Soft- --
17-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
18-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
19-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
20-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
21--                                                                          --
22-- As a special exception under Section 7 of GPL version 3, you are granted --
23-- additional permissions described in the GCC Runtime Library Exception,   --
24-- version 3.1, as published by the Free Software Foundation.               --
25--                                                                          --
26-- You should have received a copy of the GNU General Public License and    --
27-- a copy of the GCC Runtime Library Exception along with this program;     --
28-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
29-- <http://www.gnu.org/licenses/>.                                          --
30--                                                                          --
31-- GNAT was originally developed  by the GNAT team at  New York University. --
32-- Extensive contributions were provided by Ada Core Technologies Inc.      --
33--                                                                          --
34------------------------------------------------------------------------------
35
36--  This version is supported on:
37--    - all Alpha platforms
38--    - all ia64 platforms
39--    - all PowerPC platforms
40--    - all SPARC V9 platforms
41--    - all x86 platforms
42--    - all x86_64 platforms
43
44with Ada.Strings.Wide_Maps;
45private with Ada.Finalization;
46private with System.Atomic_Counters;
47
48package Ada.Strings.Wide_Unbounded is
49   pragma Preelaborate;
50
51   type Unbounded_Wide_String is private;
52   pragma Preelaborable_Initialization (Unbounded_Wide_String);
53
54   Null_Unbounded_Wide_String : constant Unbounded_Wide_String;
55
56   function Length (Source : Unbounded_Wide_String) return Natural;
57
58   type Wide_String_Access is access all Wide_String;
59
60   procedure Free (X : in out Wide_String_Access);
61
62   --------------------------------------------------------
63   -- Conversion, Concatenation, and Selection Functions --
64   --------------------------------------------------------
65
66   function To_Unbounded_Wide_String
67     (Source : Wide_String) return Unbounded_Wide_String;
68
69   function To_Unbounded_Wide_String
70     (Length : Natural) return Unbounded_Wide_String;
71
72   function To_Wide_String
73     (Source : Unbounded_Wide_String) return Wide_String;
74
75   procedure Set_Unbounded_Wide_String
76     (Target : out Unbounded_Wide_String;
77      Source : Wide_String);
78   pragma Ada_05 (Set_Unbounded_Wide_String);
79
80   procedure Append
81     (Source   : in out Unbounded_Wide_String;
82      New_Item : Unbounded_Wide_String);
83
84   procedure Append
85     (Source   : in out Unbounded_Wide_String;
86      New_Item : Wide_String);
87
88   procedure Append
89     (Source   : in out Unbounded_Wide_String;
90      New_Item : Wide_Character);
91
92   function "&"
93     (Left  : Unbounded_Wide_String;
94      Right : Unbounded_Wide_String) return Unbounded_Wide_String;
95
96   function "&"
97     (Left  : Unbounded_Wide_String;
98      Right : Wide_String) return Unbounded_Wide_String;
99
100   function "&"
101     (Left  : Wide_String;
102      Right : Unbounded_Wide_String) return Unbounded_Wide_String;
103
104   function "&"
105     (Left  : Unbounded_Wide_String;
106      Right : Wide_Character) return Unbounded_Wide_String;
107
108   function "&"
109     (Left  : Wide_Character;
110      Right : Unbounded_Wide_String) return Unbounded_Wide_String;
111
112   function Element
113     (Source : Unbounded_Wide_String;
114      Index  : Positive) return Wide_Character;
115
116   procedure Replace_Element
117     (Source : in out Unbounded_Wide_String;
118      Index  : Positive;
119      By     : Wide_Character);
120
121   function Slice
122     (Source : Unbounded_Wide_String;
123      Low    : Positive;
124      High   : Natural) return Wide_String;
125
126   function Unbounded_Slice
127     (Source : Unbounded_Wide_String;
128      Low    : Positive;
129      High   : Natural) return Unbounded_Wide_String;
130   pragma Ada_05 (Unbounded_Slice);
131
132   procedure Unbounded_Slice
133     (Source : Unbounded_Wide_String;
134      Target : out Unbounded_Wide_String;
135      Low    : Positive;
136      High   : Natural);
137   pragma Ada_05 (Unbounded_Slice);
138
139   function "="
140     (Left  : Unbounded_Wide_String;
141      Right : Unbounded_Wide_String) return Boolean;
142
143   function "="
144     (Left  : Unbounded_Wide_String;
145      Right : Wide_String) return Boolean;
146
147   function "="
148     (Left  : Wide_String;
149      Right : Unbounded_Wide_String) return Boolean;
150
151   function "<"
152     (Left  : Unbounded_Wide_String;
153      Right : Unbounded_Wide_String) return Boolean;
154
155   function "<"
156     (Left  : Unbounded_Wide_String;
157      Right : Wide_String) return Boolean;
158
159   function "<"
160     (Left  : Wide_String;
161      Right : Unbounded_Wide_String) return Boolean;
162
163   function "<="
164     (Left  : Unbounded_Wide_String;
165      Right : Unbounded_Wide_String) return Boolean;
166
167   function "<="
168     (Left  : Unbounded_Wide_String;
169      Right : Wide_String) return Boolean;
170
171   function "<="
172     (Left  : Wide_String;
173      Right : Unbounded_Wide_String) return Boolean;
174
175   function ">"
176     (Left  : Unbounded_Wide_String;
177      Right : Unbounded_Wide_String) return Boolean;
178
179   function ">"
180     (Left  : Unbounded_Wide_String;
181      Right : Wide_String) return Boolean;
182
183   function ">"
184     (Left  : Wide_String;
185      Right : Unbounded_Wide_String) return Boolean;
186
187   function ">="
188     (Left  : Unbounded_Wide_String;
189      Right : Unbounded_Wide_String) return Boolean;
190
191   function ">="
192     (Left  : Unbounded_Wide_String;
193      Right : Wide_String) return Boolean;
194
195   function ">="
196     (Left  : Wide_String;
197      Right : Unbounded_Wide_String) return Boolean;
198
199   ------------------------
200   -- Search Subprograms --
201   ------------------------
202
203   function Index
204     (Source  : Unbounded_Wide_String;
205      Pattern : Wide_String;
206      Going   : Direction := Forward;
207      Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
208      return Natural;
209
210   function Index
211     (Source  : Unbounded_Wide_String;
212      Pattern : Wide_String;
213      Going   : Direction := Forward;
214      Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural;
215
216   function Index
217     (Source : Unbounded_Wide_String;
218      Set    : Wide_Maps.Wide_Character_Set;
219      Test   : Membership := Inside;
220      Going  : Direction  := Forward) return Natural;
221
222   function Index
223     (Source  : Unbounded_Wide_String;
224      Pattern : Wide_String;
225      From    : Positive;
226      Going   : Direction := Forward;
227      Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
228      return Natural;
229   pragma Ada_05 (Index);
230
231   function Index
232     (Source  : Unbounded_Wide_String;
233      Pattern : Wide_String;
234      From    : Positive;
235      Going   : Direction := Forward;
236      Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural;
237   pragma Ada_05 (Index);
238
239   function Index
240     (Source  : Unbounded_Wide_String;
241      Set     : Wide_Maps.Wide_Character_Set;
242      From    : Positive;
243      Test    : Membership := Inside;
244      Going   : Direction := Forward) return Natural;
245   pragma Ada_05 (Index);
246
247   function Index_Non_Blank
248     (Source : Unbounded_Wide_String;
249      Going  : Direction := Forward) return Natural;
250
251   function Index_Non_Blank
252     (Source : Unbounded_Wide_String;
253      From   : Positive;
254      Going  : Direction := Forward) return Natural;
255   pragma Ada_05 (Index_Non_Blank);
256
257   function Count
258     (Source  : Unbounded_Wide_String;
259      Pattern : Wide_String;
260      Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
261      return Natural;
262
263   function Count
264     (Source  : Unbounded_Wide_String;
265      Pattern : Wide_String;
266      Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural;
267
268   function Count
269     (Source : Unbounded_Wide_String;
270      Set    : Wide_Maps.Wide_Character_Set) return Natural;
271
272   procedure Find_Token
273     (Source : Unbounded_Wide_String;
274      Set    : Wide_Maps.Wide_Character_Set;
275      From   : Positive;
276      Test   : Membership;
277      First  : out Positive;
278      Last   : out Natural);
279   pragma Ada_2012 (Find_Token);
280
281   procedure Find_Token
282     (Source : Unbounded_Wide_String;
283      Set    : Wide_Maps.Wide_Character_Set;
284      Test   : Membership;
285      First  : out Positive;
286      Last   : out Natural);
287
288   ------------------------------------
289   -- String Translation Subprograms --
290   ------------------------------------
291
292   function Translate
293     (Source  : Unbounded_Wide_String;
294      Mapping : Wide_Maps.Wide_Character_Mapping)
295      return Unbounded_Wide_String;
296
297   procedure Translate
298     (Source  : in out Unbounded_Wide_String;
299      Mapping : Wide_Maps.Wide_Character_Mapping);
300
301   function Translate
302     (Source  : Unbounded_Wide_String;
303      Mapping : Wide_Maps.Wide_Character_Mapping_Function)
304      return Unbounded_Wide_String;
305
306   procedure Translate
307     (Source  : in out Unbounded_Wide_String;
308      Mapping : Wide_Maps.Wide_Character_Mapping_Function);
309
310   ---------------------------------------
311   -- String Transformation Subprograms --
312   ---------------------------------------
313
314   function Replace_Slice
315     (Source : Unbounded_Wide_String;
316      Low    : Positive;
317      High   : Natural;
318      By     : Wide_String) return Unbounded_Wide_String;
319
320   procedure Replace_Slice
321     (Source : in out Unbounded_Wide_String;
322      Low    : Positive;
323      High   : Natural;
324      By     : Wide_String);
325
326   function Insert
327     (Source   : Unbounded_Wide_String;
328      Before   : Positive;
329      New_Item : Wide_String) return Unbounded_Wide_String;
330
331   procedure Insert
332     (Source   : in out Unbounded_Wide_String;
333      Before   : Positive;
334      New_Item : Wide_String);
335
336   function Overwrite
337     (Source   : Unbounded_Wide_String;
338      Position : Positive;
339      New_Item : Wide_String) return Unbounded_Wide_String;
340
341   procedure Overwrite
342     (Source   : in out Unbounded_Wide_String;
343      Position : Positive;
344      New_Item : Wide_String);
345
346   function Delete
347     (Source  : Unbounded_Wide_String;
348      From    : Positive;
349      Through : Natural) return Unbounded_Wide_String;
350
351   procedure Delete
352     (Source  : in out Unbounded_Wide_String;
353      From    : Positive;
354      Through : Natural);
355
356   function Trim
357     (Source : Unbounded_Wide_String;
358      Side   : Trim_End) return Unbounded_Wide_String;
359
360   procedure Trim
361     (Source : in out Unbounded_Wide_String;
362      Side   : Trim_End);
363
364   function Trim
365     (Source : Unbounded_Wide_String;
366      Left   : Wide_Maps.Wide_Character_Set;
367      Right  : Wide_Maps.Wide_Character_Set) return Unbounded_Wide_String;
368
369   procedure Trim
370     (Source : in out Unbounded_Wide_String;
371      Left   : Wide_Maps.Wide_Character_Set;
372      Right  : Wide_Maps.Wide_Character_Set);
373
374   function Head
375     (Source : Unbounded_Wide_String;
376      Count  : Natural;
377      Pad    : Wide_Character := Wide_Space) return Unbounded_Wide_String;
378
379   procedure Head
380     (Source : in out Unbounded_Wide_String;
381      Count  : Natural;
382      Pad    : Wide_Character := Wide_Space);
383
384   function Tail
385     (Source : Unbounded_Wide_String;
386      Count  : Natural;
387      Pad    : Wide_Character := Wide_Space) return Unbounded_Wide_String;
388
389   procedure Tail
390     (Source : in out Unbounded_Wide_String;
391      Count  : Natural;
392      Pad    : Wide_Character := Wide_Space);
393
394   function "*"
395     (Left  : Natural;
396      Right : Wide_Character) return Unbounded_Wide_String;
397
398   function "*"
399     (Left  : Natural;
400      Right : Wide_String) return Unbounded_Wide_String;
401
402   function "*"
403     (Left  : Natural;
404      Right : Unbounded_Wide_String) return Unbounded_Wide_String;
405
406private
407   pragma Inline (Length);
408
409   package AF renames Ada.Finalization;
410
411   type Shared_Wide_String (Max_Length : Natural) is limited record
412      Counter : System.Atomic_Counters.Atomic_Counter;
413      --  Reference counter
414
415      Last : Natural := 0;
416      Data : Wide_String (1 .. Max_Length);
417      --  Last is the index of last significant element of the Data. All
418      --  elements with larger indexes are just extra room for expansion.
419   end record;
420
421   type Shared_Wide_String_Access is access all Shared_Wide_String;
422
423   procedure Reference (Item : not null Shared_Wide_String_Access);
424   --  Increment reference counter.
425
426   procedure Unreference (Item : not null Shared_Wide_String_Access);
427   --  Decrement reference counter. Deallocate Item when ref counter is zero
428
429   function Can_Be_Reused
430     (Item   : Shared_Wide_String_Access;
431      Length : Natural) return Boolean;
432   --  Returns True if Shared_Wide_String can be reused. There are two criteria
433   --  when Shared_Wide_String can be reused: its reference counter must be one
434   --  (thus Shared_Wide_String is owned exclusively) and its size is
435   --  sufficient to store string with specified length effectively.
436
437   function Allocate (Max_Length : Natural) return Shared_Wide_String_Access;
438   --  Allocates new Shared_Wide_String with at least specified maximum length.
439   --  Actual maximum length of the allocated Shared_Wide_String can be
440   --  slightly greater. Returns reference to Empty_Shared_Wide_String when
441   --  requested length is zero.
442
443   Empty_Shared_Wide_String : aliased Shared_Wide_String (0);
444
445   function To_Unbounded (S : Wide_String) return Unbounded_Wide_String
446     renames To_Unbounded_Wide_String;
447   --  This renames are here only to be used in the pragma Stream_Convert
448
449   type Unbounded_Wide_String is new AF.Controlled with record
450      Reference : Shared_Wide_String_Access := Empty_Shared_Wide_String'Access;
451   end record;
452
453   --  The Unbounded_Wide_String uses several techniques to increase speed of
454   --  the application:
455
456   --   - implicit sharing or copy-on-write. Unbounded_Wide_String contains
457   --     only the reference to the data which is shared between several
458   --     instances. The shared data is reallocated only when its value is
459   --     changed and the object mutation can't be used or it is inefficient to
460   --     use it;
461
462   --   - object mutation. Shared data object can be reused without memory
463   --     reallocation when all of the following requirements are meat:
464   --      - shared data object don't used anywhere longer;
465   --      - its size is sufficient to store new value;
466   --      - the gap after reuse is less than some threshold.
467
468   --   - memory preallocation. Most of used memory allocation algorithms
469   --     aligns allocated segment on the some boundary, thus some amount of
470   --     additional memory can be preallocated without any impact. Such
471   --     preallocated memory can used later by Append/Insert operations
472   --     without reallocation.
473
474   --  Reference counting uses GCC builtin atomic operations, which allows safe
475   --  sharing of internal data between Ada tasks. Nevertheless, this does not
476   --  make objects of Unbounded_String thread-safe: an instance cannot be
477   --  accessed by several tasks simultaneously.
478
479   pragma Stream_Convert (Unbounded_Wide_String, To_Unbounded, To_Wide_String);
480   --  Provide stream routines without dragging in Ada.Streams
481
482   pragma Finalize_Storage_Only (Unbounded_Wide_String);
483   --  Finalization is required only for freeing storage
484
485   overriding procedure Initialize (Object : in out Unbounded_Wide_String);
486   overriding procedure Adjust     (Object : in out Unbounded_Wide_String);
487   overriding procedure Finalize   (Object : in out Unbounded_Wide_String);
488   pragma Inline (Initialize, Adjust);
489
490   Null_Unbounded_Wide_String : constant Unbounded_Wide_String :=
491                                  (AF.Controlled with
492                                     Reference =>
493                                       Empty_Shared_Wide_String'Access);
494
495end Ada.Strings.Wide_Unbounded;
496