annotate gcc/ada/libgnat/a-btgbso.adb @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT LIBRARY COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- ADA.CONTAINERS.RED_BLACK_TREES.GENERIC_BOUNDED_SET_OPERATIONS --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
kono
parents:
diff changeset
9 -- Copyright (C) 2004-2017, Free Software Foundation, Inc. --
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
kono
parents:
diff changeset
17 -- --
kono
parents:
diff changeset
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
kono
parents:
diff changeset
19 -- additional permissions described in the GCC Runtime Library Exception, --
kono
parents:
diff changeset
20 -- version 3.1, as published by the Free Software Foundation. --
kono
parents:
diff changeset
21 -- --
kono
parents:
diff changeset
22 -- You should have received a copy of the GNU General Public License and --
kono
parents:
diff changeset
23 -- a copy of the GCC Runtime Library Exception along with this program; --
kono
parents:
diff changeset
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
kono
parents:
diff changeset
25 -- <http://www.gnu.org/licenses/>. --
kono
parents:
diff changeset
26 -- --
kono
parents:
diff changeset
27 -- This unit was originally developed by Matthew J Heaney. --
kono
parents:
diff changeset
28 ------------------------------------------------------------------------------
kono
parents:
diff changeset
29
kono
parents:
diff changeset
30 with System; use type System.Address;
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 pragma Warnings (Off, "variable ""Busy*"" is not referenced");
kono
parents:
diff changeset
35 pragma Warnings (Off, "variable ""Lock*"" is not referenced");
kono
parents:
diff changeset
36 -- See comment in Ada.Containers.Helpers
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 -----------------------
kono
parents:
diff changeset
39 -- Local Subprograms --
kono
parents:
diff changeset
40 -----------------------
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42 function Copy (Source : Set_Type) return Set_Type;
kono
parents:
diff changeset
43
kono
parents:
diff changeset
44 ----------
kono
parents:
diff changeset
45 -- Copy --
kono
parents:
diff changeset
46 ----------
kono
parents:
diff changeset
47
kono
parents:
diff changeset
48 function Copy (Source : Set_Type) return Set_Type is
kono
parents:
diff changeset
49 begin
kono
parents:
diff changeset
50 return Target : Set_Type (Source.Length) do
kono
parents:
diff changeset
51 Assign (Target => Target, Source => Source);
kono
parents:
diff changeset
52 end return;
kono
parents:
diff changeset
53 end Copy;
kono
parents:
diff changeset
54
kono
parents:
diff changeset
55 ----------------
kono
parents:
diff changeset
56 -- Difference --
kono
parents:
diff changeset
57 ----------------
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 procedure Set_Difference (Target : in out Set_Type; Source : Set_Type) is
kono
parents:
diff changeset
60 Tgt, Src : Count_Type;
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 TN : Nodes_Type renames Target.Nodes;
kono
parents:
diff changeset
63 SN : Nodes_Type renames Source.Nodes;
kono
parents:
diff changeset
64
kono
parents:
diff changeset
65 Compare : Integer;
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 begin
kono
parents:
diff changeset
68 if Target'Address = Source'Address then
kono
parents:
diff changeset
69 TC_Check (Target.TC);
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 Tree_Operations.Clear_Tree (Target);
kono
parents:
diff changeset
72 return;
kono
parents:
diff changeset
73 end if;
kono
parents:
diff changeset
74
kono
parents:
diff changeset
75 if Source.Length = 0 then
kono
parents:
diff changeset
76 return;
kono
parents:
diff changeset
77 end if;
kono
parents:
diff changeset
78
kono
parents:
diff changeset
79 TC_Check (Target.TC);
kono
parents:
diff changeset
80
kono
parents:
diff changeset
81 Tgt := Target.First;
kono
parents:
diff changeset
82 Src := Source.First;
kono
parents:
diff changeset
83 loop
kono
parents:
diff changeset
84 if Tgt = 0 then
kono
parents:
diff changeset
85 exit;
kono
parents:
diff changeset
86 end if;
kono
parents:
diff changeset
87
kono
parents:
diff changeset
88 if Src = 0 then
kono
parents:
diff changeset
89 exit;
kono
parents:
diff changeset
90 end if;
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 -- Per AI05-0022, the container implementation is required to detect
kono
parents:
diff changeset
93 -- element tampering by a generic actual subprogram.
kono
parents:
diff changeset
94
kono
parents:
diff changeset
95 declare
kono
parents:
diff changeset
96 Lock_Target : With_Lock (Target.TC'Unrestricted_Access);
kono
parents:
diff changeset
97 Lock_Source : With_Lock (Source.TC'Unrestricted_Access);
kono
parents:
diff changeset
98 begin
kono
parents:
diff changeset
99 if Is_Less (TN (Tgt), SN (Src)) then
kono
parents:
diff changeset
100 Compare := -1;
kono
parents:
diff changeset
101 elsif Is_Less (SN (Src), TN (Tgt)) then
kono
parents:
diff changeset
102 Compare := 1;
kono
parents:
diff changeset
103 else
kono
parents:
diff changeset
104 Compare := 0;
kono
parents:
diff changeset
105 end if;
kono
parents:
diff changeset
106 end;
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108 if Compare < 0 then
kono
parents:
diff changeset
109 Tgt := Tree_Operations.Next (Target, Tgt);
kono
parents:
diff changeset
110
kono
parents:
diff changeset
111 elsif Compare > 0 then
kono
parents:
diff changeset
112 Src := Tree_Operations.Next (Source, Src);
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 else
kono
parents:
diff changeset
115 declare
kono
parents:
diff changeset
116 X : constant Count_Type := Tgt;
kono
parents:
diff changeset
117 begin
kono
parents:
diff changeset
118 Tgt := Tree_Operations.Next (Target, Tgt);
kono
parents:
diff changeset
119
kono
parents:
diff changeset
120 Tree_Operations.Delete_Node_Sans_Free (Target, X);
kono
parents:
diff changeset
121 Tree_Operations.Free (Target, X);
kono
parents:
diff changeset
122 end;
kono
parents:
diff changeset
123
kono
parents:
diff changeset
124 Src := Tree_Operations.Next (Source, Src);
kono
parents:
diff changeset
125 end if;
kono
parents:
diff changeset
126 end loop;
kono
parents:
diff changeset
127 end Set_Difference;
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 function Set_Difference (Left, Right : Set_Type) return Set_Type is
kono
parents:
diff changeset
130 begin
kono
parents:
diff changeset
131 if Left'Address = Right'Address then
kono
parents:
diff changeset
132 return S : Set_Type (0); -- Empty set
kono
parents:
diff changeset
133 end if;
kono
parents:
diff changeset
134
kono
parents:
diff changeset
135 if Left.Length = 0 then
kono
parents:
diff changeset
136 return S : Set_Type (0); -- Empty set
kono
parents:
diff changeset
137 end if;
kono
parents:
diff changeset
138
kono
parents:
diff changeset
139 if Right.Length = 0 then
kono
parents:
diff changeset
140 return Copy (Left);
kono
parents:
diff changeset
141 end if;
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 return Result : Set_Type (Left.Length) do
kono
parents:
diff changeset
144 -- Per AI05-0022, the container implementation is required to detect
kono
parents:
diff changeset
145 -- element tampering by a generic actual subprogram.
kono
parents:
diff changeset
146
kono
parents:
diff changeset
147 declare
kono
parents:
diff changeset
148 Lock_Left : With_Lock (Left.TC'Unrestricted_Access);
kono
parents:
diff changeset
149 Lock_Right : With_Lock (Right.TC'Unrestricted_Access);
kono
parents:
diff changeset
150
kono
parents:
diff changeset
151 L_Node : Count_Type;
kono
parents:
diff changeset
152 R_Node : Count_Type;
kono
parents:
diff changeset
153
kono
parents:
diff changeset
154 Dst_Node : Count_Type;
kono
parents:
diff changeset
155 pragma Warnings (Off, Dst_Node);
kono
parents:
diff changeset
156
kono
parents:
diff changeset
157 begin
kono
parents:
diff changeset
158 L_Node := Left.First;
kono
parents:
diff changeset
159 R_Node := Right.First;
kono
parents:
diff changeset
160 loop
kono
parents:
diff changeset
161 if L_Node = 0 then
kono
parents:
diff changeset
162 exit;
kono
parents:
diff changeset
163 end if;
kono
parents:
diff changeset
164
kono
parents:
diff changeset
165 if R_Node = 0 then
kono
parents:
diff changeset
166 while L_Node /= 0 loop
kono
parents:
diff changeset
167 Insert_With_Hint
kono
parents:
diff changeset
168 (Dst_Set => Result,
kono
parents:
diff changeset
169 Dst_Hint => 0,
kono
parents:
diff changeset
170 Src_Node => Left.Nodes (L_Node),
kono
parents:
diff changeset
171 Dst_Node => Dst_Node);
kono
parents:
diff changeset
172
kono
parents:
diff changeset
173 L_Node := Tree_Operations.Next (Left, L_Node);
kono
parents:
diff changeset
174 end loop;
kono
parents:
diff changeset
175
kono
parents:
diff changeset
176 exit;
kono
parents:
diff changeset
177 end if;
kono
parents:
diff changeset
178
kono
parents:
diff changeset
179 if Is_Less (Left.Nodes (L_Node), Right.Nodes (R_Node)) then
kono
parents:
diff changeset
180 Insert_With_Hint
kono
parents:
diff changeset
181 (Dst_Set => Result,
kono
parents:
diff changeset
182 Dst_Hint => 0,
kono
parents:
diff changeset
183 Src_Node => Left.Nodes (L_Node),
kono
parents:
diff changeset
184 Dst_Node => Dst_Node);
kono
parents:
diff changeset
185
kono
parents:
diff changeset
186 L_Node := Tree_Operations.Next (Left, L_Node);
kono
parents:
diff changeset
187
kono
parents:
diff changeset
188 elsif Is_Less (Right.Nodes (R_Node), Left.Nodes (L_Node)) then
kono
parents:
diff changeset
189 R_Node := Tree_Operations.Next (Right, R_Node);
kono
parents:
diff changeset
190
kono
parents:
diff changeset
191 else
kono
parents:
diff changeset
192 L_Node := Tree_Operations.Next (Left, L_Node);
kono
parents:
diff changeset
193 R_Node := Tree_Operations.Next (Right, R_Node);
kono
parents:
diff changeset
194 end if;
kono
parents:
diff changeset
195 end loop;
kono
parents:
diff changeset
196 end;
kono
parents:
diff changeset
197 end return;
kono
parents:
diff changeset
198 end Set_Difference;
kono
parents:
diff changeset
199
kono
parents:
diff changeset
200 ------------------
kono
parents:
diff changeset
201 -- Intersection --
kono
parents:
diff changeset
202 ------------------
kono
parents:
diff changeset
203
kono
parents:
diff changeset
204 procedure Set_Intersection
kono
parents:
diff changeset
205 (Target : in out Set_Type;
kono
parents:
diff changeset
206 Source : Set_Type)
kono
parents:
diff changeset
207 is
kono
parents:
diff changeset
208 Tgt : Count_Type;
kono
parents:
diff changeset
209 Src : Count_Type;
kono
parents:
diff changeset
210
kono
parents:
diff changeset
211 Compare : Integer;
kono
parents:
diff changeset
212
kono
parents:
diff changeset
213 begin
kono
parents:
diff changeset
214 if Target'Address = Source'Address then
kono
parents:
diff changeset
215 return;
kono
parents:
diff changeset
216 end if;
kono
parents:
diff changeset
217
kono
parents:
diff changeset
218 TC_Check (Target.TC);
kono
parents:
diff changeset
219
kono
parents:
diff changeset
220 if Source.Length = 0 then
kono
parents:
diff changeset
221 Tree_Operations.Clear_Tree (Target);
kono
parents:
diff changeset
222 return;
kono
parents:
diff changeset
223 end if;
kono
parents:
diff changeset
224
kono
parents:
diff changeset
225 Tgt := Target.First;
kono
parents:
diff changeset
226 Src := Source.First;
kono
parents:
diff changeset
227 while Tgt /= 0
kono
parents:
diff changeset
228 and then Src /= 0
kono
parents:
diff changeset
229 loop
kono
parents:
diff changeset
230 -- Per AI05-0022, the container implementation is required to detect
kono
parents:
diff changeset
231 -- element tampering by a generic actual subprogram.
kono
parents:
diff changeset
232
kono
parents:
diff changeset
233 declare
kono
parents:
diff changeset
234 Lock_Target : With_Lock (Target.TC'Unrestricted_Access);
kono
parents:
diff changeset
235 Lock_Source : With_Lock (Source.TC'Unrestricted_Access);
kono
parents:
diff changeset
236 begin
kono
parents:
diff changeset
237 if Is_Less (Target.Nodes (Tgt), Source.Nodes (Src)) then
kono
parents:
diff changeset
238 Compare := -1;
kono
parents:
diff changeset
239 elsif Is_Less (Source.Nodes (Src), Target.Nodes (Tgt)) then
kono
parents:
diff changeset
240 Compare := 1;
kono
parents:
diff changeset
241 else
kono
parents:
diff changeset
242 Compare := 0;
kono
parents:
diff changeset
243 end if;
kono
parents:
diff changeset
244 end;
kono
parents:
diff changeset
245
kono
parents:
diff changeset
246 if Compare < 0 then
kono
parents:
diff changeset
247 declare
kono
parents:
diff changeset
248 X : constant Count_Type := Tgt;
kono
parents:
diff changeset
249 begin
kono
parents:
diff changeset
250 Tgt := Tree_Operations.Next (Target, Tgt);
kono
parents:
diff changeset
251
kono
parents:
diff changeset
252 Tree_Operations.Delete_Node_Sans_Free (Target, X);
kono
parents:
diff changeset
253 Tree_Operations.Free (Target, X);
kono
parents:
diff changeset
254 end;
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 elsif Compare > 0 then
kono
parents:
diff changeset
257 Src := Tree_Operations.Next (Source, Src);
kono
parents:
diff changeset
258
kono
parents:
diff changeset
259 else
kono
parents:
diff changeset
260 Tgt := Tree_Operations.Next (Target, Tgt);
kono
parents:
diff changeset
261 Src := Tree_Operations.Next (Source, Src);
kono
parents:
diff changeset
262 end if;
kono
parents:
diff changeset
263 end loop;
kono
parents:
diff changeset
264
kono
parents:
diff changeset
265 while Tgt /= 0 loop
kono
parents:
diff changeset
266 declare
kono
parents:
diff changeset
267 X : constant Count_Type := Tgt;
kono
parents:
diff changeset
268 begin
kono
parents:
diff changeset
269 Tgt := Tree_Operations.Next (Target, Tgt);
kono
parents:
diff changeset
270
kono
parents:
diff changeset
271 Tree_Operations.Delete_Node_Sans_Free (Target, X);
kono
parents:
diff changeset
272 Tree_Operations.Free (Target, X);
kono
parents:
diff changeset
273 end;
kono
parents:
diff changeset
274 end loop;
kono
parents:
diff changeset
275 end Set_Intersection;
kono
parents:
diff changeset
276
kono
parents:
diff changeset
277 function Set_Intersection (Left, Right : Set_Type) return Set_Type is
kono
parents:
diff changeset
278 begin
kono
parents:
diff changeset
279 if Left'Address = Right'Address then
kono
parents:
diff changeset
280 return Copy (Left);
kono
parents:
diff changeset
281 end if;
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 return Result : Set_Type (Count_Type'Min (Left.Length, Right.Length)) do
kono
parents:
diff changeset
284
kono
parents:
diff changeset
285 -- Per AI05-0022, the container implementation is required to detect
kono
parents:
diff changeset
286 -- element tampering by a generic actual subprogram.
kono
parents:
diff changeset
287
kono
parents:
diff changeset
288 declare
kono
parents:
diff changeset
289 Lock_Left : With_Lock (Left.TC'Unrestricted_Access);
kono
parents:
diff changeset
290 Lock_Right : With_Lock (Right.TC'Unrestricted_Access);
kono
parents:
diff changeset
291
kono
parents:
diff changeset
292 L_Node : Count_Type;
kono
parents:
diff changeset
293 R_Node : Count_Type;
kono
parents:
diff changeset
294
kono
parents:
diff changeset
295 Dst_Node : Count_Type;
kono
parents:
diff changeset
296 pragma Warnings (Off, Dst_Node);
kono
parents:
diff changeset
297
kono
parents:
diff changeset
298 begin
kono
parents:
diff changeset
299 L_Node := Left.First;
kono
parents:
diff changeset
300 R_Node := Right.First;
kono
parents:
diff changeset
301 loop
kono
parents:
diff changeset
302 if L_Node = 0 then
kono
parents:
diff changeset
303 exit;
kono
parents:
diff changeset
304 end if;
kono
parents:
diff changeset
305
kono
parents:
diff changeset
306 if R_Node = 0 then
kono
parents:
diff changeset
307 exit;
kono
parents:
diff changeset
308 end if;
kono
parents:
diff changeset
309
kono
parents:
diff changeset
310 if Is_Less (Left.Nodes (L_Node), Right.Nodes (R_Node)) then
kono
parents:
diff changeset
311 L_Node := Tree_Operations.Next (Left, L_Node);
kono
parents:
diff changeset
312
kono
parents:
diff changeset
313 elsif Is_Less (Right.Nodes (R_Node), Left.Nodes (L_Node)) then
kono
parents:
diff changeset
314 R_Node := Tree_Operations.Next (Right, R_Node);
kono
parents:
diff changeset
315
kono
parents:
diff changeset
316 else
kono
parents:
diff changeset
317 Insert_With_Hint
kono
parents:
diff changeset
318 (Dst_Set => Result,
kono
parents:
diff changeset
319 Dst_Hint => 0,
kono
parents:
diff changeset
320 Src_Node => Left.Nodes (L_Node),
kono
parents:
diff changeset
321 Dst_Node => Dst_Node);
kono
parents:
diff changeset
322
kono
parents:
diff changeset
323 L_Node := Tree_Operations.Next (Left, L_Node);
kono
parents:
diff changeset
324 R_Node := Tree_Operations.Next (Right, R_Node);
kono
parents:
diff changeset
325 end if;
kono
parents:
diff changeset
326 end loop;
kono
parents:
diff changeset
327 end;
kono
parents:
diff changeset
328 end return;
kono
parents:
diff changeset
329 end Set_Intersection;
kono
parents:
diff changeset
330
kono
parents:
diff changeset
331 ---------------
kono
parents:
diff changeset
332 -- Is_Subset --
kono
parents:
diff changeset
333 ---------------
kono
parents:
diff changeset
334
kono
parents:
diff changeset
335 function Set_Subset
kono
parents:
diff changeset
336 (Subset : Set_Type;
kono
parents:
diff changeset
337 Of_Set : Set_Type) return Boolean
kono
parents:
diff changeset
338 is
kono
parents:
diff changeset
339 begin
kono
parents:
diff changeset
340 if Subset'Address = Of_Set'Address then
kono
parents:
diff changeset
341 return True;
kono
parents:
diff changeset
342 end if;
kono
parents:
diff changeset
343
kono
parents:
diff changeset
344 if Subset.Length > Of_Set.Length then
kono
parents:
diff changeset
345 return False;
kono
parents:
diff changeset
346 end if;
kono
parents:
diff changeset
347
kono
parents:
diff changeset
348 -- Per AI05-0022, the container implementation is required to detect
kono
parents:
diff changeset
349 -- element tampering by a generic actual subprogram.
kono
parents:
diff changeset
350
kono
parents:
diff changeset
351 declare
kono
parents:
diff changeset
352 Lock_Subset : With_Lock (Subset.TC'Unrestricted_Access);
kono
parents:
diff changeset
353 Lock_Of_Set : With_Lock (Of_Set.TC'Unrestricted_Access);
kono
parents:
diff changeset
354
kono
parents:
diff changeset
355 Subset_Node : Count_Type;
kono
parents:
diff changeset
356 Set_Node : Count_Type;
kono
parents:
diff changeset
357 begin
kono
parents:
diff changeset
358 Subset_Node := Subset.First;
kono
parents:
diff changeset
359 Set_Node := Of_Set.First;
kono
parents:
diff changeset
360 loop
kono
parents:
diff changeset
361 if Set_Node = 0 then
kono
parents:
diff changeset
362 return Subset_Node = 0;
kono
parents:
diff changeset
363 end if;
kono
parents:
diff changeset
364
kono
parents:
diff changeset
365 if Subset_Node = 0 then
kono
parents:
diff changeset
366 return True;
kono
parents:
diff changeset
367 end if;
kono
parents:
diff changeset
368
kono
parents:
diff changeset
369 if Is_Less (Subset.Nodes (Subset_Node),
kono
parents:
diff changeset
370 Of_Set.Nodes (Set_Node))
kono
parents:
diff changeset
371 then
kono
parents:
diff changeset
372 return False;
kono
parents:
diff changeset
373 end if;
kono
parents:
diff changeset
374
kono
parents:
diff changeset
375 if Is_Less (Of_Set.Nodes (Set_Node),
kono
parents:
diff changeset
376 Subset.Nodes (Subset_Node))
kono
parents:
diff changeset
377 then
kono
parents:
diff changeset
378 Set_Node := Tree_Operations.Next (Of_Set, Set_Node);
kono
parents:
diff changeset
379 else
kono
parents:
diff changeset
380 Set_Node := Tree_Operations.Next (Of_Set, Set_Node);
kono
parents:
diff changeset
381 Subset_Node := Tree_Operations.Next (Subset, Subset_Node);
kono
parents:
diff changeset
382 end if;
kono
parents:
diff changeset
383 end loop;
kono
parents:
diff changeset
384 end;
kono
parents:
diff changeset
385 end Set_Subset;
kono
parents:
diff changeset
386
kono
parents:
diff changeset
387 -------------
kono
parents:
diff changeset
388 -- Overlap --
kono
parents:
diff changeset
389 -------------
kono
parents:
diff changeset
390
kono
parents:
diff changeset
391 function Set_Overlap (Left, Right : Set_Type) return Boolean is
kono
parents:
diff changeset
392 begin
kono
parents:
diff changeset
393 if Left'Address = Right'Address then
kono
parents:
diff changeset
394 return Left.Length /= 0;
kono
parents:
diff changeset
395 end if;
kono
parents:
diff changeset
396
kono
parents:
diff changeset
397 -- Per AI05-0022, the container implementation is required to detect
kono
parents:
diff changeset
398 -- element tampering by a generic actual subprogram.
kono
parents:
diff changeset
399
kono
parents:
diff changeset
400 declare
kono
parents:
diff changeset
401 Lock_Left : With_Lock (Left.TC'Unrestricted_Access);
kono
parents:
diff changeset
402 Lock_Right : With_Lock (Right.TC'Unrestricted_Access);
kono
parents:
diff changeset
403
kono
parents:
diff changeset
404 L_Node : Count_Type;
kono
parents:
diff changeset
405 R_Node : Count_Type;
kono
parents:
diff changeset
406 begin
kono
parents:
diff changeset
407 L_Node := Left.First;
kono
parents:
diff changeset
408 R_Node := Right.First;
kono
parents:
diff changeset
409 loop
kono
parents:
diff changeset
410 if L_Node = 0
kono
parents:
diff changeset
411 or else R_Node = 0
kono
parents:
diff changeset
412 then
kono
parents:
diff changeset
413 return False;
kono
parents:
diff changeset
414 end if;
kono
parents:
diff changeset
415
kono
parents:
diff changeset
416 if Is_Less (Left.Nodes (L_Node), Right.Nodes (R_Node)) then
kono
parents:
diff changeset
417 L_Node := Tree_Operations.Next (Left, L_Node);
kono
parents:
diff changeset
418 elsif Is_Less (Right.Nodes (R_Node), Left.Nodes (L_Node)) then
kono
parents:
diff changeset
419 R_Node := Tree_Operations.Next (Right, R_Node);
kono
parents:
diff changeset
420 else
kono
parents:
diff changeset
421 return True;
kono
parents:
diff changeset
422 end if;
kono
parents:
diff changeset
423 end loop;
kono
parents:
diff changeset
424 end;
kono
parents:
diff changeset
425 end Set_Overlap;
kono
parents:
diff changeset
426
kono
parents:
diff changeset
427 --------------------------
kono
parents:
diff changeset
428 -- Symmetric_Difference --
kono
parents:
diff changeset
429 --------------------------
kono
parents:
diff changeset
430
kono
parents:
diff changeset
431 procedure Set_Symmetric_Difference
kono
parents:
diff changeset
432 (Target : in out Set_Type;
kono
parents:
diff changeset
433 Source : Set_Type)
kono
parents:
diff changeset
434 is
kono
parents:
diff changeset
435 Tgt : Count_Type;
kono
parents:
diff changeset
436 Src : Count_Type;
kono
parents:
diff changeset
437
kono
parents:
diff changeset
438 New_Tgt_Node : Count_Type;
kono
parents:
diff changeset
439 pragma Warnings (Off, New_Tgt_Node);
kono
parents:
diff changeset
440
kono
parents:
diff changeset
441 Compare : Integer;
kono
parents:
diff changeset
442
kono
parents:
diff changeset
443 begin
kono
parents:
diff changeset
444 if Target'Address = Source'Address then
kono
parents:
diff changeset
445 Tree_Operations.Clear_Tree (Target);
kono
parents:
diff changeset
446 return;
kono
parents:
diff changeset
447 end if;
kono
parents:
diff changeset
448
kono
parents:
diff changeset
449 Tgt := Target.First;
kono
parents:
diff changeset
450 Src := Source.First;
kono
parents:
diff changeset
451 loop
kono
parents:
diff changeset
452 if Tgt = 0 then
kono
parents:
diff changeset
453 while Src /= 0 loop
kono
parents:
diff changeset
454 Insert_With_Hint
kono
parents:
diff changeset
455 (Dst_Set => Target,
kono
parents:
diff changeset
456 Dst_Hint => 0,
kono
parents:
diff changeset
457 Src_Node => Source.Nodes (Src),
kono
parents:
diff changeset
458 Dst_Node => New_Tgt_Node);
kono
parents:
diff changeset
459
kono
parents:
diff changeset
460 Src := Tree_Operations.Next (Source, Src);
kono
parents:
diff changeset
461 end loop;
kono
parents:
diff changeset
462
kono
parents:
diff changeset
463 return;
kono
parents:
diff changeset
464 end if;
kono
parents:
diff changeset
465
kono
parents:
diff changeset
466 if Src = 0 then
kono
parents:
diff changeset
467 return;
kono
parents:
diff changeset
468 end if;
kono
parents:
diff changeset
469
kono
parents:
diff changeset
470 -- Per AI05-0022, the container implementation is required to detect
kono
parents:
diff changeset
471 -- element tampering by a generic actual subprogram.
kono
parents:
diff changeset
472
kono
parents:
diff changeset
473 declare
kono
parents:
diff changeset
474 Lock_Target : With_Lock (Target.TC'Unrestricted_Access);
kono
parents:
diff changeset
475 Lock_Source : With_Lock (Source.TC'Unrestricted_Access);
kono
parents:
diff changeset
476 begin
kono
parents:
diff changeset
477 if Is_Less (Target.Nodes (Tgt), Source.Nodes (Src)) then
kono
parents:
diff changeset
478 Compare := -1;
kono
parents:
diff changeset
479 elsif Is_Less (Source.Nodes (Src), Target.Nodes (Tgt)) then
kono
parents:
diff changeset
480 Compare := 1;
kono
parents:
diff changeset
481 else
kono
parents:
diff changeset
482 Compare := 0;
kono
parents:
diff changeset
483 end if;
kono
parents:
diff changeset
484 end;
kono
parents:
diff changeset
485
kono
parents:
diff changeset
486 if Compare < 0 then
kono
parents:
diff changeset
487 Tgt := Tree_Operations.Next (Target, Tgt);
kono
parents:
diff changeset
488
kono
parents:
diff changeset
489 elsif Compare > 0 then
kono
parents:
diff changeset
490 Insert_With_Hint
kono
parents:
diff changeset
491 (Dst_Set => Target,
kono
parents:
diff changeset
492 Dst_Hint => Tgt,
kono
parents:
diff changeset
493 Src_Node => Source.Nodes (Src),
kono
parents:
diff changeset
494 Dst_Node => New_Tgt_Node);
kono
parents:
diff changeset
495
kono
parents:
diff changeset
496 Src := Tree_Operations.Next (Source, Src);
kono
parents:
diff changeset
497
kono
parents:
diff changeset
498 else
kono
parents:
diff changeset
499 declare
kono
parents:
diff changeset
500 X : constant Count_Type := Tgt;
kono
parents:
diff changeset
501 begin
kono
parents:
diff changeset
502 Tgt := Tree_Operations.Next (Target, Tgt);
kono
parents:
diff changeset
503
kono
parents:
diff changeset
504 Tree_Operations.Delete_Node_Sans_Free (Target, X);
kono
parents:
diff changeset
505 Tree_Operations.Free (Target, X);
kono
parents:
diff changeset
506 end;
kono
parents:
diff changeset
507
kono
parents:
diff changeset
508 Src := Tree_Operations.Next (Source, Src);
kono
parents:
diff changeset
509 end if;
kono
parents:
diff changeset
510 end loop;
kono
parents:
diff changeset
511 end Set_Symmetric_Difference;
kono
parents:
diff changeset
512
kono
parents:
diff changeset
513 function Set_Symmetric_Difference
kono
parents:
diff changeset
514 (Left, Right : Set_Type) return Set_Type
kono
parents:
diff changeset
515 is
kono
parents:
diff changeset
516 begin
kono
parents:
diff changeset
517 if Left'Address = Right'Address then
kono
parents:
diff changeset
518 return S : Set_Type (0); -- Empty set
kono
parents:
diff changeset
519 end if;
kono
parents:
diff changeset
520
kono
parents:
diff changeset
521 if Right.Length = 0 then
kono
parents:
diff changeset
522 return Copy (Left);
kono
parents:
diff changeset
523 end if;
kono
parents:
diff changeset
524
kono
parents:
diff changeset
525 if Left.Length = 0 then
kono
parents:
diff changeset
526 return Copy (Right);
kono
parents:
diff changeset
527 end if;
kono
parents:
diff changeset
528
kono
parents:
diff changeset
529 return Result : Set_Type (Left.Length + Right.Length) do
kono
parents:
diff changeset
530
kono
parents:
diff changeset
531 -- Per AI05-0022, the container implementation is required to detect
kono
parents:
diff changeset
532 -- element tampering by a generic actual subprogram.
kono
parents:
diff changeset
533
kono
parents:
diff changeset
534 declare
kono
parents:
diff changeset
535 Lock_Left : With_Lock (Left.TC'Unrestricted_Access);
kono
parents:
diff changeset
536 Lock_Right : With_Lock (Right.TC'Unrestricted_Access);
kono
parents:
diff changeset
537
kono
parents:
diff changeset
538 L_Node : Count_Type;
kono
parents:
diff changeset
539 R_Node : Count_Type;
kono
parents:
diff changeset
540
kono
parents:
diff changeset
541 Dst_Node : Count_Type;
kono
parents:
diff changeset
542 pragma Warnings (Off, Dst_Node);
kono
parents:
diff changeset
543
kono
parents:
diff changeset
544 begin
kono
parents:
diff changeset
545 L_Node := Left.First;
kono
parents:
diff changeset
546 R_Node := Right.First;
kono
parents:
diff changeset
547 loop
kono
parents:
diff changeset
548 if L_Node = 0 then
kono
parents:
diff changeset
549 while R_Node /= 0 loop
kono
parents:
diff changeset
550 Insert_With_Hint
kono
parents:
diff changeset
551 (Dst_Set => Result,
kono
parents:
diff changeset
552 Dst_Hint => 0,
kono
parents:
diff changeset
553 Src_Node => Right.Nodes (R_Node),
kono
parents:
diff changeset
554 Dst_Node => Dst_Node);
kono
parents:
diff changeset
555
kono
parents:
diff changeset
556 R_Node := Tree_Operations.Next (Right, R_Node);
kono
parents:
diff changeset
557 end loop;
kono
parents:
diff changeset
558
kono
parents:
diff changeset
559 exit;
kono
parents:
diff changeset
560 end if;
kono
parents:
diff changeset
561
kono
parents:
diff changeset
562 if R_Node = 0 then
kono
parents:
diff changeset
563 while L_Node /= 0 loop
kono
parents:
diff changeset
564 Insert_With_Hint
kono
parents:
diff changeset
565 (Dst_Set => Result,
kono
parents:
diff changeset
566 Dst_Hint => 0,
kono
parents:
diff changeset
567 Src_Node => Left.Nodes (L_Node),
kono
parents:
diff changeset
568 Dst_Node => Dst_Node);
kono
parents:
diff changeset
569
kono
parents:
diff changeset
570 L_Node := Tree_Operations.Next (Left, L_Node);
kono
parents:
diff changeset
571 end loop;
kono
parents:
diff changeset
572
kono
parents:
diff changeset
573 exit;
kono
parents:
diff changeset
574 end if;
kono
parents:
diff changeset
575
kono
parents:
diff changeset
576 if Is_Less (Left.Nodes (L_Node), Right.Nodes (R_Node)) then
kono
parents:
diff changeset
577 Insert_With_Hint
kono
parents:
diff changeset
578 (Dst_Set => Result,
kono
parents:
diff changeset
579 Dst_Hint => 0,
kono
parents:
diff changeset
580 Src_Node => Left.Nodes (L_Node),
kono
parents:
diff changeset
581 Dst_Node => Dst_Node);
kono
parents:
diff changeset
582
kono
parents:
diff changeset
583 L_Node := Tree_Operations.Next (Left, L_Node);
kono
parents:
diff changeset
584
kono
parents:
diff changeset
585 elsif Is_Less (Right.Nodes (R_Node), Left.Nodes (L_Node)) then
kono
parents:
diff changeset
586 Insert_With_Hint
kono
parents:
diff changeset
587 (Dst_Set => Result,
kono
parents:
diff changeset
588 Dst_Hint => 0,
kono
parents:
diff changeset
589 Src_Node => Right.Nodes (R_Node),
kono
parents:
diff changeset
590 Dst_Node => Dst_Node);
kono
parents:
diff changeset
591
kono
parents:
diff changeset
592 R_Node := Tree_Operations.Next (Right, R_Node);
kono
parents:
diff changeset
593
kono
parents:
diff changeset
594 else
kono
parents:
diff changeset
595 L_Node := Tree_Operations.Next (Left, L_Node);
kono
parents:
diff changeset
596 R_Node := Tree_Operations.Next (Right, R_Node);
kono
parents:
diff changeset
597 end if;
kono
parents:
diff changeset
598 end loop;
kono
parents:
diff changeset
599 end;
kono
parents:
diff changeset
600 end return;
kono
parents:
diff changeset
601 end Set_Symmetric_Difference;
kono
parents:
diff changeset
602
kono
parents:
diff changeset
603 -----------
kono
parents:
diff changeset
604 -- Union --
kono
parents:
diff changeset
605 -----------
kono
parents:
diff changeset
606
kono
parents:
diff changeset
607 procedure Set_Union (Target : in out Set_Type; Source : Set_Type) is
kono
parents:
diff changeset
608 Hint : Count_Type := 0;
kono
parents:
diff changeset
609
kono
parents:
diff changeset
610 procedure Process (Node : Count_Type);
kono
parents:
diff changeset
611 pragma Inline (Process);
kono
parents:
diff changeset
612
kono
parents:
diff changeset
613 procedure Iterate is new Tree_Operations.Generic_Iteration (Process);
kono
parents:
diff changeset
614
kono
parents:
diff changeset
615 -------------
kono
parents:
diff changeset
616 -- Process --
kono
parents:
diff changeset
617 -------------
kono
parents:
diff changeset
618
kono
parents:
diff changeset
619 procedure Process (Node : Count_Type) is
kono
parents:
diff changeset
620 begin
kono
parents:
diff changeset
621 Insert_With_Hint
kono
parents:
diff changeset
622 (Dst_Set => Target,
kono
parents:
diff changeset
623 Dst_Hint => Hint,
kono
parents:
diff changeset
624 Src_Node => Source.Nodes (Node),
kono
parents:
diff changeset
625 Dst_Node => Hint);
kono
parents:
diff changeset
626 end Process;
kono
parents:
diff changeset
627
kono
parents:
diff changeset
628 -- Start of processing for Union
kono
parents:
diff changeset
629
kono
parents:
diff changeset
630 begin
kono
parents:
diff changeset
631 if Target'Address = Source'Address then
kono
parents:
diff changeset
632 return;
kono
parents:
diff changeset
633 end if;
kono
parents:
diff changeset
634
kono
parents:
diff changeset
635 -- Per AI05-0022, the container implementation is required to detect
kono
parents:
diff changeset
636 -- element tampering by a generic actual subprogram.
kono
parents:
diff changeset
637
kono
parents:
diff changeset
638 declare
kono
parents:
diff changeset
639 Lock_Source : With_Lock (Source.TC'Unrestricted_Access);
kono
parents:
diff changeset
640 begin
kono
parents:
diff changeset
641 -- Note that there's no way to decide a priori whether the target has
kono
parents:
diff changeset
642 -- enough capacity for the union with source. We cannot simply
kono
parents:
diff changeset
643 -- compare the sum of the existing lengths to the capacity of the
kono
parents:
diff changeset
644 -- target, because equivalent items from source are not included in
kono
parents:
diff changeset
645 -- the union.
kono
parents:
diff changeset
646
kono
parents:
diff changeset
647 Iterate (Source);
kono
parents:
diff changeset
648 end;
kono
parents:
diff changeset
649 end Set_Union;
kono
parents:
diff changeset
650
kono
parents:
diff changeset
651 function Set_Union (Left, Right : Set_Type) return Set_Type is
kono
parents:
diff changeset
652 begin
kono
parents:
diff changeset
653 if Left'Address = Right'Address then
kono
parents:
diff changeset
654 return Copy (Left);
kono
parents:
diff changeset
655 end if;
kono
parents:
diff changeset
656
kono
parents:
diff changeset
657 if Left.Length = 0 then
kono
parents:
diff changeset
658 return Copy (Right);
kono
parents:
diff changeset
659 end if;
kono
parents:
diff changeset
660
kono
parents:
diff changeset
661 if Right.Length = 0 then
kono
parents:
diff changeset
662 return Copy (Left);
kono
parents:
diff changeset
663 end if;
kono
parents:
diff changeset
664
kono
parents:
diff changeset
665 return Result : Set_Type (Left.Length + Right.Length) do
kono
parents:
diff changeset
666 declare
kono
parents:
diff changeset
667 Lock_Left : With_Lock (Left.TC'Unrestricted_Access);
kono
parents:
diff changeset
668 Lock_Right : With_Lock (Right.TC'Unrestricted_Access);
kono
parents:
diff changeset
669 begin
kono
parents:
diff changeset
670 Assign (Target => Result, Source => Left);
kono
parents:
diff changeset
671
kono
parents:
diff changeset
672 Insert_Right : declare
kono
parents:
diff changeset
673 Hint : Count_Type := 0;
kono
parents:
diff changeset
674
kono
parents:
diff changeset
675 procedure Process (Node : Count_Type);
kono
parents:
diff changeset
676 pragma Inline (Process);
kono
parents:
diff changeset
677
kono
parents:
diff changeset
678 procedure Iterate is
kono
parents:
diff changeset
679 new Tree_Operations.Generic_Iteration (Process);
kono
parents:
diff changeset
680
kono
parents:
diff changeset
681 -------------
kono
parents:
diff changeset
682 -- Process --
kono
parents:
diff changeset
683 -------------
kono
parents:
diff changeset
684
kono
parents:
diff changeset
685 procedure Process (Node : Count_Type) is
kono
parents:
diff changeset
686 begin
kono
parents:
diff changeset
687 Insert_With_Hint
kono
parents:
diff changeset
688 (Dst_Set => Result,
kono
parents:
diff changeset
689 Dst_Hint => Hint,
kono
parents:
diff changeset
690 Src_Node => Right.Nodes (Node),
kono
parents:
diff changeset
691 Dst_Node => Hint);
kono
parents:
diff changeset
692 end Process;
kono
parents:
diff changeset
693
kono
parents:
diff changeset
694 -- Start of processing for Insert_Right
kono
parents:
diff changeset
695
kono
parents:
diff changeset
696 begin
kono
parents:
diff changeset
697 Iterate (Right);
kono
parents:
diff changeset
698 end Insert_Right;
kono
parents:
diff changeset
699 end;
kono
parents:
diff changeset
700 end return;
kono
parents:
diff changeset
701 end Set_Union;
kono
parents:
diff changeset
702
kono
parents:
diff changeset
703 end Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations;