#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)
{
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;
}