// This may look like C code, but it is really -*- C++ -*-
// RTSS --- Railway Total System Simulator
// (c) TAKAGI Ryo (at Prof. SONE's Laboratory, the Univ. of Tokyo.)
// NoRefTable.hh --- template class NoRefTable
// $Id: table.hh,v 2.4 1994/12/27 12:03:47 rt Exp $

#ifndef ___NOREFTABLE_DEF_HH
#define ___NOREFTABLE_DEF_HH

// **** 関数の定義 ****

// コンストラクタ
template <class TP>
NoRefTable<TP>::NoRefTable
() {
    data = bxold = 0;
    num = mmax = bxoldm = 0;
}

// メンバコピー
template <class TP>
void
NoRefTable<TP>::membercopy
( const NoRefTable<TP>& x ) {
    num = x.num;
    if (num > 0) {
	if (num > mmax) {
	    if ( data ) delete [] data;
	    data = new TP[ mmax = num + GETMEMORYNUMBER ];
	    // いちどにたくさんメモリを取得
	}
	for (register int i = 0; i < num; i++)
	    data[i] = x.data[i];
    }
}

// X(X&)
template <class TP>
NoRefTable<TP>::NoRefTable
( const NoRefTable<TP>& x ) {
    data = bxold = 0;
    num = mmax = bxoldm = 0;
    membercopy(x);
}

// デストラクタ
template <class TP>
NoRefTable<TP>::~NoRefTable
() {
    if ( data ) delete [] data;
    if ( bxold ) delete [] bxold;
}

// 代入演算子
template <class TP>
NoRefTable<TP>&
NoRefTable<TP>::operator=
( const NoRefTable<TP>& x ) {
    if (&x == this) return *this;
    membercopy(x);
    return *this;
}



// 配列データの参照
template < class TP >
TP
NoRefTable < TP > :: operator[]
( int i )
  const
{
  if ( i < 0 || i >= num )
  {		// この場合はエラー
    error26_name () ;			//   エラーメッセージ
    exit ( 26 ) ;			//   Exit コード 26
  }
  return data [ i ] ;
}



// 配列の最大数を変更、中身はなしでよい
template <class TP>
void
NoRefTable<TP>::renew
( int max ) {
    renew();
    if ( mmax < max ) {
	if ( mmax > 0 && data ) delete [] data;
	data = new TP[ mmax = max + GETMEMORYNUMBER ] ;
    }
}

// 配列の最大数を希望の値にセット
template <class TP>
void
NoRefTable<TP>::setnum
( int nm ) {
    renew( nm );
    num = nm;
}

// データを加える
template <class TP>
NoRefTable<TP>&
NoRefTable<TP>::operator+=
( const TP x ) {
    num_incrementation( 1 );
    data[ num - 1 ] = x;
    return *this;
}

// 配列をくっつける
template <class TP>
NoRefTable<TP>&
NoRefTable<TP>::operator+=
( const NoRefTable<TP>& x ) {
    if (&x == this) return *this;
    num_incrementation_restore( x.num );
    for ( register int i = 0; i < x.num; i++ )
        data[ i + num ] = x.data[ i ];
    num += x.num;
    return *this;
}


// 配列範囲外参照エラーメッセージ
template <class TP>
/* virtual */ void
NoRefTable<TP>::error26_name
() const {
    cerr << "Error: subscript out of range in\n";
    cerr << "       NoRefTable object TP data call\n";
}

// 配列の任意順位の要素を取り除き、その値を返す。
template <class TP>
TP
NoRefTable<TP>::remove
( int irm ) {
    bxold_resize();			// {\tt bxold} 領域を確保
    bxold [ 0 ] = data [ irm ];		// 取り除く要素を退避
    for ( register int i = irm;		// 配列を1つずつ前にずらす
          i < num; i++ )
        data [ i - 1 ] = data [ i ];
    num--;
    return bxold [ 0 ];			// 取り除いた要素を {\tt return}
}



#endif /* ! ___REFPOINTERTABLE_DEF_HH */
