excit.c 41.2 KB
Newer Older
1 2
#include <errno.h>
#include <stdlib.h>
Brice Videau's avatar
Brice Videau committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#include <excit.h>

struct excit_func_table_s {
	int (*alloc)(excit_t data);
	void (*free)(excit_t data);
	int (*copy)(excit_t dst, const excit_t src);
	int (*next)(excit_t data, excit_index_t *indexes);
	int (*peek)(const excit_t data, excit_index_t *indexes);
	int (*size)(const excit_t data, excit_index_t *size);
	int (*rewind)(excit_t data);
	int (*split)(const excit_t data, excit_index_t n,
		     excit_t *results);
	int (*nth)(const excit_t data, excit_index_t n,
		   excit_index_t *indexes);
	int (*n)(const excit_t data, const excit_index_t *indexes,
		 excit_index_t *n);
	int (*pos)(const excit_t iterator, excit_index_t *n);
20 21
};

Brice Videau's avatar
Brice Videau committed
22 23 24 25
struct excit_s {
	const struct excit_func_table_s *functions;
	excit_index_t dimension;
	enum excit_type_e type;
26 27 28 29 30 31
	void *data;
};

/*--------------------------------------------------------------------*/

struct slice_iterator_s {
Brice Videau's avatar
Brice Videau committed
32 33
	excit_t src;
	excit_t indexer;
34 35
};

Brice Videau's avatar
Brice Videau committed
36
static int slice_iterator_alloc(excit_t data)
37 38 39 40 41 42 43 44 45 46 47 48
{
	data->data = malloc(sizeof(struct slice_iterator_s));
	if (!data->data)
		return -ENOMEM;
	struct slice_iterator_s *iterator =
	    (struct slice_iterator_s *) data->data;

	iterator->src = NULL;
	iterator->indexer = NULL;
	return 0;
}

Brice Videau's avatar
Brice Videau committed
49
static void slice_iterator_free(excit_t data)
50 51 52 53
{
	struct slice_iterator_s *iterator =
	    (struct slice_iterator_s *) data->data;

Brice Videau's avatar
Brice Videau committed
54 55
	excit_free(iterator->src);
	excit_free(iterator->indexer);
56 57 58
	free(data->data);
}

Brice Videau's avatar
Brice Videau committed
59
static int slice_iterator_copy(excit_t dst, const excit_t src)
60 61 62 63 64
{
	const struct slice_iterator_s *iterator =
	    (const struct slice_iterator_s *) src->data;
	struct slice_iterator_s *result = (struct slice_iterator_s *) dst->data;

Brice Videau's avatar
Brice Videau committed
65
	result->src = excit_dup(iterator->src);
66 67
	if (!result->src)
		return -ENOMEM;
Brice Videau's avatar
Brice Videau committed
68
	result->indexer = excit_dup(iterator->indexer);
69
	if (!result->indexer) {
Brice Videau's avatar
Brice Videau committed
70
		excit_free(iterator->src);
71 72 73 74 75
		return -ENOMEM;
	}
	return 0;
}

Brice Videau's avatar
Brice Videau committed
76
static int slice_iterator_next(excit_t data, excit_index_t *indexes)
77 78 79
{
	struct slice_iterator_s *iterator =
	    (struct slice_iterator_s *) data->data;
Brice Videau's avatar
Brice Videau committed
80 81
	excit_index_t n;
	int err = excit_next(iterator->indexer, &n);
82 83 84

	if (err)
		return err;
Brice Videau's avatar
Brice Videau committed
85
	return excit_nth(iterator->src, n, indexes);
86 87
}

Brice Videau's avatar
Brice Videau committed
88 89
static int slice_iterator_peek(const excit_t data,
			       excit_index_t *indexes)
90 91 92
{
	const struct slice_iterator_s *iterator =
	    (const struct slice_iterator_s *)data->data;
Brice Videau's avatar
Brice Videau committed
93 94
	excit_index_t n;
	int err = excit_peek(iterator->indexer, &n);
95 96 97

	if (err)
		return err;
Brice Videau's avatar
Brice Videau committed
98
	return excit_nth(iterator->src, n, indexes);
99 100
}

Brice Videau's avatar
Brice Videau committed
101
static int slice_iterator_size(const excit_t data, excit_index_t *size)
102 103 104 105
{
	const struct slice_iterator_s *iterator =
	    (const struct slice_iterator_s *)data->data;

Brice Videau's avatar
Brice Videau committed
106
	return excit_size(iterator->indexer, size);
107 108
}

Brice Videau's avatar
Brice Videau committed
109
static int slice_iterator_rewind(excit_t data)
110 111 112 113
{
	struct slice_iterator_s *iterator =
	    (struct slice_iterator_s *) data->data;

Brice Videau's avatar
Brice Videau committed
114
	return excit_rewind(iterator->indexer);
115 116
}

Brice Videau's avatar
Brice Videau committed
117 118
static int slice_iterator_nth(const excit_t data, excit_index_t n,
			      excit_index_t *indexes)
119 120 121
{
	const struct slice_iterator_s *iterator =
	    (const struct slice_iterator_s *)data->data;
Brice Videau's avatar
Brice Videau committed
122 123
	excit_index_t p;
	int err = excit_nth(iterator->indexer, n, &p);
124 125 126

	if (err)
		return err;
Brice Videau's avatar
Brice Videau committed
127
	return excit_nth(iterator->src, p, indexes);
128 129
}

Brice Videau's avatar
Brice Videau committed
130 131 132
static int slice_iterator_n(const excit_t data,
			    const excit_index_t *indexes,
			    excit_index_t *n)
133 134 135
{
	const struct slice_iterator_s *iterator =
	    (const struct slice_iterator_s *)data->data;
Brice Videau's avatar
Brice Videau committed
136 137
	excit_index_t inner_n;
	int err = excit_n(iterator->src, indexes, &inner_n);
138 139 140

	if (err)
		return err;
Brice Videau's avatar
Brice Videau committed
141
	return excit_n(iterator->indexer, &inner_n, n);
142 143
}

Brice Videau's avatar
Brice Videau committed
144
static int slice_iterator_pos(const excit_t data, excit_index_t *n)
145 146 147 148
{
	const struct slice_iterator_s *iterator =
	    (const struct slice_iterator_s *)data->data;

Brice Videau's avatar
Brice Videau committed
149
	return excit_pos(iterator->indexer, n);
150 151
}

