Quick actions

cmd+k|ctrl+k

Navigation

Languages

Custom Array and defer.

Snippet info

Language

Cpp

Visibility

public

Author

evine

Created

2016-05-18T14:33:13Z

Updated

2016-05-21T04:55:21Z

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#define CONCAT_(a,b) a##b
#define CONCAT(a,b) CONCAT_(a,b)

struct v2{
    double x;
    double y;
};

// Define array types here.
#define ARRAY_TYPE_DEFINE \
X(int, s32) \
X(double, f64) \
X(int *, s32_ptr) \
X(v2, v2)

struct array_link{
    size_t local_size;
    array_link *next;
    char E_[0];
};

#define X(type, type_name)                                      \
struct Array_##type_name{                                       \
    type *E_;                                                   \
    size_t size;                                                \
    size_t local_size;                                          \
    array_link *next;                                           \
    type& operator [](size_t size_in)                           \
    {                                                           \
        if(size_in >= local_size)                               \
        {                                                       \
            assert(next);                                       \
            return ((type *)this->next->E_)[size_in - size];    \
        }                                                       \
        return E_[size_in];                                     \
    }                                                           \
    Array_##type_name(size_t size_in)                           \
    {                                                           \
        next = 0;                                               \
        size = size_in;                                         \
        E_ = (type *)malloc(size * sizeof(*E_));                \
    }                                                           \
    Array_##type_name(void *memory, size_t size_in)             \
    {                                                           \
        size = size_in;                                         \
        E_ = (type *)memory;                                    \
    }                                                           \
}; \
void array_extend(Array_##type_name *array, size_t size_in) \
{ \
    array_link *link = (array_link *)malloc(size_in * sizeof(type) + sizeof(array_link)); \
    array->size += size_in; \
    link->local_size = size_in; \
    link->next = 0; \
    if(array->next == 0) \
    { \
        array->next = link; \
    } \
    else \
    { \
        array_link *link_to = array->next; \
        while(link_to->next) \
        { \
            link_to = link_to->next; \
        } \
        link_to->next = link; \
    } \
}

ARRAY_TYPE_DEFINE
#undef X

#define array_stack(type, size_in) alloca(size_in * sizeof(type)), size_in
#define array_heap(type, type_name, size_in) Array_##type_name{ .E_ = (type *)malloc(size_in * sizeof(type)), .size = size_in}

#define defer_free(memory_pointer) \
DeferFreeStruct CONCAT(defer_free_unique_name_, __COUNTER__) = {(void **)&(memory_pointer)}
struct DeferFreeStruct{
    void **memory;
    ~DeferFreeStruct()
    {
        free(*memory);
    }
};

int main(void) {
    
    //Array_s32_ptr some_array_on_stack(array_stack(int *, 32));
    Array_f64 some_array_in_heap = 30;
    // Free some_array_in_heap when scope ends.
    defer_free(some_array_in_heap);
    array_extend(&some_array_in_heap, 25);
    array_extend(&some_array_in_heap, 32);
    array_extend(&some_array_in_heap, 93);
    /*
    array_extend(&some_array_in_heap, 1);
    array_extend(&some_array_in_heap, 1);
    array_extend(&some_array_in_heap, 1);
    array_extend(&some_array_in_heap, 1);
    array_extend(&some_array_in_heap, 1);
    */
    some_array_in_heap[37] = 51;
    
    //Array_v2 some_array_of_v2(array_stack(v2, 21));
    
    
    some_array_in_heap[10] = 300.6;
    printf("%g, %zu\n", some_array_in_heap[37], some_array_in_heap.size);
    printf("%i, %i, %i\n", some_array_in_heap.next->local_size,
        some_array_in_heap.next->next->local_size, some_array_in_heap.next->next->next->local_size);
    
    return 0;
}






INFO