src/iterator.c

changeset 853
d4baf4dd55c3
parent 851
adb4e0737c33
child 854
fe0d69d72bcd
equal deleted inserted replaced
852:16e2a3391e88 853:d4baf4dd55c3
39 struct cx_iterator_s const *iter = it; 39 struct cx_iterator_s const *iter = it;
40 return iter->elem_handle; 40 return iter->elem_handle;
41 } 41 }
42 42
43 static void cx_iter_next_fast(void *it) { 43 static void cx_iter_next_fast(void *it) {
44 struct cx_iterator_base_s *itbase = it; 44 struct cx_iterator_s *iter = it;
45 if (itbase->remove) { 45 if (iter->remove) {
46 struct cx_mut_iterator_s *iter = it; 46 iter->remove = false;
47 itbase->remove = false;
48 iter->elem_count--; 47 iter->elem_count--;
49 // only move the last element when we are not currently aiming 48 // only move the last element when we are not currently aiming
50 // at the last element already 49 // at the last element already
51 if (iter->index < iter->elem_count) { 50 if (iter->index < iter->elem_count) {
52 void *last = ((char *) iter->src_handle) 51 void *last = ((char *) iter->src_handle.m)
53 + iter->elem_count * iter->elem_size; 52 + iter->elem_count * iter->elem_size;
54 memcpy(iter->elem_handle, last, iter->elem_size); 53 memcpy(iter->elem_handle, last, iter->elem_size);
55 } 54 }
56 } else { 55 } else {
57 struct cx_iterator_s *iter = it;
58 iter->index++; 56 iter->index++;
59 iter->elem_handle = ((char *) iter->elem_handle) + iter->elem_size; 57 iter->elem_handle = ((char *) iter->elem_handle) + iter->elem_size;
60 } 58 }
61 } 59 }
62 60
63 static void cx_iter_next_slow(void *it) { 61 static void cx_iter_next_slow(void *it) {
64 struct cx_iterator_base_s *itbase = it; 62 struct cx_iterator_s *iter = it;
65 if (itbase->remove) { 63 if (iter->remove) {
66 struct cx_mut_iterator_s *iter = it; 64 iter->remove = false;
67 itbase->remove = false;
68 iter->elem_count--; 65 iter->elem_count--;
69 66
70 // number of elements to move 67 // number of elements to move
71 size_t remaining = iter->elem_count - iter->index; 68 size_t remaining = iter->elem_count - iter->index;
72 if (remaining > 0) { 69 if (remaining > 0) {
75 ((char *) iter->elem_handle) + iter->elem_size, 72 ((char *) iter->elem_handle) + iter->elem_size,
76 remaining * iter->elem_size 73 remaining * iter->elem_size
77 ); 74 );
78 } 75 }
79 } else { 76 } else {
80 struct cx_iterator_s *iter = it;
81 iter->index++; 77 iter->index++;
82 iter->elem_handle = ((char *) iter->elem_handle) + iter->elem_size; 78 iter->elem_handle = ((char *) iter->elem_handle) + iter->elem_size;
83 } 79 }
84 } 80 }
85 81
86 CxMutIterator cxMutIterator( 82 CxIterator cxMutIterator(
87 void *array, 83 void *array,
88 size_t elem_size, 84 size_t elem_size,
89 size_t elem_count, 85 size_t elem_count,
90 bool remove_keeps_order 86 bool remove_keeps_order
91 ) { 87 ) {
92 CxMutIterator iter; 88 CxIterator iter;
93 89
94 iter.index = 0; 90 iter.index = 0;
95 iter.src_handle = array; 91 iter.src_handle.m = array;
96 iter.elem_handle = array; 92 iter.elem_handle = array;
97 iter.elem_size = elem_size; 93 iter.elem_size = elem_size;
98 iter.elem_count = array == NULL ? 0 : elem_count; 94 iter.elem_count = array == NULL ? 0 : elem_count;
99 iter.base.valid = cx_iter_valid; 95 iter.valid = cx_iter_valid;
100 iter.base.current = cx_iter_current; 96 iter.current = cx_iter_current;
101 iter.base.next = remove_keeps_order ? cx_iter_next_slow : cx_iter_next_fast; 97 iter.next = remove_keeps_order ? cx_iter_next_slow : cx_iter_next_fast;
102 iter.base.remove = false; 98 iter.remove = false;
103 iter.base.mutating = true; 99 iter.mutating = true;
104 100
105 return iter; 101 return iter;
106 } 102 }
107 103
108 CxIterator cxIterator( 104 CxIterator cxIterator(
109 void const *array, 105 void const *array,
110 size_t elem_size, 106 size_t elem_size,
111 size_t elem_count 107 size_t elem_count
112 ) { 108 ) {
113 CxMutIterator iter = cxMutIterator((void*)array, elem_size, elem_count, false); 109 CxIterator iter = cxMutIterator((void*)array, elem_size, elem_count, false);
114 iter.base.mutating = false; 110 iter.mutating = false;
115 111 return iter;
116 // we know the iterators share the same memory layout
117 CxIterator ret;
118 memcpy(&ret, &iter, sizeof(CxIterator));
119 return ret;
120 } 112 }

mercurial