OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [ada/] [a-ciormu.adb] - Blame information for rev 287

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 281 jeremybenn
------------------------------------------------------------------------------
2
--                                                                          --
3
--                         GNAT LIBRARY COMPONENTS                          --
4
--                                                                          --
5
--               ADA.CONTAINERS.INDEFINITE_ORDERED_MULTISETS                --
6
--                                                                          --
7
--                                 B o d y                                  --
8
--                                                                          --
9
--          Copyright (C) 2004-2009, 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
--                                                                          --
27
-- This unit was originally developed by Matthew J Heaney.                  --
28
------------------------------------------------------------------------------
29
 
30
with Ada.Unchecked_Deallocation;
31
 
32
with Ada.Containers.Red_Black_Trees.Generic_Operations;
33
pragma Elaborate_All (Ada.Containers.Red_Black_Trees.Generic_Operations);
34
 
35
with Ada.Containers.Red_Black_Trees.Generic_Keys;
36
pragma Elaborate_All (Ada.Containers.Red_Black_Trees.Generic_Keys);
37
 
38
with Ada.Containers.Red_Black_Trees.Generic_Set_Operations;
39
pragma Elaborate_All (Ada.Containers.Red_Black_Trees.Generic_Set_Operations);
40
 
41
package body Ada.Containers.Indefinite_Ordered_Multisets is
42
 
43
   -----------------------------
44
   -- Node Access Subprograms --
45
   -----------------------------
46
 
47
   --  These subprograms provide a functional interface to access fields
48
   --  of a node, and a procedural interface for modifying these values.
49
 
50
   function Color (Node : Node_Access) return Color_Type;
51
   pragma Inline (Color);
52
 
53
   function Left (Node : Node_Access) return Node_Access;
54
   pragma Inline (Left);
55
 
56
   function Parent (Node : Node_Access) return Node_Access;
57
   pragma Inline (Parent);
58
 
59
   function Right (Node : Node_Access) return Node_Access;
60
   pragma Inline (Right);
61
 
62
   procedure Set_Parent (Node : Node_Access; Parent : Node_Access);
63
   pragma Inline (Set_Parent);
64
 
65
   procedure Set_Left (Node : Node_Access; Left : Node_Access);
66
   pragma Inline (Set_Left);
67
 
68
   procedure Set_Right (Node : Node_Access; Right : Node_Access);
69
   pragma Inline (Set_Right);
70
 
71
   procedure Set_Color (Node : Node_Access; Color : Color_Type);
72
   pragma Inline (Set_Color);
73
 
74
   -----------------------
75
   -- Local Subprograms --
76
   -----------------------
77
 
78
   function Copy_Node (Source : Node_Access) return Node_Access;
79
   pragma Inline (Copy_Node);
80
 
81
   procedure Free (X : in out Node_Access);
82
 
83
   procedure Insert_Sans_Hint
84
     (Tree     : in out Tree_Type;
85
      New_Item : Element_Type;
86
      Node     : out Node_Access);
87
 
88
   procedure Insert_With_Hint
89
     (Dst_Tree : in out Tree_Type;
90
      Dst_Hint : Node_Access;
91
      Src_Node : Node_Access;
92
      Dst_Node : out Node_Access);
93
 
94
   function Is_Equal_Node_Node (L, R : Node_Access) return Boolean;
95
   pragma Inline (Is_Equal_Node_Node);
96
 
97
   function Is_Greater_Element_Node
98
     (Left  : Element_Type;
99
      Right : Node_Access) return Boolean;
100
   pragma Inline (Is_Greater_Element_Node);
101
 
102
   function Is_Less_Element_Node
103
     (Left  : Element_Type;
104
      Right : Node_Access) return Boolean;
105
   pragma Inline (Is_Less_Element_Node);
106
 
107
   function Is_Less_Node_Node (L, R : Node_Access) return Boolean;
108
   pragma Inline (Is_Less_Node_Node);
109
 
110
   procedure Replace_Element
111
     (Tree : in out Tree_Type;
112
      Node : Node_Access;
113
      Item : Element_Type);
114
 
115
   --------------------------
116
   -- Local Instantiations --
117
   --------------------------
118
 
119
   package Tree_Operations is
120
     new Red_Black_Trees.Generic_Operations (Tree_Types);
121
 
122
   procedure Delete_Tree is
123
     new Tree_Operations.Generic_Delete_Tree (Free);
124
 
125
   function Copy_Tree is
126
     new Tree_Operations.Generic_Copy_Tree (Copy_Node, Delete_Tree);
127
 
128
   use Tree_Operations;
129
 
130
   procedure Free_Element is
131
     new Ada.Unchecked_Deallocation (Element_Type, Element_Access);
132
 
133
   function Is_Equal is
134
     new Tree_Operations.Generic_Equal (Is_Equal_Node_Node);
135
 
136
   package Set_Ops is
137
     new Generic_Set_Operations
138
       (Tree_Operations  => Tree_Operations,
139
        Insert_With_Hint => Insert_With_Hint,
140
        Copy_Tree        => Copy_Tree,
141
        Delete_Tree      => Delete_Tree,
142
        Is_Less          => Is_Less_Node_Node,
143
        Free             => Free);
144
 
145
   package Element_Keys is
146
     new Red_Black_Trees.Generic_Keys
147
       (Tree_Operations     => Tree_Operations,
148
        Key_Type            => Element_Type,
149
        Is_Less_Key_Node    => Is_Less_Element_Node,
150
        Is_Greater_Key_Node => Is_Greater_Element_Node);
151
 
152
   ---------
153
   -- "<" --
154
   ---------
155
 
156
   function "<" (Left, Right : Cursor) return Boolean is
157
   begin
158
      if Left.Node = null then
159
         raise Constraint_Error with "Left cursor equals No_Element";
160
      end if;
161
 
162
      if Right.Node = null then
163
         raise Constraint_Error with "Right cursor equals No_Element";
164
      end if;
165
 
166
      if Left.Node.Element = null then
167
         raise Program_Error with "Left cursor is bad";
168
      end if;
169
 
170
      if Right.Node.Element = null then
171
         raise Program_Error with "Right cursor is bad";
172
      end if;
173
 
174
      pragma Assert (Vet (Left.Container.Tree, Left.Node),
175
                     "bad Left cursor in ""<""");
176
 
177
      pragma Assert (Vet (Right.Container.Tree, Right.Node),
178
                     "bad Right cursor in ""<""");
179
 
180
      return Left.Node.Element.all < Right.Node.Element.all;
181
   end "<";
182
 
183
   function "<" (Left : Cursor; Right : Element_Type) return Boolean is
184
   begin
185
      if Left.Node = null then
186
         raise Constraint_Error with "Left cursor equals No_Element";
187
      end if;
188
 
189
      if Left.Node.Element = null then
190
         raise Program_Error with "Left cursor is bad";
191
      end if;
192
 
193
      pragma Assert (Vet (Left.Container.Tree, Left.Node),
194
                     "bad Left cursor in ""<""");
195
 
196
      return Left.Node.Element.all < Right;
197
   end "<";
198
 
199
   function "<" (Left : Element_Type; Right : Cursor) return Boolean is
200
   begin
201
      if Right.Node = null then
202
         raise Constraint_Error with "Right cursor equals No_Element";
