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 --
10 -- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 2, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNAT; see file COPYING. If not, write --
20 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
21 -- MA 02111-1307, USA. --
23 -- As a special exception, if other files instantiate generics from this --
24 -- unit, or you link this unit with other files to produce an executable, --
25 -- this unit does not by itself cause the resulting executable to be --
26 -- covered by the GNU General Public License. This exception does not --
27 -- however invalidate any other reasons why the executable file might be --
28 -- covered by the GNU Public License. --
30 -- GNAT was originally developed by the GNAT team at New York University. --
31 -- Extensive contributions were provided by Ada Core Technologies Inc. --
33 ------------------------------------------------------------------------------
35 with Interfaces
.C
.Strings
; use Interfaces
.C
.Strings
;
36 with System
; use System
;
38 with Unchecked_Conversion
;
40 package body Interfaces
.C
.Pointers
is
42 type Addr
is mod Memory_Size
;
44 function To_Pointer
is new Unchecked_Conversion
(Addr
, Pointer
);
45 function To_Addr
is new Unchecked_Conversion
(Pointer
, Addr
);
46 function To_Addr
is new Unchecked_Conversion
(ptrdiff_t
, Addr
);
47 function To_Ptrdiff
is new Unchecked_Conversion
(Addr
, ptrdiff_t
);
49 Elmt_Size
: constant ptrdiff_t
:=
50 (Element_Array
'Component_Size
51 + Storage_Unit
- 1) / Storage_Unit
;
53 subtype Index_Base
is Index
'Base;
59 function "+" (Left
: in Pointer
; Right
: in ptrdiff_t
) return Pointer
is
65 return To_Pointer
(To_Addr
(Left
) + To_Addr
(Elmt_Size
* Right
));
68 function "+" (Left
: in ptrdiff_t
; Right
: in Pointer
) return Pointer
is
74 return To_Pointer
(To_Addr
(Elmt_Size
* Left
) + To_Addr
(Right
));
81 function "-" (Left
: in Pointer
; Right
: in ptrdiff_t
) return Pointer
is
87 return To_Pointer
(To_Addr
(Left
) - To_Addr
(Right
* Elmt_Size
));
90 function "-" (Left
: in Pointer
; Right
: in Pointer
) return ptrdiff_t
is
92 if Left
= null or else Right
= null then
96 return To_Ptrdiff
(To_Addr
(Left
) - To_Addr
(Right
)) / Elmt_Size
;
104 (Source
: in Pointer
;
106 Length
: in ptrdiff_t
)
108 T
: Pointer
:= Target
;
109 S
: Pointer
:= Source
;
112 if S
= null or else T
= null then
113 raise Dereference_Error
;
116 for J
in 1 .. Length
loop
124 ---------------------------
125 -- Copy_Terminated_Array --
126 ---------------------------
128 procedure Copy_Terminated_Array
129 (Source
: in Pointer
;
131 Limit
: in ptrdiff_t
:= ptrdiff_t
'Last;
132 Terminator
: in Element
:= Default_Terminator
)
134 S
: Pointer
:= Source
;
135 T
: Pointer
:= Target
;
136 L
: ptrdiff_t
:= Limit
;
139 if S
= null or else T
= null then
140 raise Dereference_Error
;
145 exit when T
.all = Terminator
;
151 end Copy_Terminated_Array
;
157 procedure Decrement
(Ref
: in out Pointer
) is
166 procedure Increment
(Ref
: in out Pointer
) is
177 Terminator
: in Element
:= Default_Terminator
)
181 L
: constant Index_Base
:= Index
'First;
186 raise Dereference_Error
;
193 exit when P
.all = Terminator
;
194 H
:= Index_Base
'Succ (H
);
199 subtype A
is Element_Array
(L
.. H
);
202 function To_PA
is new Unchecked_Conversion
(Pointer
, PA
);
205 return To_PA
(Ref
).all;
212 Length
: in ptrdiff_t
)
220 raise Dereference_Error
;
222 -- For length zero, we need to return a null slice, but we can't make
223 -- the bounds of this slice Index'First, since this could cause a
224 -- Constraint_Error if Index'First = Index'Base'First.
226 elsif Length
<= 0 then
228 pragma Warnings
(Off
); -- kill warnings since X not assigned
229 X
: Element_Array
(Index
'Succ (Index
'First) .. Index
'First);
230 pragma Warnings
(On
);
236 -- Normal case (length non-zero)
240 H
:= Index
'Val (Index
'Pos (Index
'First) + Length
- 1);
243 subtype A
is Element_Array
(L
.. H
);
246 function To_PA
is new Unchecked_Conversion
(Pointer
, PA
);
249 return To_PA
(Ref
).all;
258 function Virtual_Length
260 Terminator
: in Element
:= Default_Terminator
)
268 raise Dereference_Error
;
274 while P
.all /= Terminator
loop
283 end Interfaces
.C
.Pointers
;