Brice Videau's avatar
Brice Videau committed
152 153
static int slice_iterator_split(const excit_t data, excit_index_t n,
				excit_t *results)
154 155 156
{
	const struct slice_iterator_s *iterator =
	    (const struct slice_iterator_s *)data->data;
Brice Videau's avatar
Brice Videau committed
157
	int err = excit_split(iterator->indexer, n, results);
158 159 160 161 162 163

	if (err)
		return err;
	if (!results)
		return 0;
	for (int i = 0; i < n; i++) {
Brice Videau's avatar
Brice Videau committed
164 165
		excit_t tmp;
		excit_t tmp2;
166 167

		tmp = results[i];
Brice Videau's avatar
Brice Videau committed
168
		results[i] = excit_alloc(EXCIT_SLICE);
169
		if (!results[i]) {
Brice Videau's avatar
Brice Videau committed
170
			excit_free(tmp);
171 172 173
			err = -ENOMEM;
			goto error;
		}
Brice Videau's avatar
Brice Videau committed
174
		tmp2 = excit_dup(iterator->src);
175
		if (!tmp2) {
Brice Videau's avatar
Brice Videau committed
176
			excit_free(tmp);
177 178 179
			err = -ENOMEM;
			goto error;
		}
Brice Videau's avatar
Brice Videau committed
180
		err = excit_slice_init(results[i], tmp, tmp2);
181
		if (err) {
Brice Videau's avatar
Brice Videau committed
182 183
			excit_free(tmp);
			excit_free(tmp2);
184 185 186 187 188 189
			goto error;
		}
	}
	return 0;
error:
	for (int i = 0; i < n; i++)
Brice Videau's avatar
Brice Videau committed
190
		excit_free(results[i]);
191 192 193
	return err;
}

Brice Videau's avatar
Brice Videau committed
194
static const struct excit_func_table_s excit_slice_func_table = {
195 196 197 198 199 200 201 202 203 204 205 206 207
	slice_iterator_alloc,
	slice_iterator_free,
	slice_iterator_copy,
	slice_iterator_next,
	slice_iterator_peek,
	slice_iterator_size,
	slice_iterator_rewind,
	slice_iterator_split,
	slice_iterator_nth,
	slice_iterator_n,
	slice_iterator_pos
};

Brice Videau's avatar
Brice Videau committed
208 209
int excit_slice_init(excit_t iterator, excit_t src,
			 excit_t indexer)
210
{
Brice Videau's avatar
Brice Videau committed
211
	if (!iterator || iterator->type != EXCIT_SLICE || !src || !indexer
212 213 214 215
	    || indexer->dimension != 1)
		return -EINVAL;
	struct slice_iterator_s *it =
	    (struct slice_iterator_s *) iterator->data;
Brice Videau's avatar
Brice Videau committed
216 217 218
	excit_index_t size_src;
	excit_index_t size_indexer;
	int err = excit_size(src, &size_src);
219 220 221

	if (err)
		return err;
Brice Videau's avatar
Brice Videau committed
222
	err = excit_size(indexer, &size_indexer);
223 224 225 226 227 228 229 230 231 232 233 234 235
	if (err)
		return err;
	if (size_indexer > size_src)
		return -EDOM;
	it->src = src;
	it->indexer = indexer;
	iterator->dimension = src->dimension;
	return 0;
}

/*--------------------------------------------------------------------*/

struct product_iterator_s {
Brice Videau's avatar
Brice Videau committed
236 237
	excit_index_t count;
	excit_t *iterators;
238 239
};

Brice Videau's avatar
Brice Videau committed
240
static int product_iterator_alloc(excit_t data)
241 242 243 244 245 246 247 248 249 250 251 252
{
	data->data = malloc(sizeof(struct product_iterator_s));
	if (!data->data)
		return -ENOMEM;
	struct product_iterator_s *iterator =
	    (struct product_iterator_s *) data->data;

	iterator->count = 0;
	iterator->iterators = NULL;
	return 0;
}

Brice Videau's avatar
Brice Videau committed
253
static void product_iterator_free(excit_t data)
254 255 256 257
{
	struct product_iterator_s *iterator =
	    (struct product_iterator_s *) data->data;
	if (iterator->iterators) {
Brice Videau's avatar
Brice Videau committed
258 259
		for (excit_index_t i = 0; i < iterator->count; i++)
			excit_free(iterator->iterators[i]);
260 261 262 263 264
		free(iterator->iterators);
	}
	free(data->data);
}

Brice Videau's avatar
Brice Videau committed
265
static int product_iterator_copy(excit_t dst, const excit_t src)
266 267 268 269 270 271 272
{
	const struct product_iterator_s *iterator =
	    (const struct product_iterator_s *)src->data;
	struct product_iterator_s *result =
	    (struct product_iterator_s *) dst->data;

	result->iterators =
Brice Videau's avatar
Brice Videau committed
273
	    (excit_t *) malloc(iterator->count * sizeof(excit_t));
274 275
	if (!result->iterators)
		return -ENOMEM;
Brice Videau's avatar
Brice Videau committed
276
	excit_index_t i;
277 278

	for (i = 0; i < iterator->count; i++) {
Brice Videau's avatar
Brice Videau committed
279
		result->iterators[i] = excit_dup(iterator->iterators[i]);
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
		if (!result->iterators[i]) {
			i--;
			goto error;
		}
	}
	result->count = iterator->count;
	return 0;
error:
	while (i >= 0) {
		free(result->iterators[i]);
		i--;
	}
	free(result->iterators);
	return -ENOMEM;
}

Brice Videau's avatar
Brice Videau committed
296
static int product_iterator_rewind(excit_t data)
297 298 299 300
{
	struct product_iterator_s *iterator =
	    (struct product_iterator_s *) data->data;

Brice Videau's avatar
Brice Videau committed
301 302
	for (excit_index_t i = 0; i < iterator->count; i++) {
		int err = excit_rewind(iterator->iterators[i]);
303 304 305 306 307 308 309

		if (err)
			return err;
	}
	return 0;
}

Brice Videau's avatar
Brice Videau committed
310 311
static int product_iterator_size(const excit_t data,
				 excit_index_t *size)
