//----------------------------------------------------------------------- // // Copyright (c) SekraSoft. All rights reserved. // //----------------------------------------------------------------------- #ifndef MCALC_STACK #define MCALC_STACK #include // создаёт быстрый стек без операций для массивов #define STACK_FAST(type, maxsize, size, data, \ init, deinit, push, pop, get, link) \ STACK_INIT(type, maxsize, size, data, init, deinit) \ STACK_STD_FAST(type, maxsize, size, data, push, pop, get, link) // создаёт стек без операций для массивов #define STACK_STD(type, maxsize, size, data, \ init, deinit, push, pop, get, link) \ STACK_INIT(type, maxsize, size, data, init, deinit) \ STACK_STD_ADV(type, maxsize, size, data, push, pop, get, link) // создаёт стек без операций для массивов с возможностью только добавления #define STACK_ADD(type, maxsize, size, data, \ init, deinit, push, link) \ STACK_INIT(type, maxsize, size, data, init, deinit) \ STACK_PUSH_ADV(type, maxsize, size, data, push, link) // создаёт быстрый стек c операциями для массивов #define STACK_ADV(type, maxsize, size, data, \ init, deinit, push, pop, get, \ aalloc, afree, aget, link) \ STACK_INIT(type, maxsize, size, data, init, deinit) \ STACK_STD_FAST(type, maxsize, size, data, push, pop, get, link) \ STACK_ARRAY(type, maxsize, size, data, aalloc, afree, aget) // макрос создаёт функции для инициализации/удаления стека #define STACK_INIT(type, maxsize, size, data, \ init, deinit) \ size_t maxsize = 0; \ size_t size = 0; \ type *data = 0; \ int init(size_t startsize){ \ if (startsize < 2) return 0; \ if (!(data = malloc(sizeof(type) * startsize))) return 0; \ size = 0; \ maxsize = startsize; \ return 1; \ } \ void deinit(){ if(data) free(data); data = 0; } // простые и быстрые операции для работы со стеком #define STACK_STD_FAST(type, maxsize, \ size, data, \ push, pop, get, link) \ void push(type link elem) { \ if (size >= maxsize){ \ type *new_data = (type*)realloc(data, \ (maxsize + (maxsize>>1)) * sizeof(type)); \ if (!new_data) return; \ data = new_data; \ maxsize += (maxsize>>1); \ } \ data[size] = link elem; \ ++size; \ } \ type link void pop() { \ if (size > 0) return link data[--size]; \ return (type link)0; \ } \ type link get() { \ if (size > 0) return link data[size - 1]; \ return (type link)0; \ } // операция push для работы со стеком, возвращающая результат #define STACK_PUSH_ADV(type, maxsize, \ size, data, \ push, link) \ int push(type link elem) { \ if (size >= maxsize){ \ type *new_data = (type*)realloc(data, \ (maxsize + (maxsize>>1)) * sizeof(type)); \ if (!new_data) return 0; \ data = new_data; \ maxsize += (maxsize>>1); \ } \ data[size] = link elem; \ ++size; \ return 1; \ } // операции для работы со стеком, возвращающие результат #define STACK_STD_ADV(type, maxsize, \ size, data, \ push, pop, get, link) \ STACK_PUSH_ADV(type, maxsize, size, \ data, push, link) \ int pop(type* elem) { \ if (size > 0){ \ *elem = data[--size]; \ return 1; \ } \ return 0; \ } \ int get(type* elem) { \ if (size > 0){ \ *elem = data[size - 1]; \ return 1; \ } \ return 0; \ } // макрос создаёт функции для выделения массивов на стеке #define STACK_ARRAY(type, maxsize, \ size, data, \ aalloc, afree, aget) \ size_t aalloc(size_t length){ \ size_t arr; \ if (size + length >= maxsize){ \ type *new_data = (type*)realloc(data, \ (size + length + (maxsize>>1)) * \ sizeof(type)); \ if (!new_data) return 0; \ data = new_data; \ maxsize = size + length + (maxsize>>1); \ } \ arr = size; \ size += length; \ return arr; \ } \ void afree(size_t length){ \ if (size < length){ \ size = 0; \ return; \ } \ size -= length; \ } \ type* aget(){ return data; } #endif