From bde4f38dd1869b8c80b94170d6600d218b151974 Mon Sep 17 00:00:00 2001
From: Marco Biasini <mvbiasini@gmail.com>
Date: Mon, 31 Dec 2012 12:53:05 +0100
Subject: [PATCH] don't check Vec/Mat item access in C++ by default

Some compilers (including gcc 4.2) seem to have difficulties to inline
functions with exceptions, even though it would be possible to know at
compile-time that the exceptions never get thrown.

The boundary checked versions for item access for Vec/Mat classes are
available as the VecX/MatX::At methods. The Python export has been
adapted to use the At methods, so guarantee we never crash from Python.
---
 modules/geom/pymod/export_mat2.cc | 13 +++-
 modules/geom/pymod/export_mat3.cc | 12 +++-
 modules/geom/pymod/export_mat4.cc | 43 +++++++++-----
 modules/geom/pymod/export_vec2.cc |  8 ++-
 modules/geom/pymod/export_vec3.cc |  8 ++-
 modules/geom/pymod/export_vec4.cc |  9 ++-
 modules/geom/src/mat2.hh          | 27 +++++++--
 modules/geom/src/mat3.hh          | 24 ++++++--
 modules/geom/src/mat4.cc          | 11 ----
 modules/geom/src/mat4.hh          | 32 ++++++++--
 modules/geom/src/vec2.hh          | 19 ++++--
 modules/geom/src/vec3.hh          | 19 ++++--
 modules/geom/src/vec4.hh          | 20 +++++--
 modules/geom/tests/test_geom.py   | 99 ++++++++++++++++++++++++++++++-
 modules/geom/tests/test_mat2.cc   |  9 ---
 modules/geom/tests/test_mat3.cc   | 12 ----
 modules/geom/tests/test_mat4.cc   | 11 ----
 modules/geom/tests/test_vec2.cc   | 10 ----
 modules/geom/tests/test_vec3.cc   | 17 ------
 modules/geom/tests/test_vec4.cc   | 12 ----
 20 files changed, 278 insertions(+), 137 deletions(-)

diff --git a/modules/geom/pymod/export_mat2.cc b/modules/geom/pymod/export_mat2.cc
index 0338f1ddd..446aca95c 100644
--- a/modules/geom/pymod/export_mat2.cc
+++ b/modules/geom/pymod/export_mat2.cc
@@ -23,8 +23,17 @@ using namespace boost::python;
 
 
 