312 313 314
{
	const struct product_iterator_s *iterator =
	    (const struct product_iterator_s *) data->data;
Brice Videau's avatar
Brice Videau committed
315
	excit_index_t tmp_size = 0;
316 317 318 319 320 321 322

	if (!size)
		return -EINVAL;
	if (iterator->count == 0)
		*size = 0;
	else {
		*size = 1;
Brice Videau's avatar
Brice Videau committed
323
		for (excit_index_t i = 0; i < iterator->count; i++) {
324
			int err =
Brice Videau's avatar
Brice Videau committed
325
			    excit_size(iterator->iterators[i], &tmp_size);
326 327 328 329 330 331 332 333 334 335 336

			if (err) {
				*size = 0;
				return err;
			}
			*size *= tmp_size;
		}
	}
	return 0;
}

Brice Videau's avatar
Brice Videau committed
337 338
static int product_iterator_nth(const excit_t data, excit_index_t n,
				excit_index_t *indexes)
339
{
Brice Videau's avatar
Brice Videau committed
340
	excit_index_t size;
341 342 343 344 345 346 347 348 349 350
	int err = product_iterator_size(data, &size);

	if (err)
		return err;
	if (n < 0 || n >= size)
		return -EDOM;
	const struct product_iterator_s *iterator =
	    (const struct product_iterator_s *) data->data;

	if (indexes) {
Brice Videau's avatar
Brice Videau committed
351 352
		excit_index_t subsize = 0;
		excit_index_t offset = data->dimension;
353

Brice Videau's avatar
Brice Videau committed
354
		for (excit_index_t i = iterator->count - 1; i >= 0; i--) {
355
			offset -= iterator->iterators[i]->dimension;
Brice Videau's avatar
Brice Videau committed
356
			err = excit_size(iterator->iterators[i], &subsize);
357 358 359
			if (err)
				return err;
			err =
Brice Videau's avatar
Brice Videau committed
360
			    excit_nth(iterator->iterators[i], n % subsize,
361 362 363 364 365 366 367 368 369
					  indexes + offset);
			if (err)
				return err;
			n /= subsize;
		}
	}
	return 0;
}

Brice Videau's avatar
Brice Videau committed
370 371 372
static int product_iterator_n(const excit_t data,
			      const excit_index_t *indexes,
			      excit_index_t *n)
373 374 375 376 377 378
{
	const struct product_iterator_s *iterator =
	    (const struct product_iterator_s *) data->data;

	if (iterator->count == 0)
		return -EINVAL;
Brice Videau's avatar
Brice Videau committed
379 380 381 382
	excit_index_t offset = 0;
	excit_index_t product = 0;
	excit_index_t inner_n;
	excit_index_t subsize;
383

Brice Videau's avatar
Brice Videau committed
384
	for (excit_index_t i = 0; i < iterator->count; i++) {
385
		int err =
Brice Videau's avatar
Brice Videau committed
386
		    excit_n(iterator->iterators[i], indexes + offset,
387 388 389
				&inner_n);
		if (err)
			return err;
Brice Videau's avatar
Brice Videau committed
390
		err = excit_size(iterator->iterators[i], &subsize);
391 392 393 394 395 396 397 398 399 400 401
		if (err)
			return err;
		product *= subsize;
		product += inner_n;
		offset += iterator->iterators[i]->dimension;
	}
	if (n)
		*n = product;
	return 0;
}

Brice Videau's avatar
Brice Videau committed
402
static int product_iterator_pos(const excit_t data, excit_index_t *n)
403 404 405 406 407 408
{
	const struct product_iterator_s *iterator =
	    (const struct product_iterator_s *) data->data;

	if (iterator->count == 0)
		return -EINVAL;
Brice Videau's avatar
Brice Videau committed
409 410 411
	excit_index_t product = 0;
	excit_index_t inner_n;
	excit_index_t subsize;
412

Brice Videau's avatar
Brice Videau committed
413 414
	for (excit_index_t i = 0; i < iterator->count; i++) {
		int err = excit_pos(iterator->iterators[i], &inner_n);
415 416 417

		if (err)
			return err;
Brice Videau's avatar
Brice Videau committed
418
		err = excit_size(iterator->iterators[i], &subsize);
419 420 421 422 423 424 425 426 427 428
		if (err)
			return err;
		product *= subsize;
		product += inner_n;
	}
	if (n)
		*n = product;
	return 0;
}

Brice Videau's avatar
Brice Videau committed
429 430
static inline int product_iterator_peeknext_helper(excit_t data,
						   excit_index_t *indexes,
431 432 433 434 435 436
						   int next)
{
	struct product_iterator_s *iterator =
	    (struct product_iterator_s *) data->data;
	int err;
	int looped;
Brice Videau's avatar
Brice Videau committed
437 438 439
	excit_index_t i;
	excit_index_t *next_indexes;
	excit_index_t offset = data->dimension;
440 441 442 443 444 445 446 447 448 449 450 451

	if (iterator->count == 0)
		return -EINVAL;
	looped = next;
	for (i = iterator->count - 1; i > 0; i--) {
		if (indexes) {
			offset -= iterator->iterators[i]->dimension;
			next_indexes = indexes + offset;
		} else
			next_indexes = NULL;
		if (looped)
			err =
Brice Videau's avatar
Brice Videau committed
452
			    excit_cyclic_next(iterator->iterators[i],
453 454 455
						  next_indexes, &looped);
		else
			err =
Brice Videau's avatar
Brice Videau committed
456
			    excit_peek(iterator->iterators[i],
457 458 459 460 461 462 463 464 465 466
					   next_indexes);
		if (err)
			return err;
	}
	if (indexes) {
		offset -= iterator->iterators[i]->dimension;
		next_indexes = indexes + offset;
	} else
		next_indexes = NULL;
	if (looped)
Brice Videau's avatar
Brice Videau committed
467
		err = excit_next(iterator->iterators[0], next_indexes);
468
	else
Brice Videau's avatar
Brice Videau committed
469
		err = excit_peek(iterator->iterators[0], next_indexes);
470 471 472 473 474
	if (err)
		return err;
	return 0;
}

Brice Videau's avatar
Brice Videau committed
475 476
static int product_iterator_peek(const excit_t data,
				 excit_index_t *indexes)
477 478 479 480
{
	return product_iterator_peeknext_helper(data, indexes, 0);
}

Brice Videau's avatar
Brice Videau committed
481
static int product_iterator_next(excit_t data, excit_index_t *indexes)
482 483 484 485
{
	return product_iterator_peeknext_helper(data, indexes, 1);
}

