2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://floralicense.org/license/
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FUiCtrl_LinkedList.h
20 * @brief This is the header file for the _LinkedList template.
22 * This file contains the declarations and implementation of
23 * _LinkedList template.
26 #ifndef _FUI_CTRL_INTERNAL_LINKEDLIST_H
27 #define _FUI_CTRL_INTERNAL_LINKEDLIST_H
58 friend class _LinkedList;
62 _Iterator(_ListNode& _lnr)
64 _Iterator(_ListNode* _p = null)
67 _Iterator& operator ++(void)
69 __pPos = __pPos->pNext;
73 _Iterator operator ++(int)
75 _Iterator _retval = *this;
80 _Iterator& operator +(int cnt)
84 __pPos = __pPos->pNext;
89 _Iterator& operator --(void)
91 __pPos = __pPos->pPrev;
95 _Iterator operator --(int)
97 _Iterator _retval = *this;
102 _Iterator& operator -(int cnt)
106 __pPos = __pPos->pPrev;
111 T* operator ->() const { return &__pPos->val;}
112 T& operator *() const { return __pPos->val;}
113 bool operator ==(const _Iterator& _rhs) const { return __pPos == _rhs.__pPos;}
114 bool operator !=(const _Iterator& _rhs) const { return __pPos != _rhs.__pPos;}
117 class _ReverseIterator
120 friend class _LinkedList;
124 _ReverseIterator(_ListNode& _lnr)
126 _ReverseIterator(_ListNode* _p = null)
129 _ReverseIterator& operator ++(void)
131 __pPos = __pPos->pPrev;
135 _ReverseIterator operator ++(int)
137 _ReverseIterator _retval = *this;
142 _ReverseIterator& operator --(void)
144 __pPos = __pPos->pNext;
148 _ReverseIterator operator --(int)
150 _Iterator _retval = *this;
155 T* operator ->() const { return &__pPos->val;}
156 T& operator *() const { return __pPos->val;}
157 bool operator ==(const _ReverseIterator& _rhs) const { return __pPos == _rhs.__pPos;}
158 bool operator !=(const _ReverseIterator& _rhs) const { return __pPos != _rhs.__pPos;}
159 }; // _ReverseIterator
164 _LinkedList& operator =(_LinkedList& rhs)
175 __pHead = rhs.__pHead;
176 __pTail = rhs.__pTail;
177 __length = rhs.__length;
180 rhs.__pHead = new (std::nothrow) _ListNode();
181 rhs.__pTail = new (std::nothrow) _ListNode();
183 rhs.__pHead->pNext = rhs.__pTail;
184 rhs.__pTail->pPrev = rhs.__pHead;
190 void insert(_Iterator&, const T &);
191 void erase(_Iterator&);
192 void remove(const T&);
193 void push_front(const T&);
194 void push_back(const T&);
195 void pop_front(void);
198 bool empty(void) const;
199 int size(void) const { return __length;}
200 void sort(bool (*)(T, T));
201 void advance(_Iterator& _where, int _index);
202 T& front(void) const { return __pHead->pNext->val;}
203 T& back(void) const { return __pTail->pPrev->val;}
206 _Iterator begin(void) const { return _Iterator(__pHead->pNext);}
207 _Iterator end(void) const { return _Iterator(__pTail);}
208 _ReverseIterator rbegin(void) const { return _ReverseIterator(__pTail->pPrev);}
209 _ReverseIterator rend(void) const { return _ReverseIterator(__pHead);}
212 void insert_node(_Iterator, _ListNode *, _ListNode *, const T &);
213 void delete_node(_Iterator, _ListNode *, _ListNode*);
214 void swap_node(_ListNode*, _ListNode*);
215 void sort_node(bool (*)(T, T), _ListNode *, _ListNode*);
216 int count_node(_ListNode*, _ListNode*);
219 _LinkedList(const _LinkedList& rhs);
223 _LinkedList <T>::_LinkedList(void)
228 __pHead = new (std::nothrow) _ListNode();
229 __pTail = new (std::nothrow) _ListNode();
231 __pHead->pNext = __pTail;
232 __pTail->pPrev = __pHead;
236 _LinkedList <T>::~_LinkedList(void)
248 _LinkedList <T>::insert(_Iterator& _where, const T& _val)
250 insert_node(_where, null, null, _val);
255 _LinkedList <T>::erase(_Iterator& _where)
257 delete_node(_where, null, null);
262 _LinkedList <T>::remove(const T& _val)
269 _ListNode* _pTempNode = __pHead->pNext;
271 //while(_val != _pTempNode->val)
272 while (memcmp(&(_val), &(_pTempNode->val), sizeof(T)))
274 if (_pTempNode == __pTail)
280 _pTempNode = _pTempNode->pNext;
283 if ((_pTempNode == __pHead->pNext) && (_pTempNode == __pTail->pPrev))
285 delete __pHead->pNext;
286 __pHead->pNext = __pTail;
287 __pTail->pPrev = __pHead;
289 else if (_pTempNode != null)
291 _pTempNode->pPrev->pNext = _pTempNode->pNext;
292 _pTempNode->pNext->pPrev = _pTempNode->pPrev;
306 _LinkedList <T>::push_front(const T& _val)
308 insert_node(null, __pHead->pNext, null, _val);
313 _LinkedList <T>::push_back(const T& _val)
315 insert_node(null, null, __pTail->pPrev, _val);
320 _LinkedList <T>::pop_front(void)
322 delete_node(null, __pHead->pNext, null);
327 _LinkedList <T>::pop_back(void)
329 delete_node(null, null, __pTail->pPrev);
334 _LinkedList <T>::clear(void)
336 _ListNode* _pTempNode;
338 while (__pHead->pNext != __pTail)
340 _pTempNode = __pHead->pNext;
341 __pHead->pNext = __pHead->pNext->pNext;
346 __pTail->pPrev = __pHead;
352 _LinkedList <T>::empty(void) const
364 _LinkedList <T>::sort(bool (* _compare)(T _a, T _b))
371 sort_node(_compare, __pHead->pNext, __pTail->pPrev);
376 _LinkedList <T>::advance(_Iterator& _where, int _index)
386 _LinkedList <T>::insert_node(_Iterator _where, _ListNode* _first, _ListNode* _last, const T& _val)
388 _ListNode* _pNewNode = new (std::nothrow) _ListNode;
389 _pNewNode->val = _val;
393 if (!_first && !_last)
395 __pHead->pNext = _pNewNode;
396 __pTail->pPrev = _pNewNode;
400 _pNewNode->pPrev = __pHead;
401 _pNewNode->pNext = __pHead->pNext;
402 __pHead->pNext->pPrev = _pNewNode;
403 __pHead->pNext = _pNewNode;
407 _pNewNode->pPrev = __pTail->pPrev;
408 _pNewNode->pNext = __pTail;
409 __pTail->pPrev->pNext = _pNewNode;
410 __pTail->pPrev = _pNewNode;
415 if (_where.__pPos == __pHead->pNext)
417 _pNewNode->pPrev = __pHead;
418 _pNewNode->pNext = __pHead->pNext;
419 __pHead->pNext->pPrev = _pNewNode;
420 __pHead->pNext = _pNewNode;
422 else if (_where.__pPos == __pTail)
424 _pNewNode->pPrev = __pTail->pPrev;
425 _pNewNode->pNext = __pTail;
426 __pTail->pPrev->pNext = _pNewNode;
427 __pTail->pPrev = _pNewNode;
431 _pNewNode->pPrev = _where.__pPos->pPrev;
432 _where.__pPos->pPrev->pNext = _pNewNode;
433 _pNewNode->pNext = _where.__pPos;
434 _where.__pPos->pPrev = _pNewNode;
445 _LinkedList <T>::delete_node(_Iterator _where, _ListNode* _first, _ListNode* _last)
454 if ((_first == __pHead->pNext) && (_first == __pTail->pPrev)) // only one node
456 delete __pHead->pNext;
457 __pHead->pNext = __pTail;
458 __pTail->pPrev = __pHead;
460 else if (_first) // pop_front
462 __pHead->pNext = __pHead->pNext->pNext;
463 delete __pHead->pNext->pPrev;
464 __pHead->pNext->pPrev = __pHead;
466 else if (_last) // pop_back
468 __pTail->pPrev = __pTail->pPrev->pPrev;
469 delete __pTail->pPrev->pNext;
470 __pTail->pPrev->pNext = __pTail;
479 if ((_where.__pPos == __pHead->pNext) && (_where.__pPos == __pTail->pPrev))
481 delete __pHead->pNext;
482 __pHead->pNext = __pTail;
483 __pTail->pPrev = __pHead;
487 if (_where.__pPos == __pHead->pNext)
489 __pHead->pNext = __pHead->pNext->pNext;
490 delete __pHead->pNext->pPrev;
491 __pHead->pNext->pPrev = __pHead;
493 else if (_where.__pPos == __pTail->pPrev)
495 __pTail->pPrev = __pTail->pPrev->pPrev;
496 delete __pTail->pPrev->pNext;
497 __pTail->pPrev->pNext = __pTail;
501 _where.__pPos->pPrev->pNext = _where.__pPos->pNext;
502 _where.__pPos->pNext->pPrev = _where.__pPos->pPrev;
503 delete _where.__pPos;
504 _where.__pPos = null;
514 _LinkedList <T>::swap_node(_ListNode* _a, _ListNode* _b)
525 _LinkedList <T>::sort_node(bool (* _compare)(T _a, T _b), _ListNode* _low, _ListNode* _hight)
527 // FIXME : This function implement using quick sort algorithm.
528 // You should remember that _Iterator is invalid after sorting.
529 _ListNode* _left, * _right, * _pivot;
531 int _total = count_node(_low, _hight);
533 int _rightCount = _total - 1;
538 _right = _hight->pPrev;
543 while (_compare(_left->val, _pivot->val))
545 _left = _left->pNext;
549 while (!_compare(_right->val, _pivot->val))
551 if ((_rightCount <= 1) || (_right->pPrev == null))
556 _right = _right->pPrev;
560 if ((_leftCount >= _rightCount) || (_right->pPrev == null))
565 swap_node(_left, _right);
567 _left = _left->pNext;
570 _right = _right->pPrev;
574 swap_node(_pivot, _left);
576 if ((_left->pPrev != null) && (_leftCount - 1 > 0))
577 if ((_left->pNext != _low) && (_low->pPrev != _left))
578 sort_node(_compare, _low, _left->pPrev);
580 if ((_left->pNext != null) && (_leftCount < _total))
581 if ((_left->pPrev != _hight) && (_hight->pNext != _left))
582 sort_node(_compare, _left->pNext, _hight);
588 _LinkedList <T>::count_node(_ListNode* _left, _ListNode* _right)
591 _ListNode* _pTempNode = _left;
593 while (_pTempNode != _right)
595 _pTempNode = _pTempNode->pNext;
604 _LinkedList <T>::at(int _index) const
606 if ((__length <= 0) || (_index >= __length))
611 _ListNode* _pTempNode = __pHead->pNext;
613 for (int i = 0; i < _index; i++)
615 _pTempNode = _pTempNode->pNext;
618 return _pTempNode->val;
621 #endif // _FUI_CTRL_INTERNAL_LINKEDLIST_H