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 --
11 -- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
13 -- GNAT is free software; you can redistribute it and/or modify it under --
14 -- terms of the GNU General Public License as published by the Free Soft- --
15 -- ware Foundation; either version 2, or (at your option) any later ver- --
16 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
19 -- for more details. You should have received a copy of the GNU General --
20 -- Public License distributed with GNAT; see file COPYING. If not, write --
21 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
22 -- MA 02111-1307, USA. --
24 -- As a special exception, if other files instantiate generics from this --
25 -- unit, or you link this unit with other files to produce an executable, --
26 -- this unit does not by itself cause the resulting executable to be --
27 -- covered by the GNU General Public License. This exception does not --
28 -- however invalidate any other reasons why the executable file might be --
29 -- covered by the GNU Public License. --
31 -- GNAT was originally developed by the GNAT team at New York University. --
32 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
34 ------------------------------------------------------------------------------
36 with Interfaces
.C
.Strings
; use Interfaces
.C
.Strings
;
37 with System
; use System
;
39 with Unchecked_Conversion
;
41 package body Interfaces
.C
.Pointers
is
43 type Addr
is mod Memory_Size
;
45 function To_Pointer
is new Unchecked_Conversion
(Addr
, Pointer
);
46 function To_Addr
is new Unchecked_Conversion
(Pointer
, Addr
);
47 function To_Addr
is new Unchecked_Conversion
(ptrdiff_t
, Addr
);
48 function To_Ptrdiff
is new Unchecked_Conversion
(Addr
, ptrdiff_t
);
50 Elmt_Size
: constant ptrdiff_t
:=
51 (Element_Array
'Component_Size
52 + Storage_Unit
- 1) / Storage_Unit
;
54 subtype Index_Base
is Index
'Base;
60 function "+" (Left
: in Pointer
; Right
: in ptrdiff_t
) return Pointer
is
66 return To_Pointer
(To_Addr
(Left
) + To_Addr
(Elmt_Size
* Right
));
69 function "+" (Left
: in ptrdiff_t
; Right
: in Pointer
) return Pointer
is
75 return To_Pointer
(To_Addr
(Elmt_Size
* Left
) + To_Addr
(Right
));
82 function "-" (Left
: in Pointer
; Right
: in ptrdiff_t
) return Pointer
is
88 return To_Pointer
(To_Addr
(Left
) - To_Addr
(Right
* Elmt_Size
));
91 function "-" (Left
: in Pointer
; Right
: in Pointer
) return ptrdiff_t
is
93 if Left
= null or else Right
= null then
97 return To_Ptrdiff
(To_Addr
(Left
) - To_Addr
(Right
)) / Elmt_Size
;
105 (Source
: in Pointer
;
107 Length
: in ptrdiff_t
)
109 T
: Pointer
:= Target
;
110 S
: Pointer
:= Source
;
113 if S
= null or else T
= null then
114 raise Dereference_Error
;
117 for J
in 1 .. Length
loop
125 ---------------------------
126 -- Copy_Terminated_Array --
127 ---------------------------
129 procedure Copy_Terminated_Array
130 (Source
: in Pointer
;
132 Limit
: in ptrdiff_t
:= ptrdiff_t
'Last;
133 Terminator
: in Element
:= Default_Terminator
)
135 S
: Pointer
:= Source
;
136 T
: Pointer
:= Target
;
137 L
: ptrdiff_t
:= Limit
;
140 if S
= null or else T
= null then
141 raise Dereference_Error
;
146 exit when T
.all = Terminator
;
152 end Copy_Terminated_Array
;
158 procedure Decrement
(Ref
: in out Pointer
) is
167 procedure Increment
(Ref
: in out Pointer
) is
178 Terminator
: in Element
:= Default_Terminator
)
182 L
: constant Index_Base
:= Index
'First;
187 raise Dereference_Error
;
194 exit when P
.all = Terminator
;
195 H
:= Index_Base
'Succ (H
);
200 subtype A
is Element_Array
(L
.. H
);
203 function To_PA
is new Unchecked_Conversion
(Pointer
, PA
);
206 return To_PA
(Ref
).all;
213 Length
: in ptrdiff_t
)
221 raise Dereference_Error
;
223 -- For length zero, we need to return a null slice, but we can't make
224 -- the bounds of this slice Index'First, since this could cause a
225 -- Constraint_Error if Index'First = Index'Base'First.
227 elsif Length
<= 0 then
229 pragma Warnings
(Off
); -- kill warnings since X not assigned
230 X
: Element_Array
(Index
'Succ (Index
'First) .. Index
'First);
231 pragma Warnings
(On
);
237 -- Normal case (length non-zero)
241 H
:= Index
'Val (Index
'Pos (Index
'First) + Length
- 1);
244 subtype A
is Element_Array
(L
.. H
);
247 function To_PA
is new Unchecked_Conversion
(Pointer
, PA
);
250 return To_PA
(Ref
).all;
259 function Virtual_Length
261 Terminator
: in Element
:= Default_Terminator
)
269 raise Dereference_Error
;
275 while P
.all /= Terminator
loop
284 end Interfaces
.C
.Pointers
;