Files
Platinum_Reusable_Stack/source/Silver/sequential_bounded_stacks.ads
2022-06-30 15:02:10 +02:00

109 lines
3.3 KiB
Ada

--
-- Copyright (C) 2020, AdaCore
--
-- SPDX-License-Identifier: Apache-2.0
--
-- This is the Silver level version of the generic package
generic
type Element is private;
-- The type of values contained by objects of type Stack
Default_Value : Element;
-- The default value used for stack contents. Never
-- acquired as a value from the API, but required for
-- initialization in SPARK.
package Sequential_Bounded_Stacks is
subtype Element_Count is Integer range 0 .. Integer'Last - 1;
-- The number of Element values currently contained
-- within any given stack. The lower bound is zero
-- because a stack can be empty. We limit the upper
-- bound (minimally) to preclude overflow issues.
subtype Physical_Capacity is Element_Count range 1 .. Element_Count'Last;
-- The range of values that any given stack object can
-- specify (via the discriminant) for the number of
-- Element values the object can physically contain.
-- Must be at least one.
type Stack (Capacity : Physical_Capacity) is private
with Default_Initial_Condition => Empty (Stack);
procedure Push (This : in out Stack; Item : in Element) with
Pre => not Full (This),
Post => Extent (This) = Extent (This)'Old + 1,
Global => null;
procedure Pop (This : in out Stack; Item : out Element) with
Pre => not Empty (This),
Post => Extent (This) = Extent (This)'Old - 1,
Global => null;
function Top_Element (This : Stack) return Element with
Pre => not Empty (This),
Global => null;
-- Returns the value of the Element at the "top" of This
-- stack, i.e., the most recent Element pushed. Does not
-- remove that Element or alter the state of This stack
-- in any way.
overriding function "=" (Left, Right : Stack) return Boolean with
Global => null;
procedure Copy (Destination : in out Stack; Source : Stack) with
Pre => Destination.Capacity >= Extent (Source),
Global => null;
-- An alternative to predefined assignment that does not
-- copy all the values unless necessary. It only copies
-- the part "logically" contained, so is more efficient
-- when Source is not full.
function Extent (This : Stack) return Element_Count with
Global => null;
-- Returns the number of Element values currently
-- contained within This stack.
function Empty (This : Stack) return Boolean with
Global => null;
function Full (This : Stack) return Boolean with
Global => null;
procedure Reset (This : in out Stack) with
Global => null;
private
type Content is array (Physical_Capacity range <>) of Element;
type Stack (Capacity : Physical_Capacity) is record
Values : Content (1 .. Capacity) := (others => Default_Value);
Top : Element_Count := 0;
end record with
Predicate => Top in 0 .. Capacity;
------------
-- Extent --
------------
function Extent (This : Stack) return Element_Count is
(This.Top);
-----------
-- Empty --
-----------
function Empty (This : Stack) return Boolean is
(This.Top = 0);
----------
-- Full --
----------
function Full (This : Stack) return Boolean is
(This.Top = This.Capacity);
end Sequential_Bounded_Stacks;