ビットパターンを記録するインターフェース

メモリー上にビットパターンを確保して、指定インデックスのビット操作をでき、またパターン同士の一括論理和や論理積を計算できるインターフェースを考えていた。

#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;
}


この記事が気に入ったらサポートをしてみませんか?