节点内嵌prev/next指针的双向链表,减少link节点的内存分配。
BoDrvEmbeddedList.h
1 #ifndef BoDrvEmbeddedList_H 2 #define BoDrvEmbeddedList_H 3 4 #include <stdlib.h> 5 #include <assert.h> 6 7 #define NAMESPACE_BO_BEGIN namespace BO { 8 #define NAMESPACE_BO_END } 9 10 NAMESPACE_BO_BEGIN 11 12 ////////////////////////////////////////////////////////////////////////// 13 // CBoDrvEmbeddedList 14 15 class CBoDrvEmbeddedList 16 { 17 public: 18 class CNode 19 { 20 friend CBoDrvEmbeddedList; 21 template<class TYPE> 22 friend class CBoDrvTypedEmbeddedList; 23 24 CNode* pPrev; 25 CNode* pNext; 26 27 public: 28 CNode() 29 : pPrev(NULL) 30 , pNext(NULL) 31 {} 32 }; 33 34 protected: 35 CNode* CBoDrvEmbeddedList::node_ptr(void* p) const; 36 void* CBoDrvEmbeddedList::void_ptr(CNode* pNode) const; 37 38 public: 39 CBoDrvEmbeddedList(size_t offset = 0); 40 ~CBoDrvEmbeddedList(void); 41 42 bool empty() const; 43 size_t size() const; 44 45 void push_front(void* p); 46 void push_back(void* p); 47 48 void* front() const; 49 void* back() const; 50 51 void pop_front(); 52 void pop_back(); 53 54 void clear(); 55 void clear(size_t offset); 56 57 public: 58 class iterator 59 { 60 friend class CBoDrvEmbeddedList; 61 template<class TYPE> 62 friend class CBoDrvTypedEmbeddedList; 63 64 CNode* m_pNode; 65 CBoDrvEmbeddedList* m_pList; 66 67 iterator(CNode* pNode, CBoDrvEmbeddedList* pList); 68 69 public: 70 iterator(const iterator& other); 71 72 iterator& operator=(const iterator& other); 73 74 bool operator!=(const iterator& other) const; 75 bool operator==(const iterator& other) const; 76 77 iterator& operator++(); 78 iterator operator++(int); 79 80 void* operator*() const; 81 }; 82 83 iterator begin(); 84 iterator end(); 85 iterator erase(iterator i); 86 iterator erase(iterator a, iterator b); 87 88 private: 89 CNode m_head; 90 size_t m_size; 91 size_t m_offset; 92 }; 93 94 ////////////////////////////////////////////////////////////////////////// 95 // CBoDrvEmbeddedList inline functions 96 97 inline CBoDrvEmbeddedList::CNode* CBoDrvEmbeddedList::node_ptr(void* p) const 98 { return (CNode*)((char*)p + m_offset); } 99 100 inline void* CBoDrvEmbeddedList::void_ptr(CBoDrvEmbeddedList::CNode* pNode) const 101 { return (char*)pNode - m_offset; } 102 103 inline bool CBoDrvEmbeddedList::empty() const 104 { return m_head.pNext == &m_head; } 105 106 inline size_t CBoDrvEmbeddedList::size() const 107 { return m_size; } 108 109 inline void* CBoDrvEmbeddedList::front() const 110 { 111 assert(!empty()); 112 return void_ptr(m_head.pNext); 113 } 114 115 inline void* CBoDrvEmbeddedList::back() const 116 { 117 assert(!empty()); 118 return void_ptr(m_head.pPrev); 119 } 120 121 inline void CBoDrvEmbeddedList::clear() 122 { 123 #ifndef NDEBUG 124 (void)erase(begin(), end()); 125 #endif 126 m_head.pPrev = &m_head; 127 m_head.pNext = &m_head; 128 m_size = 0; 129 } 130 131 inline void CBoDrvEmbeddedList::clear(size_t offset) 132 { 133 clear(); 134 m_offset = offset; 135 } 136 137 inline CBoDrvEmbeddedList::iterator CBoDrvEmbeddedList::begin() 138 { return iterator(m_head.pNext, this); } 139 140 inline CBoDrvEmbeddedList::iterator CBoDrvEmbeddedList::end() 141 { return iterator(&m_head, this); } 142 143 ////////////////////////////////////////////////////////////////////////// 144 // CBoDrvEmbeddedList::CIterator<TYPE> inline functions 145 146 inline CBoDrvEmbeddedList::iterator::iterator(CNode* pNode, CBoDrvEmbeddedList* pList) 147 : m_pNode(pNode) 148 , m_pList(pList) 149 {} 150 151 inline CBoDrvEmbeddedList::iterator::iterator(const iterator& other) 152 : m_pNode(other.m_pNode) 153 , m_pList(other.m_pList) 154 {} 155 156 inline CBoDrvEmbeddedList::iterator& CBoDrvEmbeddedList::iterator::operator=(const iterator& other) 157 { 158 m_pNode = other.m_pNode; 159 m_pList = other.m_pList; 160 return *this; 161 } 162 163 inline bool CBoDrvEmbeddedList::iterator::operator!=(const iterator& other) const 164 { 165 assert(m_pList == other.m_pList); 166 return m_pNode != other.m_pNode; 167 } 168 169 inline bool CBoDrvEmbeddedList::iterator::operator==(const iterator& other) const 170 { return !(*this != other); } 171 172 inline CBoDrvEmbeddedList::iterator& CBoDrvEmbeddedList::iterator::operator++() 173 { 174 assert(*this != m_pList->end()); 175 m_pNode = m_pNode->pNext; 176 return *this; 177 } 178 179 inline CBoDrvEmbeddedList::iterator CBoDrvEmbeddedList::iterator::operator++(int) 180 { 181 iterator i(m_pNode, m_pList); 182 assert(*this != m_pList->end()); 183 ++*this; 184 return i; 185 } 186 187 inline void* CBoDrvEmbeddedList::iterator::operator*() const 188 { 189 assert(*this != m_pList->end()); 190 return m_pList->void_ptr(m_pNode); 191 } 192 193 ////////////////////////////////////////////////////////////////////////// 194 // CBoDrvTypedEmbeddedList<TYPE> 195 196 template<class TYPE> 197 class CBoDrvTypedEmbeddedList : public CBoDrvEmbeddedList 198 { 199 typedef CBoDrvEmbeddedList MyBase; 200 201 public: 202 CBoDrvTypedEmbeddedList(size_t offset = 0); 203 ~CBoDrvTypedEmbeddedList(); 204 205 void push_front(TYPE* p); 206 void push_back(TYPE* p); 207 208 void* front() const; 209 void* back() const; 210 211 public: 212 class iterator : public CBoDrvEmbeddedList::iterator 213 { 214 typedef CBoDrvEmbeddedList::iterator MyBase; 215 216 public: 217 iterator(const MyBase& other); 218 219 iterator& operator=(const MyBase& other); 220 221 TYPE* operator*() const; 222 TYPE* operator->() const; 223 }; 224 }; 225 226 ////////////////////////////////////////////////////////////////////////// 227 // CBoDrvTypedEmbeddedList<TYPE> inline functions 228 229 template<class TYPE> 230 inline CBoDrvTypedEmbeddedList<TYPE>::CBoDrvTypedEmbeddedList(size_t offset /* = 0 */) 231 : MyBase(offset) {} 232 233 template<class TYPE> 234 inline CBoDrvTypedEmbeddedList<TYPE>::~CBoDrvTypedEmbeddedList() 235 {} 236 237 template<class TYPE> 238 inline void CBoDrvTypedEmbeddedList<TYPE>::push_front(TYPE* p) 239 { MyBase::push_front(p); } 240 241 template<class TYPE> 242 inline void CBoDrvTypedEmbeddedList<TYPE>::push_back(TYPE* p) 243 { MyBase::push_back(p); } 244 245 template<class TYPE> 246 inline void* CBoDrvTypedEmbeddedList<TYPE>::front() const 247 { return (TYPE*)MyBase::front(); } 248 249 template<class TYPE> 250 inline void* CBoDrvTypedEmbeddedList<TYPE>::back() const 251 { return (TYPE*)MyBase::back(); } 252 253 ////////////////////////////////////////////////////////////////////////// 254 // CBoDrvTypedEmbeddedList<TYPE>::iterator inline functions 255 256 template<class TYPE> 257 inline CBoDrvTypedEmbeddedList<TYPE>::iterator::iterator(const MyBase& other) 258 : MyBase(other) {} 259 260 template<class TYPE> 261 inline typename CBoDrvTypedEmbeddedList<TYPE>::iterator& CBoDrvTypedEmbeddedList<TYPE>::iterator::operator=(const MyBase& other) 262 { 263 (MyBase&)*this = other; 264 return *this; 265 } 266 267 template<class TYPE> 268 inline TYPE* CBoDrvTypedEmbeddedList<TYPE>::iterator::operator*() const 269 { return (TYPE*)**(const MyBase*)this; } 270 271 template<class TYPE> 272 inline TYPE* CBoDrvTypedEmbeddedList<TYPE>::iterator::operator->() const 273 { return (TYPE*)**this; } 274 275 NAMESPACE_BO_END 276 277 #endif // !BoDrvEmbeddedList_H
BoDrvEmbeddedList.cpp
1 #include "BoDrvEmbeddedList.h" 2 3 NAMESPACE_BO_BEGIN 4 5 ////////////////////////////////////////////////////////////////////////// 6 // CBoDrvEmbeddedList out-of-line functions 7 8 CBoDrvEmbeddedList::CBoDrvEmbeddedList(size_t offset /* = 0 */) 9 : m_size(0) 10 , m_offset(offset) 11 { 12 m_head.pPrev = &m_head; 13 m_head.pNext = &m_head; 14 } 15 16 17 CBoDrvEmbeddedList::~CBoDrvEmbeddedList(void) 18 { 19 #ifndef NDEBUG 20 (void)erase(begin(), end()); 21 #endif 22 } 23 24 25 void CBoDrvEmbeddedList::push_front(void* p) 26 { 27 CNode* pNode = node_ptr(p); 28 assert(NULL == pNode->pPrev && NULL == pNode->pNext); 29 30 pNode->pNext = m_head.pNext; 31 pNode->pPrev = &m_head; 32 m_head.pNext->pPrev = pNode; 33 m_head.pNext = pNode; 34 35 ++m_size; 36 } 37 38 39 void CBoDrvEmbeddedList::push_back(void* p) 40 { 41 CNode* pNode = node_ptr(p); 42 assert(NULL == pNode->pPrev && NULL == pNode->pNext); 43 44 pNode->pPrev = m_head.pPrev; 45 pNode->pNext = &m_head; 46 m_head.pPrev->pNext = pNode; 47 m_head.pPrev = pNode; 48 49 ++m_size; 50 } 51 52 53 void CBoDrvEmbeddedList::pop_front() 54 { 55 assert(!empty()); 56 57 CNode* pNode = m_head.pNext; 58 m_head.pNext = pNode->pNext; 59 pNode->pNext->pPrev = &m_head; 60 #ifndef NDEBUG 61 pNode->pPrev = NULL; 62 pNode->pNext = NULL; 63 #endif 64 --m_size; 65 } 66 67 68 void CBoDrvEmbeddedList::pop_back() 69 { 70 assert(!empty()); 71 72 CNode* pNode = m_head.pPrev; 73 74 m_head.pPrev = pNode->pPrev; 75 pNode->pPrev->pNext = &m_head; 76 #ifndef NDEBUG 77 pNode->pNext = NULL; 78 pNode->pPrev = NULL; 79 #endif 80 --m_size; 81 } 82 83 84 CBoDrvEmbeddedList::iterator CBoDrvEmbeddedList::erase(iterator i) 85 { 86 assert(i != end()); 87 88 CNode* pNode = i.m_pNode; 89 i.m_pNode = pNode->pNext; 90 91 pNode->pPrev->pNext = pNode->pNext; 92 pNode->pNext->pPrev = pNode->pPrev; 93 #ifndef NDEBUG 94 pNode->pPrev = NULL; 95 pNode->pNext = NULL; 96 #endif 97 --m_size; 98 return i; 99 } 100 101 102 CBoDrvEmbeddedList::iterator CBoDrvEmbeddedList::erase(iterator a, iterator b) 103 { 104 CNode* pBegin = a.m_pNode; 105 CNode* pEnd = b.m_pNode; 106 107 pBegin->pPrev->pNext = pEnd; 108 pEnd->pPrev = pBegin->pPrev; 109 110 for (; pBegin != pEnd; ) 111 { 112 CNode* pNode = pBegin; 113 pBegin = pBegin->pNext; 114 #ifndef NDEBUG 115 pNode->pPrev = NULL; 116 pNode->pNext = NULL; 117 #endif 118 --m_size; 119 } 120 121 return b; 122 } 123 124 NAMESPACE_BO_END