/*	
 *	clipbary.h
 *
 *	汎用ビット配列
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2011 Naoyuki Sawa
 *
 *	* Tue Dec 20 00:06:44 JST 2011 Naoyuki Sawa
 *	- 1st リリース。
 */
#ifndef __CLIP_BARY_H__
#define __CLIP_BARY_H__

/*****************************************************************************
 *	
 *****************************************************************************/

/* ビット配列のメモリを確保します。
 * [in]
 *	bit_len		ビット数。
 * [out]
 *	戻り値		ビット配列の先頭アドレス。
 * [note]
 *	* ビット配列のメモリ領域は、このマクロ以外の方法を使って確保しても構いません。
 *	  静的なメモリ領域や、別の方法で確保したメモリ領域に対して、ビット配列の操作を行うことも可能です。
 *	- ただし、必ず32ビットアライメントされたメモリ領域としてください。
 *	  高速化のため、bitarray_get()とbitarray_set()を、32ビット単位で処理を行うように実装したからです。
 *	- 8ビット単位で処理を行うようにすれば、32ビットアライメントの制約は無くなるのですが、
 *	  頻繁にビット配列を操作する場合、速度の方が重要と考えて、32ビット単位で処理を行う実装にしました。
 */
#define bitarray_alloc(bit_len) (calloc(((bit_len) + 31) >> 5, 4)) /* 指定されたbit数を、32bit単位に切り上げて、int配列として確保します */

/* ビット配列のメモリを開放します。
 * [in]
 *	ptr		ビット配列の先頭アドレス。
 */
#define bitarray_free(ptr) do { free(ptr); } while(0)

/* ビット配列の任意の位置から、{1〜32}ビット値を取得します。
 * [in]
 *	ptr		ビット配列の先頭アドレス。
 *	pos		ビット配列の先頭から、何ビット目の位置から、値を取得するか。
 *	bits		取得する値のビット数。
 * [out]
 *	戻り値		取得した値。
 * [note]
 *	* 1ビット未満、及び、32ビット超過の操作は対応していません。
 *	  bitsに1未満、又は、32超過の値を指定すると、C版の実装は実行時エラー,ASM版は動作未定義となります。
 *	* 31ビット以下の値を取得した場合、最上位ビットは符号拡張 *されません* 。
 *	  31ビット以下の値を、符号付きとして扱いたい場合は、呼び出し側で符号拡張してください。
 */
int bitarray_get(const void* ptr, int pos, int bits);

/* ビット配列の任意の位置に、{1〜32}ビット値を格納します。
 * [in]
 *	ptr		ビット配列の先頭アドレス。
 *	pos		ビット配列の先頭から、何ビット目の位置に、値を格納するか。
 *	bits		格納する値のビット数。
 *	value		格納する値。
 * [note]
 *	* 1ビット未満、及び、32ビット超過の操作は対応していません。
 *	  bitsに1未満、又は、32超過の値を指定すると、C版の実装は実行時エラー,ASM版は動作未定義となります。
 *	* 引数valueの、不要な上位ビットは、本関数内でマスクします。
 *	  呼び出し側で、マスクしておく必要はありません。
 */
void bitarray_set(void* ptr, int pos, int bits, int value);

/*****************************************************************************
 *	
 *****************************************************************************/

//	■使用例１：動的に確保したビット配列のメモリを使用する。
//	void* ba = bitarray_alloc(321);		//321ビット分確保。切り上げて324ビット(81ワード)確保される
//	bitarray_set(ba, 100, 24, 0xFEDCBA);	//100ビット目から、24ビット長の範囲に、0xFEDCBAを格納する
//	tmp = bitarray_get(ba, 100, 24);	//100ビット目から、24ビット長を取得。0x00FEDCBAが返される	//符号拡張されて0xFFFEDCBAには*ならない*ことに注意

//	■使用例２：静的に作成したビット配列のデータを使用する。
//	//                   +-------------------31ビット目
//	//                   |      +------------ 0ビット目
//	//                   |      |   +--------63ビット目
//	//                   |      |   |      +-32ビット目
//	const int ba[2] = {0x76543210,0xFEDCBA98};
//	tmp = bitarray_get(ba, 20, 16);		//20ビット目から、16ビット長を取得。0x00008765が返される	//符号拡張されて0xFFFF8765には*ならない*ことに注意

/*****************************************************************************
 *	
 *****************************************************************************/

#endif /*__CLIP_BARY_H__*/