Brice Videau's avatar
Brice Videau committed
486 487
static int product_iterator_split(const excit_t data, excit_index_t n,
				  excit_t *results)
488
{
Brice Videau's avatar
Brice Videau committed
489
	excit_index_t size;
490 491 492 493 494 495 496 497
	int err = product_iterator_size(data, &size);

	if (err)
		return err;
	if (size < n)
		return -EDOM;
	if (!results)
		return 0;
Brice Videau's avatar
Brice Videau committed
498
	excit_t range = excit_alloc(EXCIT_RANGE);
499 500 501

	if (!range)
		return -ENOMEM;
Brice Videau's avatar
Brice Videau committed
502
	err = excit_range_init(range, 0, size - 1, 1);
503 504
	if (err)
		goto error1;
Brice Videau's avatar
Brice Videau committed
505
	err = excit_split(range, n, results);
506 507 508
	if (err)
		goto error1;
	for (int i = 0; i < n; i++) {
Brice Videau's avatar
Brice Videau committed
509
		excit_t tmp, tmp2;
510

Brice Videau's avatar
Brice Videau committed
511
		tmp = excit_dup(data);
512 513 514
		if (!tmp)
			goto error2;
		tmp2 = results[i];
Brice Videau's avatar
Brice Videau committed
515
		results[i] = excit_alloc(EXCIT_SLICE);
516
		if (!results[i]) {
Brice Videau's avatar
Brice Videau committed
517
			excit_free(tmp2);
518 519
			goto error2;
		}
Brice Videau's avatar
Brice Videau committed
520
		err = excit_slice_init(results[i], tmp, tmp2);
521
		if (err) {
Brice Videau's avatar
Brice Videau committed
522
			excit_free(tmp2);
523 524 525
			goto error2;
		}
	}
Brice Videau's avatar
Brice Videau committed
526
	excit_free(range);
527 528 529
	return 0;
error2:
	for (int i = 0; i < n; i++)
Brice Videau's avatar
Brice Videau committed
530
		excit_free(results[i]);
531
error1:
Brice Videau's avatar
Brice Videau committed
532
	excit_free(range);
533 534 535
	return err;
}

Brice Videau's avatar
Brice Videau committed
536 537
int excit_product_count(const excit_t iterator,
			    excit_index_t *count)
538
{
Brice Videau's avatar
Brice Videau committed
539
	if (!iterator || iterator->type != EXCIT_PRODUCT || !count)
540 541 542 543 544
		return -EINVAL;
	*count = ((struct product_iterator_s *) iterator->data)->count;
	return 0;
}

Brice Videau's avatar
Brice Videau committed
545 546 547
int excit_product_split_dim(const excit_t iterator,
				excit_index_t dim, excit_index_t n,
				excit_t *results)
548
{
Brice Videau's avatar
Brice Videau committed
549
	if (!iterator || iterator->type != EXCIT_PRODUCT)
550 551 552
		return -EINVAL;
	if (n <= 0)
		return -EDOM;
Brice Videau's avatar
Brice Videau committed
553 554
	excit_index_t count;
	int err = excit_product_count(iterator, &count);
555 556 557 558 559 560 561 562

	if (err)
		return err;
	if (dim >= count)
		return -EDOM;
	struct product_iterator_s *product_iterator =
	    (struct product_iterator_s *) iterator->data;

Brice Videau's avatar
Brice Videau committed
563
	err = excit_split(product_iterator->iterators[dim], n, results);
564 565 566 567 568
	if (err)
		return err;
	if (!results)
		return 0;
	for (int i = 0; i < n; i++) {
Brice Videau's avatar
Brice Videau committed
569
		excit_t tmp = results[i];
570

Brice Videau's avatar
Brice Videau committed
571
		results[i] = excit_dup(iterator);
572
		if (!tmp) {
Brice Videau's avatar
Brice Videau committed
573
			excit_free(tmp);
574 575 576 577 578
			err = -ENOMEM;
			goto error;
		}
		struct product_iterator_s *new_product_iterator =
		    (struct product_iterator_s *) results[i]->data;
Brice Videau's avatar
Brice Videau committed
579
		excit_free(new_product_iterator->iterators[dim]);
580 581 582 583 584
		new_product_iterator->iterators[dim] = tmp;
	}
	return 0;
error:
	for (int i = 0; i < n; i++)
Brice Videau's avatar
Brice Videau committed
585
		excit_free(results[i]);
586 587 588
	return err;
}

Brice Videau's avatar
Brice Videau committed
589
int excit_product_add_copy(excit_t iterator, excit_t added_iterator)
590 591
{
	int err = 0;
Brice Videau's avatar
Brice Videau committed
592
	excit_t copy = excit_dup(added_iterator);
593 594 595

	if (!copy)
		return -EINVAL;
Brice Videau's avatar
Brice Videau committed
596
	err = excit_product_add(iterator, copy);
597
	if (err) {
Brice Videau's avatar
Brice Videau committed
598
		excit_free(added_iterator);
599 600 601 602 603
		return err;
	}
	return 0;
}

Brice Videau's avatar
Brice Videau committed
604
int excit_product_add(excit_t iterator, excit_t added_iterator)
605
{
Brice Videau's avatar
Brice Videau committed
606
	if (!iterator || iterator->type != EXCIT_PRODUCT || !iterator->data
607 608 609 610 611
	    || !added_iterator)
		return -EINVAL;

	struct product_iterator_s *product_iterator =
	    (struct product_iterator_s *) iterator->data;
Brice Videau's avatar
Brice Videau committed
612
	excit_index_t mew_count = product_iterator->count + 1;
613

Brice Videau's avatar
Brice Videau committed
614 615 616
	excit_t *new_its =
	    (excit_t *) realloc(product_iterator->iterators,
				    mew_count * sizeof(excit_t));
617 618 619 620 621 622 623 624 625
	if (!new_its)
		return -ENOMEM;
	product_iterator->iterators = new_its;
	product_iterator->iterators[product_iterator->count] = added_iterator;
	product_iterator->count = mew_count;
	iterator->dimension += added_iterator->dimension;
	return 0;
}

Brice Videau's avatar
Brice Videau committed
626
static const struct excit_func_table_s excit_product_func_table = {
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
	product_iterator_alloc,
	product_iterator_free,
	product_iterator_copy,
	product_iterator_next,
	product_iterator_peek,
	product_iterator_size,
	product_iterator_rewind,
	product_iterator_split,
	product_iterator_nth,
	product_iterator_n,
	product_iterator_pos
};

