class CBoDrvEmbeddedList

节点内嵌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

 

posted @ 2017-09-17 23:00  bestluning  阅读(142)  评论(0编辑  收藏  举报