| #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 |