/*--------------------------------------------------------------------*/

struct circular_fifo_s {
Brice Videau's avatar
Brice Videau committed
643 644 645 646 647
	excit_index_t length;
	excit_index_t start;
	excit_index_t end;
	excit_index_t size;
	excit_index_t *buffer;
648 649 650
};

static void circular_fifo_add(struct circular_fifo_s *fifo,
Brice Videau's avatar
Brice Videau committed
651
			      excit_index_t elem)
652 653 654 655 656 657 658 659 660 661 662 663
{
	if (fifo->size == fifo->length) {
		fifo->start = (fifo->start + 1) % fifo->length;
		fifo->end = (fifo->end + 1) % fifo->length;
	} else {
		fifo->end = (fifo->end + 1) % fifo->length;
		fifo->size++;
	}
	fifo->buffer[fifo->end] = elem;
}

static void circular_fifo_dump(const struct circular_fifo_s *fifo,
Brice Videau's avatar
Brice Videau committed
664
			       excit_index_t *vals)
665
{
Brice Videau's avatar
Brice Videau committed
666 667
	excit_index_t i;
	excit_index_t j;
668 669 670 671 672 673 674 675

	for (i = 0, j = fifo->start; i < fifo->size; i++) {
		vals[i] = fifo->buffer[j];
		j = (j + 1) % fifo->length;
	}
}

struct cons_iterator_s {
Brice Videau's avatar
Brice Videau committed
676 677
	excit_t iterator;
	excit_index_t n;
678 679 680
	struct circular_fifo_s fifo;
};

Brice Videau's avatar
Brice Videau committed
681
static int cons_iterator_alloc(excit_t data)
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698
{
	data->data = malloc(sizeof(struct cons_iterator_s));
	if (!data->data)
		return -ENOMEM;
	struct cons_iterator_s *iterator =
	    (struct cons_iterator_s *) data->data;

	iterator->iterator = NULL;
	iterator->n = 0;
	iterator->fifo.length = 0;
	iterator->fifo.start = 0;
	iterator->fifo.end = -1;
	iterator->fifo.size = 0;
	iterator->fifo.buffer = NULL;
	return 0;
}

Brice Videau's avatar
Brice Videau committed
699
static void cons_iterator_free(excit_t data)
700 701 702 703
{
	struct cons_iterator_s *iterator =
	    (struct cons_iterator_s *) data->data;

Brice Videau's avatar
Brice Videau committed
704
	excit_free(iterator->iterator);
705 706 707 708
	free(iterator->fifo.buffer);
	free(data->data);
}

Brice Videau's avatar
Brice Videau committed
709
static int cons_iterator_copy(excit_t ddst, const excit_t dsrc)
710 711 712 713
{
	struct cons_iterator_s *dst = (struct cons_iterator_s *) ddst->data;
	const struct cons_iterator_s *src =
	    (const struct cons_iterator_s *)dsrc->data;
Brice Videau's avatar
Brice Videau committed
714
	excit_t copy = excit_dup(src->iterator);
715 716 717 718 719 720 721 722 723 724

	if (!copy)
		return -EINVAL;
	dst->iterator = copy;
	dst->n = src->n;
	dst->fifo.length = src->fifo.length;
	dst->fifo.start = src->fifo.start;
	dst->fifo.end = src->fifo.end;
	dst->fifo.size = src->fifo.size;
	dst->fifo.buffer =
Brice Videau's avatar
Brice Videau committed
725 726
	    (excit_index_t *) malloc(src->fifo.length *
					 sizeof(excit_index_t));
727
	if (!dst->fifo.buffer) {
Brice Videau's avatar
Brice Videau committed
728
		excit_free(copy);
729 730 731 732 733 734 735
		return -ENOMEM;
	}
	for (int i = 0; i < dst->fifo.length; i++)
		dst->fifo.buffer[i] = src->fifo.buffer[i];
	return 0;
}

Brice Videau's avatar
Brice Videau committed
736
static int cons_iterator_size(const excit_t data, excit_index_t *size)
737 738 739
{
	const struct cons_iterator_s *iterator =
	    (const struct cons_iterator_s *)data->data;
Brice Videau's avatar
Brice Videau committed
740 741
	excit_index_t tmp_size = 0;
	int err = excit_size(iterator->iterator, &tmp_size);
742 743 744 745 746 747 748

	if (err)
		return err;
	*size = tmp_size - (iterator->n - 1);
	return 0;
}

Brice Videau's avatar
Brice Videau committed
749 750
static int cons_iterator_split(const excit_t data, excit_index_t n,
			       excit_t *results)
751
{
Brice Videau's avatar
Brice Videau committed
752
	excit_index_t size;
753 754 755 756 757 758 759 760
	int err = cons_iterator_size(data, &size);

	if (err)
		return err;
	if (size < n)
		return -EDOM;
	if (!results)
		return 0;
Brice Videau's avatar
Brice Videau committed
761
	excit_t range = excit_alloc(EXCIT_RANGE);
762 763 764

	if (!range)
		return -ENOMEM;
Brice Videau's avatar
Brice Videau committed
765
	err = excit_range_init(range, 0, size - 1, 1);
766 767
	if (err)
		goto error1;
Brice Videau's avatar
Brice Videau committed
768
	err = excit_split(range, n, results);
769 770 771 772 773
	if (err)
		goto error1;
	int i;

	for (i = 0; i < n; i++) {
Brice Videau's avatar
Brice Videau committed
774
		excit_t tmp, tmp2;
775

Brice Videau's avatar
Brice Videau committed
776
		tmp = excit_dup(data);
777 778 779
		if (!tmp)
			goto error2;
		tmp2 = results[i];
Brice Videau's avatar
Brice Videau committed
780
		results[i] = excit_alloc(EXCIT_SLICE);
781
		if (!results[i]) {
Brice Videau's avatar
Brice Videau committed
782
			excit_free(tmp2);
783 784
			goto error2;
		}
Brice Videau's avatar
Brice Videau committed
785
		err = excit_slice_init(results[i], tmp, tmp2);
786
		if (err) {
Brice Videau's avatar
Brice Videau committed
787
			excit_free(tmp2);
788 789 790
			goto error2;
		}
	}
Brice Videau's avatar
Brice Videau committed
791
	excit_free(range);
792 793 794
	return 0;
error2:
	for (; i >= 0; i--)
Brice Videau's avatar
Brice Videau committed
795
		excit_free(results[i]);
796
error1:
Brice Videau's avatar
Brice Videau committed
797
	excit_free(range);
798 799 800
	return err;
}

