blob: 391e428773a58f012c45c5afa46eb963e9bdd840 [file] [log] [blame]
/*
* 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