1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
5 -- I N T E R F A C E S . C . P O I N T E R S --
9 -- Copyright (C) 1992-2023, 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 Interfaces
.C
.Strings
; use Interfaces
.C
.Strings
;
33 with System
.Storage_Elements
; use System
.Storage_Elements
;
34 with System
; use System
;
36 with Ada
.Unchecked_Conversion
;
38 package body Interfaces
.C
.Pointers
is
40 subtype Offset
is Storage_Offset
;
42 function To_Pointer
is new Ada
.Unchecked_Conversion
(Address
, Pointer
);
43 function To_Addr
is new Ada
.Unchecked_Conversion
(Pointer
, Address
);
44 function To_Offset
is new Ada
.Unchecked_Conversion
(ptrdiff_t
, Offset
);
45 function To_Ptrdiff
is new Ada
.Unchecked_Conversion
(Offset
, ptrdiff_t
);
47 Elmt_Size
: constant ptrdiff_t
:=
48 (Element_Array
'Component_Size
49 + Storage_Unit
- 1) / Storage_Unit
;
51 subtype Index_Base
is Index
'Base;
57 function "+" (Left
: Pointer
; Right
: ptrdiff_t
) return Pointer
is
63 return To_Pointer
(To_Addr
(Left
) + To_Offset
(Elmt_Size
* Right
));
66 function "+" (Left
: ptrdiff_t
; Right
: Pointer
) return Pointer
is
72 return To_Pointer
(To_Offset
(Elmt_Size
* Left
) + To_Addr
(Right
));
79 function "-" (Left
: Pointer
; Right
: ptrdiff_t
) return Pointer
is
85 return To_Pointer
(To_Addr
(Left
) - To_Offset
(Right
* Elmt_Size
));
88 function "-" (Left
: Pointer
; Right
: Pointer
) return ptrdiff_t
is
90 if Left
= null or else Right
= null then
94 return To_Ptrdiff
(To_Addr
(Left
) - To_Addr
(Right
)) / Elmt_Size
;
110 if Source
= null or else Target
= null then
111 raise Dereference_Error
;
115 elsif To_Addr
(Target
) <= To_Addr
(Source
) then
118 for J
in 1 .. Length
loop
127 T
:= Target
+ Length
;
128 S
:= Source
+ Length
;
129 for J
in 1 .. Length
loop
137 ---------------------------
138 -- Copy_Terminated_Array --
139 ---------------------------
141 procedure Copy_Terminated_Array
144 Limit
: ptrdiff_t
:= ptrdiff_t
'Last;
145 Terminator
: Element
:= Default_Terminator
)
148 S
: Pointer
:= Source
;
151 if Source
= null or Target
= null then
152 raise Dereference_Error
;
155 -- Compute array limited length (including the terminator)
160 exit when S
.all = Terminator
;
164 Copy_Array
(Source
, Target
, L
);
165 end Copy_Terminated_Array
;
171 procedure Decrement
(Ref
: in out Pointer
) is
180 procedure Increment
(Ref
: in out Pointer
) is
191 Terminator
: Element
:= Default_Terminator
) return Element_Array
194 L
: constant Index_Base
:= Index
'First;
199 raise Dereference_Error
;
206 exit when P
.all = Terminator
;
207 H
:= Index_Base
'Succ (H
);
212 subtype A
is Element_Array
(L
.. H
);
215 for PA
'Size use System
.Parameters
.ptr_bits
;
216 function To_PA
is new Ada
.Unchecked_Conversion
(Pointer
, PA
);
219 return To_PA
(Ref
).all;
226 Length
: ptrdiff_t
) return Element_Array
233 raise Dereference_Error
;
235 -- For length zero, we need to return a null slice, but we can't make
236 -- the bounds of this slice Index'First, since this could cause a
237 -- Constraint_Error if Index'First = Index'Base'First.
239 elsif Length
<= 0 then
241 pragma Warnings
(Off
); -- kill warnings since X not assigned
242 X
: Element_Array
(Index
'Succ (Index
'First) .. Index
'First);
243 pragma Warnings
(On
);
249 -- Normal case (length non-zero)
253 H
:= Index
'Val (Index
'Pos (Index
'First) + Length
- 1);
256 subtype A
is Element_Array
(L
.. H
);
259 for PA
'Size use System
.Parameters
.ptr_bits
;
260 function To_PA
is new Ada
.Unchecked_Conversion
(Pointer
, PA
);
263 return To_PA
(Ref
).all;
272 function Virtual_Length
274 Terminator
: Element
:= Default_Terminator
) return ptrdiff_t
281 raise Dereference_Error
;
287 while P
.all /= Terminator
loop
296 end Interfaces
.C
.Pointers
;