Dead
[official-gcc.git] / gomp-20050608-branch / gcc / ada / a-coorse.adb
blob552987329d71ee8c6d747dfe8188a31a984ae546
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT LIBRARY COMPONENTS --
4 -- --
5 -- A D A . C O N T A I N E R S . O R D E R E D _ S E T S --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2004-2005, Free Software Foundation, Inc. --
10 -- --
11 -- This specification is derived from the Ada Reference Manual for use with --
12 -- GNAT. The copyright notice above, and the license provisions that follow --
13 -- apply solely to the contents of the part following the private keyword. --
14 -- --
15 -- GNAT is free software; you can redistribute it and/or modify it under --
16 -- terms of the GNU General Public License as published by the Free Soft- --
17 -- ware Foundation; either version 2, or (at your option) any later ver- --
18 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
19 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
20 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
21 -- for more details. You should have received a copy of the GNU General --
22 -- Public License distributed with GNAT; see file COPYING. If not, write --
23 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
24 -- Boston, MA 02110-1301, USA. --
25 -- --
26 -- As a special exception, if other files instantiate generics from this --
27 -- unit, or you link this unit with other files to produce an executable, --
28 -- this unit does not by itself cause the resulting executable to be --
29 -- covered by the GNU General Public License. This exception does not --
30 -- however invalidate any other reasons why the executable file might be --
31 -- covered by the GNU Public License. --
32 -- --
33 -- This unit was originally developed by Matthew J Heaney. --
34 ------------------------------------------------------------------------------
36 with Ada.Unchecked_Deallocation;
38 with Ada.Containers.Red_Black_Trees.Generic_Operations;
39 pragma Elaborate_All (Ada.Containers.Red_Black_Trees.Generic_Operations);
41 with Ada.Containers.Red_Black_Trees.Generic_Keys;
42 pragma Elaborate_All (Ada.Containers.Red_Black_Trees.Generic_Keys);
44 with Ada.Containers.Red_Black_Trees.Generic_Set_Operations;
45 pragma Elaborate_All (Ada.Containers.Red_Black_Trees.Generic_Set_Operations);
47 package body Ada.Containers.Ordered_Sets is
49 ------------------------------
50 -- Access to Fields of Node --
51 ------------------------------
53 -- These subprograms provide functional notation for access to fields
54 -- of a node, and procedural notation for modifiying these fields.
56 function Color (Node : Node_Access) return Color_Type;
57 pragma Inline (Color);
59 function Left (Node : Node_Access) return Node_Access;
60 pragma Inline (Left);
62 function Parent (Node : Node_Access) return Node_Access;
63 pragma Inline (Parent);
65 function Right (Node : Node_Access) return Node_Access;
66 pragma Inline (Right);
68 procedure Set_Color (Node : Node_Access; Color : Color_Type);
69 pragma Inline (Set_Color);
71 procedure Set_Left (Node : Node_Access; Left : Node_Access);
72 pragma Inline (Set_Left);
74 procedure Set_Right (Node : Node_Access; Right : Node_Access);
75 pragma Inline (Set_Right);
77 procedure Set_Parent (Node : Node_Access; Parent : Node_Access);
78 pragma Inline (Set_Parent);
80 -----------------------
81 -- Local Subprograms --
82 -----------------------
84 function Copy_Node (Source : Node_Access) return Node_Access;
85 pragma Inline (Copy_Node);
87 procedure Free (X : in out Node_Access);
89 procedure Insert_Sans_Hint
90 (Tree : in out Tree_Type;
91 New_Item : Element_Type;
92 Node : out Node_Access;
93 Inserted : out Boolean);
95 procedure Insert_With_Hint
96 (Dst_Tree : in out Tree_Type;
97 Dst_Hint : Node_Access;
98 Src_Node : Node_Access;
99 Dst_Node : out Node_Access);
101 function Is_Equal_Node_Node (L, R : Node_Access) return Boolean;
102 pragma Inline (Is_Equal_Node_Node);
104 function Is_Greater_Element_Node
105 (Left : Element_Type;
106 Right : Node_Access) return Boolean;
107 pragma Inline (Is_Greater_Element_Node);
109 function Is_Less_Element_Node
110 (Left : Element_Type;
111 Right : Node_Access) return Boolean;
112 pragma Inline (Is_Less_Element_Node);
114 function Is_Less_Node_Node (L, R : Node_Access) return Boolean;
115 pragma Inline (Is_Less_Node_Node);
117 procedure Replace_Element
118 (Tree : in out Tree_Type;
119 Node : Node_Access;
120 Item : Element_Type);
122 --------------------------
123 -- Local Instantiations --
124 --------------------------
126 package Tree_Operations is
127 new Red_Black_Trees.Generic_Operations (Tree_Types);
129 procedure Delete_Tree is
130 new Tree_Operations.Generic_Delete_Tree (Free);
132 function Copy_Tree is
133 new Tree_Operations.Generic_Copy_Tree (Copy_Node, Delete_Tree);
135 use Tree_Operations;
137 function Is_Equal is
138 new Tree_Operations.Generic_Equal (Is_Equal_Node_Node);
140 package Element_Keys is
141 new Red_Black_Trees.Generic_Keys
142 (Tree_Operations => Tree_Operations,
143 Key_Type => Element_Type,
144 Is_Less_Key_Node => Is_Less_Element_Node,
145 Is_Greater_Key_Node => Is_Greater_Element_Node);
147 package Set_Ops is
148 new Generic_Set_Operations
149 (Tree_Operations => Tree_Operations,
150 Insert_With_Hint => Insert_With_Hint,
151 Copy_Tree => Copy_Tree,
152 Delete_Tree => Delete_Tree,
153 Is_Less => Is_Less_Node_Node,
154 Free => Free);
156 ---------
157 -- "<" --
158 ---------
160 function "<" (Left, Right : Cursor) return Boolean is
161 begin
162 if Left.Node = null then
163 raise Constraint_Error with "Left cursor equals No_Element";
164 end if;
166 if Right.Node = null then
167 raise Constraint_Error with "Right cursor equals No_Element";
168 end if;
170 pragma Assert (Vet (Left.Container.Tree, Left.Node),
171 "bad Left cursor in ""<""");
173 pragma Assert (Vet (Right.Container.Tree, Right.Node),
174 "bad Right cursor in ""<""");
176 return Left.Node.Element < Right.Node.Element;
177 end "<";
179 function "<" (Left : Cursor; Right : Element_Type) return Boolean is
180 begin
181 if Left.Node = null then
182 raise Constraint_Error with "Left cursor equals No_Element";
183 end if;
185 pragma Assert (Vet (Left.Container.Tree, Left.Node),
186 "bad Left cursor in ""<""");
188 return Left.Node.Element < Right;
189 end "<";
191 function "<" (Left : Element_Type; Right : Cursor) return Boolean is
192 begin
193 if Right.Node = null then
194 raise Constraint_Error with "Right cursor equals No_Element";
195 end if;
197 pragma Assert (Vet (Right.Container.Tree, Right.Node),
198 "bad Right cursor in ""<""");
200 return Left < Right.Node.Element;
201 end "<";
203 ---------
204 -- "=" --
205 ---------
207 function "=" (Left, Right : Set) return Boolean is
208 begin
209 return Is_Equal (Left.Tree, Right.Tree);
210 end "=";
212 ---------
213 -- ">" --
214 ---------
216 function ">" (Left, Right : Cursor) return Boolean is
217 begin
218 if Left.Node = null then
219 raise Constraint_Error with "Left cursor equals No_Element";
220 end if;
222 if Right.Node = null then
223 raise Constraint_Error with "Right cursor equals No_Element";
224 end if;
226 pragma Assert (Vet (Left.Container.Tree, Left.Node),
227 "bad Left cursor in "">""");
229 pragma Assert (Vet (Right.Container.Tree, Right.Node),
230 "bad Right cursor in "">""");
232 -- L > R same as R < L
234 return Right.Node.Element < Left.Node.Element;
235 end ">";
237 function ">" (Left : Element_Type; Right : Cursor) return Boolean is
238 begin
239 if Right.Node = null then
240 raise Constraint_Error with "Right cursor equals No_Element";
241 end if;
243 pragma Assert (Vet (Right.Container.Tree, Right.Node),
244 "bad Right cursor in "">""");
246 return Right.Node.Element < Left;
247 end ">";
249 function ">" (Left : Cursor; Right : Element_Type) return Boolean is
250 begin
251 if Left.Node = null then
252 raise Constraint_Error with "Left cursor equals No_Element";
253 end if;
255 pragma Assert (Vet (Left.Container.Tree, Left.Node),
256 "bad Left cursor in "">""");
258 return Right < Left.Node.Element;
259 end ">";
261 ------------
262 -- Adjust --
263 ------------
265 procedure Adjust is
266 new Tree_Operations.Generic_Adjust (Copy_Tree);
268 procedure Adjust (Container : in out Set) is
269 begin
270 Adjust (Container.Tree);
271 end Adjust;
273 -------------
274 -- Ceiling --
275 -------------
277 function Ceiling (Container : Set; Item : Element_Type) return Cursor is
278 Node : constant Node_Access :=
279 Element_Keys.Ceiling (Container.Tree, Item);
281 begin
282 if Node = null then
283 return No_Element;
284 end if;
286 return Cursor'(Container'Unrestricted_Access, Node);
287 end Ceiling;
289 -----------
290 -- Clear --
291 -----------
293 procedure Clear is
294 new Tree_Operations.Generic_Clear (Delete_Tree);
296 procedure Clear (Container : in out Set) is
297 begin
298 Clear (Container.Tree);
299 end Clear;
301 -----------
302 -- Color --
303 -----------
305 function Color (Node : Node_Access) return Color_Type is
306 begin
307 return Node.Color;
308 end Color;
310 --------------
311 -- Contains --
312 --------------
314 function Contains
315 (Container : Set;
316 Item : Element_Type) return Boolean
318 begin
319 return Find (Container, Item) /= No_Element;
320 end Contains;
322 ---------------
323 -- Copy_Node --
324 ---------------
326 function Copy_Node (Source : Node_Access) return Node_Access is
327 Target : constant Node_Access :=
328 new Node_Type'(Parent => null,
329 Left => null,
330 Right => null,
331 Color => Source.Color,
332 Element => Source.Element);
333 begin
334 return Target;
335 end Copy_Node;
337 ------------
338 -- Delete --
339 ------------
341 procedure Delete (Container : in out Set; Position : in out Cursor) is
342 begin
343 if Position.Node = null then
344 raise Constraint_Error with "Position cursor equals No_Element";
345 end if;
347 if Position.Container /= Container'Unrestricted_Access then
348 raise Program_Error with "Position cursor designates wrong set";
349 end if;
351 pragma Assert (Vet (Container.Tree, Position.Node),
352 "bad cursor in Delete");
354 Tree_Operations.Delete_Node_Sans_Free (Container.Tree, Position.Node);
355 Free (Position.Node);
356 Position.Container := null;
357 end Delete;
359 procedure Delete (Container : in out Set; Item : Element_Type) is
360 X : Node_Access := Element_Keys.Find (Container.Tree, Item);
362 begin
363 if X = null then
364 raise Constraint_Error with "attempt to delete element not in set";
365 end if;
367 Tree_Operations.Delete_Node_Sans_Free (Container.Tree, X);
368 Free (X);
369 end Delete;
371 ------------------
372 -- Delete_First --
373 ------------------
375 procedure Delete_First (Container : in out Set) is
376 Tree : Tree_Type renames Container.Tree;
377 X : Node_Access := Tree.First;
379 begin
380 if X /= null then
381 Tree_Operations.Delete_Node_Sans_Free (Tree, X);
382 Free (X);
383 end if;
384 end Delete_First;
386 -----------------
387 -- Delete_Last --
388 -----------------
390 procedure Delete_Last (Container : in out Set) is
391 Tree : Tree_Type renames Container.Tree;
392 X : Node_Access := Tree.Last;
394 begin
395 if X /= null then
396 Tree_Operations.Delete_Node_Sans_Free (Tree, X);
397 Free (X);
398 end if;
399 end Delete_Last;
401 ----------------
402 -- Difference --
403 ----------------
405 procedure Difference (Target : in out Set; Source : Set) is
406 begin
407 Set_Ops.Difference (Target.Tree, Source.Tree);
408 end Difference;
410 function Difference (Left, Right : Set) return Set is
411 Tree : constant Tree_Type :=
412 Set_Ops.Difference (Left.Tree, Right.Tree);
413 begin
414 return Set'(Controlled with Tree);
415 end Difference;
417 -------------
418 -- Element --
419 -------------
421 function Element (Position : Cursor) return Element_Type is
422 begin
423 if Position.Node = null then
424 raise Constraint_Error with "Position cursor equals No_Element";
425 end if;
427 pragma Assert (Vet (Position.Container.Tree, Position.Node),
428 "bad cursor in Element");
430 return Position.Node.Element;
431 end Element;
433 -------------------------
434 -- Equivalent_Elements --
435 -------------------------
437 function Equivalent_Elements (Left, Right : Element_Type) return Boolean is
438 begin
439 if Left < Right
440 or else Right < Left
441 then
442 return False;
443 else
444 return True;
445 end if;
446 end Equivalent_Elements;
448 ---------------------
449 -- Equivalent_Sets --
450 ---------------------
452 function Equivalent_Sets (Left, Right : Set) return Boolean is
453 function Is_Equivalent_Node_Node (L, R : Node_Access) return Boolean;
454 pragma Inline (Is_Equivalent_Node_Node);
456 function Is_Equivalent is
457 new Tree_Operations.Generic_Equal (Is_Equivalent_Node_Node);
459 -----------------------------
460 -- Is_Equivalent_Node_Node --
461 -----------------------------
463 function Is_Equivalent_Node_Node (L, R : Node_Access) return Boolean is
464 begin
465 if L.Element < R.Element then
466 return False;
467 elsif R.Element < L.Element then
468 return False;
469 else
470 return True;
471 end if;
472 end Is_Equivalent_Node_Node;
474 -- Start of processing for Equivalent_Sets
476 begin
477 return Is_Equivalent (Left.Tree, Right.Tree);
478 end Equivalent_Sets;
480 -------------
481 -- Exclude --
482 -------------
484 procedure Exclude (Container : in out Set; Item : Element_Type) is
485 X : Node_Access := Element_Keys.Find (Container.Tree, Item);
487 begin
488 if X /= null then
489 Tree_Operations.Delete_Node_Sans_Free (Container.Tree, X);
490 Free (X);
491 end if;
492 end Exclude;
494 ----------
495 -- Find --
496 ----------
498 function Find (Container : Set; Item : Element_Type) return Cursor is
499 Node : constant Node_Access :=
500 Element_Keys.Find (Container.Tree, Item);
502 begin
503 if Node = null then
504 return No_Element;
505 end if;
507 return Cursor'(Container'Unrestricted_Access, Node);
508 end Find;
510 -----------
511 -- First --
512 -----------
514 function First (Container : Set) return Cursor is
515 begin
516 if Container.Tree.First = null then
517 return No_Element;
518 end if;
520 return Cursor'(Container'Unrestricted_Access, Container.Tree.First);
521 end First;
523 -------------------
524 -- First_Element --
525 -------------------
527 function First_Element (Container : Set) return Element_Type is
528 begin
529 if Container.Tree.First = null then
530 raise Constraint_Error with "set is empty";
531 end if;
533 return Container.Tree.First.Element;
534 end First_Element;
536 -----------
537 -- Floor --
538 -----------
540 function Floor (Container : Set; Item : Element_Type) return Cursor is
541 Node : constant Node_Access :=
542 Element_Keys.Floor (Container.Tree, Item);
544 begin
545 if Node = null then
546 return No_Element;
547 end if;
549 return Cursor'(Container'Unrestricted_Access, Node);
550 end Floor;
552 ----------
553 -- Free --
554 ----------
556 procedure Free (X : in out Node_Access) is
557 procedure Deallocate is
558 new Ada.Unchecked_Deallocation (Node_Type, Node_Access);
560 begin
561 if X /= null then
562 X.Parent := X;
563 X.Left := X;
564 X.Right := X;
566 Deallocate (X);
567 end if;
568 end Free;
570 ------------------
571 -- Generic_Keys --
572 ------------------
574 package body Generic_Keys is
576 -----------------------
577 -- Local Subprograms --
578 -----------------------
580 function Is_Greater_Key_Node
581 (Left : Key_Type;
582 Right : Node_Access) return Boolean;
583 pragma Inline (Is_Greater_Key_Node);
585 function Is_Less_Key_Node
586 (Left : Key_Type;
587 Right : Node_Access) return Boolean;
588 pragma Inline (Is_Less_Key_Node);
590 --------------------------
591 -- Local Instantiations --
592 --------------------------
594 package Key_Keys is
595 new Red_Black_Trees.Generic_Keys
596 (Tree_Operations => Tree_Operations,
597 Key_Type => Key_Type,
598 Is_Less_Key_Node => Is_Less_Key_Node,
599 Is_Greater_Key_Node => Is_Greater_Key_Node);
601 -------------
602 -- Ceiling --
603 -------------
605 function Ceiling (Container : Set; Key : Key_Type) return Cursor is
606 Node : constant Node_Access :=
607 Key_Keys.Ceiling (Container.Tree, Key);
609 begin
610 if Node = null then
611 return No_Element;
612 end if;
614 return Cursor'(Container'Unrestricted_Access, Node);
615 end Ceiling;
617 --------------
618 -- Contains --
619 --------------
621 function Contains (Container : Set; Key : Key_Type) return Boolean is
622 begin
623 return Find (Container, Key) /= No_Element;
624 end Contains;
626 ------------
627 -- Delete --
628 ------------
630 procedure Delete (Container : in out Set; Key : Key_Type) is
631 X : Node_Access := Key_Keys.Find (Container.Tree, Key);
633 begin
634 if X = null then
635 raise Constraint_Error with "attempt to delete key not in set";
636 end if;
638 Delete_Node_Sans_Free (Container.Tree, X);
639 Free (X);
640 end Delete;
642 -------------
643 -- Element --
644 -------------
646 function Element (Container : Set; Key : Key_Type) return Element_Type is
647 Node : constant Node_Access :=
648 Key_Keys.Find (Container.Tree, Key);
650 begin
651 if Node = null then
652 raise Constraint_Error with "key not in set";
653 end if;
655 return Node.Element;
656 end Element;
658 ---------------------
659 -- Equivalent_Keys --
660 ---------------------
662 function Equivalent_Keys (Left, Right : Key_Type) return Boolean is
663 begin
664 if Left < Right
665 or else Right < Left
666 then
667 return False;
668 else
669 return True;
670 end if;
671 end Equivalent_Keys;
673 -------------
674 -- Exclude --
675 -------------
677 procedure Exclude (Container : in out Set; Key : Key_Type) is
678 X : Node_Access := Key_Keys.Find (Container.Tree, Key);
680 begin
681 if X /= null then
682 Delete_Node_Sans_Free (Container.Tree, X);
683 Free (X);
684 end if;
685 end Exclude;
687 ----------
688 -- Find --
689 ----------
691 function Find (Container : Set; Key : Key_Type) return Cursor is
692 Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key);
694 begin
695 if Node = null then
696 return No_Element;
697 end if;
699 return Cursor'(Container'Unrestricted_Access, Node);
700 end Find;
702 -----------
703 -- Floor --
704 -----------
706 function Floor (Container : Set; Key : Key_Type) return Cursor is
707 Node : constant Node_Access := Key_Keys.Floor (Container.Tree, Key);
709 begin
710 if Node = null then
711 return No_Element;
712 end if;
714 return Cursor'(Container'Unrestricted_Access, Node);
715 end Floor;
717 -------------------------
718 -- Is_Greater_Key_Node --
719 -------------------------
721 function Is_Greater_Key_Node
722 (Left : Key_Type;
723 Right : Node_Access) return Boolean
725 begin
726 return Key (Right.Element) < Left;
727 end Is_Greater_Key_Node;
729 ----------------------
730 -- Is_Less_Key_Node --
731 ----------------------
733 function Is_Less_Key_Node
734 (Left : Key_Type;
735 Right : Node_Access) return Boolean
737 begin
738 return Left < Key (Right.Element);
739 end Is_Less_Key_Node;
741 ---------
742 -- Key --
743 ---------
745 function Key (Position : Cursor) return Key_Type is
746 begin
747 if Position.Node = null then
748 raise Constraint_Error with
749 "Position cursor equals No_Element";
750 end if;
752 pragma Assert (Vet (Position.Container.Tree, Position.Node),
753 "bad cursor in Key");
755 return Key (Position.Node.Element);
756 end Key;
758 -------------
759 -- Replace --
760 -------------
762 procedure Replace
763 (Container : in out Set;
764 Key : Key_Type;
765 New_Item : Element_Type)
767 Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key);
769 begin
770 if Node = null then
771 raise Constraint_Error with
772 "attempt to replace key not in set";
773 end if;
775 Replace_Element (Container.Tree, Node, New_Item);
776 end Replace;
778 -----------------------------------
779 -- Update_Element_Preserving_Key --
780 -----------------------------------
782 procedure Update_Element_Preserving_Key
783 (Container : in out Set;
784 Position : Cursor;
785 Process : not null access procedure (Element : in out Element_Type))
787 Tree : Tree_Type renames Container.Tree;
789 begin
790 if Position.Node = null then
791 raise Constraint_Error with
792 "Position cursor equals No_Element";
793 end if;
795 if Position.Container /= Container'Unrestricted_Access then
796 raise Program_Error with
797 "Position cursor designates wrong set";
798 end if;
800 pragma Assert (Vet (Container.Tree, Position.Node),
801 "bad cursor in Update_Element_Preserving_Key");
803 declare
804 E : Element_Type renames Position.Node.Element;
805 K : constant Key_Type := Key (E);
807 B : Natural renames Tree.Busy;
808 L : Natural renames Tree.Lock;
810 begin
811 B := B + 1;
812 L := L + 1;
814 begin
815 Process (E);
816 exception
817 when others =>
818 L := L - 1;
819 B := B - 1;
820 raise;
821 end;
823 L := L - 1;
824 B := B - 1;
826 if Equivalent_Keys (K, Key (E)) then
827 return;
828 end if;
829 end;
831 declare
832 X : Node_Access := Position.Node;
833 begin
834 Tree_Operations.Delete_Node_Sans_Free (Tree, X);
835 Free (X);
836 end;
838 raise Program_Error with "key was modified";
839 end Update_Element_Preserving_Key;
841 end Generic_Keys;
843 -----------------
844 -- Has_Element --
845 -----------------
847 function Has_Element (Position : Cursor) return Boolean is
848 begin
849 return Position /= No_Element;
850 end Has_Element;
852 -------------
853 -- Include --
854 -------------
856 procedure Include (Container : in out Set; New_Item : Element_Type) is
857 Position : Cursor;
858 Inserted : Boolean;
860 begin
861 Insert (Container, New_Item, Position, Inserted);
863 if not Inserted then
864 if Container.Tree.Lock > 0 then
865 raise Program_Error with
866 "attempt to tamper with cursors (set is locked)";
867 end if;
869 Position.Node.Element := New_Item;
870 end if;
871 end Include;
873 ------------
874 -- Insert --
875 ------------
877 procedure Insert
878 (Container : in out Set;
879 New_Item : Element_Type;
880 Position : out Cursor;
881 Inserted : out Boolean)
883 begin
884 Insert_Sans_Hint
885 (Container.Tree,
886 New_Item,
887 Position.Node,
888 Inserted);
890 Position.Container := Container'Unrestricted_Access;
891 end Insert;
893 procedure Insert
894 (Container : in out Set;
895 New_Item : Element_Type)
897 Position : Cursor;
898 Inserted : Boolean;
900 begin
901 Insert (Container, New_Item, Position, Inserted);
903 if not Inserted then
904 raise Constraint_Error with
905 "attempt to insert element already in set";
906 end if;
907 end Insert;
909 ----------------------
910 -- Insert_Sans_Hint --
911 ----------------------
913 procedure Insert_Sans_Hint
914 (Tree : in out Tree_Type;
915 New_Item : Element_Type;
916 Node : out Node_Access;
917 Inserted : out Boolean)
919 function New_Node return Node_Access;
920 pragma Inline (New_Node);
922 procedure Insert_Post is
923 new Element_Keys.Generic_Insert_Post (New_Node);
925 procedure Conditional_Insert_Sans_Hint is
926 new Element_Keys.Generic_Conditional_Insert (Insert_Post);
928 --------------
929 -- New_Node --
930 --------------
932 function New_Node return Node_Access is
933 begin
934 return new Node_Type'(Parent => null,
935 Left => null,
936 Right => null,
937 Color => Red_Black_Trees.Red,
938 Element => New_Item);
939 end New_Node;
941 -- Start of processing for Insert_Sans_Hint
943 begin
944 Conditional_Insert_Sans_Hint
945 (Tree,
946 New_Item,
947 Node,
948 Inserted);
949 end Insert_Sans_Hint;
951 ----------------------
952 -- Insert_With_Hint --
953 ----------------------
955 procedure Insert_With_Hint
956 (Dst_Tree : in out Tree_Type;
957 Dst_Hint : Node_Access;
958 Src_Node : Node_Access;
959 Dst_Node : out Node_Access)
961 Success : Boolean;
963 function New_Node return Node_Access;
964 pragma Inline (New_Node);
966 procedure Insert_Post is
967 new Element_Keys.Generic_Insert_Post (New_Node);
969 procedure Insert_Sans_Hint is
970 new Element_Keys.Generic_Conditional_Insert (Insert_Post);
972 procedure Local_Insert_With_Hint is
973 new Element_Keys.Generic_Conditional_Insert_With_Hint
974 (Insert_Post,
975 Insert_Sans_Hint);
977 --------------
978 -- New_Node --
979 --------------
981 function New_Node return Node_Access is
982 Node : constant Node_Access :=
983 new Node_Type'(Parent => null,
984 Left => null,
985 Right => null,
986 Color => Red,
987 Element => Src_Node.Element);
988 begin
989 return Node;
990 end New_Node;
992 -- Start of processing for Insert_With_Hint
994 begin
995 Local_Insert_With_Hint
996 (Dst_Tree,
997 Dst_Hint,
998 Src_Node.Element,
999 Dst_Node,
1000 Success);
1001 end Insert_With_Hint;
1003 ------------------
1004 -- Intersection --
1005 ------------------
1007 procedure Intersection (Target : in out Set; Source : Set) is
1008 begin
1009 Set_Ops.Intersection (Target.Tree, Source.Tree);
1010 end Intersection;
1012 function Intersection (Left, Right : Set) return Set is
1013 Tree : constant Tree_Type :=
1014 Set_Ops.Intersection (Left.Tree, Right.Tree);
1015 begin
1016 return Set'(Controlled with Tree);
1017 end Intersection;
1019 --------------
1020 -- Is_Empty --
1021 --------------
1023 function Is_Empty (Container : Set) return Boolean is
1024 begin
1025 return Container.Tree.Length = 0;
1026 end Is_Empty;
1028 ------------------------
1029 -- Is_Equal_Node_Node --
1030 ------------------------
1032 function Is_Equal_Node_Node (L, R : Node_Access) return Boolean is
1033 begin
1034 return L.Element = R.Element;
1035 end Is_Equal_Node_Node;
1037 -----------------------------
1038 -- Is_Greater_Element_Node --
1039 -----------------------------
1041 function Is_Greater_Element_Node
1042 (Left : Element_Type;
1043 Right : Node_Access) return Boolean
1045 begin
1046 -- Compute e > node same as node < e
1048 return Right.Element < Left;
1049 end Is_Greater_Element_Node;
1051 --------------------------
1052 -- Is_Less_Element_Node --
1053 --------------------------
1055 function Is_Less_Element_Node
1056 (Left : Element_Type;
1057 Right : Node_Access) return Boolean
1059 begin
1060 return Left < Right.Element;
1061 end Is_Less_Element_Node;
1063 -----------------------
1064 -- Is_Less_Node_Node --
1065 -----------------------
1067 function Is_Less_Node_Node (L, R : Node_Access) return Boolean is
1068 begin
1069 return L.Element < R.Element;
1070 end Is_Less_Node_Node;
1072 ---------------
1073 -- Is_Subset --
1074 ---------------
1076 function Is_Subset (Subset : Set; Of_Set : Set) return Boolean is
1077 begin
1078 return Set_Ops.Is_Subset (Subset => Subset.Tree, Of_Set => Of_Set.Tree);
1079 end Is_Subset;
1081 -------------
1082 -- Iterate --
1083 -------------
1085 procedure Iterate
1086 (Container : Set;
1087 Process : not null access procedure (Position : Cursor))
1089 procedure Process_Node (Node : Node_Access);
1090 pragma Inline (Process_Node);
1092 procedure Local_Iterate is
1093 new Tree_Operations.Generic_Iteration (Process_Node);
1095 ------------------
1096 -- Process_Node --
1097 ------------------
1099 procedure Process_Node (Node : Node_Access) is
1100 begin
1101 Process (Cursor'(Container'Unrestricted_Access, Node));
1102 end Process_Node;
1104 T : Tree_Type renames Container.Tree'Unrestricted_Access.all;
1105 B : Natural renames T.Busy;
1107 -- Start of prccessing for Iterate
1109 begin
1110 B := B + 1;
1112 begin
1113 Local_Iterate (T);
1114 exception
1115 when others =>
1116 B := B - 1;
1117 raise;
1118 end;
1120 B := B - 1;
1121 end Iterate;
1123 ----------
1124 -- Last --
1125 ----------
1127 function Last (Container : Set) return Cursor is
1128 begin
1129 if Container.Tree.Last = null then
1130 return No_Element;
1131 end if;
1133 return Cursor'(Container'Unrestricted_Access, Container.Tree.Last);
1134 end Last;
1136 ------------------
1137 -- Last_Element --
1138 ------------------
1140 function Last_Element (Container : Set) return Element_Type is
1141 begin
1142 if Container.Tree.Last = null then
1143 raise Constraint_Error with "set is empty";
1144 end if;
1146 return Container.Tree.Last.Element;
1147 end Last_Element;
1149 ----------
1150 -- Left --
1151 ----------
1153 function Left (Node : Node_Access) return Node_Access is
1154 begin
1155 return Node.Left;
1156 end Left;
1158 ------------
1159 -- Length --
1160 ------------
1162 function Length (Container : Set) return Count_Type is
1163 begin
1164 return Container.Tree.Length;
1165 end Length;
1167 ----------
1168 -- Move --
1169 ----------
1171 procedure Move is
1172 new Tree_Operations.Generic_Move (Clear);
1174 procedure Move (Target : in out Set; Source : in out Set) is
1175 begin
1176 Move (Target => Target.Tree, Source => Source.Tree);
1177 end Move;
1179 ----------
1180 -- Next --
1181 ----------
1183 function Next (Position : Cursor) return Cursor is
1184 begin
1185 if Position = No_Element then
1186 return No_Element;
1187 end if;
1189 pragma Assert (Vet (Position.Container.Tree, Position.Node),
1190 "bad cursor in Next");
1192 declare
1193 Node : constant Node_Access :=
1194 Tree_Operations.Next (Position.Node);
1196 begin
1197 if Node = null then
1198 return No_Element;
1199 end if;
1201 return Cursor'(Position.Container, Node);
1202 end;
1203 end Next;
1205 procedure Next (Position : in out Cursor) is
1206 begin
1207 Position := Next (Position);
1208 end Next;
1210 -------------
1211 -- Overlap --
1212 -------------
1214 function Overlap (Left, Right : Set) return Boolean is
1215 begin
1216 return Set_Ops.Overlap (Left.Tree, Right.Tree);
1217 end Overlap;
1219 ------------
1220 -- Parent --
1221 ------------
1223 function Parent (Node : Node_Access) return Node_Access is
1224 begin
1225 return Node.Parent;
1226 end Parent;
1228 --------------
1229 -- Previous --
1230 --------------
1232 function Previous (Position : Cursor) return Cursor is
1233 begin
1234 if Position = No_Element then
1235 return No_Element;
1236 end if;
1238 pragma Assert (Vet (Position.Container.Tree, Position.Node),
1239 "bad cursor in Previous");
1241 declare
1242 Node : constant Node_Access :=
1243 Tree_Operations.Previous (Position.Node);
1245 begin
1246 if Node = null then
1247 return No_Element;
1248 end if;
1250 return Cursor'(Position.Container, Node);
1251 end;
1252 end Previous;
1254 procedure Previous (Position : in out Cursor) is
1255 begin
1256 Position := Previous (Position);
1257 end Previous;
1259 -------------------
1260 -- Query_Element --
1261 -------------------
1263 procedure Query_Element
1264 (Position : Cursor;
1265 Process : not null access procedure (Element : Element_Type))
1267 begin
1268 if Position.Node = null then
1269 raise Constraint_Error with "Position cursor equals No_Element";
1270 end if;
1272 pragma Assert (Vet (Position.Container.Tree, Position.Node),
1273 "bad cursor in Query_Element");
1275 declare
1276 T : Tree_Type renames Position.Container.Tree;
1278 B : Natural renames T.Busy;
1279 L : Natural renames T.Lock;
1281 begin
1282 B := B + 1;
1283 L := L + 1;
1285 begin
1286 Process (Position.Node.Element);
1287 exception
1288 when others =>
1289 L := L - 1;
1290 B := B - 1;
1291 raise;
1292 end;
1294 L := L - 1;
1295 B := B - 1;
1296 end;
1297 end Query_Element;
1299 ----------
1300 -- Read --
1301 ----------
1303 procedure Read
1304 (Stream : access Root_Stream_Type'Class;
1305 Container : out Set)
1307 function Read_Node
1308 (Stream : access Root_Stream_Type'Class) return Node_Access;
1309 pragma Inline (Read_Node);
1311 procedure Read is
1312 new Tree_Operations.Generic_Read (Clear, Read_Node);
1314 ---------------
1315 -- Read_Node --
1316 ---------------
1318 function Read_Node
1319 (Stream : access Root_Stream_Type'Class) return Node_Access
1321 Node : Node_Access := new Node_Type;
1323 begin
1324 Element_Type'Read (Stream, Node.Element);
1325 return Node;
1327 exception
1328 when others =>
1329 Free (Node);
1330 raise;
1331 end Read_Node;
1333 -- Start of processing for Read
1335 begin
1336 Read (Stream, Container.Tree);
1337 end Read;
1339 procedure Read
1340 (Stream : access Root_Stream_Type'Class;
1341 Item : out Cursor)
1343 begin
1344 raise Program_Error with "attempt to stream set cursor";
1345 end Read;
1347 -------------
1348 -- Replace --
1349 -------------
1351 procedure Replace (Container : in out Set; New_Item : Element_Type) is
1352 Node : constant Node_Access :=
1353 Element_Keys.Find (Container.Tree, New_Item);
1355 begin
1356 if Node = null then
1357 raise Constraint_Error with
1358 "attempt to replace element not in set";
1359 end if;
1361 if Container.Tree.Lock > 0 then
1362 raise Program_Error with
1363 "attempt to tamper with cursors (set is locked)";
1364 end if;
1366 Node.Element := New_Item;
1367 end Replace;
1369 ---------------------
1370 -- Replace_Element --
1371 ---------------------
1373 procedure Replace_Element
1374 (Tree : in out Tree_Type;
1375 Node : Node_Access;
1376 Item : Element_Type)
1378 begin
1379 if Item < Node.Element
1380 or else Node.Element < Item
1381 then
1382 null;
1383 else
1384 if Tree.Lock > 0 then
1385 raise Program_Error with
1386 "attempt to tamper with cursors (set is locked)";
1387 end if;
1389 Node.Element := Item;
1390 return;
1391 end if;
1393 Tree_Operations.Delete_Node_Sans_Free (Tree, Node); -- Checks busy-bit
1395 Insert_New_Item : declare
1396 function New_Node return Node_Access;
1397 pragma Inline (New_Node);
1399 procedure Insert_Post is
1400 new Element_Keys.Generic_Insert_Post (New_Node);
1402 procedure Insert is
1403 new Element_Keys.Generic_Conditional_Insert (Insert_Post);
1405 --------------
1406 -- New_Node --
1407 --------------
1409 function New_Node return Node_Access is
1410 begin
1411 Node.Element := Item;
1412 Node.Color := Red;
1413 Node.Parent := null;
1414 Node.Right := null;
1415 Node.Left := null;
1417 return Node;
1418 end New_Node;
1420 Result : Node_Access;
1421 Inserted : Boolean;
1423 -- Start of processing for Insert_New_Item
1425 begin
1426 Insert
1427 (Tree => Tree,
1428 Key => Item,
1429 Node => Result,
1430 Success => Inserted); -- TODO: change param name
1432 if Inserted then
1433 pragma Assert (Result = Node);
1434 return;
1435 end if;
1436 exception
1437 when others =>
1438 null; -- Assignment must have failed
1439 end Insert_New_Item;
1441 Reinsert_Old_Element : declare
1442 function New_Node return Node_Access;
1443 pragma Inline (New_Node);
1445 procedure Insert_Post is
1446 new Element_Keys.Generic_Insert_Post (New_Node);
1448 procedure Insert is
1449 new Element_Keys.Generic_Conditional_Insert (Insert_Post);
1451 --------------
1452 -- New_Node --
1453 --------------
1455 function New_Node return Node_Access is
1456 begin
1457 Node.Color := Red;
1458 Node.Parent := null;
1459 Node.Right := null;
1460 Node.Left := null;
1462 return Node;
1463 end New_Node;
1465 Result : Node_Access;
1466 Inserted : Boolean;
1468 -- Start of processing for Reinsert_Old_Element
1470 begin
1471 Insert
1472 (Tree => Tree,
1473 Key => Node.Element,
1474 Node => Result,
1475 Success => Inserted); -- TODO: change param name
1476 exception
1477 when others =>
1478 null; -- Assignment must have failed
1479 end Reinsert_Old_Element;
1481 raise Program_Error with "attempt to replace existing element";
1482 end Replace_Element;
1484 procedure Replace_Element
1485 (Container : in out Set;
1486 Position : Cursor;
1487 New_Item : Element_Type)
1489 begin
1490 if Position.Node = null then
1491 raise Constraint_Error with
1492 "Position cursor equals No_Element";
1493 end if;
1495 if Position.Container /= Container'Unrestricted_Access then
1496 raise Program_Error with
1497 "Position cursor designates wrong set";
1498 end if;
1500 pragma Assert (Vet (Container.Tree, Position.Node),
1501 "bad cursor in Replace_Element");
1503 Replace_Element (Container.Tree, Position.Node, New_Item);
1504 end Replace_Element;
1506 ---------------------
1507 -- Reverse_Iterate --
1508 ---------------------
1510 procedure Reverse_Iterate
1511 (Container : Set;
1512 Process : not null access procedure (Position : Cursor))
1514 procedure Process_Node (Node : Node_Access);
1515 pragma Inline (Process_Node);
1517 procedure Local_Reverse_Iterate is
1518 new Tree_Operations.Generic_Reverse_Iteration (Process_Node);
1520 ------------------
1521 -- Process_Node --
1522 ------------------
1524 procedure Process_Node (Node : Node_Access) is
1525 begin
1526 Process (Cursor'(Container'Unrestricted_Access, Node));
1527 end Process_Node;
1529 T : Tree_Type renames Container.Tree'Unrestricted_Access.all;
1530 B : Natural renames T.Busy;
1532 -- Start of processing for Reverse_Iterate
1534 begin
1535 B := B + 1;
1537 begin
1538 Local_Reverse_Iterate (T);
1539 exception
1540 when others =>
1541 B := B - 1;
1542 raise;
1543 end;
1545 B := B - 1;
1546 end Reverse_Iterate;
1548 -----------
1549 -- Right --
1550 -----------
1552 function Right (Node : Node_Access) return Node_Access is
1553 begin
1554 return Node.Right;
1555 end Right;
1557 ---------------
1558 -- Set_Color --
1559 ---------------
1561 procedure Set_Color (Node : Node_Access; Color : Color_Type) is
1562 begin
1563 Node.Color := Color;
1564 end Set_Color;
1566 --------------
1567 -- Set_Left --
1568 --------------
1570 procedure Set_Left (Node : Node_Access; Left : Node_Access) is
1571 begin
1572 Node.Left := Left;
1573 end Set_Left;
1575 ----------------
1576 -- Set_Parent --
1577 ----------------
1579 procedure Set_Parent (Node : Node_Access; Parent : Node_Access) is
1580 begin
1581 Node.Parent := Parent;
1582 end Set_Parent;
1584 ---------------
1585 -- Set_Right --
1586 ---------------
1588 procedure Set_Right (Node : Node_Access; Right : Node_Access) is
1589 begin
1590 Node.Right := Right;
1591 end Set_Right;
1593 --------------------------
1594 -- Symmetric_Difference --
1595 --------------------------
1597 procedure Symmetric_Difference (Target : in out Set; Source : Set) is
1598 begin
1599 Set_Ops.Symmetric_Difference (Target.Tree, Source.Tree);
1600 end Symmetric_Difference;
1602 function Symmetric_Difference (Left, Right : Set) return Set is
1603 Tree : constant Tree_Type :=
1604 Set_Ops.Symmetric_Difference (Left.Tree, Right.Tree);
1605 begin
1606 return Set'(Controlled with Tree);
1607 end Symmetric_Difference;
1609 ------------
1610 -- To_Set --
1611 ------------
1613 function To_Set (New_Item : Element_Type) return Set is
1614 Tree : Tree_Type;
1615 Node : Node_Access;
1616 Inserted : Boolean;
1618 begin
1619 Insert_Sans_Hint (Tree, New_Item, Node, Inserted);
1620 return Set'(Controlled with Tree);
1621 end To_Set;
1623 -----------
1624 -- Union --
1625 -----------
1627 procedure Union (Target : in out Set; Source : Set) is
1628 begin
1629 Set_Ops.Union (Target.Tree, Source.Tree);
1630 end Union;
1632 function Union (Left, Right : Set) return Set is
1633 Tree : constant Tree_Type :=
1634 Set_Ops.Union (Left.Tree, Right.Tree);
1635 begin
1636 return Set'(Controlled with Tree);
1637 end Union;
1639 -----------
1640 -- Write --
1641 -----------
1643 procedure Write
1644 (Stream : access Root_Stream_Type'Class;
1645 Container : Set)
1647 procedure Write_Node
1648 (Stream : access Root_Stream_Type'Class;
1649 Node : Node_Access);
1650 pragma Inline (Write_Node);
1652 procedure Write is
1653 new Tree_Operations.Generic_Write (Write_Node);
1655 ----------------
1656 -- Write_Node --
1657 ----------------
1659 procedure Write_Node
1660 (Stream : access Root_Stream_Type'Class;
1661 Node : Node_Access)
1663 begin
1664 Element_Type'Write (Stream, Node.Element);
1665 end Write_Node;
1667 -- Start of processing for Write
1669 begin
1670 Write (Stream, Container.Tree);
1671 end Write;
1673 procedure Write
1674 (Stream : access Root_Stream_Type'Class;
1675 Item : Cursor)
1677 begin
1678 raise Program_Error with "attempt to stream set cursor";
1679 end Write;
1681 end Ada.Containers.Ordered_Sets;