リハビリ

固定長リングバッファなんぞ作ってみました。なんで固定長かというと複数のイテレータをぐるぐる回しても問題ないようにする為です。や、多分固定長じゃなくてもスマートイテレータとか作ればちゃんと動作するだろうけどめどいので固定長で。多分問題ないはず。あと、固定長だとテンプレートに入れられるのでコンパイル時に展開されるからかなり軽くなるはず。多分。

まあ、一番の目的は私のテンプレート系の実装のリハビリですし(^^;

template< class T, int T_SIZE >
class StaticRingBuffer
{
public:
	StaticRingBuffer(){}
	virtual ~StaticRingBuffer(){}
	class iterator;

	T& operator[]( int index ){
		const int temp = index % T_SIZE;
		if( 0 <= temp ){
			return m_aData[temp];
		}else{
			return m_aData[temp + T_SIZE];
		}
	}

	int size( void ){
		return T_SIZE;
	}

	iterator begin(){
		iterator temp;
		temp.m_pPointer = m_aData;
		temp.m_nPointer = 0;
		return temp;
	}

	class iterator{
	public:
		iterator(){}
		virtual ~iterator(){}

		T& operator*(){ return *( m_pPointer + m_nPointer ); }
		T* operator->(){ return ( m_pPointer + m_nPointer ); }

		iterator& operator=( iterator& po ){
			m_pPointer = po.m_pPointer;
			m_nPointer = po.m_nPointer;
			return *this;
		}
		iterator& operator++( int ){
			iterator temp = *this;
			m_nPointer++;
			if( m_nPointer == T_SIZE ){
				m_nPointer = 0;
			}
			return temp;
		}
		iterator& operator++(){
			++m_nPointer;
			if( m_nPointer == T_SIZE ){
				m_nPointer = 0;
			}
			return *this;
		}
		iterator& operator--( int ){
			iterator temp = *this;
			m_nPointer--;
			if( m_nPointer < 0 ){
				m_nPointer = T_SIZE - 1;
			}
			return temp;
		}
		iterator& operator--(){
			--m_nPointer;
			if( m_nPointer < 0 ){
				m_nPointer = T_SIZE - 1;
			}
			return *this;
		}
		iterator& operator+=( int index ){
			m_nPointer = ( m_nPointer + index ) % T_SIZE;
			if( m_nPointer < 0 ){
				m_nPointer += T_SIZE;
			}
			return *this;
		}
		iterator& operator-=( int index ){
			m_nPointer = ( m_nPointer - index ) % T_SIZE;
			if( m_nPointer < 0 ){
				m_nPointer += T_SIZE;
			}
			return *this;
		}
		iterator operator+( int index ){
			iterator temp = *this;
			return ( temp += index );
		}
		iterator operator-( int index ){
			iterator temp = *this;
			return ( temp -= index );
		}
		bool operator ==( iterator& it ){
			return ( ( m_pPointer == it.m_pPointer ) && ( m_nPointer == it.m_nPointer ) );
		}
		bool operator !=( iterator& it ){
			return ( ( m_pPointer != it.m_pPointer ) || ( m_nPointer != it.m_nPointer ) );
		}
	private:
		T* m_pPointer;
		int m_nPointer;

		friend class StaticRingBuffer;
	};

private:
	T m_aData[T_SIZE];
};

一応、STLに似せて作っているのだけれども、そもそも固定長だからあんまりメンバ関数がないのよね。まあいいか。本当なら参照しているイテレータをカウントして勝手に開放されないとか、若しくは開放された時点でイテレータを参照したら例外を吐くとかやりたかったんだけどまあこれでも実用に耐えられるかなと。

ところで、イテレータの実装方法がイマイチわからなかったのでlistのソース見て気が付いたんですけど、++itとit++だとit++は一時的にクラスを作っている分遅いんですね。++itの方が速いという噂は聞いたことあったけどその理由を始めて知りましたorz