反省してなかった
いや、意外と便利だぜこれ。vectorのコピペ。
#ifndef STACK_H #define STACK_H #define DEFAULT_STACK_SIZE 256 #define STACK_PROTOTYPE(type) \ typedef struct type##_stack_ { \ type * data; \ \ int size; \ int index; \ } * type##_stack_t; \ \ type##_stack_t make_##type##_stack(); \ void type##_stack_expand(type##_stack_t stk); \ void delete_##type##_stack(type##_stack_t stk); \ \ type type##_stack_top(type##_stack_t stk); \ type type##_stack_pop(type##_stack_t stk); \ void type##_stack_push(type##_stack_t stk, type value); \ bool type##_stack_empty(type##_stack_t stk); \ int type##_stack_length(type##_stack_t stk); #define STACK_BODY(type) \ type##_stack_t make_##type##_stack(){ \ type##_stack_t ret; \ SAFE_MALLOC(ret, sizeof(struct type##_stack_)); \ SAFE_CALLOC(ret->data, DEFAULT_STACK_SIZE, sizeof(type)); \ \ ret->size = DEFAULT_STACK_SIZE; \ ret->index = 0; \ \ return ret; \ } \ void stack_##type##_expand(type##_stack_t stk){ \ SAFE_REALLOC(stk->data, sizeof(type) * stk->size * 2); \ int i = stk->size; \ for(;i < stk->size * 2; i++){ \ stk->data[i] = (type)0; \ } \ stk->size *= 2; \ } \ void delete_##type##_stack(type##_stack_t stk){ \ free(stk->data); \ free(stk); \ } \ \ type type##_stack_top(type##_stack_t stk){ \ if (stk->index == 0){ \ return (type)0; \ } \ \ return stk->data[stk->index - 1]; \ } \ type type##_stack_pop(type##_stack_t stk){ \ if (stk->index == 0){ \ return (type)0; \ } \ \ return stk->data[--stk->index]; \ } \ void type##_stack_push(type##_stack_t stk, type value){ \ while(stk->index >= stk->size){ \ stack_##type##_expand(stk); \ } \ \ stk->data[stk->index++] = value; \ } \ bool type##_stack_empty(type##_stack_t stk){ \ if (stk->index == 0) return TRUE; \ else return FALSE; \ } \ int type##_stack_length(type##_stack_t stk){ \ return stk->index; \ } #define STACK_DEFINE(type) \ STACK_PROTOTYPE(type); \ STACK_BODY(type) #endif
テストケースも書いたよ(> <)!!
#include "test.h" #include "stack.h" /* STACK_DEFINE(int) */ STACK_PROTOTYPE(int); STACK_BODY(int); STACK_DEFINE(char); STACK_DEFINE(double); int main(int argc, char * argv[]){ int_stack_t istk = make_int_stack(); TEST_ASSERT(int_stack_empty(istk) == TRUE); TEST_ASSERT(int_stack_top(istk) == 0); int_stack_push(istk, 12345); TEST_ASSERT(int_stack_empty(istk) == FALSE); TEST_ASSERT(int_stack_top(istk) == 12345); TEST_ASSERT(int_stack_pop(istk) == 12345); TEST_ASSERT(int_stack_empty(istk) == TRUE); int_stack_push(istk, 12345); int_stack_push(istk, 23456); int_stack_push(istk, 34567); TEST_ASSERT(int_stack_empty(istk) == FALSE); TEST_ASSERT(int_stack_top(istk) == 34567); TEST_ASSERT(int_stack_pop(istk) == 34567); TEST_ASSERT(int_stack_empty(istk) == FALSE); TEST_ASSERT(int_stack_top(istk) == 23456); TEST_ASSERT(int_stack_pop(istk) == 23456); TEST_ASSERT(int_stack_empty(istk) == FALSE); TEST_ASSERT(int_stack_top(istk) == 12345); TEST_ASSERT(int_stack_pop(istk) == 12345); TEST_ASSERT(int_stack_empty(istk) == TRUE); delete_int_stack(istk); char_stack_t cstk = make_char_stack(); TEST_ASSERT(char_stack_empty(cstk) == TRUE); TEST_ASSERT(char_stack_top(cstk) == 0); char_stack_push(cstk, 123); TEST_ASSERT(char_stack_empty(cstk) == FALSE); TEST_ASSERT(char_stack_top(cstk) == 123); TEST_ASSERT(char_stack_pop(cstk) == 123); TEST_ASSERT(char_stack_empty(cstk) == TRUE); char_stack_push(cstk, 123); char_stack_push(cstk, 23); char_stack_push(cstk, 67); TEST_ASSERT(char_stack_empty(cstk) == FALSE); TEST_ASSERT(char_stack_top(cstk) == 67); TEST_ASSERT(char_stack_pop(cstk) == 67); TEST_ASSERT(char_stack_empty(cstk) == FALSE); TEST_ASSERT(char_stack_top(cstk) == 23); TEST_ASSERT(char_stack_pop(cstk) == 23); TEST_ASSERT(char_stack_empty(cstk) == FALSE); TEST_ASSERT(char_stack_top(cstk) == 123); TEST_ASSERT(char_stack_pop(cstk) == 123); TEST_ASSERT(char_stack_empty(cstk) == TRUE); delete_char_stack(cstk); double_stack_t dstk = make_double_stack(); TEST_ASSERT(double_stack_empty(dstk) == TRUE); TEST_ASSERT(double_stack_top(dstk) == 0); double_stack_push(dstk, 12.345); TEST_ASSERT(double_stack_empty(dstk) == FALSE); TEST_ASSERT(double_stack_top(dstk) == 12.345); TEST_ASSERT(double_stack_pop(dstk) == 12.345); TEST_ASSERT(double_stack_empty(dstk) == TRUE); double_stack_push(dstk, 12.345); double_stack_push(dstk, 0.0023456); double_stack_push(dstk, 34567e10); TEST_ASSERT(double_stack_empty(dstk) == FALSE); TEST_ASSERT(double_stack_top(dstk) == 34567e10); TEST_ASSERT(double_stack_pop(dstk) == 34567e10); TEST_ASSERT(double_stack_empty(dstk) == FALSE); TEST_ASSERT(double_stack_top(dstk) == 0.0023456); TEST_ASSERT(double_stack_pop(dstk) == 0.0023456); TEST_ASSERT(double_stack_empty(dstk) == FALSE); TEST_ASSERT(double_stack_top(dstk) == 12.345); TEST_ASSERT(double_stack_pop(dstk) == 12.345); TEST_ASSERT(double_stack_empty(dstk) == TRUE); delete_double_stack(dstk); return 0; }