/*
* Copyright 2010 University of Helsinki.
*
* This file is part of libgu.
*
* Libgu is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Libgu is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with libgu. If not, see .
*/
/** @file
*
* Lists.
*/
#ifndef GU_LIST_H_
#define GU_LIST_H_
#include
#define GuList(t) \
struct { \
const int len; \
t elems[]; \
}
void* gu_list_alloc(GuPool* pool, size_t base_size, size_t elem_size,
int n_elems, size_t alignment);
#define gu_new_list(t, pool, n) \
((t*) gu_list_alloc(pool, \
sizeof(t), \
sizeof(((t*)NULL)->elems[0]), \
(n), \
gu_flex_alignof(t)))
static inline int
gu_list_length(const void* list)
{
return *(const int*) list;
}
#define gu_list_elems(lst) \
((lst)->elems)
#define gu_list_index(lst, i) \
(gu_list_elems(lst)[i])
typedef GuList(void*) GuPointers;
//typedef GuList(uint8_t) GuBytes;
typedef GuList(int) GuInts;
#define GuListN(t_, len_) \
struct { \
int len; \
t elems[len_]; \
}
#define gu_list_(qual_, t_, ...) \
((qual_ GuList(t_) *) \
((qual_ GuListN(t_, (sizeof((t_[]){__VA_ARGS__}) / sizeof(t_)))[]){ \
__VA_ARGS__ \
}))
#define gu_list(t_, ...) \
gu_list_(, t_, __VA_ARGS__)
#define gu_clist(t_, ...) \
gu_list_(const, t_, __VA_ARGS__)
#define GuSList(t) \
const struct { \
int len; \
t* elems; \
}
#define GU_SLIST_0 { .len = 0, .elems = NULL }
#define GU_SLIST(t, ...) \
{ \
.len = GU_ARRAY_LEN(t,GU_ID({__VA_ARGS__})), \
.elems = ((t[]){__VA_ARGS__}) \
}
#include
//
// list
//
typedef const struct GuListType GuListType, GuType_GuList;
struct GuListType {
GuType_abstract abstract_base;
size_t size;
size_t align;
GuType* elem_type;
ptrdiff_t elems_offset;
};
#define GU_TYPE_INIT_GuList(k_, t_, elem_type_) { \
.abstract_base = GU_TYPE_INIT_abstract(k_, t_, _), \
.size = sizeof(t_), \
.align = gu_alignof(t_), \
.elem_type = elem_type_, \
.elems_offset = offsetof(t_, elems) \
}
extern GU_DECLARE_KIND(GuList);
void*
gu_list_type_alloc(GuListType* ltype, int n_elems, GuPool* pool);
void*
gu_list_type_index(GuListType* ltype, void* list, int i);
#include
typedef GuList(GuStr) GuStrs;
typedef GuStrs* GuStrsP;
extern GU_DECLARE_TYPE(GuStrs, GuList);
extern GU_DECLARE_TYPE(GuStrsP, pointer);
#endif // GU_LIST_H_