* gcc.dg/compat/struct-layout-1_generate.c (dg_options): New. Moved
[official-gcc.git] / gcc / ada / a-coorma.adb
blob7924fcd7ebec469b7f720777591bc2cb00fdd2a9
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 _ M A P S --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2004-2007, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
21 -- --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
28 -- --
29 -- This unit was originally developed by Matthew J Heaney. --
30 ------------------------------------------------------------------------------
32 with Ada.Unchecked_Deallocation;
34 with Ada.Containers.Red_Black_Trees.Generic_Operations;
35 pragma Elaborate_All (Ada.Containers.Red_Black_Trees.Generic_Operations);
37 with Ada.Containers.Red_Black_Trees.Generic_Keys;
38 pragma Elaborate_All (Ada.Containers.Red_Black_Trees.Generic_Keys);
40 package body Ada.Containers.Ordered_Maps is
42 -----------------------------
43 -- Node Access Subprograms --
44 -----------------------------
46 -- These subprograms provide a functional interface to access fields
47 -- of a node, and a procedural interface for modifying these values.
49 function Color (Node : Node_Access) return Color_Type;
50 pragma Inline (Color);
52 function Left (Node : Node_Access) return Node_Access;
53 pragma Inline (Left);
55 function Parent (Node : Node_Access) return Node_Access;
56 pragma Inline (Parent);
58 function Right (Node : Node_Access) return Node_Access;
59 pragma Inline (Right);
61 procedure Set_Parent (Node : Node_Access; Parent : Node_Access);
62 pragma Inline (Set_Parent);
64 procedure Set_Left (Node : Node_Access; Left : Node_Access);
65 pragma Inline (Set_Left);
67 procedure Set_Right (Node : Node_Access; Right : Node_Access);
68 pragma Inline (Set_Right);
70 procedure Set_Color (Node : Node_Access; Color : Color_Type);
71 pragma Inline (Set_Color);
73 -----------------------
74 -- Local Subprograms --
75 -----------------------
77 function Copy_Node (Source : Node_Access) return Node_Access;
78 pragma Inline (Copy_Node);
80 procedure Free (X : in out Node_Access);
82 function Is_Equal_Node_Node (L, R : Node_Access) return Boolean;
83 pragma Inline (Is_Equal_Node_Node);
85 function Is_Greater_Key_Node
86 (Left : Key_Type;
87 Right : Node_Access) return Boolean;
88 pragma Inline (Is_Greater_Key_Node);
90 function Is_Less_Key_Node
91 (Left : Key_Type;
92 Right : Node_Access) return Boolean;
93 pragma Inline (Is_Less_Key_Node);
95 --------------------------
96 -- Local Instantiations --
97 --------------------------
99 package Tree_Operations is
100 new Red_Black_Trees.Generic_Operations (Tree_Types);
102 procedure Delete_Tree is
103 new Tree_Operations.Generic_Delete_Tree (Free);
105 function Copy_Tree is
106 new Tree_Operations.Generic_Copy_Tree (Copy_Node, Delete_Tree);
108 use Tree_Operations;
110 package Key_Ops is
111 new Red_Black_Trees.Generic_Keys
112 (Tree_Operations => Tree_Operations,
113 Key_Type => Key_Type,
114 Is_Less_Key_Node => Is_Less_Key_Node,
115 Is_Greater_Key_Node => Is_Greater_Key_Node);
117 function Is_Equal is
118 new Tree_Operations.Generic_Equal (Is_Equal_Node_Node);
120 ---------
121 -- "<" --
122 ---------
124 function "<" (Left, Right : Cursor) return Boolean is
125 begin
126 if Left.Node = null then
127 raise Constraint_Error with "Left cursor of ""<"" equals No_Element";
128 end if;
130 if Right.Node = null then
131 raise Constraint_Error with "Right cursor of ""<"" equals No_Element";
132 end if;
134 pragma Assert (Vet (Left.Container.Tree, Left.Node),
135 "Left cursor of ""<"" is bad");
137 pragma Assert (Vet (Right.Container.Tree, Right.Node),
138 "Right cursor of ""<"" is bad");
140 return Left.Node.Key < Right.Node.Key;
141 end "<";
143 function "<" (Left : Cursor; Right : Key_Type) return Boolean is
144 begin
145 if Left.Node = null then
146 raise Constraint_Error with "Left cursor of ""<"" equals No_Element";
147 end if;
149 pragma Assert (Vet (Left.Container.Tree, Left.Node),
150 "Left cursor of ""<"" is bad");
152 return Left.Node.Key < Right;
153 end "<";
155 function "<" (Left : Key_Type; Right : Cursor) return Boolean is
156 begin
157 if Right.Node = null then
158 raise Constraint_Error with "Right cursor of ""<"" equals No_Element";
159 end if;
161 pragma Assert (Vet (Right.Container.Tree, Right.Node),
162 "Right cursor of ""<"" is bad");
164 return Left < Right.Node.Key;
165 end "<";
167 ---------
168 -- "=" --
169 ---------
171 function "=" (Left, Right : Map) return Boolean is
172 begin
173 return Is_Equal (Left.Tree, Right.Tree);
174 end "=";
176 ---------
177 -- ">" --
178 ---------
180 function ">" (Left, Right : Cursor) return Boolean is
181 begin
182 if Left.Node = null then
183 raise Constraint_Error with "Left cursor of "">"" equals No_Element";
184 end if;
186 if Right.Node = null then
187 raise Constraint_Error with "Right cursor of "">"" equals No_Element";
188 end if;
190 pragma Assert (Vet (Left.Container.Tree, Left.Node),
191 "Left cursor of "">"" is bad");
193 pragma Assert (Vet (Right.Container.Tree, Right.Node),
194 "Right cursor of "">"" is bad");
196 return Right.Node.Key < Left.Node.Key;
197 end ">";
199 function ">" (Left : Cursor; Right : Key_Type) return Boolean is
200 begin
201 if Left.Node = null then
202 raise Constraint_Error with "Left cursor of "">"" equals No_Element";
203 end if;
205 pragma Assert (Vet (Left.Container.Tree, Left.Node),
206 "Left cursor of "">"" is bad");
208 return Right < Left.Node.Key;
209 end ">";
211 function ">" (Left : Key_Type; Right : Cursor) return Boolean is
212 begin
213 if Right.Node = null then
214 raise Constraint_Error with "Right cursor of "">"" equals No_Element";
215 end if;
217 pragma Assert (Vet (Right.Container.Tree, Right.Node),
218 "Right cursor of "">"" is bad");
220 return Right.Node.Key < Left;
221 end ">";
223 ------------
224 -- Adjust --
225 ------------
227 procedure Adjust is
228 new Tree_Operations.Generic_Adjust (Copy_Tree);
230 procedure Adjust (Container : in out Map) is
231 begin
232 Adjust (Container.Tree);
233 end Adjust;
235 -------------
236 -- Ceiling --
237 -------------
239 function Ceiling (Container : Map; Key : Key_Type) return Cursor is
240 Node : constant Node_Access := Key_Ops.Ceiling (Container.Tree, Key);
242 begin
243 if Node = null then
244 return No_Element;
245 end if;
247 return Cursor'(Container'Unrestricted_Access, Node);
248 end Ceiling;
250 -----------
251 -- Clear --
252 -----------
254 procedure Clear is
255 new Tree_Operations.Generic_Clear (Delete_Tree);
257 procedure Clear (Container : in out Map) is
258 begin
259 Clear (Container.Tree);
260 end Clear;
262 -----------
263 -- Color --
264 -----------
266 function Color (Node : Node_Access) return Color_Type is
267 begin
268 return Node.Color;
269 end Color;
271 --------------
272 -- Contains --
273 --------------
275 function Contains (Container : Map; Key : Key_Type) return Boolean is
276 begin
277 return Find (Container, Key) /= No_Element;
278 end Contains;
280 ---------------
281 -- Copy_Node --
282 ---------------
284 function Copy_Node (Source : Node_Access) return Node_Access is
285 Target : constant Node_Access :=
286 new Node_Type'(Color => Source.Color,
287 Key => Source.Key,
288 Element => Source.Element,
289 Parent => null,
290 Left => null,
291 Right => null);
292 begin
293 return Target;
294 end Copy_Node;
296 ------------
297 -- Delete --
298 ------------
300 procedure Delete (Container : in out Map; Position : in out Cursor) is
301 Tree : Tree_Type renames Container.Tree;
303 begin
304 if Position.Node = null then
305 raise Constraint_Error with
306 "Position cursor of Delete equals No_Element";
307 end if;
309 if Position.Container /= Container'Unrestricted_Access then
310 raise Program_Error with
311 "Position cursor of Delete designates wrong map";
312 end if;
314 pragma Assert (Vet (Tree, Position.Node),
315 "Position cursor of Delete is bad");
317 Tree_Operations.Delete_Node_Sans_Free (Tree, Position.Node);
318 Free (Position.Node);
320 Position.Container := null;
321 end Delete;
323 procedure Delete (Container : in out Map; Key : Key_Type) is
324 X : Node_Access := Key_Ops.Find (Container.Tree, Key);
326 begin
327 if X = null then
328 raise Constraint_Error with "key not in map";
329 end if;
331 Tree_Operations.Delete_Node_Sans_Free (Container.Tree, X);
332 Free (X);
333 end Delete;
335 ------------------
336 -- Delete_First --
337 ------------------
339 procedure Delete_First (Container : in out Map) is
340 X : Node_Access := Container.Tree.First;
342 begin
343 if X /= null then
344 Tree_Operations.Delete_Node_Sans_Free (Container.Tree, X);
345 Free (X);
346 end if;
347 end Delete_First;
349 -----------------
350 -- Delete_Last --
351 -----------------
353 procedure Delete_Last (Container : in out Map) is
354 X : Node_Access := Container.Tree.Last;
356 begin
357 if X /= null then
358 Tree_Operations.Delete_Node_Sans_Free (Container.Tree, X);
359 Free (X);
360 end if;
361 end Delete_Last;
363 -------------
364 -- Element --
365 -------------
367 function Element (Position : Cursor) return Element_Type is
368 begin
369 if Position.Node = null then
370 raise Constraint_Error with
371 "Position cursor of function Element equals No_Element";
372 end if;
374 pragma Assert (Vet (Position.Container.Tree, Position.Node),
375 "Position cursor of function Element is bad");
377 return Position.Node.Element;
378 end Element;
380 function Element (Container : Map; Key : Key_Type) return Element_Type is
381 Node : constant Node_Access := Key_Ops.Find (Container.Tree, Key);
383 begin
384 if Node = null then
385 raise Constraint_Error with "key not in map";
386 end if;
388 return Node.Element;
389 end Element;
391 ---------------------
392 -- Equivalent_Keys --
393 ---------------------
395 function Equivalent_Keys (Left, Right : Key_Type) return Boolean is
396 begin
397 if Left < Right
398 or else Right < Left
399 then
400 return False;
401 else
402 return True;
403 end if;
404 end Equivalent_Keys;
406 -------------
407 -- Exclude --
408 -------------
410 procedure Exclude (Container : in out Map; Key : Key_Type) is
411 X : Node_Access := Key_Ops.Find (Container.Tree, Key);
413 begin
414 if X /= null then
415 Tree_Operations.Delete_Node_Sans_Free (Container.Tree, X);
416 Free (X);
417 end if;
418 end Exclude;
420 ----------
421 -- Find --
422 ----------
424 function Find (Container : Map; Key : Key_Type) return Cursor is
425 Node : constant Node_Access := Key_Ops.Find (Container.Tree, Key);
427 begin
428 if Node = null then
429 return No_Element;
430 end if;
432 return Cursor'(Container'Unrestricted_Access, Node);
433 end Find;
435 -----------
436 -- First --
437 -----------
439 function First (Container : Map) return Cursor is
440 T : Tree_Type renames Container.Tree;
442 begin
443 if T.First = null then
444 return No_Element;
445 end if;
447 return Cursor'(Container'Unrestricted_Access, T.First);
448 end First;
450 -------------------
451 -- First_Element --
452 -------------------
454 function First_Element (Container : Map) return Element_Type is
455 T : Tree_Type renames Container.Tree;
457 begin
458 if T.First = null then
459 raise Constraint_Error with "map is empty";
460 end if;
462 return T.First.Element;
463 end First_Element;
465 ---------------
466 -- First_Key --
467 ---------------
469 function First_Key (Container : Map) return Key_Type is
470 T : Tree_Type renames Container.Tree;
472 begin
473 if T.First = null then
474 raise Constraint_Error with "map is empty";
475 end if;
477 return T.First.Key;
478 end First_Key;
480 -----------
481 -- Floor --
482 -----------
484 function Floor (Container : Map; Key : Key_Type) return Cursor is
485 Node : constant Node_Access := Key_Ops.Floor (Container.Tree, Key);
487 begin
488 if Node = null then
489 return No_Element;
490 end if;
492 return Cursor'(Container'Unrestricted_Access, Node);
493 end Floor;
495 ----------
496 -- Free --
497 ----------
499 procedure Free (X : in out Node_Access) is
500 procedure Deallocate is
501 new Ada.Unchecked_Deallocation (Node_Type, Node_Access);
503 begin
504 if X = null then
505 return;
506 end if;
508 X.Parent := X;
509 X.Left := X;
510 X.Right := X;
512 Deallocate (X);
513 end Free;
515 -----------------
516 -- Has_Element --
517 -----------------
519 function Has_Element (Position : Cursor) return Boolean is
520 begin
521 return Position /= No_Element;
522 end Has_Element;
524 -------------
525 -- Include --
526 -------------
528 procedure Include
529 (Container : in out Map;
530 Key : Key_Type;
531 New_Item : Element_Type)
533 Position : Cursor;
534 Inserted : Boolean;
536 begin
537 Insert (Container, Key, New_Item, Position, Inserted);
539 if not Inserted then
540 if Container.Tree.Lock > 0 then
541 raise Program_Error with
542 "attempt to tamper with cursors (map is locked)";
543 end if;
545 Position.Node.Key := Key;
546 Position.Node.Element := New_Item;
547 end if;
548 end Include;
550 procedure Insert
551 (Container : in out Map;
552 Key : Key_Type;
553 New_Item : Element_Type;
554 Position : out Cursor;
555 Inserted : out Boolean)
557 function New_Node return Node_Access;
558 pragma Inline (New_Node);
560 procedure Insert_Post is
561 new Key_Ops.Generic_Insert_Post (New_Node);
563 procedure Insert_Sans_Hint is
564 new Key_Ops.Generic_Conditional_Insert (Insert_Post);
566 --------------
567 -- New_Node --
568 --------------
570 function New_Node return Node_Access is
571 begin
572 return new Node_Type'(Key => Key,
573 Element => New_Item,
574 Color => Red_Black_Trees.Red,
575 Parent => null,
576 Left => null,
577 Right => null);
578 end New_Node;
580 -- Start of processing for Insert
582 begin
583 Insert_Sans_Hint
584 (Container.Tree,
585 Key,
586 Position.Node,
587 Inserted);
589 Position.Container := Container'Unrestricted_Access;
590 end Insert;
592 procedure Insert
593 (Container : in out Map;
594 Key : Key_Type;
595 New_Item : Element_Type)
597 Position : Cursor;
598 pragma Unreferenced (Position);
600 Inserted : Boolean;
602 begin
603 Insert (Container, Key, New_Item, Position, Inserted);
605 if not Inserted then
606 raise Constraint_Error with "key already in map";
607 end if;
608 end Insert;
610 ------------
611 -- Insert --
612 ------------
614 procedure Insert
615 (Container : in out Map;
616 Key : Key_Type;
617 Position : out Cursor;
618 Inserted : out Boolean)
620 function New_Node return Node_Access;
621 pragma Inline (New_Node);
623 procedure Insert_Post is
624 new Key_Ops.Generic_Insert_Post (New_Node);
626 procedure Insert_Sans_Hint is
627 new Key_Ops.Generic_Conditional_Insert (Insert_Post);
629 --------------
630 -- New_Node --
631 --------------
633 function New_Node return Node_Access is
634 begin
635 return new Node_Type'(Key => Key,
636 Element => <>,
637 Color => Red_Black_Trees.Red,
638 Parent => null,
639 Left => null,
640 Right => null);
641 end New_Node;
643 -- Start of processing for Insert
645 begin
646 Insert_Sans_Hint
647 (Container.Tree,
648 Key,
649 Position.Node,
650 Inserted);
652 Position.Container := Container'Unrestricted_Access;
653 end Insert;
655 --------------
656 -- Is_Empty --
657 --------------
659 function Is_Empty (Container : Map) return Boolean is
660 begin
661 return Container.Tree.Length = 0;
662 end Is_Empty;
664 ------------------------
665 -- Is_Equal_Node_Node --
666 ------------------------
668 function Is_Equal_Node_Node
669 (L, R : Node_Access) return Boolean is
670 begin
671 if L.Key < R.Key then
672 return False;
674 elsif R.Key < L.Key then
675 return False;
677 else
678 return L.Element = R.Element;
679 end if;
680 end Is_Equal_Node_Node;
682 -------------------------
683 -- Is_Greater_Key_Node --
684 -------------------------
686 function Is_Greater_Key_Node
687 (Left : Key_Type;
688 Right : Node_Access) return Boolean
690 begin
691 -- k > node same as node < k
693 return Right.Key < Left;
694 end Is_Greater_Key_Node;
696 ----------------------
697 -- Is_Less_Key_Node --
698 ----------------------
700 function Is_Less_Key_Node
701 (Left : Key_Type;
702 Right : Node_Access) return Boolean
704 begin
705 return Left < Right.Key;
706 end Is_Less_Key_Node;
708 -------------
709 -- Iterate --
710 -------------
712 procedure Iterate
713 (Container : Map;
714 Process : not null access procedure (Position : Cursor))
716 procedure Process_Node (Node : Node_Access);
717 pragma Inline (Process_Node);
719 procedure Local_Iterate is
720 new Tree_Operations.Generic_Iteration (Process_Node);
722 ------------------
723 -- Process_Node --
724 ------------------
726 procedure Process_Node (Node : Node_Access) is
727 begin
728 Process (Cursor'(Container'Unrestricted_Access, Node));
729 end Process_Node;
731 B : Natural renames Container.Tree'Unrestricted_Access.all.Busy;
733 -- Start of processing for Iterate
735 begin
736 B := B + 1;
738 begin
739 Local_Iterate (Container.Tree);
740 exception
741 when others =>
742 B := B - 1;
743 raise;
744 end;
746 B := B - 1;
747 end Iterate;
749 ---------
750 -- Key --
751 ---------
753 function Key (Position : Cursor) return Key_Type is
754 begin
755 if Position.Node = null then
756 raise Constraint_Error with
757 "Position cursor of function Key equals No_Element";
758 end if;
760 pragma Assert (Vet (Position.Container.Tree, Position.Node),
761 "Position cursor of function Key is bad");
763 return Position.Node.Key;
764 end Key;
766 ----------
767 -- Last --
768 ----------
770 function Last (Container : Map) return Cursor is
771 T : Tree_Type renames Container.Tree;
773 begin
774 if T.Last = null then
775 return No_Element;
776 end if;
778 return Cursor'(Container'Unrestricted_Access, T.Last);
779 end Last;
781 ------------------
782 -- Last_Element --
783 ------------------
785 function Last_Element (Container : Map) return Element_Type is
786 T : Tree_Type renames Container.Tree;
788 begin
789 if T.Last = null then
790 raise Constraint_Error with "map is empty";
791 end if;
793 return T.Last.Element;
794 end Last_Element;
796 --------------
797 -- Last_Key --
798 --------------
800 function Last_Key (Container : Map) return Key_Type is
801 T : Tree_Type renames Container.Tree;
803 begin
804 if T.Last = null then
805 raise Constraint_Error with "map is empty";
806 end if;
808 return T.Last.Key;
809 end Last_Key;
811 ----------
812 -- Left --
813 ----------
815 function Left (Node : Node_Access) return Node_Access is
816 begin
817 return Node.Left;
818 end Left;
820 ------------
821 -- Length --
822 ------------
824 function Length (Container : Map) return Count_Type is
825 begin
826 return Container.Tree.Length;
827 end Length;
829 ----------
830 -- Move --
831 ----------
833 procedure Move is
834 new Tree_Operations.Generic_Move (Clear);
836 procedure Move (Target : in out Map; Source : in out Map) is
837 begin
838 Move (Target => Target.Tree, Source => Source.Tree);
839 end Move;
841 ----------
842 -- Next --
843 ----------
845 procedure Next (Position : in out Cursor) is
846 begin
847 Position := Next (Position);
848 end Next;
850 function Next (Position : Cursor) return Cursor is
851 begin
852 if Position = No_Element then
853 return No_Element;
854 end if;
856 pragma Assert (Vet (Position.Container.Tree, Position.Node),
857 "Position cursor of Next is bad");
859 declare
860 Node : constant Node_Access :=
861 Tree_Operations.Next (Position.Node);
863 begin
864 if Node = null then
865 return No_Element;
866 end if;
868 return Cursor'(Position.Container, Node);
869 end;
870 end Next;
872 ------------
873 -- Parent --
874 ------------
876 function Parent (Node : Node_Access) return Node_Access is
877 begin
878 return Node.Parent;
879 end Parent;
881 --------------
882 -- Previous --
883 --------------
885 procedure Previous (Position : in out Cursor) is
886 begin
887 Position := Previous (Position);
888 end Previous;
890 function Previous (Position : Cursor) return Cursor is
891 begin
892 if Position = No_Element then
893 return No_Element;
894 end if;
896 pragma Assert (Vet (Position.Container.Tree, Position.Node),
897 "Position cursor of Previous is bad");
899 declare
900 Node : constant Node_Access :=
901 Tree_Operations.Previous (Position.Node);
903 begin
904 if Node = null then
905 return No_Element;
906 end if;
908 return Cursor'(Position.Container, Node);
909 end;
910 end Previous;
912 -------------------
913 -- Query_Element --
914 -------------------
916 procedure Query_Element
917 (Position : Cursor;
918 Process : not null access procedure (Key : Key_Type;
919 Element : Element_Type))
921 begin
922 if Position.Node = null then
923 raise Constraint_Error with
924 "Position cursor of Query_Element equals No_Element";
925 end if;
927 pragma Assert (Vet (Position.Container.Tree, Position.Node),
928 "Position cursor of Query_Element is bad");
930 declare
931 T : Tree_Type renames Position.Container.Tree;
933 B : Natural renames T.Busy;
934 L : Natural renames T.Lock;
936 begin
937 B := B + 1;
938 L := L + 1;
940 declare
941 K : Key_Type renames Position.Node.Key;
942 E : Element_Type renames Position.Node.Element;
944 begin
945 Process (K, E);
946 exception
947 when others =>
948 L := L - 1;
949 B := B - 1;
950 raise;
951 end;
953 L := L - 1;
954 B := B - 1;
955 end;
956 end Query_Element;
958 ----------
959 -- Read --
960 ----------
962 procedure Read
963 (Stream : not null access Root_Stream_Type'Class;
964 Container : out Map)
966 function Read_Node
967 (Stream : not null access Root_Stream_Type'Class) return Node_Access;
968 pragma Inline (Read_Node);
970 procedure Read is
971 new Tree_Operations.Generic_Read (Clear, Read_Node);
973 ---------------
974 -- Read_Node --
975 ---------------
977 function Read_Node
978 (Stream : not null access Root_Stream_Type'Class) return Node_Access
980 Node : Node_Access := new Node_Type;
981 begin
982 Key_Type'Read (Stream, Node.Key);
983 Element_Type'Read (Stream, Node.Element);
984 return Node;
985 exception
986 when others =>
987 Free (Node);
988 raise;
989 end Read_Node;
991 -- Start of processing for Read
993 begin
994 Read (Stream, Container.Tree);
995 end Read;
997 procedure Read
998 (Stream : not null access Root_Stream_Type'Class;
999 Item : out Cursor)
1001 begin
1002 raise Program_Error with "attempt to stream map cursor";
1003 end Read;
1005 -------------
1006 -- Replace --
1007 -------------
1009 procedure Replace
1010 (Container : in out Map;
1011 Key : Key_Type;
1012 New_Item : Element_Type)
1014 Node : constant Node_Access := Key_Ops.Find (Container.Tree, Key);
1016 begin
1017 if Node = null then
1018 raise Constraint_Error with "key not in map";
1019 end if;
1021 if Container.Tree.Lock > 0 then
1022 raise Program_Error with
1023 "attempt to tamper with cursors (map is locked)";
1024 end if;
1026 Node.Key := Key;
1027 Node.Element := New_Item;
1028 end Replace;
1030 ---------------------
1031 -- Replace_Element --
1032 ---------------------
1034 procedure Replace_Element
1035 (Container : in out Map;
1036 Position : Cursor;
1037 New_Item : Element_Type)
1039 begin
1040 if Position.Node = null then
1041 raise Constraint_Error with
1042 "Position cursor of Replace_Element equals No_Element";
1043 end if;
1045 if Position.Container /= Container'Unrestricted_Access then
1046 raise Program_Error with
1047 "Position cursor of Replace_Element designates wrong map";
1048 end if;
1050 if Container.Tree.Lock > 0 then
1051 raise Program_Error with
1052 "attempt to tamper with cursors (map is locked)";
1053 end if;
1055 pragma Assert (Vet (Container.Tree, Position.Node),
1056 "Position cursor of Replace_Element is bad");
1058 Position.Node.Element := New_Item;
1059 end Replace_Element;
1061 ---------------------
1062 -- Reverse_Iterate --
1063 ---------------------
1065 procedure Reverse_Iterate
1066 (Container : Map;
1067 Process : not null access procedure (Position : Cursor))
1069 procedure Process_Node (Node : Node_Access);
1070 pragma Inline (Process_Node);
1072 procedure Local_Reverse_Iterate is
1073 new Tree_Operations.Generic_Reverse_Iteration (Process_Node);
1075 ------------------
1076 -- Process_Node --
1077 ------------------
1079 procedure Process_Node (Node : Node_Access) is
1080 begin
1081 Process (Cursor'(Container'Unrestricted_Access, Node));
1082 end Process_Node;
1084 B : Natural renames Container.Tree'Unrestricted_Access.all.Busy;
1086 -- Start of processing for Reverse_Iterate
1088 begin
1089 B := B + 1;
1091 begin
1092 Local_Reverse_Iterate (Container.Tree);
1093 exception
1094 when others =>
1095 B := B - 1;
1096 raise;
1097 end;
1099 B := B - 1;
1100 end Reverse_Iterate;
1102 -----------
1103 -- Right --
1104 -----------
1106 function Right (Node : Node_Access) return Node_Access is
1107 begin
1108 return Node.Right;
1109 end Right;
1111 ---------------
1112 -- Set_Color --
1113 ---------------
1115 procedure Set_Color
1116 (Node : Node_Access;
1117 Color : Color_Type)
1119 begin
1120 Node.Color := Color;
1121 end Set_Color;
1123 --------------
1124 -- Set_Left --
1125 --------------
1127 procedure Set_Left (Node : Node_Access; Left : Node_Access) is
1128 begin
1129 Node.Left := Left;
1130 end Set_Left;
1132 ----------------
1133 -- Set_Parent --
1134 ----------------
1136 procedure Set_Parent (Node : Node_Access; Parent : Node_Access) is
1137 begin
1138 Node.Parent := Parent;
1139 end Set_Parent;
1141 ---------------
1142 -- Set_Right --
1143 ---------------
1145 procedure Set_Right (Node : Node_Access; Right : Node_Access) is
1146 begin
1147 Node.Right := Right;
1148 end Set_Right;
1150 --------------------
1151 -- Update_Element --
1152 --------------------
1154 procedure Update_Element
1155 (Container : in out Map;
1156 Position : Cursor;
1157 Process : not null access procedure (Key : Key_Type;
1158 Element : in out Element_Type))
1160 begin
1161 if Position.Node = null then
1162 raise Constraint_Error with
1163 "Position cursor of Update_Element equals No_Element";
1164 end if;
1166 if Position.Container /= Container'Unrestricted_Access then
1167 raise Program_Error with
1168 "Position cursor of Update_Element designates wrong map";
1169 end if;
1171 pragma Assert (Vet (Container.Tree, Position.Node),
1172 "Position cursor of Update_Element is bad");
1174 declare
1175 T : Tree_Type renames Container.Tree;
1177 B : Natural renames T.Busy;
1178 L : Natural renames T.Lock;
1180 begin
1181 B := B + 1;
1182 L := L + 1;
1184 declare
1185 K : Key_Type renames Position.Node.Key;
1186 E : Element_Type renames Position.Node.Element;
1188 begin
1189 Process (K, E);
1191 exception
1192 when others =>
1193 L := L - 1;
1194 B := B - 1;
1195 raise;
1196 end;
1198 L := L - 1;
1199 B := B - 1;
1200 end;
1201 end Update_Element;
1203 -----------
1204 -- Write --
1205 -----------
1207 procedure Write
1208 (Stream : not null access Root_Stream_Type'Class;
1209 Container : Map)
1211 procedure Write_Node
1212 (Stream : not null access Root_Stream_Type'Class;
1213 Node : Node_Access);
1214 pragma Inline (Write_Node);
1216 procedure Write is
1217 new Tree_Operations.Generic_Write (Write_Node);
1219 ----------------
1220 -- Write_Node --
1221 ----------------
1223 procedure Write_Node
1224 (Stream : not null access Root_Stream_Type'Class;
1225 Node : Node_Access)
1227 begin
1228 Key_Type'Write (Stream, Node.Key);
1229 Element_Type'Write (Stream, Node.Element);
1230 end Write_Node;
1232 -- Start of processing for Write
1234 begin
1235 Write (Stream, Container.Tree);
1236 end Write;
1238 procedure Write
1239 (Stream : not null access Root_Stream_Type'Class;
1240 Item : Cursor)
1242 begin
1243 raise Program_Error with "attempt to stream map cursor";
1244 end Write;
1246 end Ada.Containers.Ordered_Maps;