File : asgc.ads
-- The Ada Structured Library - A set of container classes and general
-- tools for use with Ada95.
-- Copyright (C) 1998-1999 Corey Minyard (minyard@acm.org)
--
-- This library is free software; you can redistribute it and/or modify it
-- under the terms of the GNU General Public License as published by the
-- Free Software Foundation; either version 2 of the License, or (at your
-- option) any later version.
--
-- This library is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- General Public License for more details.
--
-- You should have received a copy of the GNU General Public License along
-- with this library; if not, write to the Free Software Foundation, Inc.,
-- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
--
-- As a special exception, if other files instantiate generics from this
-- unit, or you link this unit with other files to produce an executable,
-- this unit does not by itself cause the resulting executable to be
-- covered by the GNU General Public License. This exception does not
-- however invalidate any other reasons why the executable file might be
-- covered by the GNU Public License.
--
with Baseclass;
generic
-- This is the type being contained in the container.
type Contained_Type is private;
-- An equivalence function, if necessary, can be supplied.
with function "=" (V1, V2 : in Contained_Type) return Boolean is <>;
package Asgc is
------------------------------------------------------------------------
-- All container objects derive from this class.
type Object is abstract new Baseclass.Object with private;
type Object_Class is access all Object'Class;
-- Add a value to the container. How this is done is
-- container-specific. If the container does not support duplicates
-- and the value is already in the container, Item_Already_Exists
-- will be raised.
procedure Add (O : in out Object;
Val : in Contained_Type)
is abstract;
-- Delete a value to the container. If the container can hold
-- more than one of the same value, only one of the items is
-- deleted. If the item is not in the container, then
-- Item_Not_Found will be raised.
procedure Delete (O : in out Object;
Val : in Contained_Type)
is abstract;
-- Return True if the value is in the container and False if not. Boy,
-- I'd like it if I could define an "in" operator for this.
function Value_Exists (O : in Object;
Val : in Contained_Type)
return Boolean
is abstract;
-- Return the number of items in the container.
function Member_Count (O : in Object)
return Natural
is abstract;
-- Compare two containers to see if they are the same. The meaning
-- of "same" depends on the specific container.
function "=" (O1, O2 : in Object) return Boolean is abstract;
-- Verify the integrity of the container's data structures. This will
-- raise exceptions if the container has integrity problems, otherwise
-- it will just return.
procedure Verify_Integrity (O : in Object) is abstract;
-- Generate an exact copy of a container.
function Copy (O : in Object) return Object_Class
is abstract;
------------------------------------------------------------------------
-- A callback routine that can be provided to an object to tell when
-- objects are added or deleted from the collection;
type Callbacks is abstract new Baseclass.Object with private;
type Callbacks_Class is access all Callbacks'Class;
-- A value was added to the container.
procedure Added (Cb : access Callbacks;
O : in Object'Class;
Val : in out Contained_Type)
is abstract;
-- A value was copied to a new container.
procedure Copied (Cb : access Callbacks;
O : in Object'Class;
Val : in out Contained_Type)
is abstract;
-- A value was deleted from a container.
procedure Deleted (Cb : access Callbacks;
O : in Object'Class;
Val : in out Contained_Type)
is abstract;
-- Set the callbacks for an object. Setting it to null will turn the
-- callbacks off.
procedure Set_Callbacks (O : in out Object;
Cb : in Callbacks_Class);
-- Call the Operate procedure supplied for every item in the container.
generic
with procedure Operate (Val : in Contained_Type);
procedure Generic_For_All (O : in Object_Class);
------------------------------------------------------------------------
-- An object that can iterate through another object. A container can
-- have more than one iterator operating on it at any point in time.
-- Note that an update to a container will invalidate all iterators
-- using that container except the one through which the change came.
type Iterator is abstract new Baseclass.Object with private;
type Iterator_Class is access all Iterator'Class;
-- Return an iterator for a container. It will be dynamically
-- allocated and must be freed with the "Free" function below.
function New_Iterator (O : access Object) return Iterator_Class
is abstract;
-- Free an iterator allocated with New_Iterator.
procedure Free (Iter : access Iterator)
is abstract;
-- Set the container for an iterator. Before the container is set, the
-- iterator cannot be used. After it is set, the iterator must still be
-- positioned, it will be at an invalid position after this call.
procedure Set_Container (Iter : in out Iterator;
O : in Object_Class)
is abstract;
-- Add a value to the container the iterator references and move the
-- iterator to the newly added item's position.
procedure Add (Iter : in out Iterator;
Val : in Contained_Type)
is abstract;
-- Functions to do simple iteration through a container. All containers
-- will support this, but efficiency obviously varies with different
-- container types.
type End_Marker is (Past_End, Not_Past_End);
-- If First returns Past_End in Is_End, then the container is empty and
-- iterator will not be valid.
procedure First (Iter : in out Iterator; Is_End : out End_Marker)
is abstract;
-- If Next returns Past_End in Is_End, then the iterator will not be
-- moved, the entry at call time was the last item.
procedure Next (Iter : in out Iterator; Is_End : out End_Marker)
is abstract;
-- Delete the item from the container that the iterator points to. All
-- other iterators but this one will be invalidated. If the contained
-- object is the last object in the container, then Is_End will be
-- set to Past_End and the iterator will be invalid. Otherwise,
-- Not_Past_Pnd will be returned and the iterator will point to the
-- next object after the one deleted.
procedure Delete (Iter : in out Iterator; Is_End : out End_Marker)
is abstract;
-- Do two iterators point to the same element of the same object?
function Is_Same (Iter1, Iter2 : in Iterator) return Boolean
is abstract;
-- Return the value the iterator points to.
function Get (Iter : in Iterator) return Contained_Type
is abstract;
-- Get the current value and move to the next position. If the iterator
-- points to the last position, the iterator will be set invalid and
-- Is_End set to Past_End. Otherwise, Is_End will be set to Not_Past_End.
-- A valid value is returned in either case
procedure Get_Incr (Iter : in out Iterator;
Val : out Contained_Type;
Is_End : out End_Marker)
is abstract;
-- Are the items the two iterators point to equal (tested by the "="
-- function provided generically?
function "=" (Iter1, Iter2 : in Iterator) return Boolean
is abstract;
-- Is the item the iterator points to equal to the supplied item?
function "=" (Iter : in Iterator; Val : in Contained_Type) return Boolean
is abstract;
function "=" (Val : in Contained_Type; Iter : in Iterator) return Boolean
is abstract;
-- Search for a value in the conatiner for the given value. This is
-- implemented as a linear search in this package, but other functions
-- are free to reimplement this.
procedure Search (Iter : in out Iterator;
Val : in Contained_Type;
Found : out Boolean);
-- Search for the value in the container from the position following the
-- iterator to the end of the container. The value searched for is the
-- value the iterater currently references, so this can be used with the
-- Search method to find all items in the container of the specific value.
procedure Search_Again (Iter : in out Iterator;
Found : out Boolean);
------------------------------------------------------------------------
-- Exceptions for various operations
-- The iterator is invalid. Either the iterator was not initialized
-- or the position of the iterator was not valid.
Invalid_Iterator : exception;
-- The iterators performed an operations that required them to point
-- to the same container but the containers were different.
Iterator_Mismatch : exception;
-- An operation was attempted on an object that has been freed
Object_Free : exception;
-- An operation was attempted on an iterator that has been freed
Iterator_Free : exception;
-- The container has changed since the last time the iterator was set.
Object_Updated : exception;
-- A comparison of contained types that do not support comparison.
Invalid_Compare : exception;
-- An item was not found in the container
Item_Not_Found : exception;
-- An item was already in the container
Item_Already_Exists : exception;
-- A container has filled up and the item being added will not fit.
Container_Full : exception;
private
type Update_Count is mod 2 ** 32;
Invalid_Update : constant Update_Count := 0 - 1;
type Object is abstract new Baseclass.Object with record
Cb : Callbacks_Class := null;
Update : Update_Count := 0;
Is_Free : Boolean := False;
end record;
type Iterator is abstract new Baseclass.Object with record
Update : Update_Count := Invalid_Update;
Is_Free : Boolean := False;
end record;
type Callbacks is abstract new Baseclass.Object with null record;
end Asgc;