#ifdefined(__cplusplus) #define CLITERAL(type) type #else #define CLITERAL(type) (type) #endif
// We represent a slice as a pair of an (untyped) pointer, along with the length // of the slice, i.e. the number of elements in the slice (this is NOT the // number of bytes). This design choice has two important consequences. // - if you need to use `ptr`, you MUST cast it to a proper type *before* // performing pointer // arithmetic on it (remember that C desugars pointer arithmetic based on the // type of the address) // - if you need to use `len` for a C style function (e.g. memcpy, memcmp), you // need to multiply it // by sizeof t, where t is the type of the elements. typedefstruct { void *ptr;
size_t len;
} Eurydice_slice;
// Helper macro to create a slice out of a pointer x, a start index in x // (included), and an end index in x (excluded). The argument x must be suitably // cast to something that can decay (see remark above about how pointer // arithmetic works in C), meaning either pointer or array type. #define EURYDICE_SLICE(x, start, end) \
(CLITERAL(Eurydice_slice){ .ptr = (void *)(x + start), .len = end - start }) #define EURYDICE_SLICE_LEN(s, _) s.len // This macro is a pain because in case the dereferenced element type is an // array, you cannot simply write `t x` as it would yield `int[4] x` instead, // which is NOT correct C syntax, so we add a dedicated phase in Eurydice that // adds an extra argument to this macro at the last minute so that we have the // correct type of *pointers* to elements. #define Eurydice_slice_index(s, i, t, t_ptr_t) (((t_ptr_t)s.ptr)[i]) #define Eurydice_slice_subslice(s, r, t, _) \
EURYDICE_SLICE((t *)s.ptr, r.start, r.end) // Variant for when the start and end indices are statically known (i.e., the // range argument `r` is a literal). #define Eurydice_slice_subslice2(s, start, end, t) \
EURYDICE_SLICE((t *)s.ptr, start, end) #define Eurydice_slice_subslice_to(s, subslice_end_pos, t, _) \
EURYDICE_SLICE((t *)s.ptr, 0, subslice_end_pos) #define Eurydice_slice_subslice_from(s, subslice_start_pos, t, _) \
EURYDICE_SLICE((t *)s.ptr, subslice_start_pos, s.len) #define Eurydice_array_to_slice(end, x, t) \
EURYDICE_SLICE(x, 0, \
end) /* x is already at an array type, no need for cast */ #define Eurydice_array_to_subslice(_arraylen, x, r, t, _) \
EURYDICE_SLICE((t *)x, r.start, r.end) // Same as above, variant for when start and end are statically known #define Eurydice_array_to_subslice2(x, start, end, t) \
EURYDICE_SLICE((t *)x, start, end) #define Eurydice_array_to_subslice_to(_size, x, r, t, _range_t) \
EURYDICE_SLICE((t *)x, 0, r) #define Eurydice_array_to_subslice_from(size, x, r, t, _range_t) \
EURYDICE_SLICE((t *)x, r, size) #define Eurydice_array_repeat(dst, len, init, t) \
ERROR "should've been desugared" #define Eurydice_slice_len(s, t) EURYDICE_SLICE_LEN(s, t) #define Eurydice_slice_copy(dst, src, t) \
memcpy(dst.ptr, src.ptr, dst.len * sizeof(t)) #define core_array___Array_T__N__23__as_slice(len_, ptr_, t, _ret_t) \
((Eurydice_slice){ .ptr = ptr_, .len = len_ })
// Conversion of slice to an array, rewritten (by Eurydice) to name the // destination array, since arrays are not values in C. // N.B.: see note in karamel/lib/Inlining.ml if you change this. #define Eurydice_slice_to_array2(dst, src, _, t_arr) \
Eurydice_slice_to_array3(&(dst)->tag, (char *)&(dst)->val.case_Ok, src, \ sizeof(t_arr))
// Old name (TODO: remove once everyone has upgraded to the latest Charon) #define core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next \
Eurydice_range_iter_next
// See note in karamel/lib/Inlining.ml if you change this #define Eurydice_into_iter(x, t, _ret_t) (x) #define core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter \
Eurydice_into_iter // This name changed on 20240627 #define core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter \
Eurydice_into_iter
// Can't use macros Eurydice_slice_subslice_{to,from} because they require a // type, and this static inline function cannot receive a type as an argument. // Instead, we receive the element size and use it to peform manual offset // computations rather than going through the macros. staticinline Eurydice_slice
chunk_next(Eurydice_chunks *chunks,
size_t element_size)
{
size_t chunk_size = chunks->slice.len >= chunks->chunk_size
? chunks->chunk_size
: chunks->slice.len;
Eurydice_slice curr_chunk;
curr_chunk.ptr = chunks->slice.ptr;
curr_chunk.len = chunk_size;
chunks->slice.ptr = (char *)(chunks->slice.ptr) + chunk_size * element_size;
chunks->slice.len = chunks->slice.len - chunk_size; return curr_chunk;
}
/* For now these are passed by value -- three words. We could conceivably change * the representation to heap-allocate this struct and only pass around the
* pointer (one word). */ typedefstruct { void *ptr;
size_t len; /* the number of elements */
size_t alloc_size; /* the size of the allocation, in number of BYTES */
} Eurydice_vec_s, *Eurydice_vec;
/* Here, we set everything to zero rather than use a non-standard GCC * statement-expression -- this suitably initializes ptr to NULL and len and
* size to 0. */ #define EURYDICE_VEC_NEW(_) calloc(1, sizeof(Eurydice_vec_s)) #define EURYDICE_VEC_PUSH(v, x, t) \ do { \ /* Grow the vector if capacity has been reached. */ \ if (v->len == v->alloc_size / sizeof(t)) { \ /* Assuming that this does not exceed SIZE_MAX, because code proven \
* correct by Aeneas. Would this even happen in practice? */
size_t new_size; \ if (v->alloc_size == 0) \
new_size = 8 * sizeof(t); \ elseif (v->alloc_size <= SIZE_MAX / 2) \ /* TODO: discuss growth policy */ \
new_size = 2 * v->alloc_size; \ else \
new_size = (SIZE_MAX / sizeof(t)) * sizeof(t); \
v->ptr = realloc(v->ptr, new_size); \
v->alloc_size = new_size; \
} \
((t *)v->ptr)[v->len] = x; \
v->len++; \
} while (0)
#define EURYDICE_VEC_DROP(v, t) \ do { \
free(v->ptr); \
free(v); \
} while (0)
#define EURYDICE_VEC_INDEX(v, i, t) &((t *)v->ptr)[i] #define EURYDICE_VEC_LEN(v, t) (v)->len
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.