From: "Matthew Heaney" <mheaney@on2.com>
Subject: Re: List Container Strawman 1.4
Date: Sat, 29 Dec 2001 18:23:40 -0500
Date: 2001-12-29T18:23:40-05:00 [thread overview]
Message-ID: <u2sjro7fckej62@corp.supernews.com> (raw)
In-Reply-To: u2pitjhps1bp07@corp.supernews.com
"Matthew Heaney" <mheaney@on2.com> wrote in message
news:u2pitjhps1bp07@corp.supernews.com...
> If you wanted, you could generalize this further (as the STL does) to
> abstract away the target type (in the example above we've hard-coded an
> array type as the target type). To do this for arrays you'd need an
> appropriate iterator type; maybe Interfaces.C.Pointers would work.
In the example below I wrote an array iterator and a Generic_Copy algorithm
that works for any target type. The basic idea is:
declare
...
procedure Copy is
new Generic_Copy
(Integer_Lists.Iterator_Type,
Integer_Arrays.Iterator_Type);
Items : aliased Integer_Array (1 .. Length (List));
Iter : Integer_Arrays.Iterator_Type := Items
(Items'First)'Unchecked_Access;
begin
Copy (First (List), Back (List), Iter);
end;
This is exactly how the STL does things.
The code below is suitable for use with gnatchop.
--STX
with System.Storage_Elements;
with Ada.Unchecked_Conversion;
package body Array_Iterators is
use type System.Storage_Elements.Storage_Offset;
function To_Iterator is
new Ada.Unchecked_Conversion (System.Address, Iterator_Type);
function First (Items : access Array_Type) return Iterator_Type is
begin
return Items (Items'First)'Access;
end;
function Back (Items : access Array_Type) return Iterator_Type is
First_Address : constant System.Address := Items
(Items'First)'Address;
Length : constant System.Storage_Elements.Storage_Count :=
Items'Length;
Offset : constant System.Storage_Elements.Storage_Count :=
Length * Array_Type'Component_Size / System.Storage_Unit;
Back_Address : constant System.Address := First_Address + Offset;
begin
return To_Iterator (Back_Address);
end;
function Item (Iterator : Iterator_Type) return Item_Type is
begin
return Iterator.all;
end;
procedure Next (Iterator : in out Iterator_Type) is
Curr_Address : constant System.Address := Iterator.all'Address;
Offset : constant System.Storage_Elements.Storage_Count :=
Array_Type'Component_Size / System.Storage_Unit;
Next_Address : constant System.Address := Curr_Address + Offset;
begin
Iterator := To_Iterator (Next_Address);
end;
end Array_Iterators;
generic
type Item_Type is limited private;
type Index_Type is range <>;
type Array_Type is array (Index_Type range <>) of aliased Item_Type;
package Array_Iterators is
type Iterator_Type is access all Item_Type;
for Iterator_Type'Storage_Size use 0;
function First (Items : access Array_Type) return Iterator_Type;
function Back (Items : access Array_Type) return Iterator_Type;
function Item (Iterator : Iterator_Type) return Item_Type;
procedure Next (Iterator : in out Iterator_Type);
end Array_Iterators;
procedure Generic_Copy
(First : in Source_Iterator_Type;
Back : in Source_Iterator_Type;
Target : in out Target_Iterator_Type) is
Source : Source_Iterator_Type := First;
begin
while Source /= Back loop
Set_Item (Source, Target);
Next (Source);
Next (Target);
end loop;
end Generic_Copy;
generic
type Source_Iterator_Type (<>) is private;
type Target_Iterator_Type (<>) is private;
with procedure Set_Item
(Source : Source_Iterator_Type;
Target : Target_Iterator_Type) is <>;
with procedure Next (Iterator : in out Source_Iterator_Type) is <>;
with procedure Next (Iterator : in out Target_Iterator_Type) is <>;
with function "=" (L, R : Source_Iterator_Type) return Boolean is <>;
procedure Generic_Copy
(First : in Source_Iterator_Type;
Back : in Source_Iterator_Type;
Target : in out Target_Iterator_Type);
with Array_Iterators;
pragma Elaborate_All (Array_Iterators);
package Integer_Arrays is
type Integer_Array is array (Positive range <>) of aliased Integer;
package Integer_Array_Iterators is
new Array_Iterators (Integer, Positive, Integer_Array);
type Iterator_Type is new Integer_Array_Iterators.Iterator_Type;
end Integer_Arrays;
with Unbounded_Lists;
pragma Elaborate_All (Unbounded_Lists);
package Integer_Lists is
new Unbounded_Lists (Integer);
with Integer_Lists; use Integer_Lists;
with Integer_Arrays; use Integer_Arrays;
with Generic_Copy;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Test_Copy is
List : List_Type;
begin
for I in 1 .. 5 loop
Push_Back (List, I);
end loop;
declare
Iter : Integer_Lists.Iterator_Type := First (List);
Back : constant Integer_Lists.Iterator_Type := Integer_Lists.Back
(List);
begin
Put ("source:");
while Iter /= Back loop
Put (' ');
Put (Item (Iter), Width => 0);
Next (Iter);
end loop;
New_Line;
end;
declare
procedure Set_Item
(Source : Integer_Lists.Iterator_Type;
Target : Integer_Arrays.Iterator_Type) is
begin
Target.all := Item (Source);
end;
pragma Warnings (Off, Set_Item);
procedure Copy is
new Generic_Copy
(Integer_Lists.Iterator_Type,
Integer_Arrays.Iterator_Type);
Items : aliased Integer_Array (1 .. Length (List));
Iter : Integer_Arrays.Iterator_Type := Items
(Items'First)'Unchecked_Access;
begin
Copy (First (List), Back (List), Iter);
Put ("target:");
for I in Items'Range loop
Put (' ');
Put (Items (I), Width => 0);
end loop;
New_Line;
end;
end Test_Copy;
with Ada.Unchecked_Deallocation; --should pass in storage_pool
package body Unbounded_Lists is
procedure Free is
new Ada.Unchecked_Deallocation (Node_Type, Node_Access);
procedure Initialize (List : in out List_Type) is
begin
List.Front := new Node_Type;
List.Back := new Node_Type;
List.Front.Next := List.Back;
List.Back.Prev := List.Front;
List.Length := 0;
end Initialize;
procedure Finalize (List : in out List_Type) is
begin
Clear (List);
Free (List.Front);
Free (List.Back);
end;
procedure Push_Front
(List : in out List_Type;
Item : in Item_Type) is
Node : constant Node_Access :=
new Node_Type'(Item => Item,
Next => List.Front.Next,
Prev => List.Front);
begin
Node.Next.Prev := Node;
List.Front.Next := Node;
List.Length := List.Length + 1;
end;
procedure Push_Front
(List : access List_Type;
Item : in Item_Type) is
begin
Push_Front (List.all, Item);
end;
procedure Push_Back
(List : in out List_Type;
Item : in Item_Type) is
Node : constant Node_Access :=
new Node_Type'(Item => Item,
Next => List.Back,
Prev => List.Back.Prev);
begin
Node.Prev.Next := Node;
List.Back.Prev := Node;
List.Length := List.Length + 1;
end;
procedure Push_Back
(List : access List_Type;
Item : in Item_Type) is
begin
Push_Back (List.all, Item);
end;
procedure Push_Front (List : in out List_Type) is
Node : constant Node_Access := new Node_Type;
begin
Node.Next := List.Front.Next;
Node.Prev := List.Front;
Node.Next.Prev := Node;
List.Front.Next := Node;
List.Length := List.Length + 1;
end;
procedure Push_Back (List : in out List_Type) is
Node : constant Node_Access := new Node_Type;
begin
Node.Next := List.Back;
Node.Prev := List.Back.Prev;
Node.Prev.Next := Node;
List.Back.Prev := Node;
List.Length := List.Length + 1;
end;
procedure Pop_Front (List : in out List_Type) is
pragma Assert (List.Length > 0);
Node : Node_Access := List.Front.Next;
begin
List.Front.Next := Node.Next;
Node.Next.Prev := List.Front;
List.Length := List.Length - 1;
Free (Node);
end;
procedure Pop_Back (List : in out List_Type) is
pragma Assert (List.Length > 0);
Node : Node_Access := List.Back.Prev;
begin
List.Back.Prev := Node.Prev;
Node.Prev.Next := List.Back;
List.Length := List.Length - 1;
Free (Node);
end;
function Length (List : List_Type) return Natural is
begin
return List.Length;
end;
procedure Clear (List : in out List_Type) is
Node : Node_Access := List.Front.Next;
Next : Node_Access;
begin
while Node /= List.Back loop
Next := Node.Next;
Free (Node);
Node := Next;
end loop;
List.Front.Next := List.Back;
List.Back.Prev := List.Front;
List.Length := 0;
end;
function First (List : List_Type) return Item_Type is
pragma Assert (List.Length > 0);
begin
return List.Front.Next.Item;
end;
function Last (List : List_Type) return Item_Type is
pragma Assert (List.Length > 0);
begin
return List.Back.Prev.Item;
end;
procedure Swap (L, R : in out List_Type) is
Front : constant Node_Access := L.Front;
Back : constant Node_Access := L.Back;
Length : constant Natural := L.Length;
begin
L.Front := R.Front;
L.Back := R.Back;
L.Length := R.Length;
R.Front := Front;
R.Back := Back;
R.Length := Length;
end;
function First (List : List_Type) return Iterator_Type is
pragma Assert (List.Length > 0);
begin
return Iterator_Type'(Node => List.Front.Next);
end;
function Last (List : List_Type) return Iterator_Type is
pragma Assert (List.Length > 0);
begin
return Iterator_Type'(Node => List.Back.Prev);
end;
function Front (List : List_Type) return Iterator_Type is
begin
return Iterator_Type'(Node => List.Front);
end;
function Back (List : List_Type) return Iterator_Type is
begin
return Iterator_Type'(Node => List.Back);
end;
procedure Next (Iterator : in out Iterator_Type) is
begin
Iterator.Node := Iterator.Node.Next;
end;
procedure Previous (Iterator : in out Iterator_Type) is
begin
Iterator.Node := Iterator.Node.Prev;
end;
function Item (Iterator : Iterator_Type) return Item_Type is
begin
return Iterator.Node.Item;
end;
end Unbounded_Lists;
with Ada.Finalization;
generic
type Item_Type is private;
package Unbounded_Lists is
type List_Type is limited private;
procedure Push_Front
(List : in out List_Type;
Item : in Item_Type);
procedure Push_Front
(List : access List_Type;
Item : in Item_Type);
procedure Push_Front (List : in out List_Type);
procedure Pop_Front (List : in out List_Type);
procedure Push_Back
(List : in out List_Type;
Item : in Item_Type);
procedure Push_Back
(List : access List_Type;
Item : in Item_Type);
procedure Push_Back (List : in out List_Type);
procedure Pop_Back (List : in out List_Type);
function Length (List : List_Type) return Natural;
procedure Clear (List : in out List_Type);
function First (List : List_Type) return Item_Type;
function Last (List : List_Type) return Item_Type;
procedure Swap (L, R : in out List_Type);
type Iterator_Type is private;
function First (List : List_Type) return Iterator_Type;
function Last (List : List_Type) return Iterator_Type;
function Front (List : List_Type) return Iterator_Type;
function Back (List : List_Type) return Iterator_Type;
procedure Next (Iterator : in out Iterator_Type);
procedure Previous (Iterator : in out Iterator_Type);
function Item (Iterator : Iterator_Type) return Item_Type;
private
type Node_Type;
type Node_Access is access Node_Type;
type Node_Type is
record
Item : aliased Item_Type;
Next : Node_Access;
Prev : Node_Access;
end record;
type Handle_Type (L : access List_Type) is limited null record;
type List_Type is
new Ada.Finalization.Limited_Controlled with record
H : Handle_Type (List_Type'Access);
Front : Node_Access;
Back : Node_Access;
Length : Natural;
end record;
procedure Initialize (List : in out List_Type);
procedure Finalize (List : in out List_Type);
type Iterator_Type is
record
Node : Node_Access;
end record;
end Unbounded_Lists;
next prev parent reply other threads:[~2001-12-29 23:23 UTC|newest]
Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-12-13 3:23 List Container Strawman 1.4 Ted Dennison
2001-12-13 18:11 ` Brian Hanson
2001-12-13 23:02 ` Nick Roberts
2001-12-14 15:19 ` Ted Dennison
2001-12-14 23:54 ` Ted Dennison
2001-12-15 2:06 ` Server - tasking and long lived connections Eric Merritt
2001-12-15 3:10 ` James Rogers
2001-12-15 12:10 ` Florian Weimer
2001-12-15 14:38 ` Larry Kilgallen
2001-12-15 16:51 ` Steve Doiel
2001-12-17 9:15 ` Thierry Lelegard
2001-12-17 9:34 ` Jean-Pierre Rosen
2001-12-17 10:16 ` Thierry Lelegard
2001-12-18 9:08 ` Jean-Pierre Rosen
2001-12-17 15:08 ` Larry Kilgallen
2001-12-17 15:39 ` Pat Rogers
2001-12-19 18:20 ` Matthew Heaney
2001-12-19 18:50 ` Eric Merritt
2001-12-15 1:20 ` List Container Strawman 1.4 Nick Roberts
2001-12-15 20:29 ` Ted Dennison
2001-12-16 18:45 ` Nick Roberts
2001-12-21 15:53 ` Ted Dennison
2001-12-21 16:42 ` Marin David Condic
2001-12-21 18:28 ` Ted Dennison
2001-12-21 18:47 ` Marin David Condic
2001-12-21 19:39 ` Ted Dennison
2001-12-21 19:48 ` Marin David Condic
2001-12-22 12:29 ` Simon Wright
2001-12-21 20:03 ` Nick Roberts
2001-12-21 16:52 ` Marin David Condic
2001-12-21 18:41 ` Ted Dennison
2001-12-21 19:14 ` Marin David Condic
2001-12-21 21:13 ` Ted Dennison
2001-12-22 5:34 ` John B. Matthews
2001-12-21 20:19 ` Stephen Leake
2001-12-21 21:35 ` Ted Dennison
2001-12-24 11:58 ` Florian Weimer
2001-12-24 14:42 ` Eric Merritt
2001-12-24 22:47 ` Ted Dennison
2001-12-25 22:15 ` Florian Weimer
2001-12-28 13:58 ` Ted Dennison
2001-12-21 17:43 ` Stephen Leake
2001-12-21 18:44 ` Ted Dennison
2001-12-16 21:53 ` Larry Hazel
2001-12-15 22:27 ` Ted Dennison
2001-12-16 4:32 ` Darren New
2001-12-24 13:53 ` Florian Weimer
2001-12-15 23:19 ` Florian Weimer
2001-12-16 4:46 ` Ted Dennison
2001-12-24 13:57 ` Florian Weimer
2001-12-28 14:00 ` Ted Dennison
2001-12-28 16:43 ` Hyman Rosen
2001-12-28 19:12 ` Nick Roberts
2001-12-28 19:49 ` Matthew Heaney
2001-12-29 23:23 ` Matthew Heaney [this message]
2001-12-30 6:31 ` Hyman Rosen
2002-01-03 0:09 ` Matthew Heaney
2002-01-03 0:20 ` Brian Rogoff
2001-12-17 8:34 ` Mark Lundquist
2001-12-18 21:56 ` Florian Weimer
2001-12-18 21:54 ` Larry Kilgallen
2001-12-18 22:34 ` Mark Lundquist
2001-12-19 4:03 ` Nick Roberts
2001-12-24 13:54 ` Florian Weimer
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox