/*
 $Id: array3.c,v 1.1 1996/10/10 10:01:12 roitzsch Exp $
 (C)opyright 1996 by Konrad-Zuse-Center, Berlin
 All rights reserved.
 Part of the Kaskade distribution
*/

#include "array3.h"


template<class T> void Array3<T>:: allocate(int ll0, int lh0, int rl0,
					    int rh0, int cl0, int ch0)	 
{									 
	int i, j, k, length;						 
	ll=ll0;  lh=lh0;  rl=rl0;  rh=rh0;  cl=cl0;  ch=ch0;		 

	// cout << "\n\n--- array3: cl, ch = " << cl << " " << ch <<"\n";

	layer = (T***) new T*[lh-ll+1];		 		 
	if (!layer) { cout << "\n*** class Array3: allocation failure\n"; 
		      cout.flush(); abort(); }
	layer -= ll;							 
									 
	layer[ll] = new T*[(lh-ll+1)*(rh-rl+1)];			 
	if (!layer[ll]) { cout << "\n*** class Array3: allocation failure\n"; 
			  cout.flush(); abort(); }
	layer[ll] -= rl;						 
        for (i=ll+1; i<=lh; ++i)  layer[i] = layer[i-1] + rh-rl+1;  	 
									 
	T* base = new T[(lh-ll+1)*(rh-rl+1)*(ch-cl+1)];		 
	if (!base) cout << "\n*** array3: allocation failure\n";
	base -= cl;							 
	length = ch-cl+1;						 
	k=0;						        	 
        for (i=ll; i<=lh; ++i)  					 
            for (j=rl; j<=rh; ++j)  {					 
	        layer[i][j] = base + k*length;				 
	        ++k;							 
	    }								 
}

template<class T> void Array3<T>:: checkBounds(int i, int j, int k) const
{
    if (i<ll || i>lh || j<rl || j>rh || k<cl || k>ch)	
    {
	cout << "\n*** array3d index ("<<i<<","<<j<<","<<k<<") out of range\n";
	cout.flush(); abort();
    }
}
template<class T> void Array3<T>:: checkBounds(int i, int j) const
{
    if (i<ll || i>lh || j<rl || j>rh)	
    {
	cout << "\n*** array3d index ("<<i<<","<<j<<") out of range\n";
	cout.flush(); abort();
    }
}
template<class T> void Array3<T>:: checkBounds(int i) const
{
    if (i<ll || i>lh)	
    {
	cout << "\n*** array3d index ("<<i<<") of range\n";
	cout.flush(); abort();
    }
}
//-------------------------------------------------------------------------


template<class T> Array3<T>:: Array3(Array3<T>& /*vec*/)
{
    notImplemented("Array3:: copy constructor! Check function arguments");
}
	
/*							 
  template<class T>   Array3<T>& Array3<T>::operator= (Array3<T>& m)
  {
  int i,j,k; 
  
  for(i=ll; i<=lh; ++i)
  for(j=rl; j<=rh; ++j) 
  for(k=cl; k<=ch; ++k) (*this)(i,j,k) = m(i,j,k);  
  return *this; 
  }    
  
  template<class T>   Array3<T>& Array3<T>::operator= (T m)
  {
  int i,j,k; 
  
  for(i=ll; i<=lh; ++i)
  for(j=rl; j<=rh; ++j) 
  for(k=cl; k<=ch; ++k) (*this)(i,j,k) = m;
  return *this; 
  }    
  */

template<class T> int Array3<T>:: size()    
{ 
    return (lh-ll+1)*(rh-rl+1)*(ch-cl+1); 
}
template<class T> int Array3<T>:: memSize() 
{ 
    return (lh-ll+1)*(rh-rl+1)*(ch-cl+1)*sizeof(T); 
}

template<class T> void Array3<T>:: print() const
{									 
     int i, j, k;		

     for (k=ll; k<=lh; ++k) {
         cout << "\nLayer " << k << ":";
         for (i=rl; i<=rh; ++i) {	
		cout << "\n";						 
		for (j=cl; j<=ch; ++j)  cout << layer[k][i][j] << " ";	 
        } 
     }
     cout << "\n";
}
//-------------------------------------------------------------------------

template<class T> void Array3<T>:: notImplemented(const char* s) const
{
    cout << "\n*** Class Array3: called function " 
    					<< s << " not implemented\n";
    cout.flush(); abort();

}

