//
//  SkTRefArray.h
//  core
//
//  Created by Mike Reed on 7/17/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#ifndef SkTRefArray_DEFINED
#define SkTRefArray_DEFINED

#include "SkRefCnt.h"
#include <new>

/**
 *  Wrapper to manage thread-safe sharing of an array of T objects. The array
 *  cannot be grown or shrunk.
 */
template <typename T> class SkTRefArray : public SkRefCnt {
    /*
     *  Shared factory to allocate the space needed for our instance plus N
     *  T entries at the end. We call our constructor, but not the constructors
     *  for the elements. Those are called by the proper Create method.
     */
    static SkTRefArray<T>* Alloc(int count) {
        // space for us, and our [count] elements
        size_t size = sizeof(SkTRefArray<T>) + count * sizeof(T);
        SkTRefArray<T>* obj = (SkTRefArray<T>*)sk_malloc_throw(size);

        SkNEW_PLACEMENT(obj, SkTRefArray<T>);
        obj->fCount = count;
        return obj;
    }

public:
    /**
     *  Return a new array with 'count' elements, initialized to their default
     *  value. To change them to some other value, use writableBegin/End or
     *  writableAt(), but do that before this array is given to another thread.
     */
    static SkTRefArray<T>* Create(int count) {
        SkTRefArray<T>* obj = Alloc(count);
        T* array = const_cast<T*>(obj->begin());
        for (int i = 0; i < count; ++i) {
            SkNEW_PLACEMENT(&array[i], T);
        }
        return obj;
    }

    /**
     *  Return a new array with 'count' elements, initialized from the provided
     *  src array. To change them to some other value, use writableBegin/End or
     *  writableAt(), but do that before this array is given to another thread.
     */
    static SkTRefArray<T>* Create(const T src[], int count) {
        SkTRefArray<T>* obj = Alloc(count);
        T* array = const_cast<T*>(obj->begin());
        for (int i = 0; i < count; ++i) {
            SkNEW_PLACEMENT_ARGS(&array[i], T, (src[i]));
        }
        return obj;
    }

    int count() const { return fCount; }
    const T* begin() const { return (const T*)(this + 1); }
    const T* end() const { return this->begin() + fCount; }
    const T& at(int index) const {
        SkASSERT((unsigned)index < (unsigned)fCount);
        return this->begin()[index];
    }
    const T& operator[](int index) const { return this->at(index); }

    // For the writable methods, we assert that we are the only owner if we
    // call these, since other owners are not informed if we change an element.

    T* writableBegin() {
        SkASSERT(this->unique());
        return (T*)(this + 1);
    }
    T* writableEnd() {
        return this->writableBegin() + fCount;
    }
    T& writableAt(int index) {
        SkASSERT((unsigned)index < (unsigned)fCount);
        return this->writableBegin()[index];
    }

protected:
    virtual void internal_dispose() const SK_OVERRIDE {
        T* array = const_cast<T*>(this->begin());
        int n = fCount;

        for (int i = 0; i < n; ++i) {
            array->~T();
            array += 1;
        }

        this->internal_dispose_restore_refcnt_to_1();
        this->~SkTRefArray<T>();
        sk_free((void*)this);
    }

private:
    int fCount;

    // hide this
    virtual ~SkTRefArray() {}

    typedef SkRefCnt INHERITED;
};

#endif
