basic wrapping of Annotations
[mussa.git] / py / stl_container_adapter.hpp
index 87582476eec0ef9ed47c5d10eb6fc78dc9412cf6..37f66fe64d56b7daabd11d7e12ccc1512f78dcfe 100644 (file)
@@ -2,73 +2,98 @@
 #define STL_CONTAINER_ADAPTER_HPP_
 
 #include <algorithm>
+#include <exception>
+
 #include <boost/python.hpp>
 
 // This template started off life at
 // http://wiki.python.org/moin/boost.python/StlContainers
 
-void IndexError() { PyErr_SetString(PyExc_IndexError, "Index out of range"); }
+struct IndexError : std::exception
+{
+  explicit IndexError(): std::exception() {};
+};
+
+void translate_index_error(IndexError const &e);
+
+
 template<typename T>
 struct std_item
 {
-    typedef typename T::value_type V;
-    static V& get(T& x, int i)
-    {
-        if( i<0 ) i+=x.size();
-        if( i>=0 && i<x.size() ) return x[i];
-        IndexError();
-    }
-    static void set(T& x, int i, V const& v)
-    {
-        if( i<0 ) i+=x.size();
-        if( i>=0 && i<x.size() ) x[i]=v;
-        else IndexError();
-    }
-    static void del(T& x, int i)
-    {
-        if( i<0 ) i+=x.size();
-        if( i>=0 && i<x.size() ) {
-          typename T::iterator itor = x.begin();
-          itor += i; 
-          x.erase(itor);
-        } else IndexError();
-    }
-    static void add(T& x, V& v)
-    {
-        x.push_back(v);
-    }
-    static bool in(T const& x, V const& v)
-    {
-        return std::find(x.begin(), x.end(), v) != x.end();
-    }    
-    static int index(T const& x, V const& v)
-    {
-        int i=0;
-        for(typename T::const_iterator it=x.begin; it!=x.end(); ++it,++i)
-          if( *it == v ) return i;
-        return -1;
-    }
+  typedef typename T::value_type V;
+  typedef typename T::reference R;
+  typedef typename T::const_reference CR;
+
+  static R get(T& x, int i)
+  {
+    if( i<0 ) i+=x.size();
+    if( i>=0 && i<x.size() ) return x[i];
+    throw IndexError();
+  }
+  static CR get_const(T& x, int i)
+  {
+    if( i<0 ) i+=x.size();
+    if( i>=0 && i<x.size() ) return x[i];
+    throw IndexError();
+  }
+  static void set(T& x, int i, V const& v)
+  {
+    if( i<0 ) i+=x.size();
+    if( i>=0 && i<x.size() ) x[i]=v;
+    else throw IndexError();
+  }
+  static void del(T& x, int i)
+  {
+    if( i<0 ) i+=x.size();
+    if( i>=0 && i<x.size() ) {
+      typename T::iterator itor = x.begin();
+      itor += i; 
+      x.erase(itor);
+    } else throw IndexError();
+  }
+  static void add(T& x, V& v)
+  {
+    x.push_back(v);
+  }
+  static bool in(T const& x, V const& v)
+  {
+    return std::find(x.begin(), x.end(), v) != x.end();
+  }    
+  static int index(T const& x, V const& v)
+  {
+    int i=0;
+    for(typename T::const_iterator it=x.begin; it!=x.end(); ++it,++i)
+      if( *it == v ) return i;
+    return -1;
+  }
+};
+
+struct KeyError : std::exception
+{
+public:
+  explicit KeyError(): std::exception() {};
 };
 
-void KeyError() { PyErr_SetString(PyExc_KeyError, "Key not found"); }
+void translate_key_error(KeyError const &e);
+
 template<typename T>
 struct map_item
 {
     typedef typename T::key_type K;
     typedef typename T::mapped_type V;
-    static V& get(T const& x, K const& i)
+    static V& get(T & x, K const& i)
     {
         if( x.find(i) != x.end() ) return x[i];
-        KeyError();
+        throw KeyError();
     }
-    static void set(T const& x, K const& i, V const& v)
+    static void set(T & x, K const& i, V const& v)
     {
         x[i]=v; // use map autocreation feature
     }
-    static void del(T const& x, K const& i)
+    static void del(T & x, K const& i)
     {
         if( x.find(i) != x.end() ) x.erase(i);
-        else KeyError();
+        else throw KeyError();
     }
     static bool in(T const& x, K const& i)
     {
@@ -77,28 +102,28 @@ struct map_item
     static boost::python::list keys(T const& x)
     {
         boost::python::list t;
-        for(typename T::const_iterator it=x.begin; it!=x.end(); ++it)
+        for(typename T::const_iterator it=x.begin(); it!=x.end(); ++it)
           t.append(it->first);
         return t;
     }
     static boost::python::list values(T const& x)
     {
         boost::python::list t;
-        for(typename T::const_iterator it=x.begin; it!=x.end(); ++it)
+        for(typename T::const_iterator it=x.begin(); it!=x.end(); ++it)
           t.append(it->second);
         return t;
     }
     static boost::python::list items(T const& x)
     {
         boost::python::list t;
-        for(typename T::const_iterator it=x.begin; it!=x.end(); ++it)
+        for(typename T::const_iterator it=x.begin(); it!=x.end(); ++it)
           t.append(boost::python::make_tuple(it->first,it->second));
         return t;
     }
     static int index(T const& x,  K const& k)
     {
         int i=0;
-        for(typename T::const_iterator it=x.begin; it!=x.end(); ++it,++i)
+        for(typename T::const_iterator it=x.begin(); it!=x.end(); ++it,++i)
           if( it->first == k ) return i;
         return -1;
     }