203
      end if;
204
 
205
      if Right.Node.Element = null then
206
         raise Program_Error with "Right cursor is bad";
207
      end if;
208
 
209
      pragma Assert (Vet (Right.Container.Tree, Right.Node),
210
                     "bad Right cursor in ""<""");
211
 
212
      return Left < Right.Node.Element.all;
213
   end "<";
214
 
215
   ---------
216
   -- "=" --
217
   ---------
218
 
219
   function "=" (Left, Right : Set) return Boolean is
220
   begin
221
      return Is_Equal (Left.Tree, Right.Tree);
222
   end "=";
223
 
224
   ---------
225
   -- ">" --
226
   ---------
227
 
228
   function ">" (Left, Right : Cursor) return Boolean is
229
   begin
230
      if Left.Node = null then
231
         raise Constraint_Error with "Left cursor equals No_Element";
232
      end if;
233
 
234
      if Right.Node = null then
235
         raise Constraint_Error with "Right cursor equals No_Element";
236
      end if;
237
 
238
      if Left.Node.Element = null then
239
         raise Program_Error with "Left cursor is bad";
240
      end if;
241
 
242
      if Right.Node.Element = null then
243
         raise Program_Error with "Right cursor is bad";
244
      end if;
245
 
246
      pragma Assert (Vet (Left.Container.Tree, Left.Node),
247
                     "bad Left cursor in "">""");
248
 
249
      pragma Assert (Vet (Right.Container.Tree, Right.Node),
250
                     "bad Right cursor in "">""");
251
 
252
      --  L > R same as R < L
253
 
254
      return Right.Node.Element.all < Left.Node.Element.all;
255
   end ">";
256
 
257
   function ">" (Left : Cursor; Right : Element_Type) return Boolean is
258
   begin
259
      if Left.Node = null then
260
         raise Constraint_Error with "Left cursor equals No_Element";
261
      end if;
262
 
263
      if Left.Node.Element = null then
264
         raise Program_Error with "Left cursor is bad";
265
      end if;
266
 
267
      pragma Assert (Vet (Left.Container.Tree, Left.Node),
268
                     "bad Left cursor in "">""");
269
 
270
      return Right < Left.Node.Element.all;
271
   end ">";
272
 
273
   function ">" (Left : Element_Type; Right : Cursor) return Boolean is
274
   begin
275
      if Right.Node = null then
276
         raise Constraint_Error with "Right cursor equals No_Element";
277
      end if;
278
 
279
      if Right.Node.Element = null then
280
         raise Program_Error with "Right cursor is bad";
281
      end if;
282
 
283
      pragma Assert (Vet (Right.Container.Tree, Right.Node),
284
                     "bad Right cursor in "">""");
285
 
286
      return Right.Node.Element.all < Left;
287
   end ">";
288
 
289
   ------------
290
   -- Adjust --
291
   ------------
292
 
293
   procedure Adjust is
294
      new Tree_Operations.Generic_Adjust (Copy_Tree);
295
 
296
   procedure Adjust (Container : in out Set) is
297
   begin
298
      Adjust (Container.Tree);
299
   end Adjust;
300
 
301
   -------------
302
   -- Ceiling --
303
   -------------
304
 
305
   function Ceiling (Container : Set; Item : Element_Type) return Cursor is
306
      Node : constant Node_Access :=
307
               Element_Keys.Ceiling (Container.Tree, Item);
308
 
309
   begin
310
      if Node = null then
311
         return No_Element;
312
      end if;
313
 
314
      return Cursor'(Container'Unrestricted_Access, Node);
315
   end Ceiling;
316
 
317
   -----------
318
   -- Clear --
319
   -----------
320
 
321
   procedure Clear is
322
      new Tree_Operations.Generic_Clear (Delete_Tree);
323
 
324
   procedure Clear (Container : in out Set) is
325
   begin
326
      Clear (Container.Tree);
327
   end Clear;
328
 
329
   -----------
330
   -- Color --
331
   -----------
332
 
333
   function Color (Node : Node_Access) return Color_Type is
334
   begin
335
      return Node.Color;
336
   end Color;
337
 
338
   --------------
339
   -- Contains --
340
   --------------
341
 
342
   function Contains (Container : Set; Item : Element_Type) return Boolean is
343
   begin
344
      return Find (Container, Item) /= No_Element;
345
   end Contains;
346
 
347
   ---------------
348
   -- Copy_Node --
349
   ---------------
350
 
351
   function Copy_Node (Source : Node_Access) return Node_Access is
352
      X : Element_Access := new Element_Type'(Source.Element.all);
353
 
354
   begin
355
      return new Node_Type'(Parent  => null,
356
                            Left    => null,
357
                            Right   => null,
358
                            Color   => Source.Color,
359
                            Element => X);
360
 
361
   exception
362
      when others =>
363
         Free_Element (X);
364
         raise;
365
   end Copy_Node;
366
 
367
   ------------
368
   -- Delete --
369
   ------------
370
 
371
   procedure Delete (Container : in out Set; Item : Element_Type) is
372
      Tree : Tree_Type renames Container.Tree;
373
      Node : Node_Access := Element_Keys.Ceiling (Tree, Item);
374
      Done : constant Node_Access := Element_Keys.Upper_Bound (Tree, Item);
375
      X    : Node_Access;
376
 
377
   begin
378
      if Node = Done then
379
         raise Constraint_Error with "attempt to delete element not in set";
380
      end if;
381
 
382
      loop
383
         X := Node;
384
         Node := Tree_Operations.Next (Node);
385
         Tree_Operations.Delete_Node_Sans_Free (Tree, X);
386
         Free (X);
387
 
388
         exit when Node = Done;
389
      end loop;
390
   end Delete;
391
 
392
   procedure Delete (Container : in out Set; Position : in out Cursor) is
393
   begin
394
      if Position.Node = null then
395
         raise Constraint_Error with "Position cursor equals No_Element";
396
      end if;
397
 
398
      if Position.Node.Element = null then
399
         raise Program_Error with "Position cursor is bad";
400
      end if;
401
 
402
      if Position.Container /= Container'Unrestricted_Access then
403
         raise Program_Error with "Position cursor designates wrong set";
404
      end if;
405
 
406
      pragma Assert (Vet (Container.Tree, Position.Node),
407
                     "bad cursor in Delete");
408
 
409
      Tree_Operations.Delete_Node_Sans_Free (Container.Tree, Position.Node);
410
      Free (Position.Node);
411
 
412
      Position.Container := null;
413
   end Delete;
414
 
415
   ------------------
416
   -- Delete_First --
417
   ------------------
418
 
419
   procedure Delete_First (Container : in out Set) is
420
      Tree : Tree_Type renames Container.Tree;
421
      X    : Node_Access := Tree.First;
422
 
423
   begin
424
      if X = null then
425
         return;
426
      end if;
427
 
428
      Tree_Operations.Delete_Node_Sans_Free (Tree, X);
429
      Free (X);
430
   end Delete_First;
431
 
432
   -----------------
433
   -- Delete_Last --
434
   -----------------
435
 
436
   procedure Delete_Last (Container : in out Set) is
437
      Tree : Tree_Type renames Container.Tree;
438
      X    : Node_Access := Tree.Last;
