Span

// Stores a fixed-size array of items locally without allocating from the heap. Can be used to store an 
// array of items as a local variable in a function or as member variable in a class. Template param [M] 
// is the maximum items the array can hold.
template<typename T, uint M = 8>
class Span
{
public:
    class const_iterator
    {
    public:
        typedef const_iterator self_type;
        typedef const T value_type;
        typedef const T &reference;
        typedef const T *pointer;
        typedef int difference_type;

        int index() const { return n; };

        self_type operator++() { n++; return *this; }
        self_type operator++(int ignore) { self_type i = *this; n++; return i; }
        reference operator*() const { return (*span)[n]; }
        pointer operator->() const { return &(*span)[n]; }
        bool operator==(const self_type &rhs) const { return n == rhs.n; }
        bool operator!=(const self_type &rhs) const { return n != rhs.n; }

        const_iterator(const Span<T, M> &span, int n) : span(&span), n(n) {}
        const_iterator() : span(0), n(0) {}

    private:
        const Span<T, M> *span;
        int n;
    };

    class iterator
    {
    public:
        typedef iterator self_type;
        typedef T value_type;
        typedef T &reference;
        typedef T *pointer;
        typedef int difference_type;

        int index() const { return n; };

        self_type operator++() { n++; return *this; }
        self_type operator++(int ignore) { self_type i = *this; n++; return i; }
        reference operator*() const { return (*span)[n]; }
        pointer operator->() const { return &(*span)[n]; }
        bool operator==(const self_type &rhs) const { return n == rhs.n; }
        bool operator!=(const self_type &rhs) const { return n != rhs.n; }

        iterator(Span<T, M> &span, int n) : span(&span), n(n) {}
        iterator() : span(0), n(0) {}

    private:
        Span<T, M> *span;
        int n;
    };

    class const_reverse_iterator
    {
    public:
        typedef const_reverse_iterator self_type;
        typedef const T value_type;
        typedef const T &reference;
        typedef const T *pointer;
        typedef int difference_type;

        int index() const { return n; };

        self_type operator++() { n--; return *this; }
        self_type operator++(int ignore) { self_type i = *this; n--; return i; }
        reference operator*() const { return (*span)[n]; }
        pointer operator->() const { return &(*span)[n]; }
        bool operator==(const self_type &rhs) const { return n == rhs.n; }
        bool operator!=(const self_type &rhs) const { return n != rhs.n; }

        const_reverse_iterator(const Span<T, M> &span, int n) : span(&span), n(n) {}
        const_reverse_iterator() : span(0), n(0) {}

    private:
        const Span<T, M> *span;
        int n;
    };

    class reverse_iterator
    {
    public:
        typedef reverse_iterator self_type;
        typedef T value_type;
        typedef T &reference;
        typedef T *pointer;
        typedef int difference_type;

        int index() const { return n; };

        self_type operator++() { n--; return *this; }
        self_type operator++(int ignore) { self_type i = *this; n--; return i; }
        reference operator*() const { return (*span)[n]; }
        pointer operator->() const { return &(*span)[n]; }
        bool operator==(const self_type &rhs) const { return n == rhs.n; }
        bool operator!=(const self_type &rhs) const { return n != rhs.n; }

        reverse_iterator(Span<T, M> &span, int n) : span(&span), n(n) {}
        reverse_iterator() : span(0), n(0) {}

    private:
        Span<T, M> *span;
        int n;
    };

    // Get constant begin iterator.
    const_iterator begin() const { return const_iterator(*this, 0); }

    // Get constant end iterator.
    const_iterator end() const { return const_iterator(*this, GetCount()); }

    // Get begin iterator.
    iterator begin() { return iterator(*this, 0); }

    // Get end iterator.
    iterator end() { return iterator(*this, GetCount()); }

    // Get constant reverse begin iterator.
    const_reverse_iterator rbegin() const { return const_reverse_iterator(*this, GetCount() - 1); }

    // Get constant reverse end iterator.
    const_reverse_iterator rend() const { return const_reverse_iterator(*this, -1); }

    // Get reverse begin iterator.
    reverse_iterator rbegin() { return reverse_iterator(*this, GetCount() - 1); }

    // Get reverse end iterator.
    reverse_iterator rend() { return reverse_iterator(*this, -1); }

    // Get item count.
    uint GetCount() const { return count; }

    // Check if array is empty.
    bool operator ! () const { return !count; }

    // Get item at index
    const T &operator [](int index) const { if (index < 0) index += count; return ((T *)buf)[index]; }

    // Add item to end of array. Returns memory to use with new. Usage: new (array.Add()) T().
    void *Add() { return &(*this)[count++]; }

    // Delete item at end of array.
    void Delete() { ((T &)(*this)[--count]).~T(); }

    // Clear all items from array.
    void Clear() { while (count) Delete(); }

    // Constuctor. See template parameter [M] for setting capacity.
    Span() : count(0) {}

    // Destructor.
    ~Span() { Clear(); }

private:
    T buf[M];
    uint count;
};