/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef GAPII_SLICE_H
#define GAPII_SLICE_H

#include "pool.h"
#include "abort_exception.h"

#include <gapic/assert.h>

#include <memory>
#include <stdint.h>

namespace gapii {

template<typename T>
class Slice {
public:
    inline Slice();
    inline Slice(T* base, uint64_t count, const std::shared_ptr<Pool>& pool);

    // Returns the number of elements in the slice.
    inline uint64_t count() const;

    // Returns the size of the slice in bytes.
    inline uint64_t size() const;

    // Returns true if this is a slice on the application pool (external memory).
    inline bool isApplicationPool() const;

    // Returns a new subset slice from this slice.
    inline Slice<T> operator()(uint64_t start, uint64_t end) const;

    // Returns a reference to a single element in the slice.
    // Care must be taken to not mutate data in the application pool.
    inline T& operator[](uint64_t index) const;

    // As casts this slice to a slice of type U.
    // The return slice length will be calculated so that the returned slice length is no longer
    // (in bytes) than this slice.
    template<typename U> inline Slice<U> as() const;

    // Support for range-based for looping
    inline T* begin() const;
    inline T* end() const;

private:
    T* mBase;
    uint64_t mCount;
    std::shared_ptr<Pool> mPool;
};

template<typename T>
inline Slice<T>::Slice() : mBase(nullptr), mCount(0) {}

template<typename T>
inline Slice<T>::Slice(T* base, uint64_t count, const std::shared_ptr<Pool>& pool)
    : mBase(base), mCount(count), mPool(pool) {
    gapii::spyAssert(mBase != nullptr || count == 0, "Slice: null pointer");
}

template<typename T>
inline uint64_t Slice<T>::count() const {
    return mCount;
}

template<typename T>
inline uint64_t Slice<T>::size() const {
    return mCount * sizeof(T);
}

template<typename T>
inline bool Slice<T>::isApplicationPool() const {
    return mPool.get() == nullptr;
}

template<typename T>
inline Slice<T> Slice<T>::operator()(uint64_t start, uint64_t end) const {
    gapii::spyAssert(start <= end, "Slice: start > end");
    gapii::spyAssert(end <= mCount, "Slice: index out of bounds");
    gapii::spyAssert(mBase != nullptr || (start == end), "Slice: null pointer");
    return Slice<T>(mBase+start, end-start, mPool);
}

template<typename T>
inline T& Slice<T>::operator[](uint64_t index) const {
    gapii::spyAssert(index >= 0 && index < mCount, "Slice: index out of bounds");
    return mBase[index];
}

template<typename T> template<typename U>
inline Slice<U> Slice<T>::as() const {
    uint64_t count = size() / sizeof(U);
    return Slice<U>(reinterpret_cast<U*>(mBase), count, mPool);
}

template<typename T>
inline T* Slice<T>::begin() const {
    return mBase;
}

template<typename T>
inline T* Slice<T>::end() const {
    return mBase + mCount;
}

}  // namespace gapii

#endif // GAPII_SLICE_H