439
 
440
   begin
441
      if X = null then
442
         return;
443
      end if;
444
 
445
      Tree_Operations.Delete_Node_Sans_Free (Tree, X);
446
      Free (X);
447
   end Delete_Last;
448
 
449
   ----------------
450
   -- Difference --
451
   ----------------
452
 
453
   procedure Difference (Target : in out Set; Source : Set) is
454
   begin
455
      Set_Ops.Difference (Target.Tree, Source.Tree);
456
   end Difference;
457
 
458
   function Difference (Left, Right : Set) return Set is
459
      Tree : constant Tree_Type :=
460
               Set_Ops.Difference (Left.Tree, Right.Tree);
461
   begin
462
      return Set'(Controlled with Tree);
463
   end Difference;
464
 
465
   -------------
466
   -- Element --
467
   -------------
468
 
469
   function Element (Position : Cursor) return Element_Type is
470
   begin
471
      if Position.Node = null then
472
         raise Constraint_Error with "Position cursor equals No_Element";
473
      end if;
474
 
475
      if Position.Node.Element = null then
476
         raise Program_Error with "Position cursor is bad";
477
      end if;
478
 
479
      pragma Assert (Vet (Position.Container.Tree, Position.Node),
480
                     "bad cursor in Element");
481
 
482
      return Position.Node.Element.all;
483
   end Element;
484
 
485
   -------------------------
486
   -- Equivalent_Elements --
487
   -------------------------
488
 
489
   function Equivalent_Elements (Left, Right : Element_Type) return Boolean is
490
   begin
491
      if Left < Right
492
        or else Right < Left
493
      then
494
         return False;
495
      else
496
         return True;
497
      end if;
498
   end Equivalent_Elements;
499
 
500
   ---------------------
501
   -- Equivalent_Sets --
502
   ---------------------
503
 
504
   function Equivalent_Sets (Left, Right : Set) return Boolean is
505
 
506
      function Is_Equivalent_Node_Node (L, R : Node_Access) return Boolean;
507
      pragma Inline (Is_Equivalent_Node_Node);
508
 
509
      function Is_Equivalent is
510
         new Tree_Operations.Generic_Equal (Is_Equivalent_Node_Node);
511
 
512
      -----------------------------
513
      -- Is_Equivalent_Node_Node --
514
      -----------------------------
515
 
516
      function Is_Equivalent_Node_Node (L, R : Node_Access) return Boolean is
517
      begin
518
         if L.Element.all < R.Element.all then
519
            return False;
520
         elsif R.Element.all < L.Element.all then
521
            return False;
522
         else
523
            return True;
524
         end if;
525
      end Is_Equivalent_Node_Node;
526
 
527
   --  Start of processing for Equivalent_Sets
528
 
529
   begin
530
      return Is_Equivalent (Left.Tree, Right.Tree);
531
   end Equivalent_Sets;
532
 
533
   -------------
534
   -- Exclude --
535
   -------------
536
 
537
   procedure Exclude (Container : in out Set; Item : Element_Type) is
538
      Tree : Tree_Type renames Container.Tree;
539
      Node : Node_Access := Element_Keys.Ceiling (Tree, Item);
540
      Done : constant Node_Access := Element_Keys.Upper_Bound (Tree, Item);
541
      X    : Node_Access;
542
 
543
   begin
544
      while Node /= Done loop
545
         X := Node;
546
         Node := Tree_Operations.Next (Node);
547
         Tree_Operations.Delete_Node_Sans_Free (Tree, X);
548
         Free (X);
549
      end loop;
550
   end Exclude;
551
 
552
   ----------
553
   -- Find --
554
   ----------
555
 
556
   function Find (Container : Set; Item : Element_Type) return Cursor is
557
      Node : constant Node_Access :=
558
               Element_Keys.Find (Container.Tree, Item);
559
 
560
   begin
561
      if Node = null then
562
         return No_Element;
563
      end if;
564
 
565
      return Cursor'(Container'Unrestricted_Access, Node);
566
   end Find;
567
 
568
   -----------
569
   -- First --
570
   -----------
571
 
572
   function First (Container : Set) return Cursor is
573
   begin
574
      if Container.Tree.First = null then
575
         return No_Element;
576
      end if;
577
 
578
      return Cursor'(Container'Unrestricted_Access, Container.Tree.First);
579
   end First;
580
 
581
   -------------------
582
   -- First_Element --
583
   -------------------
584
 
585
   function First_Element (Container : Set) return Element_Type is
586
   begin
587
      if Container.Tree.First = null then
588
         raise Constraint_Error with "set is empty";
589
      end if;
590
 
591
      pragma Assert (Container.Tree.First.Element /= null);
592
      return Container.Tree.First.Element.all;
593
   end First_Element;
594
 
595
   -----------
596
   -- Floor --
597
   -----------
598
 
599
   function Floor (Container : Set; Item : Element_Type) return Cursor is
600
      Node : constant Node_Access :=
601
               Element_Keys.Floor (Container.Tree, Item);
602
 
603
   begin
604
      if Node = null then
605
         return No_Element;
606
      end if;
607
 
608
      return Cursor'(Container'Unrestricted_Access, Node);
609
   end Floor;
610
 
611
   ----------
612
   -- Free --
613
   ----------
614
 
615
   procedure Free (X : in out Node_Access) is
616
      procedure Deallocate is
617
        new Ada.Unchecked_Deallocation (Node_Type, Node_Access);
618
 
619
   begin
620
      if X = null then
621
         return;
622
      end if;
623
 
624
      X.Parent := X;
625
      X.Left := X;
626
      X.Right := X;
627
 
628
      begin
629
         Free_Element (X.Element);
630
      exception
631
         when others =>
632
            X.Element := null;
633
            Deallocate (X);
634
            raise;
635
      end;
636
 
637
      Deallocate (X);
638
   end Free;
639
 
640
   ------------------
641
   -- Generic_Keys --
642
   ------------------
643
 
644
   package body Generic_Keys is
645
 
646
      -----------------------
647
      -- Local Subprograms --
648
      -----------------------
649
 
650
      function Is_Less_Key_Node
651
        (Left  : Key_Type;
652
         Right : Node_Access) return Boolean;
653
      pragma Inline (Is_Less_Key_Node);
654
 
655
      function Is_Greater_Key_Node
656
        (Left  : Key_Type;
657
         Right : Node_Access) return Boolean;
658
      pragma Inline (Is_Greater_Key_Node);
659
 
660
      --------------------------
661
      -- Local Instantiations --
662
      --------------------------
663
 
664
      package Key_Keys is
665
        new Red_Black_Trees.Generic_Keys
666
          (Tree_Operations     => Tree_Operations,
667
           Key_Type            => Key_Type,
668
           Is_Less_Key_Node    => Is_Less_Key_Node,
669
           Is_Greater_Key_Node => Is_Greater_Key_Node);
670
 
671
      -------------
672
      -- Ceiling --
673
      -------------
674
 
675
      function Ceiling (Container : Set; Key : Key_Type) return Cursor is
676
         Node : constant Node_Access :=
677
                  Key_Keys.Ceiling (Container.Tree, Key);
678
 
679
      begin
680
         if Node = null then
681
            return No_Element;
682
         end if;
683
 
