1 ------------------------------------------------------------------------------
3 -- GNAT LIBRARY COMPONENTS --
5 -- A D A . C O N T A I N E R S . B O U N D E D _ O R D E R E D _ M A P S --
9 -- Copyright (C) 2004-2010, Free Software Foundation, Inc. --
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. --
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. --
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/>. --
27 -- This unit was originally developed by Matthew J Heaney. --
28 ------------------------------------------------------------------------------
30 with Ada.Containers.Red_Black_Trees.Generic_Bounded_Operations;
32 (Ada.Containers.Red_Black_Trees.Generic_Bounded_Operations);
34 with Ada.Containers.Red_Black_Trees.Generic_Bounded_Keys;
36 (Ada.Containers.Red_Black_Trees.Generic_Bounded_Keys);
38 with System; use type System.Address;
40 package body Ada.Containers.Bounded_Ordered_Maps is
43 Map_Iterator_Interfaces.Reversible_Iterator with record
44 Container : Map_Access;
48 overriding function First (Object : Iterator) return Cursor;
49 overriding function Last (Object : Iterator) return Cursor;
51 overriding function Next
53 Position : Cursor) return Cursor;
55 overriding function Previous
57 Position : Cursor) return Cursor;
59 -----------------------------
60 -- Node Access Subprograms --
61 -----------------------------
63 -- These subprograms provide a functional interface to access fields
64 -- of a node, and a procedural interface for modifying these values.
66 function Color (Node : Node_Type) return Color_Type;
67 pragma Inline (Color);
69 function Left (Node : Node_Type) return Count_Type;
72 function Parent (Node : Node_Type) return Count_Type;
73 pragma Inline (Parent);
75 function Right (Node : Node_Type) return Count_Type;
76 pragma Inline (Right);
78 procedure Set_Parent (Node : in out Node_Type; Parent : Count_Type);
79 pragma Inline (Set_Parent);
81 procedure Set_Left (Node : in out Node_Type; Left : Count_Type);
82 pragma Inline (Set_Left);
84 procedure Set_Right (Node : in out Node_Type; Right : Count_Type);
85 pragma Inline (Set_Right);
87 procedure Set_Color (Node : in out Node_Type; Color : Color_Type);
88 pragma Inline (Set_Color);
90 -----------------------
91 -- Local Subprograms --
92 -----------------------
94 function Is_Greater_Key_Node
96 Right : Node_Type) return Boolean;
97 pragma Inline (Is_Greater_Key_Node);
99 function Is_Less_Key_Node
101 Right : Node_Type) return Boolean;
102 pragma Inline (Is_Less_Key_Node);
104 --------------------------
105 -- Local Instantiations --
106 --------------------------
108 package Tree_Operations is
109 new Red_Black_Trees.Generic_Bounded_Operations (Tree_Types);
114 new Red_Black_Trees.Generic_Bounded_Keys
115 (Tree_Operations => Tree_Operations,
116 Key_Type => Key_Type,
117 Is_Less_Key_Node => Is_Less_Key_Node,
118 Is_Greater_Key_Node => Is_Greater_Key_Node);
124 function "<" (Left, Right : Cursor) return Boolean is
126 if Left.Node = 0 then
127 raise Constraint_Error with "Left cursor of ""<"" equals No_Element";
130 if Right.Node = 0 then
131 raise Constraint_Error with "Right cursor of ""<"" equals No_Element";
134 pragma Assert (Vet (Left.Container.all, Left.Node),
135 "Left cursor of ""<"" is bad");
137 pragma Assert (Vet (Right.Container.all, Right.Node),
138 "Right cursor of ""<"" is bad");
141 LN : Node_Type renames Left.Container.Nodes (Left.Node);
142 RN : Node_Type renames Right.Container.Nodes (Right.Node);
145 return LN.Key < RN.Key;
149 function "<" (Left : Cursor; Right : Key_Type) return Boolean is
151 if Left.Node = 0 then
152 raise Constraint_Error with "Left cursor of ""<"" equals No_Element";
155 pragma Assert (Vet (Left.Container.all, Left.Node),
156 "Left cursor of ""<"" is bad");
159 LN : Node_Type renames Left.Container.Nodes (Left.Node);
162 return LN.Key < Right;
166 function "<" (Left : Key_Type; Right : Cursor) return Boolean is
168 if Right.Node = 0 then
169 raise Constraint_Error with "Right cursor of ""<"" equals No_Element";
172 pragma Assert (Vet (Right.Container.all, Right.Node),
173 "Right cursor of ""<"" is bad");
176 RN : Node_Type renames Right.Container.Nodes (Right.Node);
179 return Left < RN.Key;
187 function "=" (Left, Right : Map) return Boolean is
188 function Is_Equal_Node_Node (L, R : Node_Type) return Boolean;
189 pragma Inline (Is_Equal_Node_Node);
192 new Tree_Operations.Generic_Equal (Is_Equal_Node_Node);
194 ------------------------
195 -- Is_Equal_Node_Node --
196 ------------------------
198 function Is_Equal_Node_Node
199 (L, R : Node_Type) return Boolean is
201 if L.Key < R.Key then
204 elsif R.Key < L.Key then
208 return L.Element = R.Element;
210 end Is_Equal_Node_Node;
212 -- Start of processing for "="
215 return Is_Equal (Left, Right);
222 function ">" (Left, Right : Cursor) return Boolean is
224 if Left.Node = 0 then
225 raise Constraint_Error with "Left cursor of "">"" equals No_Element";
228 if Right.Node = 0 then
229 raise Constraint_Error with "Right cursor of "">"" equals No_Element";
232 pragma Assert (Vet (Left.Container.all, Left.Node),
233 "Left cursor of "">"" is bad");
235 pragma Assert (Vet (Right.Container.all, Right.Node),
236 "Right cursor of "">"" is bad");
239 LN : Node_Type renames Left.Container.Nodes (Left.Node);
240 RN : Node_Type renames Right.Container.Nodes (Right.Node);
243 return RN.Key < LN.Key;
247 function ">" (Left : Cursor; Right : Key_Type) return Boolean is
249 if Left.Node = 0 then
250 raise Constraint_Error with "Left cursor of "">"" equals No_Element";
253 pragma Assert (Vet (Left.Container.all, Left.Node),
254 "Left cursor of "">"" is bad");
257 LN : Node_Type renames Left.Container.Nodes (Left.Node);
260 return Right < LN.Key;
264 function ">" (Left : Key_Type; Right : Cursor) return Boolean is
266 if Right.Node = 0 then
267 raise Constraint_Error with "Right cursor of "">"" equals No_Element";
270 pragma Assert (Vet (Right.Container.all, Right.Node),
271 "Right cursor of "">"" is bad");
274 RN : Node_Type renames Right.Container.Nodes (Right.Node);
277 return RN.Key < Left;
285 procedure Assign (Target : in out Map; Source : Map) is
286 procedure Append_Element (Source_Node : Count_Type);
288 procedure Append_Elements is
289 new Tree_Operations.Generic_Iteration (Append_Element);
295 procedure Append_Element (Source_Node : Count_Type) is
296 SN : Node_Type renames Source.Nodes (Source_Node);
298 procedure Set_Element (Node : in out Node_Type);
299 pragma Inline (Set_Element);
301 function New_Node return Count_Type;
302 pragma Inline (New_Node);
304 procedure Insert_Post is
305 new Key_Ops.Generic_Insert_Post (New_Node);
307 procedure Unconditional_Insert_Sans_Hint is
308 new Key_Ops.Generic_Unconditional_Insert (Insert_Post);
310 procedure Unconditional_Insert_Avec_Hint is
311 new Key_Ops.Generic_Unconditional_Insert_With_Hint
313 Unconditional_Insert_Sans_Hint);
315 procedure Allocate is
316 new Tree_Operations.Generic_Allocate (Set_Element);
322 function New_Node return Count_Type is
326 Allocate (Target, Result);
334 procedure Set_Element (Node : in out Node_Type) is
337 Node.Element := SN.Element;
340 Target_Node : Count_Type;
342 -- Start of processing for Append_Element
345 Unconditional_Insert_Avec_Hint
349 Node => Target_Node);
352 -- Start of processing for Assign
355 if Target'Address = Source'Address then
359 if Target.Capacity < Source.Length then
361 with "Target capacity is less than Source length";
364 Tree_Operations.Clear_Tree (Target);
365 Append_Elements (Source);
372 function Ceiling (Container : Map; Key : Key_Type) return Cursor is
373 Node : constant Count_Type := Key_Ops.Ceiling (Container, Key);
380 return Cursor'(Container'Unrestricted_Access, Node);
387 procedure Clear (Container : in out Map) is
389 Tree_Operations.Clear_Tree (Container);
396 function Color (Node : Node_Type) return Color_Type is
405 function Contains (Container : Map; Key : Key_Type) return Boolean is
407 return Find (Container, Key) /= No_Element;
414 function Copy (Source : Map; Capacity : Count_Type := 0) return Map is
421 elsif Capacity >= Source.Length then
425 raise Capacity_Error with "Capacity value too small";
428 return Target : Map (Capacity => C) do
429 Assign (Target => Target, Source => Source);
437 procedure Delete (Container : in out Map; Position : in out Cursor) is
439 if Position.Node = 0 then
440 raise Constraint_Error with
441 "Position cursor of Delete equals No_Element";
444 if Position.Container /= Container'Unrestricted_Access then
445 raise Program_Error with
446 "Position cursor of Delete designates wrong map";
449 pragma Assert (Vet (Container, Position.Node),
450 "Position cursor of Delete is bad");
452 Tree_Operations.Delete_Node_Sans_Free (Container, Position.Node);
453 Tree_Operations.Free (Container, Position.Node);
455 Position := No_Element;
458 procedure Delete (Container : in out Map; Key : Key_Type) is
459 X : constant Count_Type := Key_Ops.Find (Container, Key);
463 raise Constraint_Error with "key not in map";
466 Tree_Operations.Delete_Node_Sans_Free (Container, X);
467 Tree_Operations.Free (Container, X);
474 procedure Delete_First (Container : in out Map) is
475 X : constant Count_Type := Container.First;
479 Tree_Operations.Delete_Node_Sans_Free (Container, X);
480 Tree_Operations.Free (Container, X);
488 procedure Delete_Last (Container : in out Map) is
489 X : constant Count_Type := Container.Last;
493 Tree_Operations.Delete_Node_Sans_Free (Container, X);
494 Tree_Operations.Free (Container, X);
502 function Element (Position : Cursor) return Element_Type is
504 if Position.Node = 0 then
505 raise Constraint_Error with
506 "Position cursor of function Element equals No_Element";
509 pragma Assert (Vet (Position.Container.all, Position.Node),
510 "Position cursor of function Element is bad");
512 return Position.Container.Nodes (Position.Node).Element;
515 function Element (Container : Map; Key : Key_Type) return Element_Type is
516 Node : constant Count_Type := Key_Ops.Find (Container, Key);
520 raise Constraint_Error with "key not in map";
523 return Container.Nodes (Node).Element;
526 ---------------------
527 -- Equivalent_Keys --
528 ---------------------
530 function Equivalent_Keys (Left, Right : Key_Type) return Boolean is
545 procedure Exclude (Container : in out Map; Key : Key_Type) is
546 X : constant Count_Type := Key_Ops.Find (Container, Key);
550 Tree_Operations.Delete_Node_Sans_Free (Container, X);
551 Tree_Operations.Free (Container, X);
559 function Find (Container : Map; Key : Key_Type) return Cursor is
560 Node : constant Count_Type := Key_Ops.Find (Container, Key);
567 return Cursor'(Container'Unrestricted_Access, Node);
574 function First (Container : Map) return Cursor is
576 if Container.First = 0 then
580 return Cursor'(Container'Unrestricted_Access, Container.First);
583 function First (Object : Iterator) return Cursor is
584 F : constant Count_Type := Object.Container.First;
591 Cursor'(Object.Container.all'Unchecked_Access, F);
598 function First_Element (Container : Map) return Element_Type is
600 if Container.First = 0 then
601 raise Constraint_Error with "map is empty";
604 return Container.Nodes (Container.First).Element;
611 function First_Key (Container : Map) return Key_Type is
613 if Container.First = 0 then
614 raise Constraint_Error with "map is empty";
617 return Container.Nodes (Container.First).Key;
624 function Floor (Container : Map; Key : Key_Type) return Cursor is
625 Node : constant Count_Type := Key_Ops.Floor (Container, Key);
632 return Cursor'(Container'Unrestricted_Access, Node);
639 function Has_Element (Position : Cursor) return Boolean is
641 return Position /= No_Element;
649 (Container : in out Map;
651 New_Item : Element_Type)
657 Insert (Container, Key, New_Item, Position, Inserted);
660 if Container.Lock > 0 then
661 raise Program_Error with
662 "attempt to tamper with elements (map is locked)";
666 N : Node_Type renames Container.Nodes (Position.Node);
670 N.Element := New_Item;
680 (Container : in out Map;
682 New_Item : Element_Type;
683 Position : out Cursor;
684 Inserted : out Boolean)
686 procedure Assign (Node : in out Node_Type);
687 pragma Inline (Assign);
689 function New_Node return Count_Type;
690 pragma Inline (New_Node);
692 procedure Insert_Post is
693 new Key_Ops.Generic_Insert_Post (New_Node);
695 procedure Insert_Sans_Hint is
696 new Key_Ops.Generic_Conditional_Insert (Insert_Post);
698 procedure Allocate is
699 new Tree_Operations.Generic_Allocate (Assign);
705 procedure Assign (Node : in out Node_Type) is
708 Node.Element := New_Item;
715 function New_Node return Count_Type is
719 Allocate (Container, Result);
723 -- Start of processing for Insert
732 Position.Container := Container'Unrestricted_Access;
736 (Container : in out Map;
738 New_Item : Element_Type)
741 pragma Unreferenced (Position);
746 Insert (Container, Key, New_Item, Position, Inserted);
749 raise Constraint_Error with "key already in map";
754 (Container : in out Map;
756 Position : out Cursor;
757 Inserted : out Boolean)
759 procedure Assign (Node : in out Node_Type);
760 pragma Inline (Assign);
762 function New_Node return Count_Type;
763 pragma Inline (New_Node);
765 procedure Insert_Post is
766 new Key_Ops.Generic_Insert_Post (New_Node);
768 procedure Insert_Sans_Hint is
769 new Key_Ops.Generic_Conditional_Insert (Insert_Post);
771 procedure Allocate is
772 new Tree_Operations.Generic_Allocate (Assign);
778 procedure Assign (Node : in out Node_Type) is
781 -- Node.Element := New_Item;
788 function New_Node return Count_Type is
792 Allocate (Container, Result);
796 -- Start of processing for Insert
805 Position.Container := Container'Unrestricted_Access;
812 function Is_Empty (Container : Map) return Boolean is
814 return Container.Length = 0;
817 -------------------------
818 -- Is_Greater_Key_Node --
819 -------------------------
821 function Is_Greater_Key_Node
823 Right : Node_Type) return Boolean
826 -- k > node same as node < k
828 return Right.Key < Left;
829 end Is_Greater_Key_Node;
831 ----------------------
832 -- Is_Less_Key_Node --
833 ----------------------
835 function Is_Less_Key_Node
837 Right : Node_Type) return Boolean
840 return Left < Right.Key;
841 end Is_Less_Key_Node;
849 Process : not null access procedure (Position : Cursor))
851 procedure Process_Node (Node : Count_Type);
852 pragma Inline (Process_Node);
854 procedure Local_Iterate is
855 new Tree_Operations.Generic_Iteration (Process_Node);
861 procedure Process_Node (Node : Count_Type) is
863 Process (Cursor'(Container'Unrestricted_Access, Node));
866 B : Natural renames Container'Unrestricted_Access.all.Busy;
868 -- Start of processing for Iterate
874 Local_Iterate (Container);
885 (Container : Map) return Map_Iterator_Interfaces.Forward_Iterator'class
887 It : constant Iterator :=
888 (Container'Unrestricted_Access, Container.First);
893 function Iterate (Container : Map; Start : Cursor)
894 return Map_Iterator_Interfaces.Reversible_Iterator'class
896 It : constant Iterator := (Container'Unrestricted_Access, Start.Node);
905 function Key (Position : Cursor) return Key_Type is
907 if Position.Node = 0 then
908 raise Constraint_Error with
909 "Position cursor of function Key equals No_Element";
912 pragma Assert (Vet (Position.Container.all, Position.Node),
913 "Position cursor of function Key is bad");
915 return Position.Container.Nodes (Position.Node).Key;
922 function Last (Container : Map) return Cursor is
924 if Container.Last = 0 then
928 return Cursor'(Container'Unrestricted_Access, Container.Last);
931 function Last (Object : Iterator) return Cursor is
932 F : constant Count_Type := Object.Container.Last;
939 Cursor'(Object.Container.all'Unchecked_Access, F);
946 function Last_Element (Container : Map) return Element_Type is
948 if Container.Last = 0 then
949 raise Constraint_Error with "map is empty";
952 return Container.Nodes (Container.Last).Element;
959 function Last_Key (Container : Map) return Key_Type is
961 if Container.Last = 0 then
962 raise Constraint_Error with "map is empty";
965 return Container.Nodes (Container.Last).Key;
972 function Left (Node : Node_Type) return Count_Type is
981 function Length (Container : Map) return Count_Type is
983 return Container.Length;
990 procedure Move (Target : in out Map; Source : in out Map) is
992 if Target'Address = Source'Address then
996 if Source.Busy > 0 then
997 raise Program_Error with
998 "attempt to tamper with cursors (container is busy)";
1001 Assign (Target => Target, Source => Source);
1008 procedure Next (Position : in out Cursor) is
1010 Position := Next (Position);
1013 function Next (Position : Cursor) return Cursor is
1015 if Position = No_Element then
1019 pragma Assert (Vet (Position.Container.all, Position.Node),
1020 "Position cursor of Next is bad");
1023 M : Map renames Position.Container.all;
1025 Node : constant Count_Type :=
1026 Tree_Operations.Next (M, Position.Node);
1033 return Cursor'(Position.Container, Node);
1039 Position : Cursor) return Cursor
1041 pragma Unreferenced (Object);
1043 return Next (Position);
1050 function Parent (Node : Node_Type) return Count_Type is
1059 procedure Previous (Position : in out Cursor) is
1061 Position := Previous (Position);
1064 function Previous (Position : Cursor) return Cursor is
1066 if Position = No_Element then
1070 pragma Assert (Vet (Position.Container.all, Position.Node),
1071 "Position cursor of Previous is bad");
1074 M : Map renames Position.Container.all;
1076 Node : constant Count_Type :=
1077 Tree_Operations.Previous (M, Position.Node);
1084 return Cursor'(Position.Container, Node);
1090 Position : Cursor) return Cursor
1092 pragma Unreferenced (Object);
1094 return Previous (Position);
1101 procedure Query_Element
1103 Process : not null access procedure (Key : Key_Type;
1104 Element : Element_Type))
1107 if Position.Node = 0 then
1108 raise Constraint_Error with
1109 "Position cursor of Query_Element equals No_Element";
1112 pragma Assert (Vet (Position.Container.all, Position.Node),
1113 "Position cursor of Query_Element is bad");
1116 M : Map renames Position.Container.all;
1117 N : Node_Type renames M.Nodes (Position.Node);
1119 B : Natural renames M.Busy;
1120 L : Natural renames M.Lock;
1127 Process (N.Key, N.Element);
1145 (Stream : not null access Root_Stream_Type'Class;
1146 Container : out Map)
1148 procedure Read_Element (Node : in out Node_Type);
1149 pragma Inline (Read_Element);
1151 procedure Allocate is
1152 new Tree_Operations.Generic_Allocate (Read_Element);
1154 procedure Read_Elements is
1155 new Tree_Operations.Generic_Read (Allocate);
1161 procedure Read_Element (Node : in out Node_Type) is
1163 Key_Type'Read (Stream, Node.Key);
1164 Element_Type'Read (Stream, Node.Element);
1167 -- Start of processing for Read
1170 Read_Elements (Stream, Container);
1174 (Stream : not null access Root_Stream_Type'Class;
1178 raise Program_Error with "attempt to stream map cursor";
1182 (Stream : not null access Root_Stream_Type'Class;
1183 Item : out Reference_Type)
1186 raise Program_Error with "attempt to stream reference";
1190 (Stream : not null access Root_Stream_Type'Class;
1191 Item : out Constant_Reference_Type)
1194 raise Program_Error with "attempt to stream reference";
1201 function Constant_Reference (Container : Map; Key : Key_Type)
1202 return Constant_Reference_Type
1205 return (Element => Container.Element (Key)'Unrestricted_Access);
1206 end Constant_Reference;
1208 function Reference (Container : Map; Key : Key_Type)
1209 return Reference_Type
1212 return (Element => Container.Element (Key)'Unrestricted_Access);
1220 (Container : in out Map;
1222 New_Item : Element_Type)
1224 Node : constant Count_Type := Key_Ops.Find (Container, Key);
1228 raise Constraint_Error with "key not in map";
1231 if Container.Lock > 0 then
1232 raise Program_Error with
1233 "attempt to tamper with elements (map is locked)";
1237 N : Node_Type renames Container.Nodes (Node);
1241 N.Element := New_Item;
1245 ---------------------
1246 -- Replace_Element --
1247 ---------------------
1249 procedure Replace_Element
1250 (Container : in out Map;
1252 New_Item : Element_Type)
1255 if Position.Node = 0 then
1256 raise Constraint_Error with
1257 "Position cursor of Replace_Element equals No_Element";
1260 if Position.Container /= Container'Unrestricted_Access then
1261 raise Program_Error with
1262 "Position cursor of Replace_Element designates wrong map";
1265 if Container.Lock > 0 then
1266 raise Program_Error with
1267 "attempt to tamper with elements (map is locked)";
1270 pragma Assert (Vet (Container, Position.Node),
1271 "Position cursor of Replace_Element is bad");
1273 Container.Nodes (Position.Node).Element := New_Item;
1274 end Replace_Element;
1276 ---------------------
1277 -- Reverse_Iterate --
1278 ---------------------
1280 procedure Reverse_Iterate
1282 Process : not null access procedure (Position : Cursor))
1284 procedure Process_Node (Node : Count_Type);
1285 pragma Inline (Process_Node);
1287 procedure Local_Reverse_Iterate is
1288 new Tree_Operations.Generic_Reverse_Iteration (Process_Node);
1294 procedure Process_Node (Node : Count_Type) is
1296 Process (Cursor'(Container'Unrestricted_Access, Node));
1299 B : Natural renames Container'Unrestricted_Access.all.Busy;
1301 -- Start of processing for Reverse_Iterate
1307 Local_Reverse_Iterate (Container);
1315 end Reverse_Iterate;
1321 function Right (Node : Node_Type) return Count_Type is
1331 (Node : in out Node_Type;
1335 Node.Color := Color;
1342 procedure Set_Left (Node : in out Node_Type; Left : Count_Type) is
1351 procedure Set_Parent (Node : in out Node_Type; Parent : Count_Type) is
1353 Node.Parent := Parent;
1360 procedure Set_Right (Node : in out Node_Type; Right : Count_Type) is
1362 Node.Right := Right;
1365 --------------------
1366 -- Update_Element --
1367 --------------------
1369 procedure Update_Element
1370 (Container : in out Map;
1372 Process : not null access procedure (Key : Key_Type;
1373 Element : in out Element_Type))
1376 if Position.Node = 0 then
1377 raise Constraint_Error with
1378 "Position cursor of Update_Element equals No_Element";
1381 if Position.Container /= Container'Unrestricted_Access then
1382 raise Program_Error with
1383 "Position cursor of Update_Element designates wrong map";
1386 pragma Assert (Vet (Container, Position.Node),
1387 "Position cursor of Update_Element is bad");
1390 N : Node_Type renames Container.Nodes (Position.Node);
1391 B : Natural renames Container.Busy;
1392 L : Natural renames Container.Lock;
1399 Process (N.Key, N.Element);
1418 (Stream : not null access Root_Stream_Type'Class;
1421 procedure Write_Node
1422 (Stream : not null access Root_Stream_Type'Class;
1424 pragma Inline (Write_Node);
1426 procedure Write_Nodes is
1427 new Tree_Operations.Generic_Write (Write_Node);
1433 procedure Write_Node
1434 (Stream : not null access Root_Stream_Type'Class;
1438 Key_Type'Write (Stream, Node.Key);
1439 Element_Type'Write (Stream, Node.Element);
1442 -- Start of processing for Write
1445 Write_Nodes (Stream, Container);
1449 (Stream : not null access Root_Stream_Type'Class;
1453 raise Program_Error with "attempt to stream map cursor";
1457 (Stream : not null access Root_Stream_Type'Class;
1458 Item : Reference_Type)
1461 raise Program_Error with "attempt to stream reference";
1465 (Stream : not null access Root_Stream_Type'Class;
1466 Item : Constant_Reference_Type)
1469 raise Program_Error with "attempt to stream reference";
1472 end Ada.Containers.Bounded_Ordered_Maps;