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-2015, 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
; use System
;
35 with Ada
.Unchecked_Conversion
;
37 package body Interfaces
.C
.Pointers
is
39 type Addr
is mod 2 ** System
.Parameters
.ptr_bits
;
41 function To_Pointer
is new Ada
.Unchecked_Conversion
(Addr
, Pointer
);
42 function To_Addr
is new Ada
.Unchecked_Conversion
(Pointer
, Addr
);
43 function To_Addr
is new Ada
.Unchecked_Conversion
(ptrdiff_t
, Addr
);
44 function To_Ptrdiff
is new Ada
.Unchecked_Conversion
(Addr
, ptrdiff_t
);
46 Elmt_Size
: constant ptrdiff_t
:=
47 (Element_Array
'Component_Size
48 + Storage_Unit
- 1) / Storage_Unit
;
50 subtype Index_Base
is Index
'Base;
56 function "+" (Left
: Pointer
; Right
: ptrdiff_t
) return Pointer
is
62 return To_Pointer
(To_Addr
(Left
) + To_Addr
(Elmt_Size
* Right
));
65 function "+" (Left
: ptrdiff_t
; Right
: Pointer
) return Pointer
is
71 return To_Pointer
(To_Addr
(Elmt_Size
* Left
) + To_Addr
(Right
));
78 function "-" (Left
: Pointer
; Right
: ptrdiff_t
) return Pointer
is
84 return To_Pointer
(To_Addr
(Left
) - To_Addr
(Right
* Elmt_Size
));
87 function "-" (Left
: Pointer
; Right
: Pointer
) return ptrdiff_t
is
89 if Left
= null or else Right
= null then
93 return To_Ptrdiff
(To_Addr
(Left
) - To_Addr
(Right
)) / Elmt_Size
;
109 if Source
= null or else Target
= null then
110 raise Dereference_Error
;
114 elsif To_Addr
(Target
) <= To_Addr
(Source
) then
117 for J
in 1 .. Length
loop
126 T
:= Target
+ Length
;
127 S
:= Source
+ Length
;
128 for J
in 1 .. Length
loop
136 ---------------------------
137 -- Copy_Terminated_Array --
138 ---------------------------
140 procedure Copy_Terminated_Array
143 Limit
: ptrdiff_t
:= ptrdiff_t
'Last;
144 Terminator
: Element
:= Default_Terminator
)
147 S
: Pointer
:= Source
;
150 if Source
= null or Target
= null then
151 raise Dereference_Error
;
154 -- Compute array limited length (including the terminator)
159 exit when S
.all = Terminator
;
163 Copy_Array
(Source
, Target
, L
);
164 end Copy_Terminated_Array
;
170 procedure Decrement
(Ref
: in out Pointer
) is
179 procedure Increment
(Ref
: in out Pointer
) is
190 Terminator
: Element
:= Default_Terminator
) return Element_Array
193 L
: constant Index_Base
:= Index
'First;
198 raise Dereference_Error
;
205 exit when P
.all = Terminator
;
206 H
:= Index_Base
'Succ (H
);
211 subtype A
is Element_Array
(L
.. H
);
214 for PA
'Size use System
.Parameters
.ptr_bits
;
215 function To_PA
is new Ada
.Unchecked_Conversion
(Pointer
, PA
);
218 return To_PA
(Ref
).all;
225 Length
: ptrdiff_t
) return Element_Array
232 raise Dereference_Error
;
234 -- For length zero, we need to return a null slice, but we can't make
235 -- the bounds of this slice Index'First, since this could cause a
236 -- Constraint_Error if Index'First = Index'Base'First.
238 elsif Length
<= 0 then
240 pragma Warnings
(Off
); -- kill warnings since X not assigned
241 X
: Element_Array
(Index
'Succ (Index
'First) .. Index
'First);
242 pragma Warnings
(On
);
248 -- Normal case (length non-zero)
252 H
:= Index
'Val (Index
'Pos (Index
'First) + Length
- 1);
255 subtype A
is Element_Array
(L
.. H
);
258 for PA
'Size use System
.Parameters
.ptr_bits
;
259 function To_PA
is new Ada
.Unchecked_Conversion
(Pointer
, PA
);
262 return To_PA
(Ref
).all;
271 function Virtual_Length
273 Terminator
: Element
:= Default_Terminator
) return ptrdiff_t
280 raise Dereference_Error
;
286 while P
.all /= Terminator
loop
295 end Interfaces
.C
.Pointers
;