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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [ada/] [a-ciorse.adb] - Blame information for rev 16

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

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

powered by: WebSVN 2.1.0

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