684
         return Cursor'(Container'Unrestricted_Access, Node);
685
      end Ceiling;
686
 
687
      --------------
688
      -- Contains --
689
      --------------
690
 
691
      function Contains (Container : Set; Key : Key_Type) return Boolean is
692
      begin
693
         return Find (Container, Key) /= No_Element;
694
      end Contains;
695
 
696
      ------------
697
      -- Delete --
698
      ------------
699
 
700
      procedure Delete (Container : in out Set; Key : Key_Type) is
701
         Tree : Tree_Type renames Container.Tree;
702
         Node : Node_Access := Key_Keys.Ceiling (Tree, Key);
703
         Done : constant Node_Access := Key_Keys.Upper_Bound (Tree, Key);
704
         X    : Node_Access;
705
 
706
      begin
707
         if Node = Done then
708
            raise Constraint_Error with "attempt to delete key not in set";
709
         end if;
710
 
711
         loop
712
            X := Node;
713
            Node := Tree_Operations.Next (Node);
714
            Tree_Operations.Delete_Node_Sans_Free (Tree, X);
715
            Free (X);
716
 
717
            exit when Node = Done;
718
         end loop;
719
      end Delete;
720
 
721
      -------------
722
      -- Element --
723
      -------------
724
 
725
      function Element (Container : Set; Key : Key_Type) return Element_Type is
726
         Node : constant Node_Access :=
727
                  Key_Keys.Find (Container.Tree, Key);
728
 
729
      begin
730
         if Node = null then
731
            raise Constraint_Error with "key not in set";
732
         end if;
733
 
734
         return Node.Element.all;
735
      end Element;
736
 
737
      ---------------------
738
      -- Equivalent_Keys --
739
      ---------------------
740
 
741
      function Equivalent_Keys (Left, Right : Key_Type) return Boolean is
742
      begin
743
         if Left < Right
744
           or else Right < Left
745
         then
746
            return False;
747
         else
748
            return True;
749
         end if;
750
      end Equivalent_Keys;
751
 
752
      -------------
753
      -- Exclude --
754
      -------------
755
 
756
      procedure Exclude (Container : in out Set; Key : Key_Type) is
757
         Tree : Tree_Type renames Container.Tree;
758
         Node : Node_Access := Key_Keys.Ceiling (Tree, Key);
759
         Done : constant Node_Access := Key_Keys.Upper_Bound (Tree, Key);
760
         X    : Node_Access;
761
 
762
      begin
763
         while Node /= Done loop
764
            X := Node;
765
            Node := Tree_Operations.Next (Node);
766
            Tree_Operations.Delete_Node_Sans_Free (Tree, X);
767
            Free (X);
768
         end loop;
769
      end Exclude;
770
 
771
      ----------
772
      -- Find --
773
      ----------
774
 
775
      function Find (Container : Set; Key : Key_Type) return Cursor is
776
         Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key);
777
 
778
      begin
779
         if Node = null then
780
            return No_Element;
781
         end if;
782
 
783
         return Cursor'(Container'Unrestricted_Access, Node);
784
      end Find;
785
 
786
      -----------
787
      -- Floor --
788
      -----------
789
 
790
      function Floor (Container : Set; Key : Key_Type) return Cursor is
791
         Node : constant Node_Access := Key_Keys.Floor (Container.Tree, Key);
792
 
793
      begin
794
         if Node = null then
795
            return No_Element;
796
         end if;
797
 
798
         return Cursor'(Container'Unrestricted_Access, Node);
799
      end Floor;
800
 
801
      -------------------------
802
      -- Is_Greater_Key_Node --
803
      -------------------------
804
 
805
      function Is_Greater_Key_Node
806
        (Left  : Key_Type;
807
         Right : Node_Access) return Boolean
808
      is
809
      begin
810
         return Key (Right.Element.all) < Left;
811
      end Is_Greater_Key_Node;
812
 
813
      ----------------------
814
      -- Is_Less_Key_Node --
815
      ----------------------
816
 
817
      function Is_Less_Key_Node
818
        (Left  : Key_Type;
819
         Right : Node_Access) return Boolean
820
      is
821
      begin
822
         return Left < Key (Right.Element.all);
823
      end Is_Less_Key_Node;
824
 
825
      -------------
826
      -- Iterate --
827
      -------------
828
 
829
      procedure Iterate
830
        (Container : Set;
831
         Key       : Key_Type;
832
         Process   : not null access procedure (Position : Cursor))
833
      is
834
         procedure Process_Node (Node : Node_Access);
835
         pragma Inline (Process_Node);
836
 
837
         procedure Local_Iterate is
838
           new Key_Keys.Generic_Iteration (Process_Node);
839
 
840
         ------------------
841
         -- Process_Node --
842
         ------------------
843
 
844
         procedure Process_Node (Node : Node_Access) is
845
         begin
846
            Process (Cursor'(Container'Unrestricted_Access, Node));
847
         end Process_Node;
848
 
849
         T : Tree_Type renames Container.Tree'Unrestricted_Access.all;
850
         B : Natural renames T.Busy;
851
 
852
      --  Start of processing for Iterate
853
 
854
      begin
855
         B := B + 1;
856
 
857
         begin
858
            Local_Iterate (T, Key);
859
         exception
860
            when others =>
861
               B := B - 1;
862
               raise;
863
         end;
864
 
865
         B := B - 1;
866
      end Iterate;
867
 
868
      ---------
869
      -- Key --
870
      ---------
871
 
872
      function Key (Position : Cursor) return Key_Type is
873
      begin
874
         if Position.Node = null then
875
            raise Constraint_Error with
876
              "Position cursor equals No_Element";
877
         end if;
878
 
879
         if Position.Node.Element = null then
880
            raise Program_Error with
881
              "Position cursor is bad";
882
         end if;
883
 
884
         pragma Assert (Vet (Position.Container.Tree, Position.Node),
885
                        "bad cursor in Key");
886
 
887
         return Key (Position.Node.Element.all);
888
      end Key;
889
 
890
      ---------------------
891
      -- Reverse_Iterate --
892
      ---------------------
893
 
894
      procedure Reverse_Iterate
895
        (Container : Set;
896
         Key       : Key_Type;
897
         Process   : not null access procedure (Position : Cursor))
898
      is
899
         procedure Process_Node (Node : Node_Access);
900
         pragma Inline (Process_Node);
901
 
902
         -------------
903
         -- Iterate --
904
         -------------
905
 
906
         procedure Local_Reverse_Iterate is
907
            new Key_Keys.Generic_Reverse_Iteration (Process_Node);
908
 
909
         ------------------
910
         -- Process_Node --
911
         ------------------
912
 
913
         procedure Process_Node (Node : Node_Access) is
914
         begin
915
            Process (Cursor'(Container'Unrestricted_Access, Node));
916
         end Process_Node;
917
 
918
         T : Tree_Type renames Container.Tree'Unrestricted_Access.all;
919
         B : Natural renames T.Busy;
920
 
921
      --  Start of processing for Reverse_Iterate
922
 
923
      begin
924
         B := B + 1;
925
 
926
         begin
927
            Local_Reverse_Iterate (T, Key);
928
         exception
929
            when others =>
930
               B := B - 1;
931
               raise;
932
         end;
933
 
934
         B := B - 1;
