2015-06-23 Paolo Carlini <paolo.carlini@oracle.com>
[official-gcc.git] / gcc / ada / a-coinho.adb
blob0135ea55db463d79411408fb7137f7ebafe65e2e
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT LIBRARY COMPONENTS --
4 -- --
5 -- A D A . C O N T A I N E R S . I N D E F I N I T E _ H O L D E R S --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2012-2014, Free Software Foundation, Inc. --
10 -- --
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. --
17 -- --
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. --
21 -- --
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/>. --
26 ------------------------------------------------------------------------------
28 with Ada.Unchecked_Deallocation;
30 package body Ada.Containers.Indefinite_Holders is
32 pragma Annotate (CodePeer, Skip_Analysis);
34 procedure Free is
35 new Ada.Unchecked_Deallocation (Element_Type, Element_Access);
37 ---------
38 -- "=" --
39 ---------
41 function "=" (Left, Right : Holder) return Boolean is
42 begin
43 if Left.Element = null and Right.Element = null then
44 return True;
45 elsif Left.Element /= null and Right.Element /= null then
46 return Left.Element.all = Right.Element.all;
47 else
48 return False;
49 end if;
50 end "=";
52 ------------
53 -- Adjust --
54 ------------
56 overriding procedure Adjust (Container : in out Holder) is
57 begin
58 if Container.Element /= null then
59 Container.Element := new Element_Type'(Container.Element.all);
60 end if;
62 Container.Busy := 0;
63 end Adjust;
65 overriding procedure Adjust (Control : in out Reference_Control_Type) is
66 begin
67 if Control.Container /= null then
68 declare
69 B : Natural renames Control.Container.Busy;
70 begin
71 B := B + 1;
72 end;
73 end if;
74 end Adjust;
76 ------------
77 -- Assign --
78 ------------
80 procedure Assign (Target : in out Holder; Source : Holder) is
81 begin
82 if Target.Busy /= 0 then
83 raise Program_Error with "attempt to tamper with elements";
84 end if;
86 if Target.Element /= Source.Element then
87 Free (Target.Element);
89 if Source.Element /= null then
90 Target.Element := new Element_Type'(Source.Element.all);
91 end if;
92 end if;
93 end Assign;
95 -----------
96 -- Clear --
97 -----------
99 procedure Clear (Container : in out Holder) is
100 begin
101 if Container.Busy /= 0 then
102 raise Program_Error with "attempt to tamper with elements";
103 end if;
105 Free (Container.Element);
106 end Clear;
108 ------------------------
109 -- Constant_Reference --
110 ------------------------
112 function Constant_Reference
113 (Container : aliased Holder) return Constant_Reference_Type
115 Ref : constant Constant_Reference_Type :=
116 (Element => Container.Element.all'Access,
117 Control => (Controlled with Container'Unrestricted_Access));
118 B : Natural renames Ref.Control.Container.Busy;
119 begin
120 B := B + 1;
121 return Ref;
122 end Constant_Reference;
124 ----------
125 -- Copy --
126 ----------
128 function Copy (Source : Holder) return Holder is
129 begin
130 if Source.Element = null then
131 return (Controlled with null, 0);
132 else
133 return (Controlled with new Element_Type'(Source.Element.all), 0);
134 end if;
135 end Copy;
137 -------------
138 -- Element --
139 -------------
141 function Element (Container : Holder) return Element_Type is
142 begin
143 if Container.Element = null then
144 raise Constraint_Error with "container is empty";
145 else
146 return Container.Element.all;
147 end if;
148 end Element;
150 --------------
151 -- Finalize --
152 --------------
154 overriding procedure Finalize (Container : in out Holder) is
155 begin
156 if Container.Busy /= 0 then
157 raise Program_Error with "attempt to tamper with elements";
158 end if;
160 Free (Container.Element);
161 end Finalize;
163 overriding procedure Finalize (Control : in out Reference_Control_Type) is
164 begin
165 if Control.Container /= null then
166 declare
167 B : Natural renames Control.Container.Busy;
168 begin
169 B := B - 1;
170 end;
171 end if;
173 Control.Container := null;
174 end Finalize;
176 --------------
177 -- Is_Empty --
178 --------------
180 function Is_Empty (Container : Holder) return Boolean is
181 begin
182 return Container.Element = null;
183 end Is_Empty;
185 ----------
186 -- Move --
187 ----------
189 procedure Move (Target : in out Holder; Source : in out Holder) is
190 begin
191 if Target.Busy /= 0 then
192 raise Program_Error with "attempt to tamper with elements";
193 end if;
195 if Source.Busy /= 0 then
196 raise Program_Error with "attempt to tamper with elements";
197 end if;
199 if Target.Element /= Source.Element then
200 Free (Target.Element);
201 Target.Element := Source.Element;
202 Source.Element := null;
203 end if;
204 end Move;
206 -------------------
207 -- Query_Element --
208 -------------------
210 procedure Query_Element
211 (Container : Holder;
212 Process : not null access procedure (Element : Element_Type))
214 B : Natural renames Container'Unrestricted_Access.Busy;
216 begin
217 if Container.Element = null then
218 raise Constraint_Error with "container is empty";
219 end if;
221 B := B + 1;
223 begin
224 Process (Container.Element.all);
225 exception
226 when others =>
227 B := B - 1;
228 raise;
229 end;
231 B := B - 1;
232 end Query_Element;
234 ----------
235 -- Read --
236 ----------
238 procedure Read
239 (Stream : not null access Ada.Streams.Root_Stream_Type'Class;
240 Container : out Holder)
242 begin
243 Clear (Container);
245 if not Boolean'Input (Stream) then
246 Container.Element := new Element_Type'(Element_Type'Input (Stream));
247 end if;
248 end Read;
250 procedure Read
251 (Stream : not null access Root_Stream_Type'Class;
252 Item : out Constant_Reference_Type)
254 begin
255 raise Program_Error with "attempt to stream reference";
256 end Read;
258 procedure Read
259 (Stream : not null access Root_Stream_Type'Class;
260 Item : out Reference_Type)
262 begin
263 raise Program_Error with "attempt to stream reference";
264 end Read;
266 ---------------
267 -- Reference --
268 ---------------
270 function Reference
271 (Container : aliased in out Holder) return Reference_Type
273 Ref : constant Reference_Type :=
274 (Element => Container.Element.all'Access,
275 Control => (Controlled with Container'Unrestricted_Access));
276 begin
277 Container.Busy := Container.Busy + 1;
278 return Ref;
279 end Reference;
281 ---------------------
282 -- Replace_Element --
283 ---------------------
285 procedure Replace_Element
286 (Container : in out Holder;
287 New_Item : Element_Type)
289 begin
290 if Container.Busy /= 0 then
291 raise Program_Error with "attempt to tamper with elements";
292 end if;
294 declare
295 X : Element_Access := Container.Element;
297 -- Element allocator may need an accessibility check in case actual
298 -- type is class-wide or has access discriminants (RM 4.8(10.1) and
299 -- AI12-0035).
301 pragma Unsuppress (Accessibility_Check);
303 begin
304 Container.Element := new Element_Type'(New_Item);
305 Free (X);
306 end;
307 end Replace_Element;
309 ---------------
310 -- To_Holder --
311 ---------------
313 function To_Holder (New_Item : Element_Type) return Holder is
315 -- The element allocator may need an accessibility check in the case the
316 -- actual type is class-wide or has access discriminants (RM 4.8(10.1)
317 -- and AI12-0035).
319 pragma Unsuppress (Accessibility_Check);
321 begin
322 return (Controlled with new Element_Type'(New_Item), 0);
323 end To_Holder;
325 --------------------
326 -- Update_Element --
327 --------------------
329 procedure Update_Element
330 (Container : in out Holder;
331 Process : not null access procedure (Element : in out Element_Type))
333 B : Natural renames Container.Busy;
335 begin
336 if Container.Element = null then
337 raise Constraint_Error with "container is empty";
338 end if;
340 B := B + 1;
342 begin
343 Process (Container.Element.all);
344 exception
345 when others =>
346 B := B - 1;
347 raise;
348 end;
350 B := B - 1;
351 end Update_Element;
353 -----------
354 -- Write --
355 -----------
357 procedure Write
358 (Stream : not null access Ada.Streams.Root_Stream_Type'Class;
359 Container : Holder)
361 begin
362 Boolean'Output (Stream, Container.Element = null);
364 if Container.Element /= null then
365 Element_Type'Output (Stream, Container.Element.all);
366 end if;
367 end Write;
369 procedure Write
370 (Stream : not null access Root_Stream_Type'Class;
371 Item : Reference_Type)
373 begin
374 raise Program_Error with "attempt to stream reference";
375 end Write;
377 procedure Write
378 (Stream : not null access Root_Stream_Type'Class;
379 Item : Constant_Reference_Type)
381 begin
382 raise Program_Error with "attempt to stream reference";
383 end Write;
385 end Ada.Containers.Indefinite_Holders;