/*	
 *	clipwkst.h
 *
 *	ワークシート(多階層ハッシュテーブル)
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2015-2016 Naoyuki Sawa
 *
 *	* Mon Jul 13 21:22:16 JST 2015 Naoyuki Sawa
 *	- 1st リリース。
 *	* Wed Jul 15 01:12:55 JST 2015 Naoyuki Sawa
 *	- Worksheet_ref_l(),Worksheet_ref_a(),Worksheet_ref_v()を追加しました。
 *	- Worksheet_sum_l(),Worksheet_sum_a(),Worksheet_sum_v()を追加しました。
 *	* Thu Jul 16 22:21:18 JST 2015 Naoyuki Sawa
 *	- Worksheet_sort(),Worksheet_sort_l(),Worksheet_sort_a(),Worksheet_sort_v()を追加しました。
 *	* Sun Jul 19 12:59:05 JST 2015 Naoyuki Sawa
 *	- コメントのみ追記:
 *	  当モジュールの関数は、キーや値に指定できるのは数値のみで、文字列は指定できません。
 *	  キーや値に文字列を指定したい場合は、本日clipstr.cモジュールに追加した、quark_from_string(),quark_to_string()を併用してください。
 *	  <例>
 *	  │Worksheet_set_l(ws,quark_from_string("Value"),quark_from_string("Key"),-1);
 *	  │iVal=Worksheet_get_l(ws,quark_from_string("Key"),-1);
 *	  │if(iVal!=-1){puts(quark_to_string(iVal));}
 *	* Wed Nov 18 21:37:53 JST 2015 Naoyuki Sawa
 *	- 'extern "C" {'〜'}'で囲みました。.cppを含むWin32プロジェクトからもインクルード出来るようにするためです。
 *	* Fri Dec 11 21:38:17 JST 2015 Naoyuki Sawa
 *	- Worksheet_incr_l()等が、これまでは戻り値無しでしたが、(1)増加後の値を返すようにしました。
 *	  カウンタとして用いる場合、セルの値を(1)増加して、すぐにその値を参照する事が多いからです。
 *	- 戻り値を無視すれば動作は変わっていないので、既存のアプリケーションへの影響は有りません。
 *	* Sun Jul 17 21:03:07 JST 2016 Naoyuki Sawa
 *	- Worksheet_ref_l(),Worksheet_get_l(),Worksheet_sum_l(),Worksheet_set_l(),Worksheet_unset_l(),Worksheet_incr_l(),Worksheet_first_l(),Worksheet_sort_l(),
 *	  Worksheet_ref_a(),Worksheet_get_a(),Worksheet_sum_a(),Worksheet_set_a(),Worksheet_unset_a(),Worksheet_incr_a(),Worksheet_first_a(),Worksheet_sort_a()をアセンブラ化しました。
 *	  主な目的は、コードサイズの低減です。
 *	  当モジュールコードサイズが、1468バイト⇒1016バイトに減りました。
 *	* Sun Jul 17 22:34:56 JST 2016 Naoyuki Sawa
 *	- USE_WORKSHEET_GTREEシンボルを定義すると、当モジュールがgtree.cモジュールを使用するようにしました。
 *	  USE_WORKSHEET_GTREEシンボルを定義しなければ、これまで通り、ght_hash_table.cモジュールを使用します。
 *	  当面は、USE_WORKSHEET_GTREEシンボルを定義して、gtree.cモジュールを使用するようにして、動作を検証しようと思います。
 *	  万一、動作上の問題が生じたら、ght_hash_table.cモジュールを使用するように戻して下さい。
 *	- gtree.cモジュールを使用するように変更したい理由は、ソート関数(Worksheet_sort()等)が不要になるからです。
 *	  ツリーは常にソートされているので、アプリケーションがイテレーション等の前に、明示的にソートする必要が無くなります。
 *	  USE_WORKSHEET_GTREEが定義されている場合はソート関数はダミー処理となります。
 *	  USE_WORKSHEET_GTREEが定義されている場合はソート関数を無効にしても良いのですが、ソート関数を呼び出している既存のアプリケーションのために残しておく事にしました。
 */