935
      end Reverse_Iterate;
936
 
937
      --------------------
938
      -- Update_Element --
939
      --------------------
940
 
941
      procedure Update_Element
942
        (Container : in out Set;
943
         Position  : Cursor;
944
         Process   : not null access procedure (Element : in out Element_Type))
945
      is
946
         Tree : Tree_Type renames Container.Tree;
947
         Node : constant Node_Access := Position.Node;
948
 
949
      begin
950
         if Node = null then
951
            raise Constraint_Error with "Position cursor equals No_Element";
952
         end if;
953
 
954
         if Node.Element = null then
955
            raise Program_Error with "Position cursor is bad";
956
         end if;
957
 
958
         if Position.Container /= Container'Unrestricted_Access then
959
            raise Program_Error with "Position cursor designates wrong set";
960
         end if;
961
 
962
         pragma Assert (Vet (Tree, Node),
963
                        "bad cursor in Update_Element");
964
 
965
         declare
966
            E : Element_Type renames Node.Element.all;
967
            K : constant Key_Type := Key (E);
968
 
969
            B : Natural renames Tree.Busy;
970
            L : Natural renames Tree.Lock;
971
 
972
         begin
973
            B := B + 1;
974
            L := L + 1;
975
 
976
            begin
977
               Process (E);
978
            exception
979
               when others =>
980
                  L := L - 1;
981
                  B := B - 1;
982
                  raise;
983
            end;
984
 
985
            L := L - 1;
986
            B := B - 1;
987
 
988
            if Equivalent_Keys (Left => K, Right => Key (E)) then
989
               return;
990
            end if;
991
         end;
992
 
993
         --  Delete_Node checks busy-bit
994
 
995
         Tree_Operations.Delete_Node_Sans_Free (Tree, Node);
996
 
997
         Insert_New_Item : declare
998
            function New_Node return Node_Access;
999
            pragma Inline (New_Node);
1000
 
1001
            procedure Insert_Post is
1002
               new Element_Keys.Generic_Insert_Post (New_Node);
1003
 
1004
            procedure Unconditional_Insert is
1005
               new Element_Keys.Generic_Unconditional_Insert (Insert_Post);
1006
 
1007
            --------------
1008
            -- New_Node --
1009
            --------------
1010
 
1011
            function New_Node return Node_Access is
1012
            begin
1013
               Node.Color := Red_Black_Trees.Red;
1014
               Node.Parent := null;
1015
               Node.Left := null;
1016
               Node.Right := null;
1017
 
1018
               return Node;
1019
            end New_Node;
1020
 
1021
            Result : Node_Access;
1022
 
1023
         --  Start of processing for Insert_New_Item
1024
 
1025
         begin
1026
            Unconditional_Insert
1027
              (Tree => Tree,
1028
               Key  => Node.Element.all,
1029
               Node => Result);
1030
 
1031
            pragma Assert (Result = Node);
1032
         end Insert_New_Item;
1033
      end Update_Element;
1034
 
1035
   end Generic_Keys;
1036
 
1037
   -----------------
1038
   -- Has_Element --
1039
   -----------------
1040
 
1041
   function Has_Element (Position : Cursor) return Boolean is
1042
   begin
1043
      return Position /= No_Element;
1044
   end Has_Element;
1045
 
1046
   ------------
1047
   -- Insert --
1048
   ------------
1049
 
1050
   procedure Insert (Container : in out Set; New_Item : Element_Type) is
1051
      Position : Cursor;
1052
      pragma Unreferenced (Position);
1053
   begin
1054
      Insert (Container, New_Item, Position);
1055
   end Insert;
1056
 
1057
   procedure Insert
1058
     (Container : in out Set;
1059
      New_Item  : Element_Type;
1060
      Position  : out Cursor)
1061
   is
1062
   begin
1063
      Insert_Sans_Hint (Container.Tree, New_Item, Position.Node);
1064
      Position.Container := Container'Unrestricted_Access;
1065
   end Insert;
1066
 
1067
   ----------------------
1068
   -- Insert_Sans_Hint --
1069
   ----------------------
1070
 
1071
   procedure Insert_Sans_Hint
1072
     (Tree     : in out Tree_Type;
1073
      New_Item : Element_Type;
1074
      Node     : out Node_Access)
1075
   is
1076
      function New_Node return Node_Access;
1077
      pragma Inline (New_Node);
1078
 
1079
      procedure Insert_Post is
1080
        new Element_Keys.Generic_Insert_Post (New_Node);
1081
 
1082
      procedure Unconditional_Insert is
1083
        new Element_Keys.Generic_Unconditional_Insert (Insert_Post);
1084
 
1085
      --------------
1086
      -- New_Node --
1087
      --------------
1088
 
1089
      function New_Node return Node_Access is
1090
         Element : Element_Access := new Element_Type'(New_Item);
1091
 
1092
      begin
1093
         return new Node_Type'(Parent  => null,
1094
                               Left    => null,
1095
                               Right   => null,
1096
                               Color   => Red_Black_Trees.Red,
1097
                               Element => Element);
1098
      exception
1099
         when others =>
1100
            Free_Element (Element);
1101
            raise;
1102
      end New_Node;
1103
 
1104
   --  Start of processing for Insert_Sans_Hint
1105
 
1106
   begin
1107
      Unconditional_Insert (Tree, New_Item, Node);
1108
   end Insert_Sans_Hint;
1109
 
1110
   ----------------------
1111
   -- Insert_With_Hint --
1112
   ----------------------
1113
 
1114
   procedure Insert_With_Hint
1115
     (Dst_Tree : in out Tree_Type;
1116
      Dst_Hint : Node_Access;
1117
      Src_Node : Node_Access;
1118
      Dst_Node : out Node_Access)
1119
   is
1120
      function New_Node return Node_Access;
1121
      pragma Inline (New_Node);
1122
 
1123
      procedure Insert_Post is
1124
        new Element_Keys.Generic_Insert_Post (New_Node);
1125
 
1126
      procedure Insert_Sans_Hint is
1127
        new Element_Keys.Generic_Unconditional_Insert (Insert_Post);
1128
 
1129
      procedure Local_Insert_With_Hint is
1130
        new Element_Keys.Generic_Unconditional_Insert_With_Hint
1131
          (Insert_Post,
1132
           Insert_Sans_Hint);
1133
 
1134
      --------------
1135
      -- New_Node --
1136
      --------------
1137
 
1138
      function New_Node return Node_Access is
1139
         X : Element_Access := new Element_Type'(Src_Node.Element.all);
1140
 
1141
      begin
1142
         return new Node_Type'(Parent  => null,
1143
                               Left    => null,
1144
                               Right   => null,
1145
                               Color   => Red,
1146
                               Element => X);
1147
 
1148
      exception
1149
         when others =>
1150
            Free_Element (X);
1151
            raise;
1152
      end New_Node;
1153
 
1154
   --  Start of processing for Insert_With_Hint
1155
 
1156
   begin
1157
      Local_Insert_With_Hint
1158
        (Dst_Tree,
1159
         Dst_Hint,
1160
         Src_Node.Element.all,
1161
         Dst_Node);
1162
   end Insert_With_Hint;
1163
 
1164
   ------------------
1165
   -- Intersection --
1166
   ------------------
