This patch corrects the implementation of routine Insert_Child in the following
multiway tree packages:
Ada.Containers.Indefinite_Multiway_Trees
Ada.Containers.Multiway_Trees
As a result, Insert_Child no longer returns a faulty Position when inserting
elements.
------------
-- Source --
------------
-- multi_main.adb
with Ada.Containers.Multiway_Trees;
with Ada.Text_IO; use Ada.Text_IO;
procedure Multi_Main is
Size : constant := 4;
type Small_Int is new Integer range 1 .. 9
with Default_Value => 1;
package MWT is new Ada.Containers.Multiway_Trees (Small_Int);
use MWT;
procedure Print_Tree (T : Tree) is
procedure Output (C : Cursor) is
begin
Put_Line (Element (C)'Img);
end Output;
begin
T.Iterate (Output'Access);
end Print_Tree;
T : Tree;
R : constant Cursor := T.Root;
C : Cursor;
begin
for Index in 1 .. Size loop
T.Prepend_Child (R, 8);
end loop;
T.Clear;
T.Insert_Child
(Parent => R,
Before => No_Element,
Position => C,
Count => 1);
T.Insert_Child
(Parent => R,
Before => C,
Position => C,
New_Item => 2,
Count => 2);
Print_Tree (T);
end Multi_Main;
----------------------------
-- Compilation and output --
----------------------------
$ gnatmake -q multi_main.adb
$ ./multi_main
2
2
1
Tested on x86_64-pc-linux-gnu, committed on trunk
2014-10-30 Hristian Kirtchev <[email protected]>
* a-comutr.adb, a-cimutr.adb (Insert_Child): Add new variable First.
Update the position after all insertions have taken place.
Index: a-cimutr.adb
===================================================================
--- a-cimutr.adb (revision 216770)
+++ a-cimutr.adb (working copy)
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2004-2013, Free Software Foundation, Inc. --
+-- Copyright (C) 2004-2014, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -1217,6 +1217,7 @@
Position : out Cursor;
Count : Count_Type := 1)
is
+ First : Tree_Node_Access;
Last : Tree_Node_Access;
Element : Element_Access;
@@ -1249,8 +1250,6 @@
with "attempt to tamper with cursors (tree is busy)";
end if;
- Position.Container := Parent.Container;
-
declare
-- The element allocator may need an accessibility check in the case
-- the actual type is class-wide or has access discriminants (see
@@ -1264,16 +1263,16 @@
Element := new Element_Type'(New_Item);
end;
- Position.Node := new Tree_Node_Type'(Parent => Parent.Node,
- Element => Element,
- others => <>);
+ First := new Tree_Node_Type'(Parent => Parent.Node,
+ Element => Element,
+ others => <>);
- Last := Position.Node;
+ Last := First;
+ for J in Count_Type'(2) .. Count loop
- for J in Count_Type'(2) .. Count loop
-- Reclaim other nodes if Storage_Error. ???
- Element := new Element_Type'(New_Item);
+ Element := new Element_Type'(New_Item);
Last.Next := new Tree_Node_Type'(Parent => Parent.Node,
Prev => Last,
Element => Element,
@@ -1283,7 +1282,7 @@
end loop;
Insert_Subtree_List
- (First => Position.Node,
+ (First => First,
Last => Last,
Parent => Parent.Node,
Before => Before.Node);
@@ -1293,6 +1292,8 @@
-- nodes we just inserted.
Container.Count := Container.Count + Count;
+
+ Position := Cursor'(Parent.Container, First);
end Insert_Child;
-------------------------
Index: a-comutr.adb
===================================================================
--- a-comutr.adb (revision 216770)
+++ a-comutr.adb (working copy)
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2004-2013, Free Software Foundation, Inc. --
+-- Copyright (C) 2004-2014, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -272,7 +272,8 @@
New_Item : Element_Type;
Count : Count_Type := 1)
is
- First, Last : Tree_Node_Access;
+ First : Tree_Node_Access;
+ Last : Tree_Node_Access;
begin
if Parent = No_Element then
@@ -297,7 +298,6 @@
others => <>);
Last := First;
-
for J in Count_Type'(2) .. Count loop
-- Reclaim other nodes if Storage_Error. ???
@@ -1171,7 +1171,8 @@
Position : out Cursor;
Count : Count_Type := 1)
is
- Last : Tree_Node_Access;
+ First : Tree_Node_Access;
+ Last : Tree_Node_Access;
begin
if Parent = No_Element then
@@ -1202,13 +1203,11 @@
with "attempt to tamper with cursors (tree is busy)";
end if;
- Position.Container := Parent.Container;
- Position.Node := new Tree_Node_Type'(Parent => Parent.Node,
- Element => New_Item,
- others => <>);
+ First := new Tree_Node_Type'(Parent => Parent.Node,
+ Element => New_Item,
+ others => <>);
- Last := Position.Node;
-
+ Last := First;
for J in Count_Type'(2) .. Count loop
-- Reclaim other nodes if Storage_Error. ???
@@ -1222,7 +1221,7 @@
end loop;
Insert_Subtree_List
- (First => Position.Node,
+ (First => First,
Last => Last,
Parent => Parent.Node,
Before => Before.Node);
@@ -1232,6 +1231,8 @@
-- nodes we just inserted.
Container.Count := Container.Count + Count;
+
+ Position := Cursor'(Parent.Container, First);
end Insert_Child;
procedure Insert_Child
@@ -1241,7 +1242,8 @@
Position : out Cursor;
Count : Count_Type := 1)
is
- Last : Tree_Node_Access;
+ First : Tree_Node_Access;
+ Last : Tree_Node_Access;
begin
if Parent = No_Element then
@@ -1272,13 +1274,11 @@
with "attempt to tamper with cursors (tree is busy)";
end if;
- Position.Container := Parent.Container;
- Position.Node := new Tree_Node_Type'(Parent => Parent.Node,
- Element => <>,
- others => <>);
+ First := new Tree_Node_Type'(Parent => Parent.Node,
+ Element => <>,
+ others => <>);
- Last := Position.Node;
-
+ Last := First;
for J in Count_Type'(2) .. Count loop
-- Reclaim other nodes if Storage_Error. ???
@@ -1292,7 +1292,7 @@
end loop;
Insert_Subtree_List
- (First => Position.Node,
+ (First => First,
Last => Last,
Parent => Parent.Node,
Before => Before.Node);
@@ -1302,6 +1302,8 @@
-- nodes we just inserted.
Container.Count := Container.Count + Count;
+
+ Position := Cursor'(Parent.Container, First);
end Insert_Child;
-------------------------