rsList.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #ifndef ANDROID_RENDERSCRIPT_LIST_H
  2. #define ANDROID_RENDERSCRIPT_LIST_H
  3. namespace android {
  4. namespace renderscript {
  5. namespace {
  6. constexpr size_t BUFFER_SIZE = 64;
  7. } // anonymous namespace
  8. template <class T>
  9. class List {
  10. private:
  11. class LinkedBuffer {
  12. public:
  13. LinkedBuffer() : next(nullptr) {}
  14. union {
  15. char raw[BUFFER_SIZE - sizeof(LinkedBuffer*)];
  16. T typed;
  17. } data;
  18. LinkedBuffer* next;
  19. };
  20. public:
  21. class iterator;
  22. List() : last(nullptr), first(&firstBuffer.data.typed),
  23. beginIterator(this, &firstBuffer, const_cast<T*>(first)),
  24. _size(0) {
  25. current = const_cast<T*>(first);
  26. currentBuffer = &firstBuffer;
  27. }
  28. template <class InputIterator>
  29. List(InputIterator first, InputIterator last) : List() {
  30. for (InputIterator it = first; it != last; ++it) {
  31. push_back(*it);
  32. }
  33. }
  34. ~List() {
  35. LinkedBuffer* p = firstBuffer.next;
  36. LinkedBuffer* next;
  37. while (p != nullptr) {
  38. next = p->next;
  39. delete p;
  40. p = next;
  41. }
  42. }
  43. void push_back(const T& value) {
  44. last = current;
  45. *current++ = value;
  46. _size++;
  47. if ((void*)current >= (void*)&currentBuffer->next) {
  48. LinkedBuffer* newBuffer = new LinkedBuffer();
  49. currentBuffer->next = newBuffer;
  50. currentBuffer = newBuffer;
  51. current = &currentBuffer->data.typed;
  52. }
  53. }
  54. class iterator {
  55. friend class List;
  56. public:
  57. iterator& operator++() {
  58. p++;
  59. if ((void*)p >= (void*)&buffer->next) {
  60. buffer = buffer->next;
  61. if (buffer != nullptr) {
  62. p = &buffer->data.typed;
  63. } else {
  64. p = nullptr;
  65. }
  66. }
  67. return *this;
  68. }
  69. bool operator==(const iterator& other) const {
  70. return p == other.p && buffer == other.buffer && list == other.list;
  71. }
  72. bool operator!=(const iterator& other) const {
  73. return p != other.p || buffer != other.buffer || list != other.list;
  74. }
  75. const T& operator*() const { return *p; }
  76. T* operator->() { return p; }
  77. protected:
  78. explicit iterator(const List* list_) : list(list_) {}
  79. iterator(const List* list_, LinkedBuffer* buffer_, T* p_) :
  80. p(p_), buffer(buffer_), list(list_) {}
  81. private:
  82. T* p;
  83. LinkedBuffer* buffer;
  84. const List* list;
  85. };
  86. const iterator& begin() const { return beginIterator; }
  87. iterator end() const { return iterator(this, currentBuffer, current); }
  88. bool empty() const { return current == first; }
  89. T& front() const { return *const_cast<T*>(first); }
  90. T& back() const { return *last; }
  91. size_t size() const { return _size; }
  92. private:
  93. T* current;
  94. T* last;
  95. LinkedBuffer* currentBuffer;
  96. LinkedBuffer firstBuffer;
  97. const T* first;
  98. const iterator beginIterator;
  99. size_t _size;
  100. };
  101. } // namespace renderscript
  102. } // namespace android
  103. #endif // ANDROID_RENDERSCRIPT_LIST_H