Brice Videau's avatar
Brice Videau committed
801 802
static int cons_iterator_nth(const excit_t data, excit_index_t n,
			     excit_index_t *indexes)
803
{
Brice Videau's avatar
Brice Videau committed
804
	excit_index_t size;
805 806 807 808 809 810 811 812 813 814 815 816 817
	int err = cons_iterator_size(data, &size);

	if (err)
		return err;
	if (n < 0 || n >= size)
		return -EDOM;
	const struct cons_iterator_s *iterator =
	    (const struct cons_iterator_s *) data->data;
	int dim = iterator->iterator->dimension;

	if (indexes) {
		for (int i = 0; i < iterator->n; i++) {
			err =
Brice Videau's avatar
Brice Videau committed
818
			    excit_nth(iterator->iterator, n + i,
819 820 821 822 823 824 825 826
					  indexes + dim * i);
			if (err)
				return err;
		}
	}
	return 0;
}

Brice Videau's avatar
Brice Videau committed
827 828 829
static int cons_iterator_n(const excit_t data,
			   const excit_index_t *indexes,
			   excit_index_t *n)
830 831 832
{
	const struct cons_iterator_s *iterator =
	    (const struct cons_iterator_s *) data->data;
Brice Videau's avatar
Brice Videau committed
833 834
	excit_index_t inner_n, inner_n_tmp;
	int err = excit_n(iterator->iterator, indexes, &inner_n);
835 836 837 838 839 840 841

	if (err)
		return err;
	int dim = iterator->iterator->dimension;

	for (int i = 1; i < iterator->n; i++) {
		err =
Brice Videau's avatar
Brice Videau committed
842
		    excit_n(iterator->iterator, indexes + dim * i,
843 844 845 846 847 848 849 850 851 852 853 854
				&inner_n_tmp);
		if (err)
			return err;
		if (inner_n_tmp != inner_n + 1)
			return -EINVAL;
		inner_n = inner_n_tmp;
	}
	if (n)
		*n = inner_n - (iterator->n - 1);
	return 0;
}

Brice Videau's avatar
Brice Videau committed
855
static int cons_iterator_pos(const excit_t data, excit_index_t *n)
856
{
Brice Videau's avatar
Brice Videau committed
857
	excit_index_t inner_n;
858 859
	const struct cons_iterator_s *iterator =
	    (const struct cons_iterator_s *) data->data;
Brice Videau's avatar
Brice Videau committed
860
	int err = excit_pos(iterator->iterator, &inner_n);
861 862 863 864 865 866 867 868

	if (err)
		return err;
	if (n)
		*n = inner_n - (iterator->n - 1);
	return 0;
}

Brice Videau's avatar
Brice Videau committed
869 870
static int cons_iterator_peek(const excit_t data,
			      excit_index_t *indexes)
871 872 873 874 875 876 877 878 879 880
{
	const struct cons_iterator_s *iterator =
	    (const struct cons_iterator_s *) data->data;
	int err;
	int dim = iterator->iterator->dimension;
	int n = iterator->n;

	if (indexes) {
		circular_fifo_dump(&iterator->fifo, indexes);
		err =
Brice Videau's avatar
Brice Videau committed
881
		    excit_peek(iterator->iterator, indexes + dim * (n - 1));
882
	} else
Brice Videau's avatar
Brice Videau committed
883
		err = excit_peek(iterator->iterator, NULL);
884 885 886 887 888
	if (err)
		return err;
	return 0;
}

Brice Videau's avatar
Brice Videau committed
889
static int cons_iterator_next(excit_t data, excit_index_t *indexes)
890 891 892 893 894 895 896 897 898 899
{
	struct cons_iterator_s *iterator =
	    (struct cons_iterator_s *) data->data;
	int err;
	int dim = iterator->iterator->dimension;
	int n = iterator->n;

	if (indexes) {
		circular_fifo_dump(&iterator->fifo, indexes);
		err =
Brice Videau's avatar
Brice Videau committed
900
		    excit_next(iterator->iterator, indexes + dim * (n - 1));
901
	} else
Brice Videau's avatar
Brice Videau committed
902
		err = excit_next(iterator->iterator, NULL);
903 904 905 906 907 908 909 910
	if (err)
		return err;
	if (indexes)
		for (int i = dim * (n - 1); i < dim * n; i++)
			circular_fifo_add(&iterator->fifo, indexes[i]);
	return 0;
}

Brice Videau's avatar
Brice Videau committed
911
static int cons_iterator_rewind(excit_t data)
912 913 914
{
	struct cons_iterator_s *iterator =
	    (struct cons_iterator_s *) data->data;
Brice Videau's avatar
Brice Videau committed
915
	int err = excit_rewind(iterator->iterator);
916 917 918 919 920 921 922 923 924 925 926

	if (err)
		return err;
	iterator->fifo.start = 0;
	iterator->fifo.end = -1;
	iterator->fifo.size = 0;

	for (int i = 0; i < iterator->n - 1; i++) {
		int err;

		err =
Brice Videau's avatar
Brice Videau committed
927
		    excit_next(iterator->iterator,
928 929 930 931 932 933 934 935 936 937
				   iterator->fifo.buffer +
				   iterator->iterator->dimension * i);
		if (err)
			return err;
		iterator->fifo.size += iterator->iterator->dimension;
		iterator->fifo.end += iterator->iterator->dimension;
	}
	return 0;
}

Brice Videau's avatar
Brice Videau committed
938 939
int excit_cons_init(excit_t iterator, excit_t src,
			excit_index_t n)
