-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- align the returned memory on the maximum alignment as malloc does not
-- know the target alignment.
- procedure Sync_Add_And_Fetch
- (Ptr : access Interfaces.Unsigned_32;
- Value : Interfaces.Unsigned_32);
- pragma Import (Intrinsic, Sync_Add_And_Fetch, "__sync_add_and_fetch_4");
-
- function Sync_Sub_And_Fetch
- (Ptr : access Interfaces.Unsigned_32;
- Value : Interfaces.Unsigned_32) return Interfaces.Unsigned_32;
- pragma Import (Intrinsic, Sync_Sub_And_Fetch, "__sync_sub_and_fetch_4");
-
function Aligned_Max_Length (Max_Length : Natural) return Natural;
-- Returns recommended length of the shared string which is greater or
-- equal to specified length. Calculation take in sense alignment of the
Reference (Empty_Shared_String'Access);
DR := Empty_Shared_String'Access;
- -- Left string is empty, return Rigth string
+ -- Left string is empty, return Right string
elsif LR.Last = 0 then
Reference (RR);
Reference (LR);
DR := LR;
- -- Overwise, allocate new shared string and fill data
+ -- Otherwise, allocate new shared string and fill data
else
DR := Allocate (LR.Last + RR.Last);
function Can_Be_Reused
(Item : Shared_String_Access;
- Length : Natural) return Boolean
- is
- use Interfaces;
+ Length : Natural) return Boolean is
begin
return
- Item.Counter = 1
+ System.Atomic_Counters.Is_One (Item.Counter)
and then Item.Max_Length >= Length
and then Item.Max_Length <=
Aligned_Max_Length (Length + Length / Growth_Factor);
procedure Find_Token
(Source : Unbounded_String;
Set : Maps.Character_Set;
+ From : Positive;
+ Test : Strings.Membership;
+ First : out Positive;
+ Last : out Natural)
+ is
+ SR : constant Shared_String_Access := Source.Reference;
+ begin
+ Search.Find_Token (SR.Data (From .. SR.Last), Set, Test, First, Last);
+ end Find_Token;
+
+ procedure Find_Token
+ (Source : Unbounded_String;
+ Set : Maps.Character_Set;
Test : Strings.Membership;
First : out Positive;
Last : out Natural)
procedure Reference (Item : not null Shared_String_Access) is
begin
- Sync_Add_And_Fetch (Item.Counter'Access, 1);
+ System.Atomic_Counters.Increment (Item.Counter);
end Reference;
---------------------
DR : Shared_String_Access;
begin
- -- Bounds check.
+ -- Bounds check
if Index <= SR.Last then
-- Do replace operation when removed slice is not empty
if High >= Low then
- DL := By'Length + SR.Last + Low - High - 1;
+ DL := By'Length + SR.Last + Low - Integer'Min (High, SR.Last) - 1;
+ -- This is the number of characters remaining in the string after
+ -- replacing the slice.
-- Result is empty string, reuse empty shared string
-- Do replace operation only when replaced slice is not empty
if High >= Low then
- DL := By'Length + SR.Last + Low - High - 1;
+ DL := By'Length + SR.Last + Low - Integer'Min (High, SR.Last) - 1;
+ -- This is the number of characters remaining in the string after
+ -- replacing the slice.
-- Result is empty string, reuse empty shared string
-----------------
procedure Unreference (Item : not null Shared_String_Access) is
- use Interfaces;
procedure Free is
new Ada.Unchecked_Deallocation (Shared_String, Shared_String_Access);
Aux : Shared_String_Access := Item;
begin
- if Sync_Sub_And_Fetch (Aux.Counter'Access, 1) = 0 then
+ if System.Atomic_Counters.Decrement (Aux.Counter) then
-- Reference counter of Empty_Shared_String must never reach zero