Start wrapping seq_span
[mussa.git] / py / stl_container_adapter.hpp
1 #ifndef STL_CONTAINER_ADAPTER_HPP_
2 #define STL_CONTAINER_ADAPTER_HPP_
3
4 #include <algorithm>
5 #include <exception>
6
7 #include <boost/python.hpp>
8
9 // This template started off life at
10 // http://wiki.python.org/moin/boost.python/StlContainers
11
12 struct IndexError : std::exception
13 {
14 public:
15   explicit IndexError(): std::exception() {};
16 };
17
18 void translate(IndexError const &e);
19
20
21 template<typename T>
22 struct std_item
23 {
24   typedef typename T::value_type V;
25   typedef typename T::reference R;
26   typedef typename T::const_reference CR;
27
28   static R get(T& x, int i)
29   {
30     if( i<0 ) i+=x.size();
31     if( i>=0 && i<x.size() ) return x[i];
32     throw IndexError();
33   }
34   static CR get_const(T& x, int i)
35   {
36     if( i<0 ) i+=x.size();
37     if( i>=0 && i<x.size() ) return x[i];
38     throw IndexError();
39   }
40   static void set(T& x, int i, V const& v)
41   {
42     if( i<0 ) i+=x.size();
43     if( i>=0 && i<x.size() ) x[i]=v;
44     else throw IndexError();
45   }
46   static void del(T& x, int i)
47   {
48     if( i<0 ) i+=x.size();
49     if( i>=0 && i<x.size() ) {
50       typename T::iterator itor = x.begin();
51       itor += i; 
52       x.erase(itor);
53     } else throw IndexError();
54   }
55   static void add(T& x, V& v)
56   {
57     x.push_back(v);
58   }
59   static bool in(T const& x, V const& v)
60   {
61     return std::find(x.begin(), x.end(), v) != x.end();
62   }    
63   static int index(T const& x, V const& v)
64   {
65     int i=0;
66     for(typename T::const_iterator it=x.begin; it!=x.end(); ++it,++i)
67       if( *it == v ) return i;
68     return -1;
69   }
70 };
71
72 struct KeyError : std::exception
73 {
74 public:
75   explicit KeyError(): std::exception() {};
76 };
77
78 void translate(KeyError const &e);
79
80 template<typename T>
81 struct map_item
82 {
83     typedef typename T::key_type K;
84     typedef typename T::mapped_type V;
85     static V& get(T const& x, K const& i)
86     {
87         if( x.find(i) != x.end() ) return x[i];
88         throw KeyError();
89     }
90     static void set(T const& x, K const& i, V const& v)
91     {
92         x[i]=v; // use map autocreation feature
93     }
94     static void del(T const& x, K const& i)
95     {
96         if( x.find(i) != x.end() ) x.erase(i);
97         else throw KeyError();
98     }
99     static bool in(T const& x, K const& i)
100     {
101         return x.find(i) != x.end();
102     }
103     static boost::python::list keys(T const& x)
104     {
105         boost::python::list t;
106         for(typename T::const_iterator it=x.begin; it!=x.end(); ++it)
107           t.append(it->first);
108         return t;
109     }
110     static boost::python::list values(T const& x)
111     {
112         boost::python::list t;
113         for(typename T::const_iterator it=x.begin; it!=x.end(); ++it)
114           t.append(it->second);
115         return t;
116     }
117     static boost::python::list items(T const& x)
118     {
119         boost::python::list t;
120         for(typename T::const_iterator it=x.begin; it!=x.end(); ++it)
121           t.append(boost::python::make_tuple(it->first,it->second));
122         return t;
123     }
124     static int index(T const& x,  K const& k)
125     {
126         int i=0;
127         for(typename T::const_iterator it=x.begin; it!=x.end(); ++it,++i)
128           if( it->first == k ) return i;
129         return -1;
130     }
131 };
132
133
134 #endif /*STL_CONTAINER_ADAPTER_HPP_*/