File Annotation

Not logged in
dcdd144598 2011-02-23        kinaba: #ifndef _KILIB_KTL_GAP_H_
dcdd144598 2011-02-23        kinaba: #define _KILIB_KTL_GAP_H_
dcdd144598 2011-02-23        kinaba: #include "types.h"
dcdd144598 2011-02-23        kinaba: #include "memory.h"
dcdd144598 2011-02-23        kinaba: #ifndef __ccdoc__
dcdd144598 2011-02-23        kinaba: namespace ki {
dcdd144598 2011-02-23        kinaba: #endif
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: //@{ @pkg ki.KTL //@}
dcdd144598 2011-02-23        kinaba: //@{
dcdd144598 2011-02-23        kinaba: //	基本型専用ギャップバッファ
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: //	小耳に挟んだギャップバッファというもの。
dcdd144598 2011-02-23        kinaba: //	ものすごい勘違いをして別物ができているかもしれませんが、
dcdd144598 2011-02-23        kinaba: //	細かいことはあまり気にしないでください。
dcdd144598 2011-02-23        kinaba: //	配列のようにランダムアクセス可能で、
dcdd144598 2011-02-23        kinaba: //	同一箇所への連続した挿入/削除が速いというデータ構造です。
dcdd144598 2011-02-23        kinaba: //	( 下の図で言うと、gap_startへの挿入/削除にはデータの移動が必要ない )
dcdd144598 2011-02-23        kinaba: //	<pre>
dcdd144598 2011-02-23        kinaba: //@@  D  <--0
dcdd144598 2011-02-23        kinaba: //@@  D
dcdd144598 2011-02-23        kinaba: //@@  |  <--gap_start
dcdd144598 2011-02-23        kinaba: //@@  |
dcdd144598 2011-02-23        kinaba: //@@  D  <--gap_end
dcdd144598 2011-02-23        kinaba: //@@  D
dcdd144598 2011-02-23        kinaba: //@@     <--array_end
dcdd144598 2011-02-23        kinaba: //	</pre>
dcdd144598 2011-02-23        kinaba: //	メモリイメージをそのままコピーしてる実装なので、
dcdd144598 2011-02-23        kinaba: //	プリミティブ型以外では絶対に使わないこと。
dcdd144598 2011-02-23        kinaba: //@}
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: template<class T>
dcdd144598 2011-02-23        kinaba: class gapbuf : public Object
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: public:
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	//@{
dcdd144598 2011-02-23        kinaba: 	//	コンストラクタ
dcdd144598 2011-02-23        kinaba: 	//	@param alloc_size
dcdd144598 2011-02-23        kinaba: 	//		最初に確保する"メモリの"サイズ。
dcdd144598 2011-02-23        kinaba: 	//		"配列の"サイズではないことに注意。
dcdd144598 2011-02-23        kinaba: 	//@}
dcdd144598 2011-02-23        kinaba: 	explicit gapbuf( ulong alloc_size=40 )
dcdd144598 2011-02-23        kinaba: 		: alen_( Max(alloc_size, 10UL) )
dcdd144598 2011-02-23        kinaba: 		, gs_  ( 0 )
dcdd144598 2011-02-23        kinaba: 		, ge_  ( alen_ )
dcdd144598 2011-02-23        kinaba: 		, buf_ ( new T[alen_] )
dcdd144598 2011-02-23        kinaba: 		{}
dcdd144598 2011-02-23        kinaba: 	~gapbuf()
dcdd144598 2011-02-23        kinaba: 		{ delete [] buf_; }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	//@{ 要素挿入 //@}
dcdd144598 2011-02-23        kinaba: 	void InsertAt( ulong i, const T& x )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			MakeGapAt( i );
dcdd144598 2011-02-23        kinaba: 			buf_[gs_++] = x;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			if( gs_==ge_ )
dcdd144598 2011-02-23        kinaba: 				Reallocate( alen_<<1 );
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	//@{ 要素挿入(複数) //@}
dcdd144598 2011-02-23        kinaba: 	void InsertAt( ulong i, const T* x, ulong len )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			MakeGapAt( size() );
dcdd144598 2011-02-23        kinaba: 			MakeGapAt( i );
dcdd144598 2011-02-23        kinaba: 			if( ge_-gs_ <= len )
dcdd144598 2011-02-23        kinaba: 				Reallocate( Max(alen_+len+1, alen_<<1) );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			memmove( buf_+gs_, x, len*sizeof(T) );
dcdd144598 2011-02-23        kinaba: 			gs_ += len;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	//@{ 末尾に要素を追加 //@}
dcdd144598 2011-02-23        kinaba: 	void Add( const T& x )
dcdd144598 2011-02-23        kinaba: 		{ InsertAt( size(), x ); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	//@{ 末尾に要素を追加(複数) //@}
dcdd144598 2011-02-23        kinaba: 	void Add( const T* x, ulong len )
dcdd144598 2011-02-23        kinaba: 		{ InsertAt( size(), x, len ); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	//@{ 要素削除 //@}
dcdd144598 2011-02-23        kinaba: 	void RemoveAt( ulong i, ulong len=1 )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			if( i <= gs_ && gs_ <= i+len )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				// この場合はメモリ移動の必要がない
dcdd144598 2011-02-23        kinaba: 				// まず前半を削除
dcdd144598 2011-02-23        kinaba: 				len -= (gs_-i);
dcdd144598 2011-02-23        kinaba: 				gs_ = i;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 			else
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				MakeGapAt( i );
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			// 後半を削除
dcdd144598 2011-02-23        kinaba: 			ge_ += len;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	//@{ 要素削除(全部) //@}
dcdd144598 2011-02-23        kinaba: 	void RemoveAll()
dcdd144598 2011-02-23        kinaba: 		{ RemoveAt( 0, size() ); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	//@{ 要素削除(指定index以降全部) //@}
dcdd144598 2011-02-23        kinaba: 	void RemoveToTail( ulong i )
dcdd144598 2011-02-23        kinaba: 		{ RemoveAt( i, size()-i ); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	//@{ 要素コピー(指定index以降全部) //@}
dcdd144598 2011-02-23        kinaba: 	ulong CopyToTail( ulong i, T* x )
dcdd144598 2011-02-23        kinaba: 		{ return CopyAt( i, size()-i, x ); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	//@{ 要素コピー //@}
dcdd144598 2011-02-23        kinaba: 	ulong CopyAt( ulong i, ulong len, T* x )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			ulong copyed=0;
dcdd144598 2011-02-23        kinaba: 			if( i < gs_ )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				// 前半
dcdd144598 2011-02-23        kinaba: 				copyed += Min( len, gs_-i );
dcdd144598 2011-02-23        kinaba: 				memmove( x, buf_+i, copyed*sizeof(T) );
dcdd144598 2011-02-23        kinaba: 				x   += copyed;
dcdd144598 2011-02-23        kinaba: 				len -= copyed;
dcdd144598 2011-02-23        kinaba: 				i   += copyed;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			// 後半
dcdd144598 2011-02-23        kinaba: 			memmove( x, buf_+(i-gs_)+ge_, len*sizeof(T) );
dcdd144598 2011-02-23        kinaba: 			return copyed + len;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: public:
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	//@{ 要素数 //@}
dcdd144598 2011-02-23        kinaba: 	ulong size() const
dcdd144598 2011-02-23        kinaba: 		{ return alen_ - (ge_-gs_); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	//@{ 要素取得 //@}
dcdd144598 2011-02-23        kinaba: 	T& operator[]( ulong i )
dcdd144598 2011-02-23        kinaba: 		{ return buf_[ ( i<gs_ ) ? i : i+(ge_-gs_) ]; }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	//@{ 要素取得(const) //@}
dcdd144598 2011-02-23        kinaba: 	const T& operator[]( ulong i ) const
dcdd144598 2011-02-23        kinaba: 		{ return buf_[ ( i<gs_ ) ? i : i+(ge_-gs_) ]; }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: protected:
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	ulong alen_;
dcdd144598 2011-02-23        kinaba: 	ulong gs_;
dcdd144598 2011-02-23        kinaba: 	ulong ge_;
dcdd144598 2011-02-23        kinaba: 	T*    buf_;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: protected:
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	void MakeGapAt( ulong i )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			if( i<gs_ )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				ge_ -= (gs_-i);
dcdd144598 2011-02-23        kinaba: 				memmove( buf_+ge_, buf_+i, (gs_-i)*sizeof(T) );
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 			else if( i>gs_ )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				int j = i+(ge_-gs_);
dcdd144598 2011-02-23        kinaba: 				memmove( buf_+gs_, buf_+ge_, (j-ge_)*sizeof(T) );
dcdd144598 2011-02-23        kinaba: 				ge_ = j;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 			gs_ = i;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	void Reallocate( ulong newalen )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			T *tmp = new T[newalen], *old=buf_;
dcdd144598 2011-02-23        kinaba: 			const ulong tail = alen_-ge_;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			memmove( tmp, old, gs_*sizeof(T) );
dcdd144598 2011-02-23        kinaba: 			memmove( tmp+newalen-tail, old+ge_, tail*sizeof(T) );
dcdd144598 2011-02-23        kinaba: 			delete [] old;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			buf_  = tmp;
dcdd144598 2011-02-23        kinaba: 			ge_   = newalen-tail;
dcdd144598 2011-02-23        kinaba: 			alen_ = newalen;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: private:
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	NOCOPY(gapbuf<T>);
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: //@{
dcdd144598 2011-02-23        kinaba: //	gapbuf + smartptr のふり
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: //	要素削除時にdeleteを実行しっちゃったりするバージョン。
dcdd144598 2011-02-23        kinaba: //	任意オブジェクトをギャップバッファで使いたいときは
dcdd144598 2011-02-23        kinaba: //	これでてきとーに代用すべし。
dcdd144598 2011-02-23        kinaba: //@}
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: template<class T>
dcdd144598 2011-02-23        kinaba: class gapbufobj : public gapbuf<T*>
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: public:
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	explicit gapbufobj( ulong alloc_size=40 )
dcdd144598 2011-02-23        kinaba: 		: gapbuf<T*>( alloc_size )
dcdd144598 2011-02-23        kinaba: 		{ }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	void RemoveAt( ulong i, ulong len=1 )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			ulong& gs_ = gapbuf<T*>::gs_;
dcdd144598 2011-02-23        kinaba: 			ulong& ge_ = gapbuf<T*>::ge_;
dcdd144598 2011-02-23        kinaba: 			T**&   buf_= gapbuf<T*>::buf_;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			if( i <= gs_ && gs_ <= i+len )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				// 前半を削除
dcdd144598 2011-02-23        kinaba: 				for( ulong j=i, ed=gs_; j<ed; ++j )
dcdd144598 2011-02-23        kinaba: 					delete buf_[j];
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 				len -= (gs_-i);
dcdd144598 2011-02-23        kinaba: 				gs_  = i;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 			else
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				gapbuf<T*>::MakeGapAt( i );
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			// 後半を削除
dcdd144598 2011-02-23        kinaba: 			for( ulong j=ge_, ed=ge_+len; j<ed; ++j )
dcdd144598 2011-02-23        kinaba: 				delete buf_[j];
dcdd144598 2011-02-23        kinaba: 			ge_ = ge_+len;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	~gapbufobj()
dcdd144598 2011-02-23        kinaba: 		{ RemoveAt( 0, gapbuf<T*>::size() ); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	void RemoveAll( ulong i )
dcdd144598 2011-02-23        kinaba: 		{ RemoveAt( 0, gapbuf<T*>::size() ); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	void RemoveToTail( ulong i )
dcdd144598 2011-02-23        kinaba: 		{ RemoveAt( i, gapbuf<T*>::size()-i ); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: public:
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	T& operator[]( ulong i )
dcdd144598 2011-02-23        kinaba: 		{ return *gapbuf<T*>::operator[](i); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	const T& operator[]( ulong i ) const
dcdd144598 2011-02-23        kinaba: 		{ return *gapbuf<T*>::operator[](i); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: private:
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	NOCOPY(gapbufobj<T>);
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: }      // namespace ki
dcdd144598 2011-02-23        kinaba: #endif // _KILIB_KTL_GAP_H_