excit.c 6.49 KB
Newer Older
1
#include <stdlib.h>
2 3 4 5 6 7 8 9
#include "excit.h"
#include "slice.h"
#include "range.h"
#include "repeat.h"
#include "prod.h"
#include "cons.h"
#include "hilbert2d.h"
#include "tleaf.h"
10

11 12 13 14
#define CASE(val) case val: return #val; break;

const char * excit_type_name(enum excit_type_e type)
{
15 16 17 18 19 20 21 22 23 24 25 26 27
  switch (type) {
    CASE(EXCIT_RANGE)
      CASE(EXCIT_CONS)
      CASE(EXCIT_REPEAT)
      CASE(EXCIT_HILBERT2D)
      CASE(EXCIT_PRODUCT)
      CASE(EXCIT_SLICE)
      CASE(EXCIT_TLEAF)
      CASE(EXCIT_USER)
      CASE(EXCIT_TYPE_MAX)
  default:
    return NULL;
  }
28 29 30 31
}

const char * excit_error_name(enum excit_error_e err)
{
32 33 34 35 36 37 38 39 40 41 42
  switch (err) {
    CASE(EXCIT_SUCCESS)
      CASE(EXCIT_STOPIT)
      CASE(EXCIT_ENOMEM)
      CASE(EXCIT_EINVAL)
      CASE(EXCIT_EDOM)
      CASE(EXCIT_ENOTSUP)
      CASE(EXCIT_ERROR_MAX)
  default:
    return NULL;
  }
43 44 45 46
}

#undef CASE

47
struct excit_s {
48 49 50 51
  struct excit_func_table_s *func_table;
  ssize_t dimension;
  enum excit_type_e type;
  void *data;
52 53 54 55
};

int excit_set_dimension(excit_t it, ssize_t dimension)
{
56 57 58 59 60 61
  if (!it)
    return -EXCIT_EINVAL;
  /* if (it->type != EXCIT_USER) */
  /* 	return -EXCIT_ENOTSUP; */
  it->dimension = dimension;
  return EXCIT_SUCCESS;
62 63
}

64
ssize_t excit_get_dimension(excit_t it)
65
{
66 67 68 69 70 71
  if(it)
  {
    return it->dimension;
  } else {
    return -1;
  }   
72 73
}

74
int excit_get_data(excit_t it, void **data)
75
{
76 77 78 79 80 81
  if (!it)
    return -EXCIT_EINVAL;
  /* if (it->type != EXCIT_USER) */
  /* 	return -EXCIT_ENOTSUP; */ // WHY !!!
  *data = it->data;
  return EXCIT_SUCCESS;
82 83
}

84
int excit_set_func_table(excit_t it, struct excit_func_table_s *func_table)
85
{
86 87 88 89
  if (!it)
    return -EXCIT_EINVAL;
  it->func_table = func_table;
  return EXCIT_SUCCESS;
90 91
}

92
int excit_get_func_table(excit_t it, struct excit_func_table_s **func_table)
93
{
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
  if (!it)
    return -EXCIT_EINVAL;
  *func_table = it->func_table;
  return EXCIT_SUCCESS;
}

