1 //---------------------------------------------------------------------------- 2 // EDGE Array Class 3 //---------------------------------------------------------------------------- 4 // 5 // Copyright (c) 2002-2008 The EDGE Team. 6 // 7 // This program is free software; you can redistribute it and/or 8 // modify it under the terms of the GNU General Public License 9 // as published by the Free Software Foundation; either version 2 10 // of the License, or (at your option) any later version. 11 // 12 // This program is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 // 17 //---------------------------------------------------------------------------- 18 #ifndef __EPI_ARRAY_CLASS__ 19 #define __EPI_ARRAY_CLASS__ 20 21 #ifndef NULL 22 #define NULL ((void*)0) 23 #endif 24 25 namespace epi 26 { 27 // Forward declarations 28 class array_c; 29 class array_iterator_c; 30 31 // Typedefs 32 typedef int array_block_t; 33 34 // Classes 35 36 // The array 37 class array_c 38 { 39 friend class array_iterator_c; 40 41 public: 42 array_c(const int objsize); 43 virtual ~array_c(); 44 45 protected: 46 unsigned int array_block_objsize; 47 unsigned int array_objsize; 48 49 array_block_t *array; 50 array_block_t *array_end; 51 int array_entries; 52 int array_max_entries; 53 54 void* ExpandAtTail(void); 55 FetchObjectDirect(int pos)56 void* FetchObjectDirect(int pos) const 57 { return (void*)&array[pos*array_block_objsize]; } 58 59 void ShrinkAtTail(void); 60 61 // Count management DecrementCount()62 void DecrementCount() 63 { 64 array_entries--; 65 array_end -= array_block_objsize; 66 } 67 IncrementCount()68 void IncrementCount() 69 { 70 array_entries++; 71 array_end += array_block_objsize; 72 } 73 SetCount(int count)74 void SetCount(int count) 75 { 76 array_entries = count; 77 array_end = array + (array_block_objsize*array_entries); 78 } 79 80 public: 81 // Object Management 82 virtual void CleanupObject(void *obj) = 0; 83 void* FetchObject(int pos) const; 84 int InsertObject(void *obj, int pos = -1); 85 void RemoveObject(int pos); 86 87 // Iterator handling 88 array_iterator_c GetBaseIterator(); 89 array_iterator_c GetIterator(int pos); 90 array_iterator_c GetTailIterator(); 91 92 // List Management 93 void Clear(void); 94 bool Size(int entries); 95 bool Trim(void); ZeroiseCount(void)96 void ZeroiseCount(void) { array_end = array; array_entries = 0; } 97 }; 98 99 100 // The array iterator 101 class array_iterator_c 102 { 103 public: array_iterator_c()104 array_iterator_c() 105 { 106 parent = (epi::array_c*)NULL; 107 idx = 0; 108 } 109 array_iterator_c(array_c * ptr,int initpos)110 array_iterator_c(array_c *ptr, int initpos) 111 { 112 parent = ptr; 113 idx = initpos*parent->array_block_objsize; 114 } 115 ~array_iterator_c()116 ~array_iterator_c() 117 { 118 } 119 120 private: 121 array_c* parent; 122 int idx; 123 124 public: GetPos()125 int GetPos() { return idx ? idx/parent->array_block_objsize : 0; } 126 IsValid()127 bool IsValid() 128 { 129 return ((parent->array + idx) >= parent->array_end)?false:true; 130 } 131 SetPos(int pos)132 void SetPos(int pos) { idx = pos * parent->array_block_objsize; } 133 134 operator void* () const 135 { 136 return (void*)((array_block_t*)(parent->array + idx)); 137 } 138 139 void operator++(int) 140 { 141 idx += parent->array_block_objsize; 142 } 143 144 void operator--(int) 145 { 146 if (idx) 147 idx -= parent->array_block_objsize; 148 else 149 idx = parent->array_entries*parent->array_block_objsize; // Max out to make invalid 150 } 151 }; 152 }; 153 154 // Helper defines 155 #define BEGIN_IMPLEMENT_ARRAY(_type, _name) \ 156 class _name : public epi::array_c \ 157 {\ 158 public:\ 159 _name() : epi::array_c(sizeof(_type)) {}\ 160 ~_name() { Clear(); } \ 161 \ 162 int GetSize() const { return array_entries; } \ 163 _type* operator[](int idx) { return (_type*)FetchObject(idx); } 164 165 #define END_IMPLEMENT_ARRAY \ 166 } 167 168 #define IMPLEMENT_PRIMITIVE_ARRAY(_type, _name) \ 169 BEGIN_IMPLEMENT_ARRAY(_type, _name) \ 170 private: void CleanupObject(void *obj) { /* Do Nothing */ } \ 171 public: int Insert(_type p) { return InsertObject((void*)&p); } \ 172 END_IMPLEMENT_ARRAY 173 174 #define ITERATOR_TO_PTR(_it, _type) \ 175 ((_type*)((void*)(_it))) 176 177 #define ITERATOR_TO_TYPE(_it, _type) \ 178 (*(_type*)((void*)(_it))) 179 180 #endif /* __EPI_ARRAY_CLASS__ */ 181 182 //--- editor settings --- 183 // vi:ts=4:sw=4:noexpandtab 184