View RSS Feed

Development Team Blog

Need a Stack Class?

Rate this Entry
Amidst all the Arrays & Structs in-depth multi-part series by Sonny Falk, why not take a look at an example of using an array? The code shown here uses a single-dimensional array as the base for a stack class.

A stack is, by definition, a "last in, first out" (LIFO) abstract structure where elements can be added or taken off from only one end, called the "top". A stack can have any abstract data type as an element, but is characterized by two fundamental operations: push and pop.

This class, called cStack, contains all the basic stack operations (peek, push and pop) among others that will make it easy for your applications to handle any stack. cStack uses a variant array property to store the stack you create, allowing a stack to be of any data type you need.

This is what the cStack class looks like:
Code:
 Class cStack is a cObject
 
    Procedure Construct_Object
        Forward Send Construct_Object
 
        Property Variant[] pvStack
    End_Procedure  // Construct_Object
 
 
    // Function NumberOfNodesInStack
    // Returns number of nodes in the stack
    // --------------------------------------------------------------
    Function StackSize Returns Integer
        Variant[] Stack
        Get pvStack to Stack
        Function_Return (SizeOfArray(Stack))
    End_Function
 
 
    // Function IsStackEmpty
    // Returns True if stack is empty
    // --------------------------------------------------------------
    Function IsStackEmpty Returns Boolean
        Integer iNumStackElements
 
        Get StackSize to iNumStackElements
        Function_Return (iNumStackElements = 0)
    End_Function
 
 
    // Function Peek
    // Returns top element of the stack
    // --------------------------------------------------------------
    Function Peek Returns Variant
        Variant TopOfStack
        Variant[] Stack
        Integer iNumOfElements
 
        Get pvStack to Stack
        Move (SizeOfArray(Stack)) to iNumOfElements
        If (iNumOfElements > 0) Begin
            Move Stack[iNumOfElements - 1] to TopOfStack 
        End        
 
        Function_Return TopOfStack
    End_Function
 
 
    // Function Pop
    // Remove top node from stack  
    // Returns the top node of the stack that was removed
    // --------------------------------------------------------------
    Function Pop Returns Variant
        Variant TopOfStack
        Variant[] Stack
        Integer iNumOfElements
 
        Get pvStack to Stack
        Move (SizeOfArray(Stack)) to iNumOfElements
        If (iNumOfElements > 0) Begin
            Move Stack[iNumOfElements - 1] to TopOfStack 
            Move (ResizeArray(Stack, iNumOfElements - 1)) to Stack
            Set pvStack to Stack
        End
        Function_Return TopOfStack
    End_Function
 
 
    // Function Push
    // Adds node to the top of the stack  
    // Returns the index where the new node was placed in the stack
    // --------------------------------------------------------------
    Function Push Variant ElementToAdd Returns Integer
        Variant[] Stack
        Integer iNumOfElements
 
        Get pvStack to Stack
        Move (SizeOfArray(Stack)) to iNumOfElements
        Move ElementToAdd to Stack[iNumOfElements]
        Set pvStack to Stack
        Function_Return iNumOfElements
    End_Function    
 
 
    // Procedure ClearStack
    // Clear the stack 
    // -------------------------------------------------------------- 
    Procedure ClearStack 
        Variant[] Stack
 
        Set pvStack to Stack
    End_Procedure    
 
End_Class
To use cStack you will need to create a variant array variable when manipulating the whole stack. When manipulating one of the elements in the stack, you will need to create a variable of the data type you are storing in the stack. Something like this:

Code:
    // Function CurrentSWSStack
    // Returns the current SWS stack
    // --------------------------------------------------------------
    Function CurrentSWSStack Returns Variant[]
        Variant[] StackOfSWSs
 
        Get pvStack to StackOfSWSs
        Function_Return StackOfSWSs
    End_Function
 
 
    // Function PopSWSFromStack
    // Remove top node from stack  
    // Returns the top node of the SWS stack that was removed
    // tSWSDetails: structure that stores contents read from SWS file
    // --------------------------------------------------------------
    Function PopSWSFromStack Returns tSWSDetails
        tSWSDetails TopOfStack          
        Boolean bEmpty
 
        Get IsSWSStackEmpty to bEmpty
        If (not(bEmpty)) Begin
            Get Pop to TopOfStack
        End
 
        Function_Return TopOfStack
    End_Function
When using the cStack class, you may find it better to create a subclass and add code to deal with the specific needs of the elements you are storing in the stack. In a subclass you may simply add functions that will describe better the operations you will be performing, in other words, the name of the functions used in your programs will be more meaningful to what you are doing.

For example, for a stack of workspace files (SWS), you may have a function called TopSWS that will really perform a peek and return the top element of the stack, like this:

Code:
    // Function IsSWSStackEmpty
    // Returns True if stack is empty
    // --------------------------------------------------------------  
    Function IsSWSStackEmpty Returns Boolean
        Boolean bEmpty
 
        Get IsStackEmpty to bEmpty
        Function_Return bEmpty
    End_Function
 
 
    // Function TopSWS
    // Returns top node of the SWS stack
    // tSWSDetails: structure that stores contents read from SWS file
    // --------------------------------------------------------------    
    Function TopSWS Returns tSWSDetails
        tSWSDetails TopOfStack           
        Boolean bEmpty
 
        Get IsSWSStackEmpty to bEmpty
        If (not(bEmpty)) Begin
          Get Peek to TopOfStack  
        End
 
        Function_Return TopOfStack
    End_Function
For anything managed in a LIFO style you can do the same. You may want to create a subclass to organize the latest news. In your subclass you can create a function called ReadNews which will perform pops on your stack, LatestNews. You may also create a function to ReadLatest that will really perform a peek on LatestNews.

Note: If you need to do a very high number of push or pop operations (e.g. a loop to perform push/pop through many, many, many elements of your stack), you should consider updating the array property from the class straight into your code instead of using the class push/pop access methods. Access methods that translate into a Get-Modify-Set transaction will negatively affect performance when highly used, as Sonny will explain in his future posts. Stay tuned.

As you can see, a cStack object should be able to handle any kind of elements, including object handles. This class should give you the flexibility and the functionality you were looking for. Try it out!
Categories
Uncategorized

Comments