#ifndef __CLIP_WKST_H__
#define __CLIP_WKST_H__
#ifdef  __cplusplus
extern "C" {
#endif//__cplusplus
// * Sun Jul 17 22:34:56 JST 2016 Naoyuki Sawa
// - USE_WORKSHEET_GTREEシンボルを定義すると、当モジュールがgtree.cモジュールを使用するようにしました。
//   USE_WORKSHEET_GTREEシンボルを定義しなければ、これまで通り、ght_hash_table.cモジュールを使用します。
//   当面は、USE_WORKSHEET_GTREEシンボルを定義して、gtree.cモジュールを使用するようにして、動作を検証しようと思います。
//   万一、動作上の問題が生じたら、ght_hash_table.cモジュールを使用するように戻して下さい。
// - gtree.cモジュールを使用するように変更したい理由は、ソート関数(Worksheet_sort()等)が不要になるからです。
//   ツリーは常にソートされているので、アプリケーションがイテレーション等の前に、明示的にソートする必要が無くなります。
//   USE_WORKSHEET_GTREEが定義されている場合はソート関数はダミー処理となります。
//   USE_WORKSHEET_GTREEが定義されている場合はソート関数を無効にしても良いのですが、ソート関数を呼び出している既存のアプリケーションのために残しておく事にしました。
#define USE_WORKSHEET_GTREE
/****************************************************************************
 *	
 ****************************************************************************/
//集計表の単一階層
typedef struct _ST_Worksheet {
	int			iVal;		//この階層のセルの値
#ifndef USE_WORKSHEET_GTREE
	ght_hash_table_t*	tKey;		//子階層のハッシュテーブル
#else //USE_WORKSHEET_GTREE
	GTree*			tKey;		//子階層のツリー
#endif//USE_WORKSHEET_GTREE
} ST_Worksheet;
/*--------------------------------------------------------------------------*/
//集計表のイテレータ
typedef struct _ST_Worksheet_Iterator {
#ifndef USE_WORKSHEET_GTREE
	ght_hash_table_t*	p_ht;		//走査中のハッシュテーブル
	ght_iterator_t		it;		//ハッシュテーブルのイテレータ
#else //USE_WORKSHEET_GTREE
	GTree*			tree;		//走査中のツリー
	GTreeIteratorNP		it;		//ツリーのイテレータ
#endif//USE_WORKSHEET_GTREE
} ST_Worksheet_Iterator;
/****************************************************************************
 *	
 ****************************************************************************/
//作成/開放
ST_Worksheet* Worksheet_new();
void Worksheet_free(ST_Worksheet* ws/*ヌル可*/);
/*--------------------------------------------------------------------------*/
//参照
ST_Worksheet* Worksheet_ref_l(ST_Worksheet* ws/*ヌル可*/, ... /*,(-1)*/);
ST_Worksheet* Worksheet_ref_a(ST_Worksheet* ws/*ヌル可*/, va_list ap);
ST_Worksheet* Worksheet_ref_v(ST_Worksheet* ws/*ヌル可*/, const int* aKey/*={key,key,...,key,-1}*/);
/*--------------------------------------------------------------------------*/
//取得
int Worksheet_get_l(ST_Worksheet* ws/*ヌル可*/, ... /*,(-1)*/);
int Worksheet_get_a(ST_Worksheet* ws/*ヌル可*/, va_list ap);
int Worksheet_get_v(ST_Worksheet* ws/*ヌル可*/, const int* aKey/*={key,key,...,key,-1}*/);
/*--------------------------------------------------------------------------*/
//合計
int Worksheet_sum_l(ST_Worksheet* ws/*ヌル可*/, ... /*,(-1)*/);
int Worksheet_sum_a(ST_Worksheet* ws/*ヌル可*/, va_list ap);
int Worksheet_sum_v(ST_Worksheet* ws/*ヌル可*/, const int* aKey/*={key,key,...,key,-1}*/);
/*--------------------------------------------------------------------------*/
//設定
void Worksheet_set_l(ST_Worksheet* ws, int iVal, ... /*,(-1)*/);
void Worksheet_set_a(ST_Worksheet* ws, int iVal, va_list ap);
void Worksheet_set_v(ST_Worksheet* ws, int iVal, const int* aKey/*={key,key,...,key,-1}*/);
/*--------------------------------------------------------------------------*/
//削除
void Worksheet_unset_l(ST_Worksheet* ws/*ヌル可*/, ... /*,(-1)*/);
void Worksheet_unset_a(ST_Worksheet* ws/*ヌル可*/, va_list ap);
void Worksheet_unset_v(ST_Worksheet* ws/*ヌル可*/, const int* aKey/*={key,key,...,key,-1}*/);
/*--------------------------------------------------------------------------*/
//計数
int Worksheet_incr_l(ST_Worksheet* ws, ... /*,(-1)*/);
int Worksheet_incr_a(ST_Worksheet* ws, va_list ap);
int Worksheet_incr_v(ST_Worksheet* ws, const int* aKey/*={key,key,...,key,-1}*/);
/*--------------------------------------------------------------------------*/
//走査開始
int Worksheet_first_l(ST_Worksheet* ws/*ヌル可*/, ST_Worksheet_Iterator* it, ... /*,(-1)*/);
int Worksheet_first_a(ST_Worksheet* ws/*ヌル可*/, ST_Worksheet_Iterator* it, va_list ap);
int Worksheet_first_v(ST_Worksheet* ws/*ヌル可*/, ST_Worksheet_Iterator* it, const int* aKey/*={key,key,...,key,-1}*/);
/*--------------------------------------------------------------------------*/
//走査継続
int Worksheet_next(ST_Worksheet_Iterator* it);
/*--------------------------------------------------------------------------*/
//ソート											//┐
void Worksheet_sort(ST_Worksheet* ws/*ヌル可*/);						//│
void Worksheet_sort_l(ST_Worksheet* ws/*ヌル可*/, ... /*,(-1)*/);				//├USE_WORKSHEET_GTREEが定義されている場合はソート関数はダミー処理となります。USE_WORKSHEET_GTREEが定義されている場合はソート関数を無効にしても良いのですが、ソート関数を呼び出している既存のアプリケーションのために残しておく事にしました。
void Worksheet_sort_a(ST_Worksheet* ws/*ヌル可*/, va_list ap);					//│
void Worksheet_sort_v(ST_Worksheet* ws/*ヌル可*/, const int* aKey/*={key,key,...,key,-1}*/);	//┘
/*--------------------------------------------------------------------------*/
//ダンプ
void Worksheet_dump(ST_Worksheet* ws/*ヌル可*/);
#ifdef  __cplusplus
}//extern "C"
#endif//__cplusplus
#endif//__CLIP_WKST_H__