940
{
Brice Videau's avatar
Brice Videau committed
941
	excit_index_t src_size;
942 943
	int err;

Brice Videau's avatar
Brice Videau committed
944
	if (!iterator || iterator->type != EXCIT_CONS || !src || n <= 0)
945
		return -EINVAL;
Brice Videau's avatar
Brice Videau committed
946
	err = excit_size(src, &src_size);
947 948 949 950 951 952 953 954
	if (err)
		return err;
	if (src_size < n)
		return -EINVAL;
	struct cons_iterator_s *cons_iterator =
	    (struct cons_iterator_s *) iterator->data;

	free(cons_iterator->fifo.buffer);
Brice Videau's avatar
Brice Videau committed
955
	excit_free(cons_iterator->iterator);
956 957 958 959 960
	iterator->dimension = n * src->dimension;
	cons_iterator->iterator = src;
	cons_iterator->n = n;
	cons_iterator->fifo.length = src->dimension * (n - 1);
	cons_iterator->fifo.buffer =
Brice Videau's avatar
Brice Videau committed
961 962
	    (excit_index_t *) malloc(cons_iterator->fifo.length *
					 sizeof(excit_index_t));
963 964 965 966 967 968 969 970 971 972
	if (!cons_iterator->fifo.buffer)
		return -ENOMEM;
	err = cons_iterator_rewind(iterator);
	if (err) {
		free(cons_iterator->fifo.buffer);
		return err;
	}
	return 0;
}

Brice Videau's avatar
Brice Videau committed
973
static const struct excit_func_table_s excit_cons_func_table = {
974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989
	cons_iterator_alloc,
	cons_iterator_free,
	cons_iterator_copy,
	cons_iterator_next,
	cons_iterator_peek,
	cons_iterator_size,
	cons_iterator_rewind,
	cons_iterator_split,
	cons_iterator_nth,
	cons_iterator_n,
	cons_iterator_pos
};

/*--------------------------------------------------------------------*/

struct repeat_iterator_s {
Brice Videau's avatar
Brice Videau committed
990 991 992
	excit_t iterator;
	excit_index_t n;
	excit_index_t counter;
993 994
};

Brice Videau's avatar
Brice Videau committed
995
static int repeat_iterator_alloc(excit_t data)
996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008
{
	data->data = malloc(sizeof(struct repeat_iterator_s));
	if (!data->data)
		return -ENOMEM;
	struct repeat_iterator_s *iterator =
	    (struct repeat_iterator_s *) data->data;

	iterator->iterator = NULL;
	iterator->n = 0;
	iterator->counter = 0;
	return 0;
}

Brice Videau's avatar
Brice Videau committed
1009
static void repeat_iterator_free(excit_t data)
1010 1011 1012 1013
{
	struct repeat_iterator_s *iterator =
	    (struct repeat_iterator_s *) data->data;

Brice Videau's avatar
Brice Videau committed
1014
	excit_free(iterator->iterator);
1015 1016 1017
	free(data->data);
}

Brice Videau's avatar
Brice Videau committed
1018
static int repeat_iterator_copy(excit_t ddst, const excit_t dsrc)
1019 1020 1021 1022
{
	struct repeat_iterator_s *dst = (struct repeat_iterator_s *) ddst->data;
	const struct repeat_iterator_s *src =
	    (const struct repeat_iterator_s *)dsrc->data;
Brice Videau's avatar
Brice Videau committed
1023
	excit_t copy = excit_dup(src->iterator);
1024 1025 1026 1027 1028 1029 1030 1031 1032

	if (!copy)
		return -EINVAL;
	dst->iterator = copy;
	dst->n = src->n;
	dst->counter = src->counter;
	return 0;
}

Brice Videau's avatar
Brice Videau committed
1033 1034
static int repeat_iterator_peek(const excit_t data,
				excit_index_t *indexes)
1035 1036 1037 1038
{
	const struct repeat_iterator_s *iterator =
	    (const struct repeat_iterator_s *) data->data;

Brice Videau's avatar
Brice Videau committed
1039
	return excit_peek(iterator->iterator, indexes);
1040 1041
}

Brice Videau's avatar
Brice Videau committed
1042
static int repeat_iterator_next(excit_t data, excit_index_t *indexes)
1043 1044 1045 1046 1047 1048
{
	struct repeat_iterator_s *iterator =
	    (struct repeat_iterator_s *) data->data;

	iterator->counter++;
	if (iterator->counter < iterator->n)
Brice Videau's avatar
Brice Videau committed
1049
		return excit_peek(iterator->iterator, indexes);
1050
	iterator->counter = 0;
Brice Videau's avatar
Brice Videau committed
1051
	return excit_next(iterator->iterator, indexes);
1052 1053
}

Brice Videau's avatar
Brice Videau committed
1054 1055
static int repeat_iterator_size(const excit_t data,
				excit_index_t *size)
1056 1057 1058
{
	const struct repeat_iterator_s *iterator =
	    (const struct repeat_iterator_s *) data->data;
Brice Videau's avatar
Brice Videau committed
1059
	int err = excit_size(iterator->iterator, size);
1060 1061 1062 1063 1064 1065 1066

	if (err)
		return err;
	*size *= iterator->n;
	return 0;
}

Brice Videau's avatar
Brice Videau committed
1067
static int repeat_iterator_rewind(excit_t data)
1068 1069 1070 1071 1072
{
	struct repeat_iterator_s *iterator =
	    (struct repeat_iterator_s *) data->data;

	iterator->counter = 0;
Brice Videau's avatar
Brice Videau committed
1073
	return excit_rewind(iterator->iterator);
1074 1075
}

Brice Videau's avatar
Brice Videau committed
1076 1077
static int repeat_iterator_nth(const excit_t data, excit_index_t n,
			       excit_index_t *val)
1078
{
Brice Videau's avatar
Brice Videau committed
1079
	excit_index_t size;
1080 1081 1082 1083 1084 1085 1086 1087 1088
	int err = repeat_iterator_size(data, &size);

	if (err)
		return err;
	if (n < 0 || n >= size)
		return -EDOM;
	const struct repeat_iterator_s *iterator =
	    (const struct repeat_iterator_s *) data->data;

Brice Videau's avatar
Brice Videau committed
1089
	return excit_nth(iterator->iterator, n / iterator->n, val);
1090 1091
}

Brice Videau's avatar
Brice Videau committed
1092
static int repeat_iterator_pos(const excit_t data, excit_index_t *n)
1093
{
Brice Videau's avatar
Brice Videau committed
1094
	excit_index_t inner_n;
1095 1096
	const struct repeat_iterator_s *iterator =
	    (const struct repeat_iterator_s *) data->data;
Brice Videau's avatar
Brice Videau committed
1097
	int err = excit_pos(iterator->iterator, &inner_n);
1098 1099 1100 1101 1102 1103 1104 1105

	if (err)
		return err;
	if (n)
		*n = inner_n * iterator->n + iterator->counter;
	return 0;
}

