#ifndef SWIFT_DATA_BITSET_H
#define SWIFT_DATA_BITSET_H

#include <swift/stdlib.h>

#include <swift/data/api.h>
#include <swift/data/types.h>

typedef struct swift_bitset_t swift_bitset_t;
typedef struct swift_bitset_iter_t swift_bitset_iter_t;

struct swift_bitset_t {
	unsigned int *data;
	size_t bit_size, size;
};

struct swift_bitset_iter_t {
	swift_bitset_t *set;
	size_t index;
};

#define SWIFT_BITSET_ITER(...) ((swift_bitset_iter_t){__VA_ARGS__})

SWIFT_DATA_API bool swift_init_bitset_size(swift_bitset_t *set,
	size_t bit_size);
SWIFT_DATA_API bool swift_init_bitset(swift_bitset_t *set);
SWIFT_DATA_API void swift_term_bitset(swift_bitset_t *set);
SWIFT_DATA_API swift_bitset_t *swift_new_bitset_size(size_t bit_size);
SWIFT_DATA_API swift_bitset_t *swift_new_bitset(void);
SWIFT_DATA_API void swift_del_bitset(swift_bitset_t *set);
SWIFT_DATA_API bool swift_bitset_resize(swift_bitset_t *set, size_t bit_size);
SWIFT_DATA_API bool swift_bitset_expand(swift_bitset_t *set, size_t count);
SWIFT_DATA_API size_t swift_bitset_count(swift_bitset_t *set);
SWIFT_DATA_API size_t swift_bitset_size(swift_bitset_t *set);

SWIFT_DATA_API bool swift_is_bit_set(swift_bitset_t *set, size_t index);
SWIFT_DATA_API bool swift_set_bit(swift_bitset_t *set, size_t index);
SWIFT_DATA_API bool swift_clear_bit(swift_bitset_t *set, size_t index);
SWIFT_DATA_API bool swift_flip_bit(swift_bitset_t *set, size_t index);

SWIFT_DATA_API size_t swift_set_bit_range(swift_bitset_t *set, size_t from,
	size_t to);
SWIFT_DATA_API size_t swift_clear_bit_range(swift_bitset_t *set, size_t from,
	size_t to);
SWIFT_DATA_API size_t swift_flip_bit_range(swift_bitset_t *set, size_t from,
	size_t to);

SWIFT_DATA_API size_t swift_next_set_bit(swift_bitset_t *set, size_t from,
	size_t to);
SWIFT_DATA_API size_t swift_next_clear_bit(swift_bitset_t *set, size_t from,
	size_t to);
SWIFT_DATA_API size_t swift_prev_set_bit(swift_bitset_t *set, size_t from,
	size_t to);
SWIFT_DATA_API size_t swift_prev_clear_bit(swift_bitset_t *set, size_t from,
	size_t to);

SWIFT_DATA_API size_t swift_bitset_and(swift_bitset_t *dst,
	swift_bitset_t *src);
SWIFT_DATA_API size_t swift_bitset_or(swift_bitset_t *dst, swift_bitset_t *src);
SWIFT_DATA_API size_t swift_bitset_xor(swift_bitset_t *dst,
	swift_bitset_t *src);

SWIFT_DATA_API swift_bitset_iter_t swift_bitset_first_set(swift_bitset_t *set);
SWIFT_DATA_API swift_bitset_iter_t swift_bitset_last_set(swift_bitset_t *set);
SWIFT_DATA_API bool swift_bitset_next_set(swift_bitset_iter_t *iter);
SWIFT_DATA_API bool swift_bitset_prev_set(swift_bitset_iter_t *iter);

SWIFT_DATA_API swift_bitset_iter_t swift_bitset_first_clear(
	swift_bitset_t *set);
SWIFT_DATA_API swift_bitset_iter_t swift_bitset_last_clear(swift_bitset_t *set);
SWIFT_DATA_API bool swift_bitset_next_clear(swift_bitset_iter_t *iter);
SWIFT_DATA_API bool swift_bitset_prev_clear(swift_bitset_iter_t *iter);

#endif /* SWIFT_DATA_BITSET_H */
