You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
3.1 KiB
131 lines
3.1 KiB
#ifndef ANDROID_RENDERSCRIPT_LIST_H
|
|
#define ANDROID_RENDERSCRIPT_LIST_H
|
|
|
|
namespace android {
|
|
namespace renderscript {
|
|
|
|
namespace {
|
|
|
|
constexpr size_t BUFFER_SIZE = 64;
|
|
|
|
} // anonymous namespace
|
|
|
|
template <class T>
|
|
class List {
|
|
private:
|
|
class LinkedBuffer {
|
|
public:
|
|
LinkedBuffer() : next(nullptr) {}
|
|
|
|
union {
|
|
char raw[BUFFER_SIZE - sizeof(LinkedBuffer*)];
|
|
T typed;
|
|
} data;
|
|
LinkedBuffer* next;
|
|
};
|
|
|
|
public:
|
|
class iterator;
|
|
|
|
List() : last(nullptr), first(&firstBuffer.data.typed),
|
|
beginIterator(this, &firstBuffer, const_cast<T*>(first)),
|
|
_size(0) {
|
|
current = const_cast<T*>(first);
|
|
currentBuffer = &firstBuffer;
|
|
}
|
|
|
|
template <class InputIterator>
|
|
List(InputIterator first, InputIterator last) : List() {
|
|
for (InputIterator it = first; it != last; ++it) {
|
|
push_back(*it);
|
|
}
|
|
}
|
|
|
|
~List() {
|
|
LinkedBuffer* p = firstBuffer.next;
|
|
LinkedBuffer* next;
|
|
while (p != nullptr) {
|
|
next = p->next;
|
|
delete p;
|
|
p = next;
|
|
}
|
|
}
|
|
|
|
void push_back(const T& value) {
|
|
last = current;
|
|
*current++ = value;
|
|
_size++;
|
|
if ((void*)current >= (void*)¤tBuffer->next) {
|
|
LinkedBuffer* newBuffer = new LinkedBuffer();
|
|
currentBuffer->next = newBuffer;
|
|
currentBuffer = newBuffer;
|
|
current = ¤tBuffer->data.typed;
|
|
}
|
|
}
|
|
|
|
class iterator {
|
|
friend class List;
|
|
public:
|
|
iterator& operator++() {
|
|
p++;
|
|
if ((void*)p >= (void*)&buffer->next) {
|
|
buffer = buffer->next;
|
|
if (buffer != nullptr) {
|
|
p = &buffer->data.typed;
|
|
} else {
|
|
p = nullptr;
|
|
}
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
bool operator==(const iterator& other) const {
|
|
return p == other.p && buffer == other.buffer && list == other.list;
|
|
}
|
|
|
|
bool operator!=(const iterator& other) const {
|
|
return p != other.p || buffer != other.buffer || list != other.list;
|
|
}
|
|
|
|
const T& operator*() const { return *p; }
|
|
|
|
T* operator->() { return p; }
|
|
|
|
protected:
|
|
explicit iterator(const List* list_) : list(list_) {}
|
|
iterator(const List* list_, LinkedBuffer* buffer_, T* p_) :
|
|
p(p_), buffer(buffer_), list(list_) {}
|
|
|
|
private:
|
|
T* p;
|
|
LinkedBuffer* buffer;
|
|
const List* list;
|
|
};
|
|
|
|
const iterator& begin() const { return beginIterator; }
|
|
|
|
iterator end() const { return iterator(this, currentBuffer, current); }
|
|
|
|
bool empty() const { return current == first; }
|
|
|
|
T& front() const { return *const_cast<T*>(first); }
|
|
|
|
T& back() const { return *last; }
|
|
|
|
size_t size() const { return _size; }
|
|
|
|
private:
|
|
T* current;
|
|
T* last;
|
|
LinkedBuffer* currentBuffer;
|
|
LinkedBuffer firstBuffer;
|
|
const T* first;
|
|
const iterator beginIterator;
|
|
size_t _size;
|
|
};
|
|
|
|
} // namespace renderscript
|
|
} // namespace android
|
|
|
|
#endif // ANDROID_RENDERSCRIPT_LIST_H
|