1 #ifndef CGPERF_POSITIONS_C
2 #define CGPERF_POSITIONS_C
9 /*------------------------------------------------------------------------------------------------*/
10 #include "namespace/positions.h"
11 /*------------------------------------------------------------------------------------------------*/
13 static struct Positions
*pos_new(void)
17 t
= calloc(1, sizeof(*t
));
23 /* the copy constructor */
24 static struct Positions
*pos_new_cpy(struct Positions
*src
)
28 t
= malloc(sizeof(*t
));
29 memcpy(t
, src
, sizeof(struct Positions
));
33 static void pos_del(struct Positions
*t
)
37 /*{{{ pos_set_useall */
38 static void pos_set_useall(struct Positions
*t
, bool useall
)
44 /* The positions are 0, 1, ..., Positions_max_key_pos-1, in descending order */
45 t
->size
= POS_MAX_KEY_POS
;
47 i
= POS_MAX_KEY_POS
- 1;
57 static bool pos_sort(struct Positions
*t
)
60 * Sorts the array in reverse order. Returns true if there are no duplicates, false
71 duplicate_free
= true;
85 if ((j
== 0) || (tmp
< base
[j
- 1]))
87 base
[j
] = base
[j
- 1];
88 if (base
[j
] == tmp
) /* oh no, a duplicate!!! */
89 duplicate_free
= false;
95 return duplicate_free
;
98 /* assumes the array is in reverse order */
99 static bool pos_contains(struct Positions
*t
, s32 pos
)
105 p
= t
->positions
+ t
->size
- 1;
119 static void pos_remove(struct Positions
*t
, s32 pos
)
123 pos_set_useall(t
, false);
128 p
= t
->positions
+ t
->size
- 1;
157 fprintf(stderr
, "Positions::remove internal error: not found\n");
161 /* assumes the array is in reverse order */
162 static void pos_add(struct Positions
*t
, s32 pos
)
167 pos_set_useall(t
, false);
170 if (count
== POS_MAX_SIZE
) {
171 fprintf(stderr
, "Positions_add internal error: overflow\n");
174 p
= t
->positions
+ t
->size
- 1;
179 fprintf(stderr
, "Positions_add internal error: duplicate\n");
191 /*{{{ pos_iterator */
193 * creates an iterator, returning the positions in descending order, that apply to strings of length
196 static struct PositionIterator
*pos_iterator(struct Positions
*t
, s32 maxlen
)
198 return positer_new(t
, maxlen
);
200 /*{{{ pos_iterator_all */
201 /* creates an iterator, returning the positions in descending order */
202 static struct PositionIterator
*pos_iterator_all(struct Positions
*t
)
204 return positer_new_all(t
);
206 /*{{{ pos_reviterator */
207 /* creates an iterator, returning the positions in ascending order */
208 static struct PositionReverseIterator
*pos_reviterator(struct Positions
*t
)
210 return posrevit_new(t
);
213 /* initializes an iterator through POSITIONS, ignoring positions >= maxlen */
214 static struct PositionIterator
*positer_new(struct Positions
*positions
, s32 maxlen
)
216 struct PositionIterator
*t
;
218 t
= calloc(1, sizeof(*t
));
221 if (positions
->useall
) {
222 t
->index
= (maxlen
<= (s32
)POS_MAX_KEY_POS
? (s32
)POS_MAX_KEY_POS
- maxlen
: 0);
228 if (index
>= positions
->size
|| positions
->positions
[index
] < maxlen
)
236 /*{{{ positer_new_all */
237 /* initializes an iterator through POSITIONS */
238 static struct PositionIterator
*positer_new_all(struct Positions
*positions
)
240 struct PositionIterator
*t
;
242 t
= calloc(1, sizeof(*t
));
246 /*{{{ positer_remaining */
247 /* returns the number of remaining positions, i.e. how often next() will return a value != EOS */
248 static u32
positer_remaining(struct PositionIterator
*t
)
250 return t
->set
->size
- t
->index
;
252 /*{{{ positer_next */
253 /* retrieves the next position, or EOS past the end */
254 static s32
positer_next(struct PositionIterator
*t
)
258 r
= t
->index
< t
->set
->size
? t
->set
->positions
[t
->index
] : POSITER_EOS
;
263 static void positer_del(struct PositionIterator
*t
)
267 /*{{{ posrevit_new */
268 static struct PositionReverseIterator
*posrevit_new(struct Positions
*positions
)
270 struct PositionReverseIterator
*t
;
272 t
= calloc(1, sizeof(*t
));
274 t
->index
= t
->set
->size
;
277 /*{{{ posrevit_del */
278 static void posrevit_del(struct PositionReverseIterator
*t
)
282 /*{{{ posrevit_next */
283 /* retrieves the next position, or EOS past the end */
284 static s32
posrevit_next(struct PositionReverseIterator
*t
)
289 r
= (t
->index
> t
->minindex
? t
->set
->positions
[t
->index
] : POSREVIT_EOS
);
294 /* _NOT_ the copy constructor */
295 static void pos_cpy(struct Positions
*d
, struct Positions
*s
)
297 memcpy(d
, s
, sizeof(struct Positions
));
300 static void pos_print(struct Positions
*t
)
312 seen_LASTCHAR
= false;
314 p
= t
->positions
+ t
->size
- 1;
319 if (*p
== POS_LASTCHAR
)
320 seen_LASTCHAR
= true;
324 printf("%d", *p
+ 1);
325 if (count
> 0 && p
[-1] == *p
+ 1) {
330 if (!(count
> 0 && p
[-1] == *p
+ 1))
333 printf("%d", *p
+ 1);
345 /*------------------------------------------------------------------------------------------------*/
347 #include "namespace/positions.h"
349 /*------------------------------------------------------------------------------------------------*/