1167
 
1168
   procedure Intersection (Target : in out Set; Source : Set) is
1169
   begin
1170
      Set_Ops.Intersection (Target.Tree, Source.Tree);
1171
   end Intersection;
1172
 
1173
   function Intersection (Left, Right : Set) return Set is
1174
      Tree : constant Tree_Type :=
1175
               Set_Ops.Intersection (Left.Tree, Right.Tree);
1176
   begin
1177
      return Set'(Controlled with Tree);
1178
   end Intersection;
1179
 
1180
   --------------
1181
   -- Is_Empty --
1182
   --------------
1183
 
1184
   function Is_Empty (Container : Set) return Boolean is
1185
   begin
1186
      return Container.Tree.Length = 0;
1187
   end Is_Empty;
1188
 
1189
   ------------------------
1190
   -- Is_Equal_Node_Node --
1191
   ------------------------
1192
 
1193
   function Is_Equal_Node_Node (L, R : Node_Access) return Boolean is
1194
   begin
1195
      return L.Element.all = R.Element.all;
1196
   end Is_Equal_Node_Node;
1197
 
1198
   -----------------------------
1199
   -- Is_Greater_Element_Node --
1200
   -----------------------------
1201
 
1202
   function Is_Greater_Element_Node
1203
     (Left  : Element_Type;
1204
      Right : Node_Access) return Boolean
1205
   is
1206
   begin
1207
      --  e > node same as node < e
1208
 
1209
      return Right.Element.all < Left;
1210
   end Is_Greater_Element_Node;
1211
 
1212
   --------------------------
1213
   -- Is_Less_Element_Node --
1214
   --------------------------
1215
 
1216
   function Is_Less_Element_Node
1217
     (Left  : Element_Type;
1218
      Right : Node_Access) return Boolean
1219
   is
1220
   begin
1221
      return Left < Right.Element.all;
1222
   end Is_Less_Element_Node;
1223
 
1224
   -----------------------
1225
   -- Is_Less_Node_Node --
1226
   -----------------------
1227
 
1228
   function Is_Less_Node_Node (L, R : Node_Access) return Boolean is
1229
   begin
1230
      return L.Element.all < R.Element.all;
1231
   end Is_Less_Node_Node;
1232
 
1233
   ---------------
1234
   -- Is_Subset --
1235
   ---------------
1236
 
1237
   function Is_Subset (Subset : Set; Of_Set : Set) return Boolean is
1238
   begin
1239
      return Set_Ops.Is_Subset (Subset => Subset.Tree, Of_Set => Of_Set.Tree);
1240
   end Is_Subset;
1241
 
1242
   -------------
1243
   -- Iterate --
1244
   -------------
1245
 
1246
   procedure Iterate
1247
     (Container : Set;
1248
      Item      : Element_Type;
1249
      Process   : not null access procedure (Position : Cursor))
1250
   is
1251
      procedure Process_Node (Node : Node_Access);
1252
      pragma Inline (Process_Node);
1253
 
1254
      procedure Local_Iterate is
1255
        new Element_Keys.Generic_Iteration (Process_Node);
1256
 
1257
      ------------------
1258
      -- Process_Node --
1259
      ------------------
1260
 
1261
      procedure Process_Node (Node : Node_Access) is
1262
      begin
1263
         Process (Cursor'(Container'Unrestricted_Access, Node));
1264
      end Process_Node;
1265
 
1266
      T : Tree_Type renames Container.Tree'Unrestricted_Access.all;
1267
      B : Natural renames T.Busy;
1268
 
1269
   --  Start of processing for Iterate
1270
 
1271
   begin
1272
      B := B + 1;
1273
 
1274
      begin
1275
         Local_Iterate (T, Item);
1276
      exception
1277
         when others =>
1278
            B := B - 1;
1279
            raise;
1280
      end;
1281
 
1282
      B := B - 1;
1283
   end Iterate;
1284
 
1285
   procedure Iterate
1286
     (Container : Set;
1287
      Process   : not null access procedure (Position : Cursor))
1288
   is
1289
      procedure Process_Node (Node : Node_Access);
1290
      pragma Inline (Process_Node);
1291
 
1292
      procedure Local_Iterate is
1293
        new Tree_Operations.Generic_Iteration (Process_Node);
1294
 
1295
      ------------------
1296
      -- Process_Node --
1297
      ------------------
1298
 
1299
      procedure Process_Node (Node : Node_Access) is
1300
      begin
1301
         Process (Cursor'(Container'Unrestricted_Access, Node));
1302
      end Process_Node;
1303
 
1304
      T : Tree_Type renames Container.Tree'Unrestricted_Access.all;
1305
      B : Natural renames T.Busy;
1306
 
1307
   --  Start of processing for Iterate
1308
 
1309
   begin
1310
      B := B + 1;
1311
 
1312
      begin
1313
         Local_Iterate (T);
1314
      exception
1315
         when others =>
1316
            B := B - 1;
1317
            raise;
1318
      end;
1319
 
1320
      B := B - 1;
1321
   end Iterate;
1322
 
1323
   ----------
1324
   -- Last --
1325
   ----------
1326
 
1327
   function Last (Container : Set) return Cursor is
1328
   begin
1329
      if Container.Tree.Last = null then
1330
         return No_Element;
1331
      end if;
1332
 
1333
      return Cursor'(Container'Unrestricted_Access, Container.Tree.Last);
1334
   end Last;
1335
 
1336
   ------------------
1337
   -- Last_Element --
1338
   ------------------
1339
 
1340
   function Last_Element (Container : Set) return Element_Type is
1341
   begin
1342
      if Container.Tree.Last = null then
1343
         raise Constraint_Error with "set is empty";
1344
      end if;
1345
 
1346
      pragma Assert (Container.Tree.Last.Element /= null);
1347
      return Container.Tree.Last.Element.all;
1348
   end Last_Element;
1349
 
1350
   ----------
1351
   -- Left --
1352
   ----------
1353
 
1354
   function Left (Node : Node_Access) return Node_Access is
1355
   begin
1356
      return Node.Left;
1357
   end Left;
1358
 
1359
   ------------
1360
   -- Length --
1361
   ------------
1362
 
1363
   function Length (Container : Set) return Count_Type is
1364
   begin
1365
      return Container.Tree.Length;
1366
   end Length;
1367
 
1368
   ----------
1369
   -- Move --
1370
   ----------
1371
 
1372
   procedure Move is
1373
      new Tree_Operations.Generic_Move (Clear);
1374
 
1375
   procedure Move (Target : in out Set; Source : in out Set) is
1376
   begin
1377
      Move (Target => Target.Tree, Source => Source.Tree);
1378
   end Move;
1379
 
1380
   ----------
1381
   -- Next --
1382
   ----------
1383
 
1384
   function Next (Position : Cursor) return Cursor is
1385
   begin
1386
      if Position = No_Element then
1387
         return No_Element;
1388
      end if;
1389
 
1390
      pragma Assert (Vet (Position.Container.Tree, Position.Node),
1391
                     "bad cursor in Next");
1392
 
1393
      declare
1394
         Node : constant Node_Access :=
1395
                  Tree_Operations.Next (Position.Node);
1396
 
1397
      begin
1398
         if Node = null then
1399
            return No_Element;
