23 #ifndef _XSENS_LIST_HPP_2006_06_08
24 #define _XSENS_LIST_HPP_2006_06_08
26 #ifndef _XSENS_LIST_H_2006_06_08
38 #define CMT_LIST_LINEAR_SEARCH_TRESHOLD 10
45 m_data = (T*) malloc(m_max *
sizeof(T));
58 m_data = (T*) malloc(m_max *
sizeof(T));
69 m_count = src.m_count;
70 m_data = (T*) malloc(m_max *
sizeof(T));
73 memcpy(m_data,src.m_data,m_count*
sizeof(T));
84 m_data = (T*) malloc(m_max *
sizeof(T));
87 memcpy(m_data,src,m_count *
sizeof(T));
101 template <
typename T>
106 if (m_manage && m_data != NULL)
112 template <
typename T>
115 for (
unsigned i=0;i<m_count;++i)
120 template <
typename T>
123 for (
unsigned i=0;i<m_count;++i)
128 template <
typename T>
134 template <
typename T>
139 if (newSize == m_max)
141 if (m_count > newSize)
148 m_data = (T*) realloc(m_data,m_max *
sizeof(T));
152 template <
typename T>
155 if (m_count == m_max)
156 resize(m_max + 1 + m_max/2);
157 m_data[m_count++] = item;
160 template <
typename T>
163 if (m_count+count > m_max)
164 resize(m_max + count + m_max/2);
165 for (
unsigned i = 0; i < count; ++i)
166 m_data[m_count++] = lst[i];
169 template <
typename T>
172 if (m_max < source.m_count + m_count)
173 resize(source.m_count + m_count);
175 for (uint32_t i = 0;i<source.m_count;++i)
176 m_data[m_count++] =
new T(*source.m_data[i]);
179 template <
typename T>
182 if (m_max < source.m_count + m_count)
183 resize(source.m_count + m_count);
185 for (uint32_t i = 0;i<source.m_count;++i)
186 m_data[m_count++] = source.m_data[i];
189 template <
typename T>
190 template <
typename TB>
193 if (m_count == m_max)
194 resize(m_max + 1 + m_max/2);
195 m_data[m_count++] =
new TB(item);
198 template <
typename T>
199 template <
typename TR>
202 if (m_count == m_max)
203 resize(m_max + 1 + m_max/2);
204 m_data[m_count++] = item;
207 template <
typename T>
210 #ifdef _XSENS_LIST_RANGE_CHECKS
212 throw "List.last: empty list";
214 return m_data[m_count-1];
217 template <
typename T>
218 T&
List<T>::get(
const uint32_t index)
const XSENS_LIST_THROW
220 #ifdef _XSENS_LIST_RANGE_CHECKS
221 if (index >= m_count)
222 throw "List.get: index out of bounds";
224 if (index >= m_count)
225 return m_data[m_count-1];
226 return m_data[index];
229 template <
typename T>
232 if (m_count == m_max)
233 resize(1 + m_max + (m_max >> 1));
234 for (
unsigned i=m_count;i>index;--i)
235 m_data[i] = m_data[i-1];
236 if (index <= m_count)
237 m_data[index] = item;
239 m_data[m_count] = item;
243 template <
typename T>
244 template <
typename TB>
247 if (m_count == m_max)
248 resize(1 + m_max + (m_max >> 1));
249 for (
unsigned i=m_count;i>index;--i)
250 m_data[i] = m_data[i-1];
251 if (index <= m_count)
252 m_data[index] =
new TB(item);
254 m_data[m_count] =
new TB(item);
258 template <
typename T>
261 #ifdef _XSENS_LIST_RANGE_CHECKS
262 if (index >= m_count)
263 throw "List[]: index out of bounds";
265 return m_data[index];
268 #if defined(_XSENS_LIST_WITH_MATH) && defined(_XSENS_LIST_IO)
270 template <
typename T>
271 std::ostream& operator << (std::ostream& os, List<T>& t)
273 os <<
'[' << t.length() <<
"]{ ";
274 for (
unsigned i=0 ; i<t.length() ; ++i)
280 #ifndef _CMTMATLABHEADERS
281 #define _CMTMATLABHEADERS
282 struct MatlabFileHeader {
283 char description[116];
284 int32_t data_offset1;
285 int32_t data_offset2;
290 struct MatlabDataHeader {
295 struct MatlabMatrixHeader {
296 int32_t flags_data_type;
297 int32_t flags_data_size;
298 int32_t flags0,flags1;
300 int32_t dimensions_data_type;
301 int32_t dimensions_data_size;
302 int32_t dimensions_m, dimensions_n;
310 template <
typename T>
311 void List<T>::saveAsMatlab(
const char* filename,
const char *varname)
const
316 MatlabFileHeader file_header;
317 MatlabMatrixHeader matrix_header;
319 MatlabDataHeader inner_header;
320 MatlabDataHeader outer_header;
322 FILE* fp = fopen(filename,
"wb");
326 strcpy(file_header.description,
"cmtMath/Xsens");
327 for (i = strlen(file_header.description); i <116; ++i)
328 file_header.description[i] =
' ';
329 file_header.data_offset1 = 0;
330 file_header.data_offset2 = 0;
331 file_header.version = 0x0100;
332 file_header.endian = (int16_t)
'M' << 8 |
'I';
336 matrix_header.flags_data_type = 6;
337 matrix_header.flags_data_size = 8;
338 matrix_header.flags0 = 6;
339 matrix_header.flags1 = 0;
340 matrix_header.dimensions_data_type = 5;
341 matrix_header.dimensions_data_size = 8;
342 matrix_header.dimensions_m = m_count;
343 matrix_header.dimensions_n = m_data[0]->size();
344 matrix_header.name_type = 1;
346 if ( varname == (
char *)NULL )
347 matrix_header.name_length = 0;
349 matrix_header.name_length = (int32_t) strlen(varname);
351 name_pad = matrix_header.name_length & 7;
353 inner_header.data_type = 9;
354 inner_header.n_bytes =
sizeof(double) * m_count * matrix_header.dimensions_n;
356 outer_header.data_type = 14;
357 outer_header.n_bytes =
sizeof(matrix_header) + matrix_header.name_length + name_pad
358 +
sizeof(MatlabDataHeader) + inner_header.n_bytes;
360 fwrite((
char*) &file_header,
sizeof(MatlabFileHeader),1,fp);
361 fwrite((
char*) &outer_header,
sizeof(MatlabDataHeader),1,fp);
362 fwrite((
char*) &matrix_header,
sizeof(MatlabMatrixHeader),1,fp);
363 fwrite(varname,
sizeof(
char),matrix_header.name_length,fp);
366 fwrite(
"\0\0\0\0\0\0\0",
sizeof(
char),8-name_pad,fp);
368 fwrite((
char*) &inner_header,
sizeof(MatlabDataHeader),1,fp);
373 for ( j = 0; j < (size_t) matrix_header.dimensions_n; j++ )
374 for ( i = 0; i < m_count; i++ )
376 tmp = (*m_data[i])[(
unsigned)j];
377 fwrite(&tmp,
sizeof(
double),1,fp);
382 #endif // _XSENS_LIST_WITH_MATH && _XSENS_LIST_IO
384 template <
typename T>
385 void List<T>::qSort(uint32_t left, uint32_t right)
387 uint32_t l_hold, r_hold;
392 pivot = m_data[left];
395 while (!(m_data[right] < pivot) && (left < right))
399 m_data[left] = m_data[right];
402 while (!(pivot < m_data[left]) && (left < right))
404 if (!(left == right))
406 m_data[right] = m_data[left];
410 m_data[left] = pivot;
412 qSort(l_hold, left-1);
414 qSort(left+1, r_hold);
417 template <
typename T>
418 void List<T>::qSortDeref(uint32_t left, uint32_t right)
420 uint32_t l_hold, r_hold;
425 pivot = m_data[left];
428 while (!(*m_data[right] < *pivot) && (left < right))
432 m_data[left] = m_data[right];
435 while (!(*pivot < *m_data[left]) && (left < right))
437 if (!(left == right))
439 m_data[right] = m_data[left];
443 m_data[left] = pivot;
445 qSortDeref(l_hold, left-1);
447 qSortDeref(left+1, r_hold);
452 #define XSENS_LIST_JOBSORT
455 template <
typename T>
460 #if defined(XSENS_LIST_QSORT)
462 #elif defined(XSENS_LIST_COMBSORT)
464 uint32_t gap = m_count;
469 while (gap > 1 || swaps > 0)
473 dgap = floor(((
double) gap) / 1.247330950103979);
474 gap = (uint32_t) dgap;
475 if (gap == 10 || gap == 9)
479 uint32_t gappedCount = m_count-gap;
481 for (uint32_t i = 0; i < gappedCount; ++i)
483 if (m_data[i] > m_data[i+gap])
486 m_data[i] = m_data[i+gap];
487 m_data[i+gap] = temp;
492 #elif defined(XSENS_LIST_JOBSORT)
500 Linker* list = (Linker*) malloc(m_count*
sizeof(Linker));
505 list[0].item = m_data[0];
509 for (uint32_t i = 1; i < m_count; ++i)
512 list[i].item = m_data[i];
513 if (m_data[i] < m_data[curr->index])
515 while (curr->prev != NULL)
518 if (!(m_data[i] < m_data[curr->index]))
521 list[i].next = curr->next;
523 curr->next->prev = &list[i];
524 curr->next = &list[i];
529 if (curr != &list[i])
533 curr->prev = &list[i];
539 while (curr->next != NULL)
542 if (m_data[i] < m_data[curr->index])
546 list[i].prev = curr->prev;
547 curr->prev->next = &list[i];
548 curr->prev = &list[i];
553 if (curr != &list[i])
557 curr->next = &list[i];
564 while (curr->prev != NULL) curr = curr->prev;
567 for (uint32_t i = 0; i < m_count; ++i)
569 m_data[i] = curr->item;
578 for (uint32_t i = 1; i < m_count; ++i)
581 for (uint32_t j = end-1; j >= i; --j)
583 if (m_data[j] < m_data[j-1])
586 m_data[j] = m_data[j-1];
597 template <
typename T>
602 #if defined(XSENS_LIST_QSORT)
603 qSortDeref(0,m_count-1);
604 #elif defined(XSENS_LIST_COMBSORT)
606 uint32_t gap = m_count;
611 while (gap > 1 || swaps > 0)
615 dgap = floor(((
double) gap) / 1.247330950103979);
616 gap = (uint32_t) dgap;
617 if (gap == 10 || gap == 9)
621 uint32_t gappedCount = m_count-gap;
623 for (uint32_t i = 0; i < gappedCount; ++i)
625 if (*m_data[i+gap] < *m_data[i])
628 m_data[i] = m_data[i+gap];
629 m_data[i+gap] = temp;
634 #elif defined(XSENS_LIST_JOBSORT)
642 Linker* list = (Linker*) malloc(m_count*
sizeof(Linker));
647 list[0].item = m_data[0];
651 for (uint32_t i = 1; i < m_count; ++i)
654 list[i].item = m_data[i];
655 if (*m_data[i] < *m_data[curr->index])
657 while (curr->prev != NULL)
660 if (!(*m_data[i] < *m_data[curr->index]))
663 list[i].next = curr->next;
665 curr->next->prev = &list[i];
666 curr->next = &list[i];
671 if (curr != &list[i])
675 curr->prev = &list[i];
681 while (curr->next != NULL)
684 if (*m_data[i] < *m_data[curr->index])
688 list[i].prev = curr->prev;
689 curr->prev->next = &list[i];
690 curr->prev = &list[i];
695 if (curr != &list[i])
699 curr->next = &list[i];
706 while (curr->prev != NULL) curr = curr->prev;
709 for (uint32_t i = 0; i < m_count; ++i)
711 m_data[i] = curr->item;
720 for (uint32_t i = 1; i < m_count; ++i)
723 for (uint32_t j = end-1; j >= i; --j)
725 if (*(m_data[j]) < *(m_data[j-1]))
728 m_data[j] = m_data[j-1];
739 template <
typename T>
740 template <
typename T2>
746 #ifdef _XSENS_LIST_RANGE_CHECKS
747 if (m_count != twin.m_count)
748 throw "List.twinSortAscending: sizes do not match";
750 uint32_t iteration = 0;
755 while (iteration < m_count-1)
758 for (uint32_t i=iteration+1;i<m_count;++i)
760 if (m_data[i] < m_data[mini])
763 if (mini != iteration)
766 m_data[mini] = m_data[iteration];
767 m_data[iteration] = tmp;
769 tmp2 = twin.m_data[mini];
770 twin.m_data[mini] = twin.m_data[iteration];
771 twin.m_data[iteration] = tmp2;
777 template <
typename T>
780 #ifdef _XSENS_LIST_RANGE_CHECKS
781 if (index >= m_count)
782 throw "List.remove: index out of bounds";
784 if (index == m_count-1)
790 for (
unsigned i = index;i < m_count;++i)
791 m_data[i] = m_data[i+1];
794 template <
typename T>
797 #ifdef _XSENS_LIST_RANGE_CHECKS
799 throw "List.removeTail: list size less than remove count";
809 template <
typename T>
812 #ifdef _XSENS_LIST_RANGE_CHECKS
814 throw "List.deleteAndRemoveTail: list size less than remove count";
818 for (
unsigned i = 0;i < count;++i)
819 delete m_data[--m_count];
825 template <
typename T>
828 #ifdef _XSENS_LIST_RANGE_CHECKS
830 throw "List.freeAndRemoveTail: list size less than remove count";
834 for (
unsigned i = 0;i < count;++i)
835 free(m_data[--m_count]);
841 template <
typename T>
844 uint32_t removed = 0;
845 for (uint32_t i=0;i < m_count; ++i)
847 for (uint32_t j=i+1;j < m_count; ++j)
849 if (m_data[i] == m_data[j])
860 template <
typename T>
863 uint32_t removed = 0;
864 for (uint32_t i=0;i < m_count; ++i)
866 for (uint32_t j=i+1;j < m_count; ++j)
868 if (*(m_data[i]) == *(m_data[j]))
879 template <
typename T>
882 #ifdef _XSENS_LIST_RANGE_CHECKS
883 if (index >= m_count)
884 throw "List.deleteAndRemove: index out of bounds";
886 delete m_data[index];
887 if (index == m_count-1)
893 for (
unsigned i = index;i < m_count;++i)
894 m_data[i] = m_data[i+1];
897 template <
typename T>
900 #ifdef _XSENS_LIST_RANGE_CHECKS
901 if (index >= m_count)
902 throw "List.freeAndRemove: index out of bounds";
905 if (index == m_count-1)
911 for (
unsigned i = index;i < m_count;++i)
912 m_data[i] = m_data[i+1];
915 template <
typename T>
916 template <
typename TB>
919 for (uint32_t i=0;i<m_count;++i)
920 if (((
const T*)m_data)[i] == item)
925 template <
typename T>
926 uint32_t
List<T>::find(
const T item, InequalityFunction fnc)
const
928 for (uint32_t i=0;i<m_count;++i)
929 if (!fnc(m_data[i],item))
934 template <
typename T>
935 template <
typename TB>
938 for (uint32_t i=0;i<m_count;++i)
939 if (*(m_data[i]) == item)
944 template <
typename T>
945 template <
typename TB>
951 uint32_t x = m_count;
959 if (m_data[i-1] == item)
961 if (m_data[i-1] < item)
969 template <
typename T>
970 template <
typename TB>
974 return findDeref(item);
976 uint32_t x = m_count;
984 if (*(m_data[i-1]) == item)
986 if (*(m_data[i-1]) < item)
994 template <
typename T>
1000 for (i=0;i<m_count;++i)
1001 if (item < m_data[i])
1011 uint32_t x = m_count;
1018 if (m_data[i-1] == item)
1023 if (m_data[i-1] < item)
1033 template <
typename T>
1039 for (i=0;i<m_count;++i)
1040 if (*item < *m_data[i])
1050 uint32_t x = m_count;
1057 if (*(m_data[i-1]) == *item)
1062 if (*(m_data[i-1]) < *item)
1072 template <
typename T>
1073 template <
typename TB>
1079 for (i=0;i<m_count;++i)
1080 if (item < m_data[i])
1082 insertCopy<TB>(item,i);
1090 uint32_t x = m_count;
1097 if (m_data[i-1] == item)
1099 insertCopy<TB>(item,i-1);
1102 if (m_data[i-1] < item)
1107 insertCopy<TB>(item,n-1);
1112 template <
typename T>
1120 m_jcf =
new JanitorClassFunc<List<T>,
void>(*
this,&List<T>::deleteAndClear);
1123 template <
typename T>
1131 m_jcf =
new JanitorClassFunc<List<T>,
void>(*
this,&List<T>::freeAndClear);
1134 template <
typename T>
1135 template <
typename TB>
1139 if (m_max < source.m_count)
1140 resize(source.m_count);
1141 m_count = source.m_count;
1142 for (uint32_t i = 0;i<m_count;++i)
1143 m_data[i] =
new TB(*source.m_data[i]);
1146 template <
typename T>
1150 if (m_max < x.m_count)
1152 m_count = x.m_count;
1153 for (uint32_t i = 0;i<m_count;++i)
1154 m_data[i] = x.m_data[i];
1157 template <
typename T>
1158 void List<T>::swap(
const uint32_t i,
const uint32_t j) XSENS_LIST_THROW
1160 #ifdef _XSENS_LIST_RANGE_CHECKS
1161 if (i >= m_count || j >= m_count)
1162 throw "List.swap: index out of bounds";
1165 m_data[i] = m_data[j];
1169 template <
typename T>
1172 uint32_t half = m_count / 2;
1173 for (uint32_t i = 0, end=m_count-1; i < half; ++i,--end)
1176 m_data[i] = m_data[end];
1183 #endif // _XSENS_LIST_HPP_2006_06_08
void remove(const uint32_t index) XSENS_LIST_THROW
Removes an item at the given index in the list.
Definition: xsens_list.h:787
void deleteItemsOnDestroy(void)
Definition: xsens_list.h:1130
void swap(const uint32_t i, const uint32_t j) XSENS_LIST_THROW
Swaps two items in the list.
Definition: xsens_list.h:1175
void freeAndRemoveTail(const uint32_t count) XSENS_LIST_THROW
Definition: xsens_list.h:835
T & get(const uint32_t index) const XSENS_LIST_THROW
Retrieves the item at the given index. An index beyond the end returns the first item.
Definition: xsens_list.h:450
void freeAndClear(void)
Calls free for all items in the list and then clears the list.
Definition: xsens_list.h:325
void deleteAndClear(void)
Calls delete for all items in the list and then clears the list.
Definition: xsens_list.h:317
void deleteAndRemove(const uint32_t index) XSENS_LIST_THROW
Removes an item at the given index in the list.
Definition: xsens_list.h:889
void reverse(void)
Reverse the order of the list, useful for sorted lists that are read/created in the reverse order...
Definition: xsens_list.h:1187
List()
Standard constructor, creates an empty list with some room for items.
Definition: xsens_list.h:238
void sortAscendingDeref(void)
Sorts the list in an ascending order, using the T::< operator on dereferenced list items...
Definition: xsens_list.h:658
uint32_t findDeref(const TB &item) const
Finds an item in an unsorted list (walk over all items) using the T::== operator on dereferenced list...
Definition: xsens_list.h:945
void clear(void)
Clears the list without explicitly deleting anything.
Definition: xsens_list.h:333
void insert(const T &item, const uint32_t index)
Inserts an item at the given index, shifting any items below it down one spot.
Definition: xsens_list.h:462
uint32_t insertSorted(const T &item)
Assumes the list is sorted and inserts the item at the appropriate spot.
Definition: xsens_list.h:1090
List class interface for use in CMT.
~List()
Destroy the list. This does NOT automatically delete items IN the list.
Definition: xsens_list.h:306
void appendDeepCopy(const List< T > &source)
Adds the contents of the source list to the end of the list.
Definition: xsens_list.h:374
uint32_t find(const TB &item) const
Finds an item in an unsorted list (walk over all items) using the T::== operator. ...
Definition: xsens_list.h:926
#define XSENS_LIST_THROW
Definition: xsens_list.h:58
void appendCopy(const TB &item)
Adds a copy of a referenced item to the end of the list using newItem = new TB(item).
Definition: xsens_list.h:395
#define XSENS_LIST_NOTFOUND
Definition: xsens_list.h:49
void deleteAndRemoveTail(const uint32_t count) XSENS_LIST_THROW
Definition: xsens_list.h:819
uint32_t removeDuplicateEntriesDeref(void)
Removes any duplicate entries and returns the number of items removed. Items are compared after deref...
Definition: xsens_list.h:870
void appendList(uint32_t count, const T *lst)
Adds a number of items to the end of the list.
Definition: xsens_list.h:365
uint32_t insertSortedCopy(const TB &item)
Assumes the list is sorted and inserts a copy of the referenced item at the appropriate spot...
Definition: xsens_list.h:1117
void freeAndRemove(const uint32_t index) XSENS_LIST_THROW
Removes an item at the given index in the list.
Definition: xsens_list.h:907
void resize(uint32_t newSize)
Resizes the list to at least the given size.
Definition: xsens_list.h:339
T & last(void) const XSENS_LIST_THROW
Retrieves the last item.
Definition: xsens_list.h:412
void appendShallowCopy(const List< T > &source)
Adds the contents of the source list to the end of the list.
Definition: xsens_list.h:384
uint32_t findSortedDeref(const TB &item) const
Finds an item in a sorted list (binary search) using the T::== and T::< operators on dereferenced lis...
Definition: xsens_list.h:1002
void isShallowCopyOf(const List< T > &source)
Overwrites the current list with a direct copy (a=b) of another list.
Definition: xsens_list.h:1164
#define CMT_LIST_LINEAR_SEARCH_TRESHOLD
Definition: xsens_list.hpp:38
uint32_t removeDuplicateEntries(void)
Removes any duplicate entries and returns the number of items removed. Items are compared directly...
Definition: xsens_list.h:851
void sortAscending(void)
Sorts the list in an ascending order, using the T::< operator.
Definition: xsens_list.h:568
void removeTail(const uint32_t count) XSENS_LIST_THROW
Removes items from the end of the list.
Definition: xsens_list.h:804
uint32_t insertSortedDeref(const T &item)
Assumes the list is sorted by dereferenced values and inserts the item at the appropriate spot...
Definition: xsens_list.h:1103
void freeItemsOnDestroy(void)
Definition: xsens_list.h:1141
void append(const T &item)
Adds an item to the end of the list.
Definition: xsens_list.h:357
T & operator[](const uint32_t index) const XSENS_LIST_THROW
Retrieves the item at the given index. An index beyond the end probably causes an exception...
Definition: xsens_list.h:491
void twinSortAscending(List< T2 > &twin)
Sorts the first list in an ascending order, using the T::< operator, the second list will be updated ...
Definition: xsens_list.h:750
void appendRelated(const TR &item)
Adds a related item to the end of the list, using the T = TR operator.
Definition: xsens_list.h:404
void insertCopy(const TB &item, const uint32_t index)
Inserts a copy of the referenced item at the given index, shifting any items below it down one spot...
Definition: xsens_list.h:477
uint32_t findSorted(const TB &item) const
Finds an item in a sorted list (binary search) using the T::== and T::< operators.
Definition: xsens_list.h:977
void isDeepCopyOf(const List< T > &source)
Make a copy of the list, duplicating list items i with: copy[i] = new TB(*source[i]) ...
Definition: xsens_list.h:1153