I would like to request some code review and feedback on a stack implementation using Swift.
Disclaimer: I might have not used protocols, optional unwrapping and error and nil
check correctly (still trying to figure out the essence of protocols - but that's the drill I'm going through now).
import Foundation
/* Node conformance */
protocol NodeProtocol {
typealias IDType;
typealias IDNode;
func insertNode(element : IDType, nextNode : IDNode?);
}
/* Stack's conformance prototol */
protocol StackProtocol {
typealias IDType;
/* Function to push element on stack */
func push(element : IDType);
}
class IDNode<IDType> : NodeProtocol
{
var element: IDType?;
var nextNode: IDNode?;
/* Sets the element and updates next pointer */
func insertNode(element: IDType, nextNode: IDNode?) {
self.element = element;
self.nextNode = nextNode;
}
}
class IDStack<IDType> : StackProtocol
{
private var stackHead: IDNode<IDType>?;
init() {
/* Constructor to initialize the stack */
stackHead = IDNode<IDType>();
}
func push(element: IDType) {
/* If stackHead is empty - just create a new stack
* Ideally the constructor should have taken care of this.
* but in our case - because of optional. stackHead can be NULL.
* So we don't want to take any chance while pushing element to stack.
*/
if(stackHead == nil) {
stackHead = IDNode<IDType>();
}
/* if stack's first element is empty - Insert as the first element
* At this point stack is guaranteed not NULL. Right?
* What if memory allocation fails from above?
*/
if(stackHead!.element == nil) {
stackHead!.insertNode(element, nextNode: nil);
}else {
/* create a new node and insert the new element at top */
var nodeToPushInStack: IDNode<IDType>! = IDNode<IDType>();
/* I'm assuming memory allocation always passes from above.
* Is it correct?
*/
nodeToPushInStack.insertNode(element, nextNode: stackHead);
/* Update stack's head to the new Node */
stackHead = nodeToPushInStack;
}
}
func popElement() -> IDType? {
/* Remove from top and return the element. */
var itemPoppedFromStack : IDType?;
if(self.stackHead == nil) {
/* Stack is empty / not initialized */
return nil;
}
itemPoppedFromStack = self.stackHead!.element!;
if(itemPoppedFromStack == nil) {
return nil;
} else {
/* restore pointer order */
stackHead = stackHead!.nextNode;
}
return itemPoppedFromStack;
}
func getLength() -> Double {
var length: Double = 0;
var headNode: IDNode<IDType>! = self.stackHead;
if(headNode == nil) {
/* stack is probably empty, just return 0 */
return 0;
}
while(self.stackHead != nil) {
length++;
self.stackHead = self.stackHead!.nextNode;
}
/* restore back stackHead to original head */
self.stackHead = headNode;
return length;
}
}
typealias
es. – nhgrif Jul 21 '15 at 16:04