#define ALLOC_EXCIT(op) {						\
    it = malloc(sizeof(struct excit_s) + sizeof(struct op## _it_s));	\
    if (!it)								\
      return NULL;							\
    it->data = (void *)((char *)it + sizeof(struct excit_s));		\
    if (!excit_ ##op## _func_table.alloc)				\
      goto error;							\
    it->func_table = &excit_ ##op## _func_table;			\
    it->dimension = 0;							\
    if (excit_ ##op## _func_table.alloc(it))				\
      goto error;							\
  }
112

113
excit_t excit_alloc(enum excit_type_e type)
114
{
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
  excit_t it = NULL;

  switch (type) {
  case EXCIT_RANGE:
    ALLOC_EXCIT(range);
    break;
  case EXCIT_CONS:
    ALLOC_EXCIT(cons);
    break;
  case EXCIT_REPEAT:
    ALLOC_EXCIT(repeat);
    break;
  case EXCIT_HILBERT2D:
    ALLOC_EXCIT(hilbert2d);
    break;
  case EXCIT_PRODUCT:
    ALLOC_EXCIT(prod);
    break;
  case EXCIT_SLICE:
    ALLOC_EXCIT(slice);
    break;
  case EXCIT_TLEAF:
    ALLOC_EXCIT(tleaf);
    break;
  default:
    goto error;
  }
  it->type = type;
  return it;
144
error:
145 146
  free(it);
  return NULL;
147 148
}

149 150
excit_t excit_alloc_user(struct excit_func_table_s *func_table,
			 size_t data_size)
151
{
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
  excit_t it;

  if (!func_table || !data_size)
    return NULL;
  it = malloc(sizeof(struct excit_s) + data_size);
  if (!it)
    return NULL;
  it->data = (void *)((char *)it + sizeof(struct excit_s));
  if (!func_table->alloc)
    goto error;
  it->func_table = func_table;
  it->dimension = 0;
  it->type = EXCIT_USER;
  if (func_table->alloc(it))
    goto error;
  return it;
168
error:
169 170
  free(it);
  return NULL;
171 172
}

173
excit_t excit_dup(excit_t it)
174
{
175 176 177 178 179 180 181 182 183 184 185 186
  excit_t result = NULL;

  if (!it || !it->data || !it->func_table
      || !it->func_table->copy)
    return NULL;
  result = excit_alloc(it->type);
  if (!result)
    return NULL;
  result->dimension = it->dimension;
  if (it->func_table->copy(result, it))
    goto error;
  return result;
187
error:
188 189
  excit_free(result);
  return NULL;
190 191
}

192
void excit_free(excit_t it)
193
{
194 195 196 197 198 199
  if (!it)
    return;
  if (!it->func_table)
    goto error;
  if (it->func_table->free)
    it->func_table->free(it);
200
error:
201
  free(it);
202 203
}

204
int excit_dimension(excit_t it, ssize_t *dimension)
205
{
206 207 208 209
  if (!it || !dimension)
    return -EXCIT_EINVAL;
  *dimension = it->dimension;
  return EXCIT_SUCCESS;
210 211
}

212
int excit_type(excit_t it, enum excit_type_e *type)
213
{
214 215 216 217
  if (!it || !type)
    return -EXCIT_EINVAL;
  *type = it->type;
  return EXCIT_SUCCESS;
218 219
}

220
int excit_next(excit_t it, ssize_t *indexes)
221
{
222 223 224 225 226
  if (!it || !it->func_table)
    return -EXCIT_EINVAL;
  if (!it->func_table->next)
    return -EXCIT_ENOTSUP;
  return it->func_table->next(it, indexes);
227 228
}

229
int excit_peek(const excit_t it, ssize_t *indexes)
230
{
231 232 233 234 235
  if (!it || !it->func_table)
    return -EXCIT_EINVAL;
  if (!it->func_table->peek)
    return -EXCIT_ENOTSUP;
  return it->func_table->peek(it, indexes);
236 237
}

238
int excit_size(const excit_t it, ssize_t *size)
239
{
240 241 242 243 244
  if (!it || !it->func_table || !size)
    return -EXCIT_EINVAL;
  if (!it->func_table->size)
    return -EXCIT_ENOTSUP;
  return it->func_table->size(it, size);
245 246
}

247
int excit_rewind(excit_t it)
248
{
249 250 251 252 253
  if (!it || !it->func_table)
    return -EXCIT_EINVAL;
  if (!it->func_table->rewind)
    return -EXCIT_ENOTSUP;
  return it->func_table->rewind(it);
254 255
}

256
int excit_split(const excit_t it, ssize_t n, excit_t *results)
257
{
258 259 260 261 262 263 264
  if (!it || !it->func_table)
    return -EXCIT_EINVAL;
  if (n <= 0)
    return -EXCIT_EDOM;
  if (!it->func_table->split)
    return -EXCIT_ENOTSUP;
  return it->func_table->split(it, n, results);
265 266
}

267
int excit_nth(const excit_t it, ssize_t n, ssize_t *indexes)
268
{
269 270 271 272 273
  if (!it || !it->func_table)
    return -EXCIT_EINVAL;
  if (!it->func_table->nth)
    return -EXCIT_ENOTSUP;
  return it->func_table->nth(it, n, indexes);
274 275
}

276
int excit_rank(const excit_t it, const ssize_t *indexes, ssize_t *n)
277
{
278 279 280 281 282
  if (!it || !it->func_table || !indexes)
    return -EXCIT_EINVAL;
  if (!it->func_table->rank)
    return -EXCIT_ENOTSUP;
  return it->func_table->rank(it, indexes, n);
283 284
}

285
int excit_pos(const excit_t it, ssize_t *n)
286
{
287 288 289 290 291
  if (!it || !it->func_table)
    return -EXCIT_EINVAL;
  if (!it->func_table->pos)
    return -EXCIT_ENOTSUP;
  return it->func_table->pos(it, n);
292 293
}

294
int excit_cyclic_next(excit_t it, ssize_t *indexes, int *looped)
295
{
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
  int err;

  if (!it)
    return -EXCIT_EINVAL;
  *looped = 0;
  err = excit_next(it, indexes);
  switch (err) {
  case EXCIT_SUCCESS:
    break;
  case EXCIT_STOPIT:
    err = excit_rewind(it);
    if (err)
      return err;
    *looped = 1;
    err = excit_next(it, indexes);
    if (err)
      return err;
    break;
  default:
    return err;
  }
  if (excit_peek(it, NULL) == EXCIT_STOPIT) {
    err = excit_rewind(it);
    if (err)
      return err;
    *looped = 1;
  }
  return EXCIT_SUCCESS;
324 325
}

326
int excit_skip(excit_t it)
327
{
328
  return excit_next(it, NULL);
329
}
330