aoutil
ちょっとしたユーティリティマクロやテンプレート関数
#ifndef AOUTIL_H_INCLUDED #define AOUTIL_H_INCLUDED #ifdef __cplusplus extern "C" { #endif //__cplusplus #define RAD2DEG(rad) ((rad) * 0.00872664625997165) #define DEG2RAD(deg) ((deg) * 114.591559026165) #define SAFE_DELETE(p) { delete (p); (p)=0;} #define SAFE_DELETE_AR(p) { delete[] (p); (p)=0; } #define nARRAY(a) ( sizeof(a)/sizeof(a[0]) ) /* 20.8: ビットの集合や配列はどうやって実装すればいいのか。 A: charやintの配列を使う。マクロを使って、しかるべきインデックス にある望みのビットにアクセスできるようにする。以下にcharの配列 を使った簡単なマクロの例を紹介する。 */ #include <limits.h> /* for CHAR_BIT */ #define BITMASK(b) (1 << ((b) % CHAR_BIT)) #define BITSLOT(b) ((b) / CHAR_BIT) #define BITSET(a, b) ((a)[BITSLOT(b)] |= BITMASK(b)) #define BITTEST(a, b) ((a)[BITSLOT(b)] & BITMASK(b)) #define dputs(N) printf("%s = \"%s\"\n", #N, N); #define dputi(N) printf("%s = %d\n", #N, N); #define dputf(N) printf("%s = %f\n", #N, N); #ifdef __cplusplus } #endif //__cplusplus #ifdef __cplusplus template< typename T > T clamp(T min, T val, T max) { if ( val < min ) return min; if ( val > max ) return max; return val; } template< typename T > void swap(T& a, T& b) { T tmp = a; a = b; b = tmp; } template< typename T > T min(T& a, T& b) { if ( a < b ) return a; else return b; } template< typename T > T max(T& a, T& b) { if ( a > b ) return a; else return b; } inline int isLittleEndian() { int x = 1; if(*(char *)&x == 1) return 1; else return 0; } #endif //__cplusplus #endif /* AOUTIL_H_INCLUDED */
readlines.c
#include <stdio.h> #include <stdlib.h> #include <string.h> long getFileSize(const char* filename) { long sz = 0; FILE* fp = fopen(filename, "rb"); if (fp == NULL) return 0; fseek(fp, 0, SEEK_END); sz = ftell(fp); fclose(fp); return sz; } // ・0バイトは0行とみなす // ・Unixのテキストファイルの定義と違い、改行で終わっていなくても1行とみなす int getLineCount(char* buf, int len) { int i; int c = 0; int inLine = 0; if (buf == NULL) return 0; for (i=0; i<len; i++) { if (buf[i] == (char)'\n') { c++; inLine = 0; } else { inLine = 1; } } if (inLine) c++; return c; } // ・0バイトは長さ0の文字列を返す char* readFileAsString(const char* filename, long* outLen) { char* buf = NULL; long size = 0; FILE* fp = fopen(filename, "rb"); if (fp == NULL) return NULL; size = getFileSize(filename); buf = (char*)malloc(size + 1); fread(buf, size, 1, fp); buf[size] = '\0'; if (outLen) *outLen = size; fclose(fp); return buf; } // 0バイトはNULLを返し、outLineCountを0にする char** readLines(const char* filename, int* outLineCount) { int i; char** list = NULL; char* buf = NULL; long len = 0; int lineCount = 0; int lineIdx = 0; buf = readFileAsString(filename, &len); if (buf == NULL) return NULL; lineCount = getLineCount(buf, len); if (lineCount == 0) { *outLineCount = 0; return NULL; } list = (char**)malloc(sizeof(char*) * lineCount); list[0] = buf; for (i=0; i<len; i++) { if (buf[i] == (char)'\n') { buf[i] = '\0'; lineIdx++; if (lineIdx < lineCount) list[lineIdx] = &buf[i + 1]; } } if (outLineCount) *outLineCount = lineCount; return list; }
vector.c
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef void* VectorType; typedef struct _Vector { long capacity; long count; VectorType* data; } Vector; Vector* Vector_new(int initialCapacity) { if (initialCapacity <= 0) return NULL; Vector* p = malloc(sizeof(Vector)); p->capacity = initialCapacity; p->count = 0; p->data = malloc(sizeof(VectorType) * p->capacity); return p; } VectorType Vector_get(Vector* self, int i) { return self->data[i]; } long Vector_count(Vector* self) { return self->count; } void Vector_push(Vector* self, VectorType d) { VectorType tmp; if (self->count + 1 > self->capacity) { tmp = realloc(self->data, sizeof(VectorType) * self->capacity * 2); if (tmp == NULL) return; self->capacity *= 2; self->data = tmp; } self->data[self->count] = d; self->count += 1; } void Vector_delete(Vector* self) { free(self); }