-const Real Mat2_getitem(const geom::Mat2& m, tuple i) {return m(extract<int> (i[0]),extract<int> (i[1]));}
-void Mat2_setitem(geom::Mat2& m,const  tuple i,const  Real val) {m(extract<int> (i[0]),extract<int> (i[1]))=val;}
+const Real Mat2_getitem(const geom::Mat2& m, tuple i) {
+  int a = extract<int> (i[0]);
+  int b = extract<int> (i[1]);
+  return m.At(a, b);
+}
+
+void Mat2_setitem(geom::Mat2& m,const  tuple i,const  Real val) {
+  int a = extract<int> (i[0]);
+  int b = extract<int> (i[1]);
+  m.At(a, b) = val;
+}
 
 String mat2_repr(const geom::Mat2& m) {
   std::stringstream ss;
diff --git a/modules/geom/pymod/export_mat3.cc b/modules/geom/pymod/export_mat3.cc
index 1e543b7d9..c12f6402c 100644
--- a/modules/geom/pymod/export_mat3.cc
+++ b/modules/geom/pymod/export_mat3.cc
@@ -25,8 +25,16 @@ using namespace geom;
 
 
 
-const Real Mat3_getitem(const geom::Mat3& m, tuple i) {return m(extract<int> (i[0]),extract<int> (i[1]));}
-void Mat3_setitem(geom::Mat3& m,const  tuple i,const  Real val) {m(extract<int> (i[0]),extract<int> (i[1]))=val;}
+const Real Mat3_getitem(const geom::Mat3& m, tuple i) {
+  int a = extract<int> (i[0]);
+  int b = extract<int> (i[1]);
+  return m.At(a, b);
+}
+void Mat3_setitem(geom::Mat3& m,const  tuple i,const  Real val) { 
+  int a = extract<int> (i[0]);
+  int b = extract<int> (i[1]);
+  m.At(a, b) = val;
+}
 
 Mat2 Mat3_getslice(const geom::Mat3& m, slice s) {
   tuple start=extract<tuple> (s.start());
diff --git a/modules/geom/pymod/export_mat4.cc b/modules/geom/pymod/export_mat4.cc
index 1745e35b7..ec003a0e3 100644
--- a/modules/geom/pymod/export_mat4.cc
+++ b/modules/geom/pymod/export_mat4.cc
@@ -26,8 +26,17 @@ using namespace geom;
 
 
 
-const Real Mat4_getitem(const geom::Mat4& m, tuple i) {return m(extract<int> (i[0]),extract<int> (i[1]));}
-void Mat4_setitem(geom::Mat4& m,const  tuple i,const  Real val) {m(extract<int> (i[0]),extract<int> (i[1]))=val;}
+const Real Mat4_getitem(const geom::Mat4& m, tuple i) {
+  int a = extract<int> (i[0]);
+  int b = extract<int> (i[1]);
+  return m.At(a, b);
+}
+
+void Mat4_setitem(geom::Mat4& m,const  tuple i,const  Real val) {
+  int a = extract<int> (i[0]);
+  int b = extract<int> (i[1]);
+  m.At(a, b) = val;
+}
 
 Mat3 Mat4_getslice(const geom::Mat4& m, slice s) {
   tuple start=extract<tuple> (s.start());
@@ -38,7 +47,9 @@ Mat3 Mat4_getslice(const geom::Mat4& m, slice s) {
   int end1=extract<int> (end[1]);
   if(end0-start0==1 && end1-start1==1) throw GeomException("Invalid slice: Only Mat3 slices allowed");
   if(end0-start0!=2 || end1-start1!=2) throw GeomException("Invalid slice");
-  return Mat3(m(start0,start1),m(start0,start1+1),m(start0,start1+2),m(start0+1,start1),m(start0+1,start1+1),m(start0+1,start1+2),m(start0+2,start1),m(start0+2,start1+1),m(start0+2,start1+2));
+  return Mat3(m.At(start0+0,start1), m.At(start0+0,start1+1), m.At(start0+0,start1+2),
+              m.At(start0+1,start1), m.At(start0+1,start1+1), m.At(start0+1,start1+2),
+              m.At(start0+2,start1), m.At(start0+2,start1+1), m.At(start0+2,start1+2));
 }
 void Mat4_setslice2(geom::Mat4& m,const  slice s,const  Mat2& m2)
 {
@@ -49,10 +60,10 @@ void Mat4_setslice2(geom::Mat4& m,const  slice s,const  Mat2& m2)
   int end0=extract<int> (end[0]);
   int end1=extract<int> (end[1]);
   if(end0-start0!=1 || end1-start1!=1) throw GeomException("Invalid slice");
-  m(start0,start1)=m2(0,0);
-  m(start0,start1+1)=m2(0,1);
-  m(start0+1,start1)=m2(1,0);
-  m(start0+1,start1+1)=m2(1,1);
+  m.At(start0,start1)=m2(0,0);
+  m.At(start0,start1+1)=m2(0,1);
+  m.At(start0+1,start1)=m2(1,0);
+  m.At(start0+1,start1+1)=m2(1,1);
 }
 void Mat4_setslice3(geom::Mat4& m,const  slice s,const  Mat3& m2)
 {
@@ -63,15 +74,15 @@ void Mat4_setslice3(geom::Mat4& m,const  slice s,const  Mat3& m2)
   int end0=extract<int> (end[0]);
   int end1=extract<int> (end[1]);
   if(end0-start0!=2 || end1-start1!=2) throw GeomException("Invalid slice");
-  m(start0,start1)=m2(0,0);
-  m(start0,start1+1)=m2(0,1);
-  m(start0,start1+2)=m2(0,2);
-  m(start0+1,start1)=m2(1,0);
-  m(start0+1,start1+1)=m2(1,1);
-  m(start0+1,start1+2)=m2(1,2);
-  m(start0+2,start1)=m2(2,0);
-  m(start0+2,start1+1)=m2(2,1);
-  m(start0+2,start1+2)=m2(2,2);
+  m.At(start0,start1)=m2(0,0);
+  m.At(start0,start1+1)=m2(0,1);
+  m.At(start0,start1+2)=m2(0,2);
+  m.At(start0+1,start1)=m2(1,0);
+  m.At(start0+1,start1+1)=m2(1,1);
+  m.At(start0+1,start1+2)=m2(1,2);
+  m.At(start0+2,start1)=m2(2,0);
+  m.At(start0+2,start1+1)=m2(2,1);
+  m.At(start0+2,start1+2)=m2(2,2);
 }
 
 String mat4_repr(const geom::Mat4& m) {
diff --git a/modules/geom/pymod/export_vec2.cc b/modules/geom/pymod/export_vec2.cc
index 161bda9f6..f760d7e70 100644
--- a/modules/geom/pymod/export_vec2.cc
+++ b/modules/geom/pymod/export_vec2.cc
@@ -24,8 +24,12 @@
 
 using namespace boost::python;
 
-const Real Vec2_getitem(const geom::Vec2& v, int i) {return v[i];}
-void Vec2_setitem(geom::Vec2& v,const  int i,const  Real val) {v[i]=val;}
+const Real Vec2_getitem(const geom::Vec2& v, int i) {
+  return v.At(i);
+}
+void Vec2_setitem(geom::Vec2& v,const  int i,const  Real val) {
+  v.At(i)=val;
+}
 
 
 String vec2_repr(const geom::Vec2& v)
diff --git a/modules/geom/pymod/export_vec3.cc b/modules/geom/pymod/export_vec3.cc
index aab91add3..e0c4ac6c8 100644
--- a/modules/geom/pymod/export_vec3.cc
+++ b/modules/geom/pymod/export_vec3.cc
@@ -24,8 +24,12 @@
 
 using namespace boost::python;
 
-const Real Vec3_getitem(const geom::Vec3& v, int i) {return v[i];}
-void Vec3_setitem(geom::Vec3& v,const  int i,const  Real val) {v[i]=val;}
+const Real Vec3_getitem(const geom::Vec3& v, int i) {
+  return v.At(i);
+}
+void Vec3_setitem(geom::Vec3& v,const  int i,const  Real val) {
+  v.At(i)=val;
+}
 
 geom::Vec3 NormalizeV3(const geom::Vec3& v) {
   return geom::Normalize(v);
diff --git a/modules/geom/pymod/export_vec4.cc b/modules/geom/pymod/export_vec4.cc
index 986fbfa73..810c9de1c 100644
--- a/modules/geom/pymod/export_vec4.cc
+++ b/modules/geom/pymod/export_vec4.cc
@@ -23,8 +23,13 @@ using namespace boost::python;
 
 
 
-const Real Vec4_getitem(const geom::Vec4& v, int i) {return v[i];}
-void Vec4_setitem(geom::Vec4& v,const  int i,const  Real val) {v[i]=val;}
+const Real Vec4_getitem(const geom::Vec4& v, int i) {
+  return v.At(i);
+}
+
+void Vec4_setitem(geom::Vec4& v,const  int i,const  Real val) {
+  v.At(i)=val;
+}
 
 String vec4_repr(const geom::Vec4& v)
 {
diff --git a/modules/geom/src/mat2.hh b/modules/geom/src/mat2.hh
index cb5910df4..b7743dfc0 100644
--- a/modules/geom/src/mat2.hh
+++ b/modules/geom/src/mat2.hh
@@ -64,20 +64,35 @@ public:
   //! comparable
   bool operator==(const Mat2& rhs) const;
 
+
+  //! const element access
+  const Real& At(std::size_t r, std::size_t c) const
+  {
+    if (r>1 || c>1) {
+      throw std::out_of_range("indices must be smaller than 2");
+    }
+    return data_[r][c];
+  }
+
   //! element access
-  Real& operator()(std::size_t r, std::size_t c)
+  Real& At(std::size_t r, std::size_t c)
   {
-    if (r>1 || c >1) {
-      throw std::out_of_range("row and column must be in the range [0-1]");
+    if (r>1 || c>1) {
+      throw std::out_of_range("indices must be smaller than 2");
     }
     return data_[r][c];
   }
+
+  //! element access
+  Real& operator()(std::size_t r, std::size_t c)
+  {
+    assert(r<2 && c<2);
+    return data_[r][c];
+  }
   //! const element access
   const Real& operator()(std::size_t r, std::size_t c) const
   {
-    if (r>1 || c >1) {
-      throw std::out_of_range("row and column must be in the range [0-1]");
-    }
+    assert(r<2 && c<2);
     return data_[r][c];
   }
 
diff --git a/modules/geom/src/mat3.hh b/modules/geom/src/mat3.hh
index 3cef352ed..35cae2f03 100644
--- a/modules/geom/src/mat3.hh
+++ b/modules/geom/src/mat3.hh
@@ -82,19 +82,31 @@ public:
     this->set(x, 0.0, 0.0, 0.0, y, 0.0, 0.0, 0.0, z);
   }
   //! element access
-  Real& operator()(std::size_t r, std::size_t c)
+  Real& At(std::size_t r, std::size_t c)
+  {
+    if (r>2 || c>2) {
+      throw std::out_of_range("indices must be smaller than 3");
+    }
+    return data_[r][c];
+  }
+  //! element access
+  const Real& At(std::size_t r, std::size_t c) const
   {
-    if (r>2 || c >2) {
-      throw std::out_of_range("row and column must be in the range [0-2]");
+    if (r>2 || c>2) {
+      throw std::out_of_range("indices must be smaller than 3");
     }
     return data_[r][c];
   }
+  //! element access
+  Real& operator()(std::size_t r, std::size_t c)
+  {
+    assert(r<3 && c<3);
+    return data_[r][c];
+  }
   //! const element access
   const Real& operator()(std::size_t r, std::size_t c) const
   {
-    if (r>2 || c >2) {
-      throw std::out_of_range("row and column must be in the range [0-2]");
-    }
+    assert(r<3 && c<3);
     return data_[r][c];
   }
 
diff --git a/modules/geom/src/mat4.cc b/modules/geom/src/mat4.cc
index fbbc1c2a0..c43780e0a 100644
--- a/modules/geom/src/mat4.cc
+++ b/modules/geom/src/mat4.cc
@@ -121,17 +121,6 @@ bool Mat4::operator==(const Mat4& rhs) const
     data_[3][3] ==  rhs.data_[3][3];
 }
 
-Real& Mat4::operator()(std::size_t r, std::size_t c)
-{
-  if(r>3 || c>3) throw std::out_of_range("row and column must be in range [0-3]");
-  return data_[r][c];
-}
-
-const Real& Mat4::operator()(std::size_t r, std::size_t c) const
-{
-  if(r>3 || c>3) throw std::out_of_range("row and column must be in range [0-3]");
-  return data_[r][c];
-}
 
 
 Mat4& Mat4::operator+=(const Mat4& rhs)
diff --git a/modules/geom/src/mat4.hh b/modules/geom/src/mat4.hh
index 0c504a571..998bbc485 100644
--- a/modules/geom/src/mat4.hh
+++ b/modules/geom/src/mat4.hh
@@ -19,6 +19,7 @@
 #ifndef GEOM_MAT4_HH
 #define GEOM_MAT4_HH
 
+#include <cassert>
 #include <cstddef> // for size_t
 #include <ostream>
 
@@ -77,10 +78,33 @@ public:
   //! comparable
   bool operator==(const Mat4& rhs) const;
 
-  //! element access
-  Real& operator()(std::size_t r, std::size_t c);
-  //! const element access
-  const Real& operator()(std::size_t r, std::size_t c) const;
+  const Real& At(std::size_t r, std::size_t c) const
+  {
+    if (r>3 || c>3) {
+      throw std::out_of_range("indices must be smaller than 4");
+    }
+    return data_[r][c];
+  }
+
+  Real& At(std::size_t r, std::size_t c)
+  {
+    if (r>3 || c>3) {
+      throw std::out_of_range("indices must be smaller than 4");
+    }
+    return data_[r][c];
+  }
+
+  Real& operator()(std::size_t r, std::size_t c)
+  {
+    assert(r<4 && c < 4);
+    return data_[r][c];
+  }
+
+  const Real& operator()(std::size_t r, std::size_t c) const
+  {
+    assert(r<4 && c < 4);
+    return data_[r][c];
+  }
 
   //! addable op
   Mat4& operator+=(const Mat4& rhs);
diff --git a/modules/geom/src/vec2.hh b/modules/geom/src/vec2.hh
index 6978381ff..b0191ac7f 100644
--- a/modules/geom/src/vec2.hh
+++ b/modules/geom/src/vec2.hh
@@ -20,6 +20,7 @@
 #define GEOM_VEC2_H
 
 #include <stdexcept>
+#include <cassert>
 #include <cstddef> // for size_t
 #include <ostream>
 #include <vector>
@@ -83,17 +84,27 @@ public:
   //! element access
   Real& operator[](std::size_t indx)
   {
-    if (indx>1) {
-      throw std::out_of_range("Index must be in the range [0-1]");
-    }
+    assert(indx<2);
     return (&x)[indx];
   }
   
   //! const element access
   const Real& operator[](std::size_t indx) const
   {
+    assert(indx<2);
+    return (&x)[indx];
+  }
+
+  Real& At(size_t indx) {
+    if (indx>1) {
+      throw std::out_of_range("index must be smaller than 2");
+    }
+    return (&x)[indx];
+  }
+
+  const Real& At(size_t indx) const {
     if (indx>1) {
-      throw std::out_of_range("Index must be in the range [0-1]");
+      throw std::out_of_range("index must be smaller than 2");
     }
     return (&x)[indx];
   }
diff --git a/modules/geom/src/vec3.hh b/modules/geom/src/vec3.hh
index c1cde046c..b585d4a76 100644
--- a/modules/geom/src/vec3.hh
+++ b/modules/geom/src/vec3.hh
@@ -20,6 +20,7 @@
 #define GEOM_VEC3_H
 
 #include <stdexcept>
+#include <cassert>
 #include <cstddef> // for size_t
 #include <ostream>
 #include <vector>
@@ -90,17 +91,27 @@ public:
   //! element access
   Real& operator[](std::size_t indx)
   {
-    if (indx>2) {
-      throw std::out_of_range("Index must be in the range [0-2]");
-    }
+    assert(indx<3);
     return (&x)[indx];
   }
   
   //! const element access
   const Real& operator[](std::size_t indx) const
   {
+    assert(indx<3);
+    return (&x)[indx];
+  }
+
+  Real& At(size_t indx) {
+    if (indx>2) {
+      throw std::out_of_range("index must be smaller than 3");
+    }
+    return (&x)[indx];
+  }
+
+  const Real& At(size_t indx) const {
     if (indx>2) {
-      throw std::out_of_range("Index must be in the range [0-2]");
+      throw std::out_of_range("index must be smaller than 3");
     }
     return (&x)[indx];
   }
diff --git a/modules/geom/src/vec4.hh b/modules/geom/src/vec4.hh
index 20b5fd2a7..5947a1c06 100644
--- a/modules/geom/src/vec4.hh
+++ b/modules/geom/src/vec4.hh
@@ -20,6 +20,7 @@
 #define GEOM_VEC4_H
 
 #include <stdexcept>
+#include <cassert>
 #include <cstddef> // for size_t
 #include <ostream>
 
@@ -83,20 +84,31 @@ public:
   //! element access
   Real& operator[](std::size_t indx)
   {
-    if (indx>3) {
-      throw std::out_of_range("Index must be in the range [0-3]");
-    }
+    assert(indx<4);
     return (&x)[indx];
   }
   
   //! const element access
   const Real& operator[](std::size_t indx) const
   {
+    assert(indx<4);
+    return (&x)[indx];
+  }
+
+  Real& At(size_t indx) {
     if (indx>3) {
-      throw std::out_of_range("Index must be in the range [0-3]");
+      throw std::out_of_range("index must be smaller than 4");
     }
     return (&x)[indx];
   }
+
+  const Real& At(size_t indx) const {
+    if (indx>3) {
+      throw std::out_of_range("index must be smaller than 4");
+    }
+    return (&x)[indx];
+  }
+
   //! element access
   Real GetX() const { return x; }
   Real GetY() const { return y; }
diff --git a/modules/geom/tests/test_geom.py b/modules/geom/tests/test_geom.py
index f563add91..60a989ac4 100644
--- a/modules/geom/tests/test_geom.py
+++ b/modules/geom/tests/test_geom.py
@@ -78,7 +78,104 @@ class TestGeom(unittest.TestCase):
                       5,6,7,8,
                       9,10,11,12,
                       13,14,15,16])
-    
+
+  def test_boundary_checks_vec2(self): 
+    v = geom.Vec2()
+
+    v[0] = v[0]
+    v[1] = v[1]
+    self.assertRaises(IndexError, v.__setitem__, (-1), 1)
+    self.assertRaises(IndexError, v.__setitem__, ( 2), 1)
+    self.assertRaises(IndexError, v.__getitem__, (-1))
+    self.assertRaises(IndexError, v.__getitem__, ( 2))
+
+  def test_boundary_checks_vec3(self): 
+    v = geom.Vec3()
+
+    v[0] = v[0]
+    v[1] = v[1]
+    v[2] = v[2]
+    self.assertRaises(IndexError, v.__setitem__, (-1), 1)
+    self.assertRaises(IndexError, v.__setitem__, ( 3), 1)
+    self.assertRaises(IndexError, v.__getitem__, (-1))
+    self.assertRaises(IndexError, v.__getitem__, ( 3))
+
+  def test_boundary_checks_vec4(self): 
+    v = geom.Vec4()
+    v[0] = v[0]
+    v[1] = v[1]
+    v[2] = v[2]
+    v[3] = v[3]
+    self.assertRaises(IndexError, v.__setitem__, (-1), 1)
+    self.assertRaises(IndexError, v.__setitem__, ( 4), 1)
+    self.assertRaises(IndexError, v.__getitem__, (-1))
+    self.assertRaises(IndexError, v.__getitem__, ( 4))
+
+  def test_boundary_checks_mat2(self): 
+    m = geom.Mat2()
+    m[0,0] = m[0,0]
+    m[0,1] = m[0,1]
+    m[1,0] = m[1,0]
+    m[1,1] = m[1,1]
+    self.assertRaises(IndexError, m.__setitem__, (-1,0), 1)
+    self.assertRaises(IndexError, m.__setitem__, ( 2,0), 1)
+    self.assertRaises(IndexError, m.__setitem__, (0,-1), 1)
+    self.assertRaises(IndexError, m.__setitem__, (-1,2), 1)
+
+    self.assertRaises(IndexError, m.__getitem__, (-1,0))
+    self.assertRaises(IndexError, m.__getitem__, ( 2,0))
+    self.assertRaises(IndexError, m.__getitem__, (0,-1))
+    self.assertRaises(IndexError, m.__getitem__, (0,2))
+
+  def test_boundary_checks_mat3(self): 
+    m = geom.Mat3()
+    m[0,0] = m[0,0]
+    m[0,1] = m[0,1]
+    m[0,2] = m[0,2]
+    m[1,0] = m[1,0]
+    m[1,1] = m[1,1]
+    m[1,2] = m[1,2]
+    m[2,0] = m[2,0]
+    m[2,1] = m[2,1]
+    m[2,2] = m[2,2]
+    self.assertRaises(IndexError, m.__setitem__, (-1,0), 1)
+    self.assertRaises(IndexError, m.__setitem__, ( 3,0), 1)
+    self.assertRaises(IndexError, m.__setitem__, (0,-1), 1)
+    self.assertRaises(IndexError, m.__setitem__, (-1,3), 1)
+
+    self.assertRaises(IndexError, m.__getitem__, (-1,0))
+    self.assertRaises(IndexError, m.__getitem__, ( 3,0))
+    self.assertRaises(IndexError, m.__getitem__, (0,-1))
+    self.assertRaises(IndexError, m.__getitem__, (0,3))
+
+  def test_boundary_checks_mat4(self): 
+    m = geom.Mat4()
+    m[0,0] = m[0,0]
+    m[0,1] = m[0,1]
+    m[0,2] = m[0,2]
+    m[0,3] = m[0,3]
+    m[1,0] = m[1,0]
+    m[1,1] = m[1,1]
+    m[1,2] = m[1,2]
+    m[1,3] = m[1,3]
+    m[2,0] = m[2,0]
+    m[2,1] = m[2,1]
+    m[2,2] = m[2,2]
+    m[2,3] = m[2,3]
+    m[3,0] = m[3,0]
+    m[3,1] = m[3,1]
+    m[3,2] = m[3,2]
+    m[3,3] = m[3,3]
+    self.assertRaises(IndexError, m.__setitem__, (-1,0), 1)
+    self.assertRaises(IndexError, m.__setitem__, ( 4,0), 1)
+    self.assertRaises(IndexError, m.__setitem__, (0,-1), 1)
+    self.assertRaises(IndexError, m.__setitem__, (-1,4), 1)
+
+    self.assertRaises(IndexError, m.__getitem__, (-1,0))
+    self.assertRaises(IndexError, m.__getitem__, ( 4,0))
+    self.assertRaises(IndexError, m.__getitem__, (0,-1))
+    self.assertRaises(IndexError, m.__getitem__, (0,4))
+
 if __name__== '__main__':
   from ost import testutils
   testutils.RunTests()
diff --git a/modules/geom/tests/test_mat2.cc b/modules/geom/tests/test_mat2.cc
index c7da1125e..613b01ee0 100644
--- a/modules/geom/tests/test_mat2.cc
+++ b/modules/geom/tests/test_mat2.cc
@@ -53,13 +53,4 @@ BOOST_AUTO_TEST_CASE(init_mat2)
   BOOST_CHECK(match(m1,m4(0,0),m4(0,1),m4(1,0),m4(1,1)));
 }
 
-
-
-BOOST_AUTO_TEST_CASE(access_mat2)
-{
-  Mat2 m;
-  BOOST_CHECK_THROW( m(2,2)=1.0, std::out_of_range);
-  BOOST_CHECK_THROW( m(2,2), std::out_of_range);
-}
-
 BOOST_AUTO_TEST_SUITE_END();
diff --git a/modules/geom/tests/test_mat3.cc b/modules/geom/tests/test_mat3.cc
index 8a8b40e53..381271a43 100644
--- a/modules/geom/tests/test_mat3.cc
+++ b/modules/geom/tests/test_mat3.cc
@@ -55,18 +55,6 @@ BOOST_AUTO_TEST_CASE(init_mat3)
   BOOST_CHECK(match(m5,2.0,3.0,0.0,4.0,5.0,0.0,0.0,0.0,1.0));
 }
 
-BOOST_AUTO_TEST_CASE(access_mat3)
-{
-  Mat3 m;
-  BOOST_CHECK_THROW( m(3,3)=1.0, std::out_of_range);
-  BOOST_CHECK_THROW( m(3,0)=1.0, std::out_of_range);
-  BOOST_CHECK_THROW( m(0,3)=1.0, std::out_of_range);
-  BOOST_CHECK_THROW( m(3,3), std::out_of_range);
-  BOOST_CHECK_THROW( m(3,0), std::out_of_range);
-  BOOST_CHECK_THROW( m(0,3), std::out_of_range);
-}
-
-
 BOOST_AUTO_TEST_CASE(mult_mat3)
 {
   Mat3 m1=rnd_mat3();
diff --git a/modules/geom/tests/test_mat4.cc b/modules/geom/tests/test_mat4.cc
index 36ea668c1..2b3160dbf 100644
--- a/modules/geom/tests/test_mat4.cc
+++ b/modules/geom/tests/test_mat4.cc
@@ -91,15 +91,4 @@ BOOST_AUTO_TEST_CASE(init_mat4)
         
 }
 
-BOOST_AUTO_TEST_CASE(access_mat4)
-{
-  Mat4 m;
-  BOOST_CHECK_THROW( m(4,4)=1.0, std::out_of_range);
-  BOOST_CHECK_THROW( m(4,0)=1.0, std::out_of_range);
-  BOOST_CHECK_THROW( m(0,4)=1.0, std::out_of_range);
-  BOOST_CHECK_THROW( m(4,4), std::out_of_range);
-  BOOST_CHECK_THROW( m(4,0), std::out_of_range);
-  BOOST_CHECK_THROW( m(0,4), std::out_of_range);
-}
-
 BOOST_AUTO_TEST_SUITE_END();
diff --git a/modules/geom/tests/test_vec2.cc b/modules/geom/tests/test_vec2.cc
index 87cc3aba0..db5d68173 100644
--- a/modules/geom/tests/test_vec2.cc
+++ b/modules/geom/tests/test_vec2.cc
@@ -61,16 +61,6 @@ BOOST_AUTO_TEST_CASE(init_vec2)
   BOOST_CHECK_THROW( Vec2(Vec4(1.0,1.0,1.0,0.0)), DivideByZeroException);
 }
 
-BOOST_AUTO_TEST_CASE(access_vec2)
-{
-  Vec2 v;
-  v[0]=1.1;
-  v[1]=2.3;
-  BOOST_CHECK(match(v,1.1,2.3));
-  BOOST_CHECK_NO_THROW( v[0]=1.0);
-  BOOST_CHECK_THROW( v[2]=1.0, std::out_of_range);
-}
-
 BOOST_AUTO_TEST_CASE(operators_vec2)
 {
   Vec2 v1(1.2,2.3);
diff --git a/modules/geom/tests/test_vec3.cc b/modules/geom/tests/test_vec3.cc
index 3964daf00..2d166b988 100644
--- a/modules/geom/tests/test_vec3.cc
+++ b/modules/geom/tests/test_vec3.cc
@@ -62,23 +62,6 @@ BOOST_AUTO_TEST_CASE(init_vec3)
   BOOST_CHECK(match(Vec3(Vec4(2.0,1.0,3.0,0.0)),2.0,1.0,3.0));
 }
 
-BOOST_AUTO_TEST_CASE(access_vec3)
-{
-  Vec3 v;
-  v[0]=1.1;
-  v[1]=2.3;
-  v[2]=5.6;
-  BOOST_CHECK(match(v,1.1,2.3,5.6));
-
-  BOOST_CHECK_NO_THROW(v[0]=1);
-  BOOST_CHECK_NO_THROW(v[1]=1);
-  BOOST_CHECK_NO_THROW(v[2]=1);
-  BOOST_CHECK_NO_THROW(v[0]);
-  BOOST_CHECK_NO_THROW(v[1]);
-  BOOST_CHECK_NO_THROW(v[2]);
-  BOOST_CHECK_THROW( v[3]=1.0, std::out_of_range);
-  BOOST_CHECK_THROW( v[3], std::out_of_range);
-}
 
 BOOST_AUTO_TEST_CASE(operators_vec3) 
 {
diff --git a/modules/geom/tests/test_vec4.cc b/modules/geom/tests/test_vec4.cc
index 25276e4f3..665e2f168 100644
--- a/modules/geom/tests/test_vec4.cc
+++ b/modules/geom/tests/test_vec4.cc
@@ -61,18 +61,6 @@ BOOST_AUTO_TEST_CASE(init_vec4)
 }
 
 
-BOOST_AUTO_TEST_CASE(access_vec4)
-{
-  Vec4 v;
-  v[0]=1.1;
-  v[1]=2.3;
-  v[2]=5.6;
-  v[3]=2.0;
-  BOOST_CHECK(match(v,1.1,2.3,5.6,2.0));
-
-  BOOST_CHECK_THROW( v[4]=1.0, std::out_of_range);
-}
-
 BOOST_AUTO_TEST_CASE(operators_vec4)
 {
   Vec4 v1(0.8,1.2,2.3,3.4);
-- 
GitLab