1. Shouldn't the std_string.i have typemaps for std::string* in them?
   Currently, public members of a class with type std::string are not
   converted automatically by SWIG.

        // file: std_string_ex.py
        %module foo
        %include "std_string.i"

        %{
           class foo
           {
            public:
                std::string bar;
                foo() { bar = "bar"; }
           };
        %}

        class foo
        {
            public:
                std::string bar;
        };

    C:\wrk\chaco_all\kiva\agg\src>swig -c++ -python -shadow std_string_ex.py
    C:\wrk\chaco_all\kiva\agg\src>g++ -shared -Ic:/Python22/include std_string_ex_wrap.cxx
                                  -Lc:/Python22/libs -lpython22 -o _foo.dll
    C:\wrk\chaco_all\kiva\agg\src>python
    Enthought Edition 1.0a1 based on
    Python 2.2.3 (#42, Jun  4 2003, 10:33:42) [MSC 32 bit (Intel)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import foo
    >>> q = foo.foo()
    >>> q.bar
    '_b8498c00_p_std__string'


   Adding the following typemaps to the file fixes this issue:

       %typemap(python,in) std::string *
       {
           if (PyString_Check ($input))
           {
             $1 = new std::string((char *)PyString_AsString($input));
           }
           else
           {
             PyErr_SetString (PyExc_TypeError, "not a String");
             return NULL;
           }
       }
       %typemap(python,out) std::string *
       {
            $result = PyString_FromString((const char *)$1->c_str());
       }
       %typemap (python, freearg) std::string *
       {
         if ($1)
         {
           delete $1;
         }
       }

    C:\wrk\chaco_all\kiva\agg\src>swig -c++ -python -shadow std_string_ex.py
    C:\wrk\chaco_all\kiva\agg\src>g++ -shared -Ic:/Python22/include std_string_ex_wrap.cxx
                                  -Lc:/Python22/libs -lpython22 -o _foo.dll
    C:\wrk\chaco_all\kiva\agg\src>python
    Enthought Edition 1.0a1 based on
    Python 2.2.3 (#42, Jun  4 2003, 10:33:42) [MSC 32 bit (Intel)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import foo
    >>> q = foo.foo()
    >>> q.bar
    'bar'

    Is there a downside to adding these?  Perhaps they should be declared as
    memberin and memberout ??

2.  How do you add a new constructor to a class?  I would like to modify a
    class that takes foo(double, double, double, double, double, double) so
    that it can be initialized through a Numeric array with 6 elements.  I
    haven't gotten very far.

    I tried doing the following:

    // file: affine_matrix.i
    %{
        #include "Numeric/arrayobject.h"
        #include "agg_affine_matrix.h"

        agg::affine_matrix* new_affine_matrix(double ary[6])
        {
            agg::affine_matrix* result = new agg::affine_matrix(ary[0], ary[1],
                                                                ary[2], ary[3],
                                                                ary[4], ary[5]);
            return result;
        }
    }

    %}

    %typemap(in) (double ary[6])
    {
        // !! cheap and cheerful -- add checks later
        PyArrayObject* ary = (PyArrayObject*) $input;
        $1 = (double*) ary->data;
    }

    %include "agg_affine_matrix.h"

    %extend agg::affine_matrix
    {
        // constructors from array
        affine_matrix(double ary[6]);
        // also tried
        // agg::affine_matrix(double ary[6]);
    }

    Unfortunately, the constructor wasn't added into the logic for overloaded
    constructor searches in the generated code.  Where am I going wrong here?

    My temporary fix has been to create a helper function and use it when I
    want to create an affine_matrix abject from an array:

    %{
    #include "Numeric/arrayobject.h"
    #include "agg_affine_matrix.h"

    agg::affine_matrix* affine_from_array(double ary[6])
    {
        return new agg::affine_matrix(ary[0], ary[1], ary[2],
                                      ary[3], ary[4], ary[5]);
    }
    %}

    // constructors from sequences
    %typemap(python,in) (double ary[6])
    {
        // !! cheap and cheerful -- add checks later
        PyArrayObject* ary = (PyArrayObject*) $input;
        $1 = (double*) ary->data;
    }

    %include "agg_affine_matrix.h"

    agg::affine_matrix* affine_from_array(double ary[6]);

    Not elegant, but it works:

    C:\wrk\chaco_all\kiva\agg\src>python
    Enthought Edition 1.0a1 based on
    Python 2.2.3 (#42, Jun  4 2003, 10:33:42) [MSC 32 bit (Intel)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from Numeric import *
    >>> import agg
    >>> agg.affine_from_array
    <built-in function affine_from_array>
    >>> agg.affine_from_array(array((1,2,3,4,5,6.)))
    affine_matrix(1,2,3,4,5,6)

3.  The following is an improved typemap for sequence->array conversion
    found in 19.5.5 of the SWIG manual as it handles coersion of values
    that can be converted to floats.

    // Map a Python sequence into any sized C double array
    // This handles arrays and sequences with non-float values correctly.
    %typemap(in) double[ANY](double temp[$1_dim0]) {
      int i;
      if (!PySequence_Check($input)) {
          PyErr_SetString(PyExc_TypeError,"Expecting a sequence");
          return NULL;
      }
      if (PyObject_Length($input) != $1_dim0) {
          PyErr_SetString(PyExc_ValueError,"Expecting a sequence with $1_dim0 elements");
          return NULL;
      }
      for (i =0; i < $1_dim0; i++) {
          PyObject *o = PySequence_GetItem($input,i);
          if (PyFloat_Check(o)) {
             temp[i] = PyFloat_AsDouble(o);
          }
          else {
             PyObject* converted = PyNumber_Float(o);
             if (!converted) {
                 PyErr_SetString(PyExc_ValueError,"Expecting a sequence of floats");
                 return NULL;
             }
             temp[i] = PyFloat_AsDouble(converted);
             Py_DECREF(converted);
          }
          else
      }
      $1 = &temp[0];
    }

3. Something is broken on my

    const affine_matrix& operator *=(const affine_matrix& other)
    {
    }
   wrappers.  It appears that whenever affine_matrix& is returned, the
   this and thisown pointers are getting goofed up because affine_matrix
   destructors are being called (and therefore clobbering memory) at times
   when they shouldn't...

4. Immutable data members should emit an error when the user tries to set them.
   Currently they are silent...
