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-2004 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 2, 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. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
29 -- GNAT was originally developed by the GNAT team at New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
32 ------------------------------------------------------------------------------
34 with Interfaces
.C
.Strings
; use Interfaces
.C
.Strings
;
35 with System
; use System
;
37 with Unchecked_Conversion
;
39 package body Interfaces
.C
.Pointers
is
41 type Addr
is mod Memory_Size
;
43 function To_Pointer
is new Unchecked_Conversion
(Addr
, Pointer
);
44 function To_Addr
is new Unchecked_Conversion
(Pointer
, Addr
);
45 function To_Addr
is new Unchecked_Conversion
(ptrdiff_t
, Addr
);
46 function To_Ptrdiff
is new Unchecked_Conversion
(Addr
, ptrdiff_t
);
48 Elmt_Size
: constant ptrdiff_t
:=
49 (Element_Array
'Component_Size
50 + Storage_Unit
- 1) / Storage_Unit
;
52 subtype Index_Base
is Index
'Base;
58 function "+" (Left
: Pointer
; Right
: ptrdiff_t
) return Pointer
is
64 return To_Pointer
(To_Addr
(Left
) + To_Addr
(Elmt_Size
* Right
));
67 function "+" (Left
: ptrdiff_t
; Right
: Pointer
) return Pointer
is
73 return To_Pointer
(To_Addr
(Elmt_Size
* Left
) + To_Addr
(Right
));
80 function "-" (Left
: Pointer
; Right
: ptrdiff_t
) return Pointer
is
86 return To_Pointer
(To_Addr
(Left
) - To_Addr
(Right
* Elmt_Size
));
89 function "-" (Left
: Pointer
; Right
: Pointer
) return ptrdiff_t
is
91 if Left
= null or else Right
= null then
95 return To_Ptrdiff
(To_Addr
(Left
) - To_Addr
(Right
)) / Elmt_Size
;
107 T
: Pointer
:= Target
;
108 S
: Pointer
:= Source
;
111 if S
= null or else T
= null then
112 raise Dereference_Error
;
115 for J
in 1 .. Length
loop
123 ---------------------------
124 -- Copy_Terminated_Array --
125 ---------------------------
127 procedure Copy_Terminated_Array
130 Limit
: ptrdiff_t
:= ptrdiff_t
'Last;
131 Terminator
: Element
:= Default_Terminator
)
133 S
: Pointer
:= Source
;
134 T
: Pointer
:= Target
;
135 L
: ptrdiff_t
:= Limit
;
138 if S
= null or else T
= null then
139 raise Dereference_Error
;
144 exit when T
.all = Terminator
;
150 end Copy_Terminated_Array
;
156 procedure Decrement
(Ref
: in out Pointer
) is
165 procedure Increment
(Ref
: in out Pointer
) is
176 Terminator
: Element
:= Default_Terminator
) return Element_Array
179 L
: constant Index_Base
:= Index
'First;
184 raise Dereference_Error
;
191 exit when P
.all = Terminator
;
192 H
:= Index_Base
'Succ (H
);
197 subtype A
is Element_Array
(L
.. H
);
200 function To_PA
is new Unchecked_Conversion
(Pointer
, PA
);
203 return To_PA
(Ref
).all;
210 Length
: ptrdiff_t
) return Element_Array
217 raise Dereference_Error
;
219 -- For length zero, we need to return a null slice, but we can't make
220 -- the bounds of this slice Index'First, since this could cause a
221 -- Constraint_Error if Index'First = Index'Base'First.
223 elsif Length
<= 0 then
225 pragma Warnings
(Off
); -- kill warnings since X not assigned
226 X
: Element_Array
(Index
'Succ (Index
'First) .. Index
'First);
227 pragma Warnings
(On
);
233 -- Normal case (length non-zero)
237 H
:= Index
'Val (Index
'Pos (Index
'First) + Length
- 1);
240 subtype A
is Element_Array
(L
.. H
);
243 function To_PA
is new 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
;