PR rtl-optimization/79386
[official-gcc.git] / gcc / ada / a-cforma.adb
blob4bf302ded63a9b8dc7274b26f08d64de25fafe88
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT LIBRARY COMPONENTS --
4 -- --
5 -- A D A . C O N T A I N E R S . F O R M A L _ O R D E R E D _ M A P S --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2010-2015, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
17 -- --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
21 -- --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
26 ------------------------------------------------------------------------------
28 with Ada.Containers.Red_Black_Trees.Generic_Bounded_Operations;
29 pragma Elaborate_All
30 (Ada.Containers.Red_Black_Trees.Generic_Bounded_Operations);
32 with Ada.Containers.Red_Black_Trees.Generic_Bounded_Keys;
33 pragma Elaborate_All (Ada.Containers.Red_Black_Trees.Generic_Bounded_Keys);
35 with System; use type System.Address;
37 package body Ada.Containers.Formal_Ordered_Maps with
38 SPARK_Mode => Off
41 -----------------------------
42 -- Node Access Subprograms --
43 -----------------------------
45 -- These subprograms provide a functional interface to access fields
46 -- of a node, and a procedural interface for modifying these values.
48 function Color
49 (Node : Node_Type) return Ada.Containers.Red_Black_Trees.Color_Type;
50 pragma Inline (Color);
52 function Left_Son (Node : Node_Type) return Count_Type;
53 pragma Inline (Left_Son);
55 function Parent (Node : Node_Type) return Count_Type;
56 pragma Inline (Parent);
58 function Right_Son (Node : Node_Type) return Count_Type;
59 pragma Inline (Right_Son);
61 procedure Set_Color
62 (Node : in out Node_Type;
63 Color : Ada.Containers.Red_Black_Trees.Color_Type);
64 pragma Inline (Set_Color);
66 procedure Set_Left (Node : in out Node_Type; Left : Count_Type);
67 pragma Inline (Set_Left);
69 procedure Set_Right (Node : in out Node_Type; Right : Count_Type);
70 pragma Inline (Set_Right);
72 procedure Set_Parent (Node : in out Node_Type; Parent : Count_Type);
73 pragma Inline (Set_Parent);
75 -----------------------
76 -- Local Subprograms --
77 -----------------------
79 -- All need comments ???
81 generic
82 with procedure Set_Element (Node : in out Node_Type);
83 procedure Generic_Allocate
84 (Tree : in out Tree_Types.Tree_Type'Class;
85 Node : out Count_Type);
87 procedure Free (Tree : in out Map; X : Count_Type);
89 function Is_Greater_Key_Node
90 (Left : Key_Type;
91 Right : Node_Type) return Boolean;
92 pragma Inline (Is_Greater_Key_Node);
94 function Is_Less_Key_Node
95 (Left : Key_Type;
96 Right : Node_Type) return Boolean;
97 pragma Inline (Is_Less_Key_Node);
99 --------------------------
100 -- Local Instantiations --
101 --------------------------
103 package Tree_Operations is
104 new Red_Black_Trees.Generic_Bounded_Operations
105 (Tree_Types => Tree_Types,
106 Left => Left_Son,
107 Right => Right_Son);
109 use Tree_Operations;
111 package Key_Ops is
112 new Red_Black_Trees.Generic_Bounded_Keys
113 (Tree_Operations => Tree_Operations,
114 Key_Type => Key_Type,
115 Is_Less_Key_Node => Is_Less_Key_Node,
116 Is_Greater_Key_Node => Is_Greater_Key_Node);
118 ---------
119 -- "=" --
120 ---------
122 function "=" (Left, Right : Map) return Boolean is
123 Lst : Count_Type;
124 Node : Count_Type;
125 ENode : Count_Type;
127 begin
128 if Length (Left) /= Length (Right) then
129 return False;
130 end if;
132 if Is_Empty (Left) then
133 return True;
134 end if;
136 Lst := Next (Left, Last (Left).Node);
138 Node := First (Left).Node;
139 while Node /= Lst loop
140 ENode := Find (Right, Left.Nodes (Node).Key).Node;
142 if ENode = 0 or else
143 Left.Nodes (Node).Element /= Right.Nodes (ENode).Element
144 then
145 return False;
146 end if;
148 Node := Next (Left, Node);
149 end loop;
151 return True;
152 end "=";
154 ------------
155 -- Assign --
156 ------------
158 procedure Assign (Target : in out Map; Source : Map) is
159 procedure Append_Element (Source_Node : Count_Type);
161 procedure Append_Elements is
162 new Tree_Operations.Generic_Iteration (Append_Element);
164 --------------------
165 -- Append_Element --
166 --------------------
168 procedure Append_Element (Source_Node : Count_Type) is
169 SN : Node_Type renames Source.Nodes (Source_Node);
171 procedure Set_Element (Node : in out Node_Type);
172 pragma Inline (Set_Element);
174 function New_Node return Count_Type;
175 pragma Inline (New_Node);
177 procedure Insert_Post is new Key_Ops.Generic_Insert_Post (New_Node);
179 procedure Unconditional_Insert_Sans_Hint is
180 new Key_Ops.Generic_Unconditional_Insert (Insert_Post);
182 procedure Unconditional_Insert_Avec_Hint is
183 new Key_Ops.Generic_Unconditional_Insert_With_Hint
184 (Insert_Post,
185 Unconditional_Insert_Sans_Hint);
187 procedure Allocate is new Generic_Allocate (Set_Element);
189 --------------
190 -- New_Node --
191 --------------
193 function New_Node return Count_Type is
194 Result : Count_Type;
195 begin
196 Allocate (Target, Result);
197 return Result;
198 end New_Node;
200 -----------------
201 -- Set_Element --
202 -----------------
204 procedure Set_Element (Node : in out Node_Type) is
205 begin
206 Node.Key := SN.Key;
207 Node.Element := SN.Element;
208 end Set_Element;
210 Target_Node : Count_Type;
212 -- Start of processing for Append_Element
214 begin
215 Unconditional_Insert_Avec_Hint
216 (Tree => Target,
217 Hint => 0,
218 Key => SN.Key,
219 Node => Target_Node);
220 end Append_Element;
222 -- Start of processing for Assign
224 begin
225 if Target'Address = Source'Address then
226 return;
227 end if;
229 if Target.Capacity < Length (Source) then
230 raise Storage_Error with "not enough capacity"; -- SE or CE? ???
231 end if;
233 Tree_Operations.Clear_Tree (Target);
234 Append_Elements (Source);
235 end Assign;
237 -------------
238 -- Ceiling --
239 -------------
241 function Ceiling (Container : Map; Key : Key_Type) return Cursor is
242 Node : constant Count_Type := Key_Ops.Ceiling (Container, Key);
244 begin
245 if Node = 0 then
246 return No_Element;
247 end if;
249 return (Node => Node);
250 end Ceiling;
252 -----------
253 -- Clear --
254 -----------
256 procedure Clear (Container : in out Map) is
257 begin
258 Tree_Operations.Clear_Tree (Container);
259 end Clear;
261 -----------
262 -- Color --
263 -----------
265 function Color (Node : Node_Type) return Color_Type is
266 begin
267 return Node.Color;
268 end Color;
270 --------------
271 -- Contains --
272 --------------
274 function Contains (Container : Map; Key : Key_Type) return Boolean is
275 begin
276 return Find (Container, Key) /= No_Element;
277 end Contains;
279 ----------
280 -- Copy --
281 ----------
283 function Copy (Source : Map; Capacity : Count_Type := 0) return Map is
284 Node : Count_Type := 1;
285 N : Count_Type;
287 begin
288 if 0 < Capacity and then Capacity < Source.Capacity then
289 raise Capacity_Error;
290 end if;
292 return Target : Map (Count_Type'Max (Source.Capacity, Capacity)) do
293 if Length (Source) > 0 then
294 Target.Length := Source.Length;
295 Target.Root := Source.Root;
296 Target.First := Source.First;
297 Target.Last := Source.Last;
298 Target.Free := Source.Free;
300 while Node <= Source.Capacity loop
301 Target.Nodes (Node).Element :=
302 Source.Nodes (Node).Element;
303 Target.Nodes (Node).Key :=
304 Source.Nodes (Node).Key;
305 Target.Nodes (Node).Parent :=
306 Source.Nodes (Node).Parent;
307 Target.Nodes (Node).Left :=
308 Source.Nodes (Node).Left;
309 Target.Nodes (Node).Right :=
310 Source.Nodes (Node).Right;
311 Target.Nodes (Node).Color :=
312 Source.Nodes (Node).Color;
313 Target.Nodes (Node).Has_Element :=
314 Source.Nodes (Node).Has_Element;
315 Node := Node + 1;
316 end loop;
318 while Node <= Target.Capacity loop
319 N := Node;
320 Formal_Ordered_Maps.Free (Tree => Target, X => N);
321 Node := Node + 1;
322 end loop;
323 end if;
324 end return;
325 end Copy;
327 ---------------------
328 -- Current_To_Last --
329 ---------------------
331 function Current_To_Last (Container : Map; Current : Cursor) return Map is
332 Curs : Cursor := First (Container);
333 C : Map (Container.Capacity) := Copy (Container, Container.Capacity);
334 Node : Count_Type;
336 begin
337 if Curs = No_Element then
338 Clear (C);
339 return C;
341 elsif Current /= No_Element and not Has_Element (Container, Current) then
342 raise Constraint_Error;
344 else
345 while Curs.Node /= Current.Node loop
346 Node := Curs.Node;
347 Delete (C, Curs);
348 Curs := Next (Container, (Node => Node));
349 end loop;
351 return C;
352 end if;
353 end Current_To_Last;
355 ------------
356 -- Delete --
357 ------------
359 procedure Delete (Container : in out Map; Position : in out Cursor) is
360 begin
361 if not Has_Element (Container, Position) then
362 raise Constraint_Error with
363 "Position cursor of Delete has no element";
364 end if;
366 pragma Assert (Vet (Container, Position.Node),
367 "Position cursor of Delete is bad");
369 Tree_Operations.Delete_Node_Sans_Free (Container,
370 Position.Node);
371 Formal_Ordered_Maps.Free (Container, Position.Node);
372 end Delete;
374 procedure Delete (Container : in out Map; Key : Key_Type) is
375 X : constant Node_Access := Key_Ops.Find (Container, Key);
377 begin
378 if X = 0 then
379 raise Constraint_Error with "key not in map";
380 end if;
382 Tree_Operations.Delete_Node_Sans_Free (Container, X);
383 Formal_Ordered_Maps.Free (Container, X);
384 end Delete;
386 ------------------
387 -- Delete_First --
388 ------------------
390 procedure Delete_First (Container : in out Map) is
391 X : constant Node_Access := First (Container).Node;
392 begin
393 if X /= 0 then
394 Tree_Operations.Delete_Node_Sans_Free (Container, X);
395 Formal_Ordered_Maps.Free (Container, X);
396 end if;
397 end Delete_First;
399 -----------------
400 -- Delete_Last --
401 -----------------
403 procedure Delete_Last (Container : in out Map) is
404 X : constant Node_Access := Last (Container).Node;
405 begin
406 if X /= 0 then
407 Tree_Operations.Delete_Node_Sans_Free (Container, X);
408 Formal_Ordered_Maps.Free (Container, X);
409 end if;
410 end Delete_Last;
412 -------------
413 -- Element --
414 -------------
416 function Element (Container : Map; Position : Cursor) return Element_Type is
417 begin
418 if not Has_Element (Container, Position) then
419 raise Constraint_Error with
420 "Position cursor of function Element has no element";
421 end if;
423 pragma Assert (Vet (Container, Position.Node),
424 "Position cursor of function Element is bad");
426 return Container.Nodes (Position.Node).Element;
428 end Element;
430 function Element (Container : Map; Key : Key_Type) return Element_Type is
431 Node : constant Node_Access := Find (Container, Key).Node;
433 begin
434 if Node = 0 then
435 raise Constraint_Error with "key not in map";
436 end if;
438 return Container.Nodes (Node).Element;
439 end Element;
441 ---------------------
442 -- Equivalent_Keys --
443 ---------------------
445 function Equivalent_Keys (Left, Right : Key_Type) return Boolean is
446 begin
447 if Left < Right
448 or else Right < Left
449 then
450 return False;
451 else
452 return True;
453 end if;
454 end Equivalent_Keys;
456 -------------
457 -- Exclude --
458 -------------
460 procedure Exclude (Container : in out Map; Key : Key_Type) is
461 X : constant Node_Access := Key_Ops.Find (Container, Key);
462 begin
463 if X /= 0 then
464 Tree_Operations.Delete_Node_Sans_Free (Container, X);
465 Formal_Ordered_Maps.Free (Container, X);
466 end if;
467 end Exclude;
469 ----------
470 -- Find --
471 ----------
473 function Find (Container : Map; Key : Key_Type) return Cursor is
474 Node : constant Count_Type := Key_Ops.Find (Container, Key);
476 begin
477 if Node = 0 then
478 return No_Element;
479 end if;
481 return (Node => Node);
482 end Find;
484 -----------
485 -- First --
486 -----------
488 function First (Container : Map) return Cursor is
489 begin
490 if Length (Container) = 0 then
491 return No_Element;
492 end if;
494 return (Node => Container.First);
495 end First;
497 -------------------
498 -- First_Element --
499 -------------------
501 function First_Element (Container : Map) return Element_Type is
502 begin
503 if Is_Empty (Container) then
504 raise Constraint_Error with "map is empty";
505 end if;
507 return Container.Nodes (First (Container).Node).Element;
508 end First_Element;
510 ---------------
511 -- First_Key --
512 ---------------
514 function First_Key (Container : Map) return Key_Type is
515 begin
516 if Is_Empty (Container) then
517 raise Constraint_Error with "map is empty";
518 end if;
520 return Container.Nodes (First (Container).Node).Key;
521 end First_Key;
523 -----------------------
524 -- First_To_Previous --
525 -----------------------
527 function First_To_Previous
528 (Container : Map;
529 Current : Cursor) return Map
531 Curs : Cursor := Current;
532 C : Map (Container.Capacity) := Copy (Container, Container.Capacity);
533 Node : Count_Type;
535 begin
536 if Curs = No_Element then
537 return C;
539 elsif not Has_Element (Container, Curs) then
540 raise Constraint_Error;
542 else
543 while Curs.Node /= 0 loop
544 Node := Curs.Node;
545 Delete (C, Curs);
546 Curs := Next (Container, (Node => Node));
547 end loop;
549 return C;
550 end if;
551 end First_To_Previous;
553 -----------
554 -- Floor --
555 -----------
557 function Floor (Container : Map; Key : Key_Type) return Cursor is
558 Node : constant Count_Type := Key_Ops.Floor (Container, Key);
560 begin
561 if Node = 0 then
562 return No_Element;
563 end if;
565 return (Node => Node);
566 end Floor;
568 ----------
569 -- Free --
570 ----------
572 procedure Free
573 (Tree : in out Map;
574 X : Count_Type)
576 begin
577 Tree.Nodes (X).Has_Element := False;
578 Tree_Operations.Free (Tree, X);
579 end Free;
581 ----------------------
582 -- Generic_Allocate --
583 ----------------------
585 procedure Generic_Allocate
586 (Tree : in out Tree_Types.Tree_Type'Class;
587 Node : out Count_Type)
589 procedure Allocate is
590 new Tree_Operations.Generic_Allocate (Set_Element);
591 begin
592 Allocate (Tree, Node);
593 Tree.Nodes (Node).Has_Element := True;
594 end Generic_Allocate;
596 -----------------
597 -- Has_Element --
598 -----------------
600 function Has_Element (Container : Map; Position : Cursor) return Boolean is
601 begin
602 if Position.Node = 0 then
603 return False;
604 end if;
606 return Container.Nodes (Position.Node).Has_Element;
607 end Has_Element;
609 -------------
610 -- Include --
611 -------------
613 procedure Include
614 (Container : in out Map;
615 Key : Key_Type;
616 New_Item : Element_Type)
618 Position : Cursor;
619 Inserted : Boolean;
621 begin
622 Insert (Container, Key, New_Item, Position, Inserted);
624 if not Inserted then
625 declare
626 N : Node_Type renames Container.Nodes (Position.Node);
627 begin
628 N.Key := Key;
629 N.Element := New_Item;
630 end;
631 end if;
632 end Include;
634 procedure Insert
635 (Container : in out Map;
636 Key : Key_Type;
637 New_Item : Element_Type;
638 Position : out Cursor;
639 Inserted : out Boolean)
641 function New_Node return Node_Access;
642 -- Comment ???
644 procedure Insert_Post is
645 new Key_Ops.Generic_Insert_Post (New_Node);
647 procedure Insert_Sans_Hint is
648 new Key_Ops.Generic_Conditional_Insert (Insert_Post);
650 --------------
651 -- New_Node --
652 --------------
654 function New_Node return Node_Access is
655 procedure Initialize (Node : in out Node_Type);
656 procedure Allocate_Node is new Generic_Allocate (Initialize);
658 procedure Initialize (Node : in out Node_Type) is
659 begin
660 Node.Key := Key;
661 Node.Element := New_Item;
662 end Initialize;
664 X : Node_Access;
666 begin
667 Allocate_Node (Container, X);
668 return X;
669 end New_Node;
671 -- Start of processing for Insert
673 begin
674 Insert_Sans_Hint
675 (Container,
676 Key,
677 Position.Node,
678 Inserted);
679 end Insert;
681 procedure Insert
682 (Container : in out Map;
683 Key : Key_Type;
684 New_Item : Element_Type)
686 Position : Cursor;
687 Inserted : Boolean;
689 begin
690 Insert (Container, Key, New_Item, Position, Inserted);
692 if not Inserted then
693 raise Constraint_Error with "key already in map";
694 end if;
695 end Insert;
697 --------------
698 -- Is_Empty --
699 --------------
701 function Is_Empty (Container : Map) return Boolean is
702 begin
703 return Length (Container) = 0;
704 end Is_Empty;
706 -------------------------
707 -- Is_Greater_Key_Node --
708 -------------------------
710 function Is_Greater_Key_Node
711 (Left : Key_Type;
712 Right : Node_Type) return Boolean
714 begin
715 -- k > node same as node < k
717 return Right.Key < Left;
718 end Is_Greater_Key_Node;
720 ----------------------
721 -- Is_Less_Key_Node --
722 ----------------------
724 function Is_Less_Key_Node
725 (Left : Key_Type;
726 Right : Node_Type) return Boolean
728 begin
729 return Left < Right.Key;
730 end Is_Less_Key_Node;
732 ---------
733 -- Key --
734 ---------
736 function Key (Container : Map; Position : Cursor) return Key_Type is
737 begin
738 if not Has_Element (Container, Position) then
739 raise Constraint_Error with
740 "Position cursor of function Key has no element";
741 end if;
743 pragma Assert (Vet (Container, Position.Node),
744 "Position cursor of function Key is bad");
746 return Container.Nodes (Position.Node).Key;
747 end Key;
749 ----------
750 -- Last --
751 ----------
753 function Last (Container : Map) return Cursor is
754 begin
755 if Length (Container) = 0 then
756 return No_Element;
757 end if;
759 return (Node => Container.Last);
760 end Last;
762 ------------------
763 -- Last_Element --
764 ------------------
766 function Last_Element (Container : Map) return Element_Type is
767 begin
768 if Is_Empty (Container) then
769 raise Constraint_Error with "map is empty";
770 end if;
772 return Container.Nodes (Last (Container).Node).Element;
773 end Last_Element;
775 --------------
776 -- Last_Key --
777 --------------
779 function Last_Key (Container : Map) return Key_Type is
780 begin
781 if Is_Empty (Container) then
782 raise Constraint_Error with "map is empty";
783 end if;
785 return Container.Nodes (Last (Container).Node).Key;
786 end Last_Key;
788 --------------
789 -- Left_Son --
790 --------------
792 function Left_Son (Node : Node_Type) return Count_Type is
793 begin
794 return Node.Left;
795 end Left_Son;
797 ------------
798 -- Length --
799 ------------
801 function Length (Container : Map) return Count_Type is
802 begin
803 return Container.Length;
804 end Length;
806 ----------
807 -- Move --
808 ----------
810 procedure Move (Target : in out Map; Source : in out Map) is
811 NN : Tree_Types.Nodes_Type renames Source.Nodes;
812 X : Node_Access;
814 begin
815 if Target'Address = Source'Address then
816 return;
817 end if;
819 if Target.Capacity < Length (Source) then
820 raise Constraint_Error with -- ???
821 "Source length exceeds Target capacity";
822 end if;
824 Clear (Target);
826 loop
827 X := First (Source).Node;
828 exit when X = 0;
830 -- Here we insert a copy of the source element into the target, and
831 -- then delete the element from the source. Another possibility is
832 -- that delete it first (and hang onto its index), then insert it.
833 -- ???
835 Insert (Target, NN (X).Key, NN (X).Element); -- optimize???
837 Tree_Operations.Delete_Node_Sans_Free (Source, X);
838 Formal_Ordered_Maps.Free (Source, X);
839 end loop;
840 end Move;
842 ----------
843 -- Next --
844 ----------
846 procedure Next (Container : Map; Position : in out Cursor) is
847 begin
848 Position := Next (Container, Position);
849 end Next;
851 function Next (Container : Map; Position : Cursor) return Cursor is
852 begin
853 if Position = No_Element then
854 return No_Element;
855 end if;
857 if not Has_Element (Container, Position) then
858 raise Constraint_Error;
859 end if;
861 pragma Assert (Vet (Container, Position.Node),
862 "bad cursor in Next");
864 return (Node => Tree_Operations.Next (Container, Position.Node));
865 end Next;
867 -------------
868 -- Overlap --
869 -------------
871 function Overlap (Left, Right : Map) return Boolean is
872 begin
873 if Length (Left) = 0 or Length (Right) = 0 then
874 return False;
875 end if;
877 declare
878 L_Node : Count_Type := First (Left).Node;
879 R_Node : Count_Type := First (Right).Node;
880 L_Last : constant Count_Type := Next (Left, Last (Left).Node);
881 R_Last : constant Count_Type := Next (Right, Last (Right).Node);
883 begin
884 if Left'Address = Right'Address then
885 return True;
886 end if;
888 loop
889 if L_Node = L_Last
890 or else R_Node = R_Last
891 then
892 return False;
893 end if;
895 if Left.Nodes (L_Node).Key < Right.Nodes (R_Node).Key then
896 L_Node := Next (Left, L_Node);
898 elsif Right.Nodes (R_Node).Key < Left.Nodes (L_Node).Key then
899 R_Node := Next (Right, R_Node);
901 else
902 return True;
903 end if;
904 end loop;
905 end;
906 end Overlap;
908 ------------
909 -- Parent --
910 ------------
912 function Parent (Node : Node_Type) return Count_Type is
913 begin
914 return Node.Parent;
915 end Parent;
917 --------------
918 -- Previous --
919 --------------
921 procedure Previous (Container : Map; Position : in out Cursor) is
922 begin
923 Position := Previous (Container, Position);
924 end Previous;
926 function Previous (Container : Map; Position : Cursor) return Cursor is
927 begin
928 if Position = No_Element then
929 return No_Element;
930 end if;
932 if not Has_Element (Container, Position) then
933 raise Constraint_Error;
934 end if;
936 pragma Assert (Vet (Container, Position.Node),
937 "bad cursor in Previous");
939 declare
940 Node : constant Count_Type :=
941 Tree_Operations.Previous (Container, Position.Node);
943 begin
944 if Node = 0 then
945 return No_Element;
946 end if;
948 return (Node => Node);
949 end;
950 end Previous;
952 -------------
953 -- Replace --
954 -------------
956 procedure Replace
957 (Container : in out Map;
958 Key : Key_Type;
959 New_Item : Element_Type)
961 begin
962 declare
963 Node : constant Node_Access := Key_Ops.Find (Container, Key);
965 begin
966 if Node = 0 then
967 raise Constraint_Error with "key not in map";
968 end if;
970 declare
971 N : Node_Type renames Container.Nodes (Node);
972 begin
973 N.Key := Key;
974 N.Element := New_Item;
975 end;
976 end;
977 end Replace;
979 ---------------------
980 -- Replace_Element --
981 ---------------------
983 procedure Replace_Element
984 (Container : in out Map;
985 Position : Cursor;
986 New_Item : Element_Type)
988 begin
989 if not Has_Element (Container, Position) then
990 raise Constraint_Error with
991 "Position cursor of Replace_Element has no element";
992 end if;
994 pragma Assert (Vet (Container, Position.Node),
995 "Position cursor of Replace_Element is bad");
997 Container.Nodes (Position.Node).Element := New_Item;
998 end Replace_Element;
1000 ---------------
1001 -- Right_Son --
1002 ---------------
1004 function Right_Son (Node : Node_Type) return Count_Type is
1005 begin
1006 return Node.Right;
1007 end Right_Son;
1009 ---------------
1010 -- Set_Color --
1011 ---------------
1013 procedure Set_Color (Node : in out Node_Type; Color : Color_Type) is
1014 begin
1015 Node.Color := Color;
1016 end Set_Color;
1018 --------------
1019 -- Set_Left --
1020 --------------
1022 procedure Set_Left (Node : in out Node_Type; Left : Count_Type) is
1023 begin
1024 Node.Left := Left;
1025 end Set_Left;
1027 ----------------
1028 -- Set_Parent --
1029 ----------------
1031 procedure Set_Parent (Node : in out Node_Type; Parent : Count_Type) is
1032 begin
1033 Node.Parent := Parent;
1034 end Set_Parent;
1036 ---------------
1037 -- Set_Right --
1038 ---------------
1040 procedure Set_Right (Node : in out Node_Type; Right : Count_Type) is
1041 begin
1042 Node.Right := Right;
1043 end Set_Right;
1045 ------------------
1046 -- Strict_Equal --
1047 ------------------
1049 function Strict_Equal (Left, Right : Map) return Boolean is
1050 LNode : Count_Type := First (Left).Node;
1051 RNode : Count_Type := First (Right).Node;
1053 begin
1054 if Length (Left) /= Length (Right) then
1055 return False;
1056 end if;
1058 while LNode = RNode loop
1059 if LNode = 0 then
1060 return True;
1061 end if;
1063 if Left.Nodes (LNode).Element /= Right.Nodes (RNode).Element
1064 or else Left.Nodes (LNode).Key /= Right.Nodes (RNode).Key
1065 then
1066 exit;
1067 end if;
1069 LNode := Next (Left, LNode);
1070 RNode := Next (Right, RNode);
1071 end loop;
1073 return False;
1074 end Strict_Equal;
1076 end Ada.Containers.Formal_Ordered_Maps;