ビットパターンを記録するインターフェース
メモリー上にビットパターンを確保して、指定インデックスのビット操作をでき、またパターン同士の一括論理和や論理積を計算できるインターフェースを考えていた。
#pragma once
#include <stdbool.h>
struct bits;
struct bits *bits_alloc(unsigned nr_bits);
void bits_free(struct bits *bits);
struct bits *bits_clone(const struct bits *bits);
/**
* spawn bits into ptr, returns the bytes consumed.
*
* number of bits is stripped.
*/
unsigned bits_spawn_bare(const struct bits *bits, void *ptr);
/**
* Create bits object from `ptr`; `ptr` should hold bare-spawned bit pattern.
*/
struct bits* bits_hatch_bare(const void *ptr, unsigned nr_bits);
/**
* Clear all bits.
*/
void bits_clear(struct bits *bits);
/**
* Set the boolean value of `set` to `bits` on the `index`.
*/
void bits_set(struct bits *bits, unsigned index, bool set);
/**
* Peek the boolean value of `bits` on the `index`.
*/
bool bits_value(const struct bits *bits, unsigned index);
/**
* count the bits set.
*/
unsigned bits_count(struct bits *bits);
/**
* Store result of bitwise `and` with `a` and `b` into `a`.
*/
void bits_and(struct bits *a, const struct bits *b);
/**
* Store result of bitwise `or` with `a` and `b` into `a`.
*/
void bits_or(struct bits *a, const struct bits *b);
/**
* Store result of bitwise `xor` with `a` and `b` into `a`.
*/
void bits_xor(struct bits *a, const struct bits *b);
/**
* Store result of bitwise inversion of `bit` into `bits`.
*/
void bits_invert(struct bits *bits);
/**
* return >0 if bit-pattern of `a` greater than `b`'s, 0 if equal, otherwise <0.
*/
int bits_compare(const struct bits *a, const struct bits *b);
ただ、自分がしたかったことに比べてオーバースペックになってしまったため仕切り直す。
けれど、全部捨てるのも勿体ないのでメモとして残しておく。
* * *
この実装はこんな感じで書き始めていた。(けれど、ビットパターン同士の比較を実行するときに、それぞれのビット数を確認するだとか面倒になってしまった……)
#include "bits.h"
inline static unsigned nr_word_for(unsigned nr_bits)
{
return (nr_bits + NBITS - 1) / NBITS;
}
struct bits
{
const unsigned nr_bits;
unsigned bits[0];
};
struct bits *bits_alloc(unsigned nr_bits)
{
unsigned *const p = calloc(sizeof(unsigned), 1 + nr_word_for(nr_bits));
p[0] = nr_bits;
return (void *)p;
}
void bits_free(struct bits *bits)
{
free(bits);
}
struct bits *bits_clone(const struct bits *bits)
{
unsigned nr_bytes = sizeof(unsigned) * (1 + nr_word_for(bits->nr_bits));
void *const p = malloc(nr_bytes);
memcpy(p, bits, nr_bytes);
return p;
}
unsigned bits_spawn_bare(const struct bits *bits, void *ptr)
{
unsigned nr_bytes = sizeof(unsigned) * nr_word_for(bits->nr_bits);
memcpy(ptr, bits->bits, nr_bytes);
return nr_bytes;
}
この記事が気に入ったらサポートをしてみませんか?