allow adding and viewing sequences to an analysis from python
[mussa.git] / py / stl_container_adapter.hpp
diff --git a/py/stl_container_adapter.hpp b/py/stl_container_adapter.hpp
new file mode 100644 (file)
index 0000000..8758247
--- /dev/null
@@ -0,0 +1,108 @@
+#ifndef STL_CONTAINER_ADAPTER_HPP_
+#define STL_CONTAINER_ADAPTER_HPP_
+
+#include <algorithm>
+#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"); }
+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;
+    }
+};
+
+void KeyError() { PyErr_SetString(PyExc_KeyError, "Key not found"); }
+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)
+    {
+        if( x.find(i) != x.end() ) return x[i];
+        KeyError();
+    }
+    static void set(T const& x, K const& i, V const& v)
+    {
+        x[i]=v; // use map autocreation feature
+    }
+    static void del(T const& x, K const& i)
+    {
+        if( x.find(i) != x.end() ) x.erase(i);
+        else KeyError();
+    }
+    static bool in(T const& x, K const& i)
+    {
+        return x.find(i) != x.end();
+    }
+    static boost::python::list keys(T const& x)
+    {
+        boost::python::list t;
+        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)
+          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)
+          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)
+          if( it->first == k ) return i;
+        return -1;
+    }
+};
+
+
+#endif /*STL_CONTAINER_ADAPTER_HPP_*/