//
// This SWIG module shows how you can create a Python array class in C++ 
// and catch C++ exceptions.

%module darray
%{

// Exception class
class RangeError { };

%}

// This defines a SWIG exception handler.   This code will be inserted
// into the wrapper code generated by SWIG.  The variable '$function' is
// substituted with the *real* C++ function call.

%except(python) {
  try {
    $function
  } 
  catch (RangeError) {
    PyErr_SetString(PyExc_IndexError,"index out-of-bounds");
    return NULL;
  }
}

// Just define our class in-line since it has been specifically designed
// for Python anyways.
	
%inline %{

  class DoubleArray {
  private:
    int n;
    double *ptr;
    int isslice;
  public:
    
    // Create a new array of fixed size

    DoubleArray(int size) {
      ptr = new double[size];
      n = size;
      isslice = 0;
    }

    // Create a slice (used internally)

#ifndef SWIG
    DoubleArray(double *pt,int size) {
      ptr = pt;
      n = size;
      isslice = 1;
    }
#endif
      
    // Destroy an array

    ~DoubleArray() {
      if (!isslice)
	delete [] ptr;
    }
    
    // Return the length of the array

    int    __len__() {
      return n;
    }
    
    // Get an item from the array and perform bounds checking.

    double __getitem__(int i) {
      if ((i >= 0) && (i < n))
	return ptr[i];
      else
	throw RangeError();
	return 0;
    }
    
    // Set an item in the array and perform bounds checking.

    void __setitem__(int i, double val) {
      if ((i >= 0) && (i < n))
	ptr[i] = val;
      else {
	throw RangeError();
      }
    }
    
    // Return a slice of this array.  
    DoubleArray __getslice__(int low,int high) {
      int i;
      if (low < 0) low = 0;
      if (low >= n) high = n;
      if (high < 0) high = 0;
      if (high >= n) high = n;
      if (low > high) low = high;
      return DoubleArray(ptr+low,high-low);
    }
  };

%}

