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-2011, 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
;
105 T
: Pointer
:= Target
;
106 S
: Pointer
:= Source
;
109 if S
= null or else T
= null then
110 raise Dereference_Error
;
113 for J
in 1 .. Length
loop
121 ---------------------------
122 -- Copy_Terminated_Array --
123 ---------------------------
125 procedure Copy_Terminated_Array
128 Limit
: ptrdiff_t
:= ptrdiff_t
'Last;
129 Terminator
: Element
:= Default_Terminator
)
131 S
: Pointer
:= Source
;
132 T
: Pointer
:= Target
;
133 L
: ptrdiff_t
:= Limit
;
136 if S
= null or else T
= null then
137 raise Dereference_Error
;
142 exit when T
.all = Terminator
;
148 end Copy_Terminated_Array
;
154 procedure Decrement
(Ref
: in out Pointer
) is
163 procedure Increment
(Ref
: in out Pointer
) is
174 Terminator
: Element
:= Default_Terminator
) return Element_Array
177 L
: constant Index_Base
:= Index
'First;
182 raise Dereference_Error
;
189 exit when P
.all = Terminator
;
190 H
:= Index_Base
'Succ (H
);
195 subtype A
is Element_Array
(L
.. H
);
198 for PA
'Size use System
.Parameters
.ptr_bits
;
199 function To_PA
is new Ada
.Unchecked_Conversion
(Pointer
, PA
);
202 return To_PA
(Ref
).all;
209 Length
: ptrdiff_t
) return Element_Array
216 raise Dereference_Error
;
218 -- For length zero, we need to return a null slice, but we can't make
219 -- the bounds of this slice Index'First, since this could cause a
220 -- Constraint_Error if Index'First = Index'Base'First.
222 elsif Length
<= 0 then
224 pragma Warnings
(Off
); -- kill warnings since X not assigned
225 X
: Element_Array
(Index
'Succ (Index
'First) .. Index
'First);
226 pragma Warnings
(On
);
232 -- Normal case (length non-zero)
236 H
:= Index
'Val (Index
'Pos (Index
'First) + Length
- 1);
239 subtype A
is Element_Array
(L
.. H
);
242 for PA
'Size use System
.Parameters
.ptr_bits
;
243 function To_PA
is new Ada
.Unchecked_Conversion
(Pointer
, PA
);
246 return To_PA
(Ref
).all;
255 function Virtual_Length
257 Terminator
: Element
:= Default_Terminator
) return ptrdiff_t
264 raise Dereference_Error
;
270 while P
.all /= Terminator
loop
279 end Interfaces
.C
.Pointers
;