1400
         end if;
1401
 
1402
         return Cursor'(Position.Container, Node);
1403
      end;
1404
   end Next;
1405
 
1406
   procedure Next (Position : in out Cursor) is
1407
   begin
1408
      Position := Next (Position);
1409
   end Next;
1410
 
1411
   -------------
1412
   -- Overlap --
1413
   -------------
1414
 
1415
   function Overlap (Left, Right : Set) return Boolean is
1416
   begin
1417
      return Set_Ops.Overlap (Left.Tree, Right.Tree);
1418
   end Overlap;
1419
 
1420
   ------------
1421
   -- Parent --
1422
   ------------
1423
 
1424
   function Parent (Node : Node_Access) return Node_Access is
1425
   begin
1426
      return Node.Parent;
1427
   end Parent;
1428
 
1429
   --------------
1430
   -- Previous --
1431
   --------------
1432
 
1433
   function Previous (Position : Cursor) return Cursor is
1434
   begin
1435
      if Position = No_Element then
1436
         return No_Element;
1437
      end if;
1438
 
1439
      pragma Assert (Vet (Position.Container.Tree, Position.Node),
1440
                     "bad cursor in Previous");
1441
 
1442
      declare
1443
         Node : constant Node_Access :=
1444
                  Tree_Operations.Previous (Position.Node);
1445
 
1446
      begin
1447
         if Node = null then
1448
            return No_Element;
1449
         end if;
1450
 
1451
         return Cursor'(Position.Container, Node);
1452
      end;
1453
   end Previous;
1454
 
1455
   procedure Previous (Position : in out Cursor) is
1456
   begin
1457
      Position := Previous (Position);
1458
   end Previous;
1459
 
1460
   -------------------
1461
   -- Query_Element --
1462
   -------------------
1463
 
1464
   procedure Query_Element
1465
     (Position : Cursor;
1466
      Process  : not null access procedure (Element : Element_Type))
1467
   is
1468
   begin
1469
      if Position.Node = null then
1470
         raise Constraint_Error with "Position cursor equals No_Element";
1471
      end if;
1472
 
1473
      if Position.Node.Element = null then
1474
         raise Program_Error with "Position cursor is bad";
1475
      end if;
1476
 
1477
      pragma Assert (Vet (Position.Container.Tree, Position.Node),
1478
                     "bad cursor in Query_Element");
1479
 
1480
      declare
1481
         T : Tree_Type renames Position.Container.Tree;
1482
 
1483
         B : Natural renames T.Busy;
1484
         L : Natural renames T.Lock;
1485
 
1486
      begin
1487
         B := B + 1;
1488
         L := L + 1;
1489
 
1490
         begin
1491
            Process (Position.Node.Element.all);
1492
         exception
1493
            when others =>
1494
               L := L - 1;
1495
               B := B - 1;
1496
               raise;
1497
         end;
1498
 
1499
         L := L - 1;
1500
         B := B - 1;
1501
      end;
1502
   end Query_Element;
1503
 
1504
   ----------
1505
   -- Read --
1506
   ----------
1507
 
1508
   procedure Read
1509
     (Stream    : not null access Root_Stream_Type'Class;
1510
      Container : out Set)
1511
   is
1512
      function Read_Node
1513
        (Stream : not null access Root_Stream_Type'Class) return Node_Access;
1514
      pragma Inline (Read_Node);
1515
 
1516
      procedure Read is
1517
         new Tree_Operations.Generic_Read (Clear, Read_Node);
1518
 
1519
      ---------------
1520
      -- Read_Node --
1521
      ---------------
1522
 
1523
      function Read_Node
1524
        (Stream : not null access Root_Stream_Type'Class) return Node_Access
1525
      is
1526
         Node : Node_Access := new Node_Type;
1527
      begin
1528
         Node.Element := new Element_Type'(Element_Type'Input (Stream));
1529
         return Node;
1530
      exception
1531
         when others =>
1532
            Free (Node);  --  Note that Free deallocates elem too
1533
            raise;
1534
      end Read_Node;
1535
 
1536
   --  Start of processing for Read
1537
 
1538
   begin
1539
      Read (Stream, Container.Tree);
1540
   end Read;
1541
 
1542
   procedure Read
1543
     (Stream : not null access Root_Stream_Type'Class;
1544
      Item   : out Cursor)
1545
   is
1546
   begin
1547
      raise Program_Error with "attempt to stream set cursor";
1548
   end Read;
1549
 
1550
   ---------------------
1551
   -- Replace_Element --
1552
   ---------------------
1553
 
1554
   procedure Replace_Element
1555
     (Tree : in out Tree_Type;
1556
      Node : Node_Access;
1557
      Item : Element_Type)
1558
   is
1559
   begin
1560
      if Item < Node.Element.all
1561
        or else Node.Element.all < Item
1562
      then
1563
         null;
1564
      else
1565
         if Tree.Lock > 0 then
1566
            raise Program_Error with
1567
              "attempt to tamper with cursors (set is locked)";
1568
         end if;
1569
 
1570
         declare
1571
            X : Element_Access := Node.Element;
1572
         begin
1573
            Node.Element := new Element_Type'(Item);
1574
            Free_Element (X);
1575
         end;
1576
 
1577
         return;
1578
      end if;
1579
 
1580
      Tree_Operations.Delete_Node_Sans_Free (Tree, Node);  -- Checks busy-bit
1581
 
1582
      Insert_New_Item : declare
1583
         function New_Node return Node_Access;
1584
         pragma Inline (New_Node);
1585
 
1586
         procedure Insert_Post is
1587
            new Element_Keys.Generic_Insert_Post (New_Node);
1588
 
1589
         procedure Unconditional_Insert is
1590
            new Element_Keys.Generic_Unconditional_Insert (Insert_Post);
1591
 
1592
         --------------
1593
         -- New_Node --
1594
         --------------
1595
 
1596
         function New_Node return Node_Access is
1597
         begin
1598
            Node.Element := new Element_Type'(Item);  -- OK if fails
1599
            Node.Color := Red_Black_Trees.Red;
1600
            Node.Parent := null;
1601
            Node.Left := null;
1602
            Node.Right := null;
1603
 
1604
            return Node;
1605
         end New_Node;
1606
 
1607
         Result : Node_Access;
1608
 
1609
         X : Element_Access := Node.Element;
1610
 
1611
      --  Start of processing for Insert_New_Item
1612
 
1613
      begin
1614
         Unconditional_Insert
1615
           (Tree => Tree,
1616
            Key  => Item,
1617
            Node => Result);
1618
         pragma Assert (Result = Node);
1619
 
1620
         Free_Element (X);  -- OK if fails
1621
      end Insert_New_Item;
1622
   end Replace_Element;
1623
 
1624
   procedure Replace_Element
1625
    (Container : in out Set;
1626
     Position  : Cursor;
1627
     New_Item  : Element_Type)
1628
   is
1629
   begin
1630
      if Position.Node = null then
1631
         raise Constraint_Error with "Position cursor equals No_Element";
1632
      end if;
1633
 
1634
      if Position.Node.Element = null then
1635
         raise Program_Error with "Position cursor is bad";
1636
      end if;
1637
 
1638
      if Position.Container /= Container'Unrestricted_Access then
1639
         raise Program_Error with "Position cursor designates wrong set";
1640
      end if;
1641
 
1642
      pragma Assert (Vet (Container.Tree, Position.Node),
1643
                     "bad cursor in Replace_Element");
1644
 
1645
      Replace_Element (Container.Tree, Position.Node, New_Item);
1646
   end Replace_Element;
1647
 
1648
   ---------------------
1649
   -- Reverse_Iterate --
1650
   ---------------------
1651
 
1652
   procedure Reverse_Iterate
1653
     (Container : Set;
1654
      Item      : Element_Type;
1655
      Process   : not null access procedure (Position : Cursor))
1656
   is
1657
      procedure Process_Node (Node : Node_Access);
1658
      pragma Inline (Process_Node);
1659
 
1660
      procedure Local_Reverse_Iterate is
1661
        new Element_Keys.Generic_Reverse_Iteration (Process_Node);
1662
 
1663
      ------------------
1664
      -- Process_Node --
1665
      ------------------
1666
 
1667
      procedure Process_Node (Node : Node_Access) is
1668
      begin
1669
         Process (Cursor'(Container'Unrestricted_Access, Node));
