00001 #ifndef _CMT_MONOLITHIC
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #endif
00031 #ifndef _XSENS_LIST_H_2006_06_08
00032 #define _XSENS_LIST_H_2006_06_08
00033
00034 #ifndef _CMT_MONOLITHIC
00035 #ifndef _PSTDINT_H_INCLUDED
00036 # include "pstdint.h"
00037 #endif
00038 #endif
00039
00040 #ifndef _JANITORS_H_2006_05_01
00041 # include "xsens_janitors.h"
00042 #endif
00043
00044
00045 #define XSENS_LIST_NOTFOUND 0xFFFFFFFF
00046
00047 #ifdef _XSENS_LIST_RANGE_CHECKS
00048 # ifdef _MSC_VER
00049 # define XSENS_LIST_THROW throw(...)
00050 # else
00051 # define XSENS_LIST_THROW
00052 # endif
00053 #else
00054 # define XSENS_LIST_THROW
00055 #endif
00056
00057 #include <stdlib.h>
00058 #include <malloc.h>
00059
00060 namespace xsens {
00061
00062 #define CMT_LIST_LINEAR_SEARCH_TRESHOLD 10
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 template <typename T>
00074 class List
00075 {
00076 private:
00077 void operator = (const List& list);
00078
00079 void qSort(uint32_t left, uint32_t right);
00080
00081 void qSortDeref(uint32_t left, uint32_t right);
00082
00083 protected:
00084 T* m_data;
00085 uint32_t m_max;
00086 uint32_t m_count;
00087 JanitorClassFunc<List<T> >* m_jcf;
00088 bool m_manage;
00089
00090
00091 List(const uint32_t size, T* src, bool manage);
00092 public:
00093
00094
00095 typedef int32_t (*cmpFunc) (const T&,const T&);
00096
00097
00098 List();
00099
00100 List(const uint32_t size);
00101
00102 List(const List<T>& src);
00103
00104 List(const uint32_t size, const T* src);
00105
00106 ~List();
00107
00108
00109 void deleteAndClear(void);
00110
00111 void freeAndClear(void);
00112
00113 void clear(void);
00114
00115 void resize(uint32_t newSize);
00116
00117 void append(const T& item);
00118
00119 void appendList(uint32_t count, const T* lst);
00120
00121 void appendDeepCopy(const List<T>& source);
00122
00123 void appendShallowCopy(const List<T>& source);
00124
00125 template <typename TB>
00126 void appendCopy(const TB& item);
00127
00128 template <typename TR>
00129 void appendRelated(const TR& item);
00130
00131 void remove(const uint32_t index) XSENS_LIST_THROW;
00132
00133 void swap(const uint32_t i, const uint32_t j) XSENS_LIST_THROW;
00134
00135 void deleteAndRemove(const uint32_t index) XSENS_LIST_THROW;
00136
00137 void freeAndRemove(const uint32_t index) XSENS_LIST_THROW;
00138
00139 T& last(void) const XSENS_LIST_THROW;
00140
00141 T& get(const uint32_t index) const XSENS_LIST_THROW;
00142
00143 T& operator [] (const uint32_t index) const XSENS_LIST_THROW;
00144
00145 void insert(const T& item, const uint32_t index);
00146
00147 template <typename TB>
00148 void insertCopy(const TB& item, const uint32_t index);
00149
00150 uint32_t insertSorted(const T& item);
00151
00152 uint32_t insertSortedDeref(const T& item);
00153
00154 template <typename TB>
00155 uint32_t insertSortedCopy(const TB& item);
00156
00157 uint32_t length(void) const { return m_count; }
00158
00159 void sortAscending(void);
00160
00161 void sortAscendingDeref(void);
00162
00163 template <typename T2>
00164 void twinSortAscending(List<T2>& twin);
00165
00166 template <typename TB>
00167 uint32_t find(const TB& item) const;
00168
00169 template <typename TB>
00170 uint32_t findDeref(const TB& item) const;
00171
00172 template <typename TB>
00173 uint32_t findSorted(const TB& item) const;
00174
00175 template <typename TB>
00176 uint32_t findSortedDeref(const TB& item) const;
00177
00178 void reverse(void);
00179
00180 void removeTail(const uint32_t count) XSENS_LIST_THROW;
00181 void deleteAndRemoveTail(const uint32_t count) XSENS_LIST_THROW;
00182 void freeAndRemoveTail(const uint32_t count) XSENS_LIST_THROW;
00183
00184
00185 typedef int32_t (__cdecl * InequalityFunction)(const T&, const T&);
00186
00187 uint32_t find(const T item, InequalityFunction fnc) const;
00188
00189 void deleteItemsOnDestroy(void);
00190 void freeItemsOnDestroy(void);
00191
00192
00193 uint32_t removeDuplicateEntries(void);
00194
00195 uint32_t removeDuplicateEntriesDeref(void);
00196
00197
00198 template <typename TB>
00199 void isDeepCopyOf(const List<T>& source);
00200
00201 void isShallowCopyOf(const List<T>& source);
00202
00203
00204 const T* getBuffer(void) const { return m_data; }
00205 };
00206
00207
00208 template <typename T>
00209 List<T>::List()
00210 {
00211 m_max = 16;
00212 m_count = 0;
00213 m_data = (T*) malloc(m_max * sizeof(T));
00214 m_jcf = NULL;
00215 m_manage = true;
00216 }
00217
00218 template <typename T>
00219 List<T>::List(uint32_t size)
00220 {
00221 m_max = size;
00222 if (m_max == 0)
00223 m_max = 1;
00224 m_count = 0;
00225 m_data = (T*) malloc(m_max * sizeof(T));
00226 m_jcf = NULL;
00227 m_manage = true;
00228 }
00229
00230 template <typename T>
00231 List<T>::List(const List<T>& src)
00232 {
00233 m_max = src.m_max;
00234 if (m_max == 0)
00235 m_max = 1;
00236 m_count = src.m_count;
00237 m_data = (T*) malloc(m_max * sizeof(T));
00238 m_jcf = NULL;
00239 if (m_count > 0)
00240 memcpy(m_data,src.m_data,m_count*sizeof(T));
00241 m_manage = true;
00242 }
00243
00244 template <typename T>
00245 List<T>::List(const uint32_t size, const T* src)
00246 {
00247 m_max = size;
00248 if (m_max == 0)
00249 m_max = 1;
00250 m_count = size;
00251 m_data = (T*) malloc(m_max * sizeof(T));
00252 m_jcf = NULL;
00253 if (m_count > 0)
00254 memcpy(m_data,src,m_count * sizeof(T));
00255 m_manage = true;
00256 }
00257
00258 template <typename T>
00259 List<T>::List(const uint32_t size, T* src, bool manage)
00260 {
00261 m_max = size;
00262 m_count = size;
00263 m_data = src;
00264 m_jcf = NULL;
00265 m_manage = manage;
00266 }
00267
00268 template <typename T>
00269 List<T>::~List()
00270 {
00271 if (m_jcf != NULL)
00272 delete m_jcf;
00273 if (m_manage && m_data != NULL)
00274 free(m_data);
00275 m_jcf = NULL;
00276 m_data = NULL;
00277 }
00278
00279 template <typename T>
00280 void List<T>::deleteAndClear(void)
00281 {
00282 for (unsigned i=0;i<m_count;++i)
00283 delete m_data[i];
00284 m_count = 0;
00285 }
00286
00287 template <typename T>
00288 void List<T>::freeAndClear(void)
00289 {
00290 for (unsigned i=0;i<m_count;++i)
00291 free(m_data[i]);
00292 m_count = 0;
00293 }
00294
00295 template <typename T>
00296 void List<T>::clear(void)
00297 {
00298 m_count = 0;
00299 }
00300
00301 template <typename T>
00302 void List<T>::resize(uint32_t newSize)
00303 {
00304 if (m_manage)
00305 {
00306 if (newSize == m_max)
00307 return;
00308 if (m_count > newSize)
00309 m_max = m_count;
00310 else
00311 m_max = newSize;
00312 if (m_max == 0)
00313 m_max = 1;
00314
00315 m_data = (T*) realloc(m_data,m_max * sizeof(T));
00316 }
00317 }
00318
00319 template <typename T>
00320 void List<T>::append(const T& item)
00321 {
00322 if (m_count == m_max)
00323 resize(m_max + 1 + m_max/2);
00324 m_data[m_count++] = item;
00325 }
00326
00327 template <typename T>
00328 void List<T>::appendList(uint32_t count, const T* lst)
00329 {
00330 if (m_count+count > m_max)
00331 resize(m_max + count + m_max/2);
00332 for (unsigned i = 0; i < count; ++i)
00333 m_data[m_count++] = lst[i];
00334 }
00335
00336 template <typename T>
00337 void List<T>::appendDeepCopy(const List<T>& source)
00338 {
00339 if (m_max < source.m_count + m_count)
00340 resize(source.m_count + m_count);
00341
00342 for (uint32_t i = 0;i<source.m_count;++i)
00343 m_data[m_count++] = new T(*source.m_data[i]);
00344 }
00345
00346 template <typename T>
00347 void List<T>::appendShallowCopy(const List<T>& source)
00348 {
00349 if (m_max < source.m_count + m_count)
00350 resize(source.m_count + m_count);
00351
00352 for (uint32_t i = 0;i<source.m_count;++i)
00353 m_data[m_count++] = source.m_data[i];
00354 }
00355
00356 template <typename T>
00357 template <typename TB>
00358 void List<T>::appendCopy(const TB& item)
00359 {
00360 if (m_count == m_max)
00361 resize(m_max + 1 + m_max/2);
00362 m_data[m_count++] = new TB(item);
00363 }
00364
00365 template <typename T>
00366 template <typename TR>
00367 void List<T>::appendRelated(const TR& item)
00368 {
00369 if (m_count == m_max)
00370 resize(m_max + 1 + m_max/2);
00371 m_data[m_count++] = item;
00372 }
00373
00374 template <typename T>
00375 T& List<T>::last(void) const XSENS_LIST_THROW
00376 {
00377 #ifdef _XSENS_LIST_RANGE_CHECKS
00378 if (m_count == 0)
00379 throw "List.last: empty list";
00380 #endif
00381 return m_data[m_count-1];
00382 }
00383
00384 template <typename T>
00385 T& List<T>::get(const uint32_t index) const XSENS_LIST_THROW
00386 {
00387 #ifdef _XSENS_LIST_RANGE_CHECKS
00388 if (index >= m_count)
00389 throw "List.get: index out of bounds";
00390 #endif
00391 if (index >= m_count)
00392 return m_data[m_count-1];
00393 return m_data[index];
00394 }
00395
00396 template <typename T>
00397 void List<T>::insert(const T& item, const uint32_t index)
00398 {
00399 if (m_count == m_max)
00400 resize(1 + m_max + (m_max >> 1));
00401 for (unsigned i=m_count;i>index;--i)
00402 m_data[i] = m_data[i-1];
00403 if (index <= m_count)
00404 m_data[index] = item;
00405 else
00406 m_data[m_count] = item;
00407 m_count++;
00408 }
00409
00410 template <typename T>
00411 template <typename TB>
00412 void List<T>::insertCopy(const TB& item, const uint32_t index)
00413 {
00414 if (m_count == m_max)
00415 resize(1 + m_max + (m_max >> 1));
00416 for (unsigned i=m_count;i>index;--i)
00417 m_data[i] = m_data[i-1];
00418 if (index <= m_count)
00419 m_data[index] = new TB(item);
00420 else
00421 m_data[m_count] = new TB(item);
00422 m_count++;
00423 }
00424
00425 template <typename T>
00426 T& List<T>::operator [] (const uint32_t index) const XSENS_LIST_THROW
00427 {
00428 #ifdef _XSENS_LIST_RANGE_CHECKS
00429 if (index >= m_count)
00430 throw "List[]: index out of bounds";
00431 #endif
00432 return m_data[index];
00433 }
00434
00435
00436 template <typename T>
00437 void List<T>::qSort(uint32_t left, uint32_t right)
00438 {
00439 uint32_t l_hold, r_hold;
00440 T pivot;
00441
00442 l_hold = left;
00443 r_hold = right;
00444 pivot = m_data[left];
00445 while (left < right)
00446 {
00447 while (!(m_data[right] < pivot) && (left < right))
00448 right--;
00449 if (left != right)
00450 {
00451 m_data[left] = m_data[right];
00452 left++;
00453 }
00454 while (!(pivot < m_data[left]) && (left < right))
00455 left++;
00456 if (!(left == right))
00457 {
00458 m_data[right] = m_data[left];
00459 right--;
00460 }
00461 }
00462 m_data[left] = pivot;
00463 if (l_hold < left)
00464 qSort(l_hold, left-1);
00465 if (r_hold > left)
00466 qSort(left+1, r_hold);
00467 }
00468
00469 template <typename T>
00470 void List<T>::qSortDeref(uint32_t left, uint32_t right)
00471 {
00472 uint32_t l_hold, r_hold;
00473 T pivot;
00474
00475 l_hold = left;
00476 r_hold = right;
00477 pivot = m_data[left];
00478 while (left < right)
00479 {
00480 while (!(*m_data[right] < *pivot) && (left < right))
00481 right--;
00482 if (left != right)
00483 {
00484 m_data[left] = m_data[right];
00485 left++;
00486 }
00487 while (!(*pivot < *m_data[left]) && (left < right))
00488 left++;
00489 if (!(left == right))
00490 {
00491 m_data[right] = m_data[left];
00492 right--;
00493 }
00494 }
00495 m_data[left] = pivot;
00496 if (l_hold < left)
00497 qSortDeref(l_hold, left-1);
00498 if (r_hold > left)
00499 qSortDeref(left+1, r_hold);
00500 }
00501
00502 template <typename T>
00503 void List<T>::sortAscending(void)
00504 {
00505 if (m_count <= 1)
00506 return;
00507 struct Linker {
00508 Linker *prev, *next;
00509 uint32_t index;
00510
00511 T item;
00512 };
00513
00514 Linker* list = (Linker*) malloc(m_count*sizeof(Linker));
00515
00516 list[0].prev = NULL;
00517 list[0].next = NULL;
00518 list[0].index = 0;
00519 list[0].item = m_data[0];
00520
00521 Linker* curr = list;
00522
00523 for (uint32_t i = 1; i < m_count; ++i)
00524 {
00525 list[i].index = i;
00526 list[i].item = m_data[i];
00527 if (m_data[i] < m_data[curr->index])
00528 {
00529 while (curr->prev != NULL)
00530 {
00531 curr = curr->prev;
00532 if (!(m_data[i] < m_data[curr->index]))
00533 {
00534
00535 list[i].next = curr->next;
00536 list[i].prev = curr;
00537 curr->next->prev = &list[i];
00538 curr->next = &list[i];
00539 curr = &list[i];
00540 break;
00541 }
00542 }
00543 if (curr != &list[i])
00544 {
00545 list[i].prev = NULL;
00546 list[i].next = curr;
00547 curr->prev = &list[i];
00548 curr = &list[i];
00549 }
00550 }
00551 else
00552 {
00553 while (curr->next != NULL)
00554 {
00555 curr = curr->next;
00556 if (m_data[i] < m_data[curr->index])
00557 {
00558
00559 list[i].next = curr;
00560 list[i].prev = curr->prev;
00561 curr->prev->next = &list[i];
00562 curr->prev = &list[i];
00563 curr = &list[i];
00564 break;
00565 }
00566 }
00567 if (curr != &list[i])
00568 {
00569 list[i].prev = curr;
00570 list[i].next = NULL;
00571 curr->next = &list[i];
00572 curr = &list[i];
00573 }
00574 }
00575 }
00576
00577
00578 while (curr->prev != NULL) curr = curr->prev;
00579
00580
00581 for (uint32_t i = 0; i < m_count; ++i)
00582 {
00583 m_data[i] = curr->item;
00584 curr = curr->next;
00585 }
00586
00587 free(list);
00588 }
00589
00590 template <typename T>
00591 void List<T>::sortAscendingDeref(void)
00592 {
00593 if (m_count <= 1)
00594 return;
00595 struct Linker {
00596 Linker *prev, *next;
00597 uint32_t index;
00598
00599 T item;
00600 };
00601
00602 Linker* list = (Linker*) malloc(m_count*sizeof(Linker));
00603
00604 list[0].prev = NULL;
00605 list[0].next = NULL;
00606 list[0].index = 0;
00607 list[0].item = m_data[0];
00608
00609 Linker* curr = list;
00610
00611 for (uint32_t i = 1; i < m_count; ++i)
00612 {
00613 list[i].index = i;
00614 list[i].item = m_data[i];
00615 if (*m_data[i] < *m_data[curr->index])
00616 {
00617 while (curr->prev != NULL)
00618 {
00619 curr = curr->prev;
00620 if (!(*m_data[i] < *m_data[curr->index]))
00621 {
00622
00623 list[i].next = curr->next;
00624 list[i].prev = curr;
00625 curr->next->prev = &list[i];
00626 curr->next = &list[i];
00627 curr = &list[i];
00628 break;
00629 }
00630 }
00631 if (curr != &list[i])
00632 {
00633 list[i].prev = NULL;
00634 list[i].next = curr;
00635 curr->prev = &list[i];
00636 curr = &list[i];
00637 }
00638 }
00639 else
00640 {
00641 while (curr->next != NULL)
00642 {
00643 curr = curr->next;
00644 if (*m_data[i] < *m_data[curr->index])
00645 {
00646
00647 list[i].next = curr;
00648 list[i].prev = curr->prev;
00649 curr->prev->next = &list[i];
00650 curr->prev = &list[i];
00651 curr = &list[i];
00652 break;
00653 }
00654 }
00655 if (curr != &list[i])
00656 {
00657 list[i].prev = curr;
00658 list[i].next = NULL;
00659 curr->next = &list[i];
00660 curr = &list[i];
00661 }
00662 }
00663 }
00664
00665
00666 while (curr->prev != NULL) curr = curr->prev;
00667
00668
00669 for (uint32_t i = 0; i < m_count; ++i)
00670 {
00671 m_data[i] = curr->item;
00672 curr = curr->next;
00673 }
00674
00675 free(list);
00676 }
00677
00678 template <typename T>
00679 template <typename T2>
00680 void List<T>::twinSortAscending(List<T2>& twin)
00681 {
00682 if (m_count <= 1)
00683 return;
00684
00685 #ifdef _XSENS_LIST_RANGE_CHECKS
00686 if (m_count != twin.m_count)
00687 throw "List.twinSortAscending: sizes do not match";
00688 #endif
00689 uint32_t iteration = 0;
00690 uint32_t mini;
00691 T tmp;
00692 T2 tmp2;
00693 if (m_count > 1)
00694 while (iteration < m_count-1)
00695 {
00696 mini = iteration;
00697 for (uint32_t i=iteration+1;i<m_count;++i)
00698 {
00699 if (m_data[i] < m_data[mini])
00700 mini = i;
00701 }
00702 if (mini != iteration)
00703 {
00704 tmp = m_data[mini];
00705 m_data[mini] = m_data[iteration];
00706 m_data[iteration] = tmp;
00707
00708 tmp2 = twin.m_data[mini];
00709 twin.m_data[mini] = twin.m_data[iteration];
00710 twin.m_data[iteration] = tmp2;
00711 }
00712 ++iteration;
00713 }
00714 }
00715
00716 template <typename T>
00717 void List<T>::remove(const uint32_t index) XSENS_LIST_THROW
00718 {
00719 #ifdef _XSENS_LIST_RANGE_CHECKS
00720 if (index >= m_count)
00721 throw "List.remove: index out of bounds";
00722 #endif
00723 if (index == m_count-1)
00724 {
00725 --m_count;
00726 return;
00727 }
00728 --m_count;
00729 for (unsigned i = index;i < m_count;++i)
00730 m_data[i] = m_data[i+1];
00731 }
00732
00733 template <typename T>
00734 void List<T>::removeTail(const uint32_t count) XSENS_LIST_THROW
00735 {
00736 #ifdef _XSENS_LIST_RANGE_CHECKS
00737 if (count > m_count)
00738 throw "List.removeTail: list size less than remove count";
00739 #endif
00740 if (m_count > count)
00741 {
00742 m_count -= count;
00743 return;
00744 }
00745 m_count = 0;
00746 }
00747
00748 template <typename T>
00749 void List<T>::deleteAndRemoveTail(const uint32_t count) XSENS_LIST_THROW
00750 {
00751 #ifdef _XSENS_LIST_RANGE_CHECKS
00752 if (count > m_count)
00753 throw "List.deleteAndRemoveTail: list size less than remove count";
00754 #endif
00755 if (m_count > count)
00756 {
00757 for (unsigned i = 0;i < count;++i)
00758 delete m_data[--m_count];
00759 return;
00760 }
00761 deleteAndClear();
00762 }
00763
00764 template <typename T>
00765 void List<T>::freeAndRemoveTail(const uint32_t count) XSENS_LIST_THROW
00766 {
00767 #ifdef _XSENS_LIST_RANGE_CHECKS
00768 if (count > m_count)
00769 throw "List.freeAndRemoveTail: list size less than remove count";
00770 #endif
00771 if (m_count > count)
00772 {
00773 for (unsigned i = 0;i < count;++i)
00774 free(m_data[--m_count]);
00775 return;
00776 }
00777 freeAndClear();
00778 }
00779
00780 template <typename T>
00781 uint32_t List<T>::removeDuplicateEntries(void)
00782 {
00783 uint32_t removed = 0;
00784 for (uint32_t i=0;i < m_count; ++i)
00785 {
00786 for (uint32_t j=i+1;j < m_count; ++j)
00787 {
00788 if (m_data[i] == m_data[j])
00789 {
00790 remove(j);
00791 ++removed;
00792 --j;
00793 }
00794 }
00795 }
00796 return removed;
00797 }
00798
00799 template <typename T>
00800 uint32_t List<T>::removeDuplicateEntriesDeref(void)
00801 {
00802 uint32_t removed = 0;
00803 for (uint32_t i=0;i < m_count; ++i)
00804 {
00805 for (uint32_t j=i+1;j < m_count; ++j)
00806 {
00807 if (*(m_data[i]) == *(m_data[j]))
00808 {
00809 remove(j);
00810 ++removed;
00811 --j;
00812 }
00813 }
00814 }
00815 return removed;
00816 }
00817
00818 template <typename T>
00819 void List<T>::deleteAndRemove(const uint32_t index) XSENS_LIST_THROW
00820 {
00821 #ifdef _XSENS_LIST_RANGE_CHECKS
00822 if (index >= m_count)
00823 throw "List.deleteAndRemove: index out of bounds";
00824 #endif
00825 delete m_data[index];
00826 if (index == m_count-1)
00827 {
00828 --m_count;
00829 return;
00830 }
00831 --m_count;
00832 for (unsigned i = index;i < m_count;++i)
00833 m_data[i] = m_data[i+1];
00834 }
00835
00836 template <typename T>
00837 void List<T>::freeAndRemove(const uint32_t index) XSENS_LIST_THROW
00838 {
00839 #ifdef _XSENS_LIST_RANGE_CHECKS
00840 if (index >= m_count)
00841 throw "List.freeAndRemove: index out of bounds";
00842 #endif
00843 free(m_data[index]);
00844 if (index == m_count-1)
00845 {
00846 --m_count;
00847 return;
00848 }
00849 --m_count;
00850 for (unsigned i = index;i < m_count;++i)
00851 m_data[i] = m_data[i+1];
00852 }
00853
00854 template <typename T>
00855 template <typename TB>
00856 uint32_t List<T>::find(const TB& item) const
00857 {
00858 for (uint32_t i=0;i<m_count;++i)
00859 if (((const T*)m_data)[i] == item)
00860 return i;
00861 return XSENS_LIST_NOTFOUND;
00862 }
00863
00864 template <typename T>
00865 uint32_t List<T>::find(const T item, InequalityFunction fnc) const
00866 {
00867 for (uint32_t i=0;i<m_count;++i)
00868 if (!fnc(m_data[i],item))
00869 return i;
00870 return XSENS_LIST_NOTFOUND;
00871 }
00872
00873 template <typename T>
00874 template <typename TB>
00875 uint32_t List<T>::findDeref(const TB& item) const
00876 {
00877 for (uint32_t i=0;i<m_count;++i)
00878 if (*(m_data[i]) == item)
00879 return i;
00880 return XSENS_LIST_NOTFOUND;
00881 }
00882
00883 template <typename T>
00884 template <typename TB>
00885 uint32_t List<T>::findSorted(const TB& item) const
00886 {
00887 if (m_count < CMT_LIST_LINEAR_SEARCH_TRESHOLD)
00888 return find(item);
00889
00890 uint32_t x = m_count;
00891 uint32_t n = 1;
00892 uint32_t i;
00893
00894 while(x >= n)
00895 {
00896 i = (x + n) >> 1;
00897
00898 if (m_data[i-1] == item)
00899 return i-1;
00900 if (m_data[i-1] < item)
00901 n = i+1;
00902 else
00903 x = i-1;
00904 }
00905 return XSENS_LIST_NOTFOUND;
00906 }
00907
00908 template <typename T>
00909 template <typename TB>
00910 uint32_t List<T>::findSortedDeref(const TB& item) const
00911 {
00912 if (m_count < CMT_LIST_LINEAR_SEARCH_TRESHOLD)
00913 return findDeref(item);
00914
00915 uint32_t x = m_count;
00916 uint32_t n = 1;
00917 uint32_t i;
00918
00919 while(x >= n)
00920 {
00921 i = (x + n) >> 1;
00922
00923 if (*(m_data[i-1]) == item)
00924 return i-1;
00925 if (*(m_data[i-1]) < item)
00926 n = i+1;
00927 else
00928 x = i-1;
00929 }
00930 return XSENS_LIST_NOTFOUND;
00931 }
00932
00933 template <typename T>
00934 uint32_t List<T>::insertSorted(const T& item)
00935 {
00936 uint32_t i;
00937 if (m_count < CMT_LIST_LINEAR_SEARCH_TRESHOLD)
00938 {
00939 for (i=0;i<m_count;++i)
00940 if (item < m_data[i])
00941 {
00942 insert(item,i);
00943 return i;
00944 }
00945 append(item);
00946 return m_count-1;
00947 }
00948 else
00949 {
00950 uint32_t x = m_count;
00951 uint32_t n = 1;
00952
00953 while(x >= n)
00954 {
00955 i = (x + n) >> 1;
00956
00957 if (m_data[i-1] == item)
00958 {
00959 insert(item,i-1);
00960 return i-1;
00961 }
00962 if (m_data[i-1] < item)
00963 n = i+1;
00964 else
00965 x = i-1;
00966 }
00967 insert(item,n-1);
00968 return n-1;
00969 }
00970 }
00971
00972 template <typename T>
00973 uint32_t List<T>::insertSortedDeref(const T& item)
00974 {
00975 uint32_t i;
00976 if (m_count < CMT_LIST_LINEAR_SEARCH_TRESHOLD)
00977 {
00978 for (i=0;i<m_count;++i)
00979 if (*item < *m_data[i])
00980 {
00981 insert(item,i);
00982 return i;
00983 }
00984 append(item);
00985 return m_count-1;
00986 }
00987 else
00988 {
00989 uint32_t x = m_count;
00990 uint32_t n = 1;
00991
00992 while(x >= n)
00993 {
00994 i = (x + n) >> 1;
00995
00996 if (*(m_data[i-1]) == *item)
00997 {
00998 insert(item,i-1);
00999 return i-1;
01000 }
01001 if (*(m_data[i-1]) < *item)
01002 n = i+1;
01003 else
01004 x = i-1;
01005 }
01006 insert(item,n-1);
01007 return n-1;
01008 }
01009 }
01010
01011 template <typename T>
01012 template <typename TB>
01013 uint32_t List<T>::insertSortedCopy(const TB& item)
01014 {
01015 uint32_t i;
01016 if (m_count < CMT_LIST_LINEAR_SEARCH_TRESHOLD)
01017 {
01018 for (i=0;i<m_count;++i)
01019 if (item < m_data[i])
01020 {
01021 insertCopy<TB>(item,i);
01022 return i;
01023 }
01024 append(item);
01025 return m_count-1;
01026 }
01027 else
01028 {
01029 uint32_t x = m_count;
01030 uint32_t n = 1;
01031
01032 while(x >= n)
01033 {
01034 i = (x + n) >> 1;
01035
01036 if (m_data[i-1] == item)
01037 {
01038 insertCopy<TB>(item,i-1);
01039 return i-1;
01040 }
01041 if (m_data[i-1] < item)
01042 n = i+1;
01043 else
01044 x = i-1;
01045 }
01046 insertCopy<TB>(item,n-1);
01047 return n-1;
01048 }
01049 }
01050
01051 template <typename T>
01052 void List<T>::deleteItemsOnDestroy(void)
01053 {
01054 if (m_jcf != NULL)
01055 {
01056 m_jcf->disable();
01057 delete m_jcf;
01058 }
01059 m_jcf = new JanitorClassFunc<List<T>, void>(*this,&List<T>::deleteAndClear);
01060 }
01061
01062 template <typename T>
01063 void List<T>::freeItemsOnDestroy(void)
01064 {
01065 if (m_jcf != NULL)
01066 {
01067 m_jcf->disable();
01068 delete m_jcf;
01069 }
01070 m_jcf = new JanitorClassFunc<List<T>, void>(*this,&List<T>::freeAndClear);
01071 }
01072
01073 template <typename T>
01074 template <typename TB>
01075 void List<T>::isDeepCopyOf(const List<T>& source)
01076 {
01077 m_count = 0;
01078 if (m_max < source.m_count)
01079 resize(source.m_count);
01080 m_count = source.m_count;
01081 for (uint32_t i = 0;i<m_count;++i)
01082 m_data[i] = new TB(*source.m_data[i]);
01083 }
01084
01085 template <typename T>
01086 void List<T>::isShallowCopyOf(const List<T>& x)
01087 {
01088 m_count = 0;
01089 if (m_max < x.m_count)
01090 resize(x.m_count);
01091 m_count = x.m_count;
01092 for (uint32_t i = 0;i<m_count;++i)
01093 m_data[i] = x.m_data[i];
01094 }
01095
01096 template <typename T>
01097 void List<T>::swap(const uint32_t i, const uint32_t j) XSENS_LIST_THROW
01098 {
01099 #ifdef _XSENS_LIST_RANGE_CHECKS
01100 if (i >= m_count || j >= m_count)
01101 throw "List.swap: index out of bounds";
01102 #endif
01103 T tmp = m_data[i];
01104 m_data[i] = m_data[j];
01105 m_data[j] = tmp;
01106 }
01107
01108 template <typename T>
01109 void List<T>::reverse(void)
01110 {
01111 uint32_t half = m_count / 2;
01112 for (uint32_t i = 0, end=m_count-1; i < half; ++i,--end)
01113 {
01114 T tmp = m_data[i];
01115 m_data[i] = m_data[end];
01116 m_data[end] = tmp;
01117 }
01118 }
01119
01120 }
01121
01122 #endif // _XSENS_LIST_H_2006_06_08