Brice Videau's avatar
Brice Videau committed
1106 1107
static int repeat_iterator_split(const excit_t data, excit_index_t n,
				 excit_t *results)
1108 1109 1110
{
	const struct repeat_iterator_s *iterator =
	    (const struct repeat_iterator_s *) data->data;
Brice Videau's avatar
Brice Videau committed
1111
	int err = excit_split(iterator->iterator, n, results);
1112 1113 1114 1115 1116 1117

	if (err)
		return err;
	if (!results)
		return 0;
	for (int i = 0; i < n; i++) {
Brice Videau's avatar
Brice Videau committed
1118
		excit_t tmp;
1119 1120

		tmp = results[i];
Brice Videau's avatar
Brice Videau committed
1121
		results[i] = excit_alloc(EXCIT_REPEAT);
1122
		if (!results[i]) {
Brice Videau's avatar
Brice Videau committed
1123
			excit_free(tmp);
1124 1125 1126
			err = -ENOMEM;
			goto error;
		}
Brice Videau's avatar
Brice Videau committed
1127
		err = excit_repeat_init(results[i], tmp, iterator->n);
1128 1129 1130 1131 1132 1133
		if (err)
			goto error;
	}
	return 0;
error:
	for (int i = 0; i < n; i++)
Brice Videau's avatar
Brice Videau committed
1134
		excit_free(results[i]);
1135 1136 1137
	return err;
}

Brice Videau's avatar
Brice Videau committed
1138
static const struct excit_func_table_s excit_repeat_func_table = {
1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151
	repeat_iterator_alloc,
	repeat_iterator_free,
	repeat_iterator_copy,
	repeat_iterator_next,
	repeat_iterator_peek,
	repeat_iterator_size,
	repeat_iterator_rewind,
	repeat_iterator_split,
	repeat_iterator_nth,
	NULL,
	repeat_iterator_pos
};

Brice Videau's avatar
Brice Videau committed
1152 1153
int excit_repeat_init(excit_t iterator, excit_t src,
			  excit_index_t n)
1154
{
Brice Videau's avatar
Brice Videau committed
1155
	if (!iterator || iterator->type != EXCIT_REPEAT || !src || n <= 0)
1156 1157 1158
		return -EINVAL;
	struct repeat_iterator_s *repeat_iterator =
	    (struct repeat_iterator_s *) iterator->data;
Brice Videau's avatar
Brice Videau committed
1159
	excit_free(repeat_iterator->iterator);
1160 1161 1162 1163 1164 1165 1166 1167 1168 1169
	iterator->dimension = src->dimension;
	repeat_iterator->iterator = src;
	repeat_iterator->n = n;
	repeat_iterator->counter = 0;
	return 0;
}

/*--------------------------------------------------------------------*/

struct hilbert2d_iterator_s {
Brice Videau's avatar
Brice Videau committed
1170 1171
	excit_index_t n;
	excit_t range_iterator;
1172 1173 1174 1175 1176
};

/* Helper functions from: https://en.wikipedia.org/wiki/Hilbert_curve */

//rotate/flip a quadrant appropriately
Brice Videau's avatar
Brice Videau committed
1177 1178 1179
static void rot(excit_index_t n, excit_index_t *x,
		excit_index_t *y, excit_index_t rx,
		excit_index_t ry)
1180 1181 1182 1183 1184 1185 1186
{
	if (ry == 0) {
		if (rx == 1) {
			*x = n - 1 - *x;
			*y = n - 1 - *y;
		}
		//Swap x and y
Brice Videau's avatar
Brice Videau committed
1187
		excit_index_t t = *x;
1188 1189 1190 1191 1192 1193 1194

		*x = *y;
		*y = t;
	}
}

//convert (x,y) to d
Brice Videau's avatar
Brice Videau committed
1195 1196
static excit_index_t xy2d(excit_index_t n, excit_index_t x,
			      excit_index_t y)
1197
{
Brice Videau's avatar
Brice Videau committed
1198
	excit_index_t rx, ry, s, d = 0;
1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209

	for (s = n / 2; s > 0; s /= 2) {
		rx = (x & s) > 0;
		ry = (y & s) > 0;
		d += s * s * ((3 * rx) ^ ry);
		rot(s, &x, &y, rx, ry);
	}
	return d;
}

//convert d to (x,y)
Brice Videau's avatar
Brice Videau committed
1210 1211
static void d2xy(excit_index_t n, excit_index_t d,
		 excit_index_t *x, excit_index_t *y)
1212
{
Brice Videau's avatar
Brice Videau committed
1213
	excit_index_t rx, ry, s, t = d;
1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227

	*x = *y = 0;
	for (s = 1; s < n; s *= 2) {
		rx = 1 & (t / 2);
		ry = 1 & (t ^ rx);
		rot(s, x, y, rx, ry);
		*x += s * rx;
		*y += s * ry;
		t /= 4;
	}
}

/* End helper functions */

Brice Videau's avatar
Brice Videau committed
1228
static int hilbert2d_iterator_alloc(excit_t data)
1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240
{
	data->data = malloc(sizeof(struct hilbert2d_iterator_s));
	if (!data->data)
		return -ENOMEM;
	struct hilbert2d_iterator_s *iterator =
	    (struct hilbert2d_iterator_s *) data->data;

	iterator->n = 0;
	iterator->range_iterator = NULL;
	return 0;
}

Brice Videau's avatar
Brice Videau committed
1241
static void hilbert2d_iterator_free(excit_t data)
1242 1243 1244 1245
{
	struct hilbert2d_iterator_s *iterator =
	    (struct hilbert2d_iterator_s *) data->data;

Brice Videau's avatar
Brice Videau committed
1246
	excit_free(iterator->range_iterator);
1247 1248 1249
	free(data->data);
}

Brice Videau's avatar
Brice Videau committed
1250
static int hilbert2d_iterator_copy(excit_t ddst, const excit_t dsrc)
1251 1252 1253 1254 1255
{
	struct hilbert2d_iterator_s *dst =
	    (struct hilbert2d_iterator_s *) ddst->data;
	const struct hilbert2d_iterator_s *src =
	    (const struct hilbert2d_iterator_s *)dsrc->data;
Brice Videau's avatar
Brice Videau committed
1256
	excit_t copy = excit_dup(src->range_iterator);