1670
      end Process_Node;
1671
 
1672
      T : Tree_Type renames Container.Tree'Unrestricted_Access.all;
1673
      B : Natural renames T.Busy;
1674
 
1675
   --  Start of processing for Reverse_Iterate
1676
 
1677
   begin
1678
      B := B + 1;
1679
 
1680
      begin
1681
         Local_Reverse_Iterate (T, Item);
1682
      exception
1683
         when others =>
1684
            B := B - 1;
1685
            raise;
1686
      end;
1687
 
1688
      B := B - 1;
1689
   end Reverse_Iterate;
1690
 
1691
   procedure Reverse_Iterate
1692
     (Container : Set;
1693
      Process   : not null access procedure (Position : Cursor))
1694
   is
1695
      procedure Process_Node (Node : Node_Access);
1696
      pragma Inline (Process_Node);
1697
 
1698
      procedure Local_Reverse_Iterate is
1699
        new Tree_Operations.Generic_Reverse_Iteration (Process_Node);
1700
 
1701
      ------------------
1702
      -- Process_Node --
1703
      ------------------
1704
 
1705
      procedure Process_Node (Node : Node_Access) is
1706
      begin
1707
         Process (Cursor'(Container'Unrestricted_Access, Node));
1708
      end Process_Node;
1709
 
1710
      T : Tree_Type renames Container.Tree'Unrestricted_Access.all;
1711
      B : Natural renames T.Busy;
1712
 
1713
   --  Start of processing for Reverse_Iterate
1714
 
1715
   begin
1716
      B := B + 1;
1717
 
1718
      begin
1719
         Local_Reverse_Iterate (T);
1720
      exception
1721
         when others =>
1722
            B := B - 1;
1723
            raise;
1724
      end;
1725
 
1726
      B := B - 1;
1727
   end Reverse_Iterate;
1728
 
1729
   -----------
1730
   -- Right --
1731
   -----------
1732
 
1733
   function Right (Node : Node_Access) return Node_Access is
1734
   begin
1735
      return Node.Right;
1736
   end Right;
1737
 
1738
   ---------------
1739
   -- Set_Color --
1740
   ---------------
1741
 
1742
   procedure Set_Color (Node : Node_Access; Color : Color_Type) is
1743
   begin
1744
      Node.Color := Color;
1745
   end Set_Color;
1746
 
1747
   --------------
1748
   -- Set_Left --
1749
   --------------
1750
 
1751
   procedure Set_Left (Node : Node_Access; Left : Node_Access) is
1752
   begin
1753
      Node.Left := Left;
1754
   end Set_Left;
1755
 
1756
   ----------------
1757
   -- Set_Parent --
1758
   ----------------
1759
 
1760
   procedure Set_Parent (Node : Node_Access; Parent : Node_Access) is
1761
   begin
1762
      Node.Parent := Parent;
1763
   end Set_Parent;
1764
 
1765
   ---------------
1766
   -- Set_Right --
1767
   ---------------
1768
 
1769
   procedure Set_Right (Node : Node_Access; Right : Node_Access) is
1770
   begin
1771
      Node.Right := Right;
1772
   end Set_Right;
1773
 
1774
   --------------------------
1775
   -- Symmetric_Difference --
1776
   --------------------------
1777
 
1778
   procedure Symmetric_Difference (Target : in out Set; Source : Set) is
1779
   begin
1780
      Set_Ops.Symmetric_Difference (Target.Tree, Source.Tree);
1781
   end Symmetric_Difference;
1782
 
1783
   function Symmetric_Difference (Left, Right : Set) return Set is
1784
      Tree : constant Tree_Type :=
1785
               Set_Ops.Symmetric_Difference (Left.Tree, Right.Tree);
1786
   begin
1787
      return Set'(Controlled with Tree);
1788
   end Symmetric_Difference;
1789
 
1790
   ------------
1791
   -- To_Set --
1792
   ------------
1793
 
1794
   function To_Set (New_Item : Element_Type) return Set is
1795
      Tree : Tree_Type;
1796
      Node : Node_Access;
1797
      pragma Unreferenced (Node);
1798
   begin
1799
      Insert_Sans_Hint (Tree, New_Item, Node);
1800
      return Set'(Controlled with Tree);
1801
   end To_Set;
1802
 
1803
   -----------
1804
   -- Union --
1805
   -----------
1806
 
1807
   procedure Union (Target : in out Set; Source : Set) is
1808
   begin
1809
      Set_Ops.Union (Target.Tree, Source.Tree);
1810
   end Union;
1811
 
1812
   function Union (Left, Right : Set) return Set is
1813
      Tree : constant Tree_Type :=
1814
               Set_Ops.Union (Left.Tree, Right.Tree);
1815
   begin
1816
      return Set'(Controlled with Tree);
1817
   end Union;
1818
 
1819
   -----------
1820
   -- Write --
1821
   -----------
1822
 
1823
   procedure Write
1824
     (Stream    : not null access Root_Stream_Type'Class;
1825
      Container : Set)
1826
   is
1827
      procedure Write_Node
1828
        (Stream : not null access Root_Stream_Type'Class;
1829
         Node   : Node_Access);
1830
      pragma Inline (Write_Node);
1831
 
1832
      procedure Write is
1833
         new Tree_Operations.Generic_Write (Write_Node);
1834
 
1835
      ----------------
1836
      -- Write_Node --
1837
      ----------------
1838
 
1839
      procedure Write_Node
1840
        (Stream : not null access Root_Stream_Type'Class;
1841
         Node   : Node_Access)
1842
      is
1843
      begin
1844
         Element_Type'Output (Stream, Node.Element.all);
1845
      end Write_Node;
1846
 
1847
   --  Start of processing for Write
1848
 
1849
   begin
1850
      Write (Stream, Container.Tree);
1851
   end Write;
1852
 
1853
   procedure Write
1854
     (Stream : not null access Root_Stream_Type'Class;
1855
      Item   : Cursor)
1856
   is
1857
   begin
1858
      raise Program_Error with "attempt to stream set cursor";
1859
   end Write;
1860
 
1861
end Ada.Containers.Indefinite_Ordered_Multisets;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.