Andrew Spott
Andrew Spott

Reputation: 3627

Creating a FIFO fixed size array in Swift

I'm attempting to create a FIFO array in swift. I want to create something that acts like this:

var Arr = FixedFIFOArray<Int>(maxSize:3)
Arr.append(1)  //Arr = [1]
Arr.append(2)  //Arr = [1,2]
Arr.append(3)  //Arr = [1,2,3]
Arr.append(4)  //Arr = [2,3,4] <- the max size is fixed to 3, so any
                                  additional values added remove old values

Other than this behavior, it should act like an array: allow slicing, indexing, iterating in for loops, etc.

In any other language, this would be a job for subclassing. We aren't changing much, just adding an initializer and amending a function or two. However, in Swift, we can't subclass array. What is the best way to do this? Do I need to implement every protocol that array implements, and just pass the associated functions off to an array? Something like this:

struct FixedFIFOArray<T> {
    var _maxSize: Int
    var _array: [T] = []

    init(maxSize: Int) {
        self._maxSize = maxSize
    }

}

extension FixedFIFOArray : Collection {
    //...
}

extension FixedFIFOArray : RandomAccessCollection {
    //...
}

extension FixedFIFOArray : Sequence {
    //...
}
// etc...

This seems like a lot of work to do something so simple. What am I missing?

Upvotes: 4

Views: 2993

Answers (1)

Martin R
Martin R

Reputation: 539745

It is not as bad as it seems, because many protocol requirements have default implementations. Unfortunately I do not have the perfect recipe to find a "minimal" implementation.

  • Some information can be found in the RandomAccessCollection documentation where some methods are marked as "Required. Default implementation provided."

  • You can also start with an empty implementation extension FixedFIFOArray : RandomAccessCollection {} and study the error messages or try the Fix-its.

  • With "Jump to Definiton" in the Xcode editor one can inspect the protocol definitions and extension methods.

In your case it turned out that it suffices to implement startIndex, endIndex, and subscript:

extension FixedFIFOArray : RandomAccessCollection {
    var startIndex: Int {
        return _array.startIndex
    }

    var endIndex: Int {
        return _array.endIndex
    }

    subscript(i: Int) -> T {
        return _array[i]
    }
}

Or, if you need a read-write subscript:

    subscript(i: Int) -> T {
        get {
            return _array[i]
        }
        set {
            _array[i] = newValue
        }
    }

Upvotes: 1

Related Questions