1 ------------------------------------------------------------------------------
3 -- GNAT RUN-TIME COMPONENTS --
5 -- A D A . S T R I N G S . U N B O U N D E D --
9 -- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
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. --
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 2, 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. See the GNU General Public License --
21 -- for more details. You should have received a copy of the GNU General --
22 -- Public License distributed with GNAT; see file COPYING. If not, write --
23 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
24 -- Boston, MA 02110-1301, USA. --
26 -- As a special exception, if other files instantiate generics from this --
27 -- unit, or you link this unit with other files to produce an executable, --
28 -- this unit does not by itself cause the resulting executable to be --
29 -- covered by the GNU General Public License. This exception does not --
30 -- however invalidate any other reasons why the executable file might be --
31 -- covered by the GNU Public License. --
33 -- GNAT was originally developed by the GNAT team at New York University. --
34 -- Extensive contributions were provided by Ada Core Technologies Inc. --
36 ------------------------------------------------------------------------------
38 -- This package provides an implementation of Ada.Strings.Unbounded that uses
39 -- reference counts to implement copy on modification (rather than copy on
40 -- assignment). This is significantly more efficient on many targets.
42 -- This version is supported on:
43 -- - all Alpha platforms
44 -- - all ia64 platforms
45 -- - all PowerPC platforms
46 -- - all SPARC V9 platforms
47 -- - all x86_64 platforms
49 -- This package uses several techniques to increase speed:
51 -- - Implicit sharing or copy-on-write. An Unbounded_String contains only
52 -- the reference to the data which is shared between several instances.
53 -- The shared data is reallocated only when its value is changed and
54 -- the object mutation can't be used or it is unefficient to use it.
56 -- - Object mutation. Shared data object can be reused without memory
57 -- reallocation when all of the following requirements are met:
58 -- - the shared data object is no longer used by anyone else;
59 -- - the size is sufficient to store the new value;
60 -- - the gap after reuse is less then a defined threshold.
62 -- - Memory preallocation. Most of used memory allocation algorithms
63 -- align allocated segments on the some boundary, thus some amount of
64 -- additional memory can be preallocated without any impact. Such
65 -- preallocated memory can used later by Append/Insert operations
66 -- without reallocation.
68 -- Reference counting uses GCC builtin atomic operations, which allows to
69 -- safely share internal data between Ada tasks. Nevertheless, this doesn't
70 -- make objects of Unbounded_String thread-safe: each instance can't be
71 -- accessed by several tasks simulatenously.
73 with Ada.Strings.Maps;
74 private with Ada.Finalization;
75 private with Interfaces;
77 package Ada.Strings.Unbounded is
80 type Unbounded_String is private;
81 pragma Preelaborable_Initialization (Unbounded_String);
83 Null_Unbounded_String : constant Unbounded_String;
85 function Length (Source : Unbounded_String) return Natural;
87 type String_Access is access all String;
89 procedure Free (X : in out String_Access);
91 --------------------------------------------------------
92 -- Conversion, Concatenation, and Selection Functions --
93 --------------------------------------------------------
95 function To_Unbounded_String
96 (Source : String) return Unbounded_String;
98 function To_Unbounded_String
99 (Length : Natural) return Unbounded_String;
101 function To_String (Source : Unbounded_String) return String;
103 procedure Set_Unbounded_String
104 (Target : out Unbounded_String;
106 pragma Ada_05 (Set_Unbounded_String);
109 (Source : in out Unbounded_String;
110 New_Item : Unbounded_String);
113 (Source : in out Unbounded_String;
117 (Source : in out Unbounded_String;
118 New_Item : Character);
121 (Left : Unbounded_String;
122 Right : Unbounded_String) return Unbounded_String;
125 (Left : Unbounded_String;
126 Right : String) return Unbounded_String;
130 Right : Unbounded_String) return Unbounded_String;
133 (Left : Unbounded_String;
134 Right : Character) return Unbounded_String;
138 Right : Unbounded_String) return Unbounded_String;
141 (Source : Unbounded_String;
142 Index : Positive) return Character;
144 procedure Replace_Element
145 (Source : in out Unbounded_String;
150 (Source : Unbounded_String;
152 High : Natural) return String;
154 function Unbounded_Slice
155 (Source : Unbounded_String;
157 High : Natural) return Unbounded_String;
158 pragma Ada_05 (Unbounded_Slice);
160 procedure Unbounded_Slice
161 (Source : Unbounded_String;
162 Target : out Unbounded_String;
165 pragma Ada_05 (Unbounded_Slice);
168 (Left : Unbounded_String;
169 Right : Unbounded_String) return Boolean;
172 (Left : Unbounded_String;
173 Right : String) return Boolean;
177 Right : Unbounded_String) return Boolean;
180 (Left : Unbounded_String;
181 Right : Unbounded_String) return Boolean;
184 (Left : Unbounded_String;
185 Right : String) return Boolean;
189 Right : Unbounded_String) return Boolean;
192 (Left : Unbounded_String;
193 Right : Unbounded_String) return Boolean;
196 (Left : Unbounded_String;
197 Right : String) return Boolean;
201 Right : Unbounded_String) return Boolean;
204 (Left : Unbounded_String;
205 Right : Unbounded_String) return Boolean;
208 (Left : Unbounded_String;
209 Right : String) return Boolean;
213 Right : Unbounded_String) return Boolean;
216 (Left : Unbounded_String;
217 Right : Unbounded_String) return Boolean;
220 (Left : Unbounded_String;
221 Right : String) return Boolean;
225 Right : Unbounded_String) return Boolean;
227 ------------------------
228 -- Search Subprograms --
229 ------------------------
232 (Source : Unbounded_String;
234 Going : Direction := Forward;
235 Mapping : Maps.Character_Mapping := Maps.Identity) return Natural;
238 (Source : Unbounded_String;
240 Going : Direction := Forward;
241 Mapping : Maps.Character_Mapping_Function) return Natural;
244 (Source : Unbounded_String;
245 Set : Maps.Character_Set;
246 Test : Membership := Inside;
247 Going : Direction := Forward) return Natural;
250 (Source : Unbounded_String;
253 Going : Direction := Forward;
254 Mapping : Maps.Character_Mapping := Maps.Identity) return Natural;
255 pragma Ada_05 (Index);
258 (Source : Unbounded_String;
261 Going : Direction := Forward;
262 Mapping : Maps.Character_Mapping_Function) return Natural;
263 pragma Ada_05 (Index);
266 (Source : Unbounded_String;
267 Set : Maps.Character_Set;
269 Test : Membership := Inside;
270 Going : Direction := Forward) return Natural;
271 pragma Ada_05 (Index);
273 function Index_Non_Blank
274 (Source : Unbounded_String;
275 Going : Direction := Forward) return Natural;
277 function Index_Non_Blank
278 (Source : Unbounded_String;
280 Going : Direction := Forward) return Natural;
281 pragma Ada_05 (Index_Non_Blank);
284 (Source : Unbounded_String;
286 Mapping : Maps.Character_Mapping := Maps.Identity) return Natural;
289 (Source : Unbounded_String;
291 Mapping : Maps.Character_Mapping_Function) return Natural;
294 (Source : Unbounded_String;
295 Set : Maps.Character_Set) return Natural;
298 (Source : Unbounded_String;
299 Set : Maps.Character_Set;
302 First : out Positive;
304 pragma Ada_2012 (Find_Token);
307 (Source : Unbounded_String;
308 Set : Maps.Character_Set;
310 First : out Positive;
313 ------------------------------------
314 -- String Translation Subprograms --
315 ------------------------------------
318 (Source : Unbounded_String;
319 Mapping : Maps.Character_Mapping) return Unbounded_String;
322 (Source : in out Unbounded_String;
323 Mapping : Maps.Character_Mapping);
326 (Source : Unbounded_String;
327 Mapping : Maps.Character_Mapping_Function) return Unbounded_String;
330 (Source : in out Unbounded_String;
331 Mapping : Maps.Character_Mapping_Function);
333 ---------------------------------------
334 -- String Transformation Subprograms --
335 ---------------------------------------
337 function Replace_Slice
338 (Source : Unbounded_String;
341 By : String) return Unbounded_String;
343 procedure Replace_Slice
344 (Source : in out Unbounded_String;
350 (Source : Unbounded_String;
352 New_Item : String) return Unbounded_String;
355 (Source : in out Unbounded_String;
360 (Source : Unbounded_String;
362 New_Item : String) return Unbounded_String;
365 (Source : in out Unbounded_String;
370 (Source : Unbounded_String;
372 Through : Natural) return Unbounded_String;
375 (Source : in out Unbounded_String;
380 (Source : Unbounded_String;
381 Side : Trim_End) return Unbounded_String;
384 (Source : in out Unbounded_String;
388 (Source : Unbounded_String;
389 Left : Maps.Character_Set;
390 Right : Maps.Character_Set) return Unbounded_String;
393 (Source : in out Unbounded_String;
394 Left : Maps.Character_Set;
395 Right : Maps.Character_Set);
398 (Source : Unbounded_String;
400 Pad : Character := Space) return Unbounded_String;
403 (Source : in out Unbounded_String;
405 Pad : Character := Space);
408 (Source : Unbounded_String;
410 Pad : Character := Space) return Unbounded_String;
413 (Source : in out Unbounded_String;
415 Pad : Character := Space);
419 Right : Character) return Unbounded_String;
423 Right : String) return Unbounded_String;
427 Right : Unbounded_String) return Unbounded_String;
430 pragma Inline (Length);
432 package AF renames Ada.Finalization;
434 type Shared_String (Max_Length : Natural) is limited record
435 Counter : aliased Interfaces.Unsigned_32 := 1;
439 Data : String (1 .. Max_Length);
440 -- Last is the index of last significant element of the Data. All
441 -- elements with larger indexes are currently insignificant.
444 type Shared_String_Access is access all Shared_String;
446 procedure Reference (Item : not null Shared_String_Access);
447 -- Increment reference counter
449 procedure Unreference (Item : not null Shared_String_Access);
450 -- Decrement reference counter, deallocate Item when counter goes to zero
452 function Can_Be_Reused
453 (Item : Shared_String_Access;
454 Length : Natural) return Boolean;
455 -- Returns True if Shared_String can be reused. There are two criteria when
456 -- Shared_String can be reused: its reference counter must be one (thus
457 -- Shared_String is owned exclusively) and its size is sufficient to
458 -- store string with specified length effectively.
460 function Allocate (Max_Length : Natural) return Shared_String_Access;
461 -- Allocates new Shared_String with at least specified maximum length.
462 -- Actual maximum length of the allocated Shared_String can be sligtly
463 -- greater. Returns reference to Empty_Shared_String when requested length
466 Empty_Shared_String : aliased Shared_String (0);
468 function To_Unbounded (S : String) return Unbounded_String
469 renames To_Unbounded_String;
470 -- This renames are here only to be used in the pragma Stream_Convert
472 type Unbounded_String is new AF.Controlled with record
473 Reference : Shared_String_Access := Empty_Shared_String'Access;
476 pragma Stream_Convert (Unbounded_String, To_Unbounded, To_String);
477 -- Provide stream routines without dragging in Ada.Streams
479 pragma Finalize_Storage_Only (Unbounded_String);
480 -- Finalization is required only for freeing storage
482 overriding procedure Initialize (Object : in out Unbounded_String);
483 overriding procedure Adjust (Object : in out Unbounded_String);
484 overriding procedure Finalize (Object : in out Unbounded_String);
486 Null_Unbounded_String : constant Unbounded_String :=
488 Reference => Empty_Shared_String'Access);
490 end Ada.Strings.Unbounded;