87582476eec0ef9ed47c5d10eb6fc78dc9412cf6
[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 <boost/python.hpp>
6
7 // This template started off life at
8 // http://wiki.python.org/moin/boost.python/StlContainers
9
10 void IndexError() { PyErr_SetString(PyExc_IndexError, "Index out of range"); }
11 template<typename T>
12 struct std_item
13 {
14     typedef typename T::value_type V;
15     static V& get(T& x, int i)
16     {
17         if( i<0 ) i+=x.size();
18         if( i>=0 && i<x.size() ) return x[i];
19         IndexError();
20     }
21     static void set(T& x, int i, V const& v)
22     {
23         if( i<0 ) i+=x.size();
24         if( i>=0 && i<x.size() ) x[i]=v;
25         else IndexError();
26     }
27     static void del(T& x, int i)
28     {
29         if( i<0 ) i+=x.size();
30         if( i>=0 && i<x.size() ) {
31           typename T::iterator itor = x.begin();
32           itor += i; 
33           x.erase(itor);
34         } else IndexError();
35     }
36     static void add(T& x, V& v)
37     {
38         x.push_back(v);
39     }
40     static bool in(T const& x, V const& v)
41     {
42         return std::find(x.begin(), x.end(), v) != x.end();
43     }    
44     static int index(T const& x, V const& v)
45     {
46         int i=0;
47         for(typename T::const_iterator it=x.begin; it!=x.end(); ++it,++i)
48           if( *it == v ) return i;
49         return -1;
50     }
51 };
52
53 void KeyError() { PyErr_SetString(PyExc_KeyError, "Key not found"); }
54 template<typename T>
55 struct map_item
56 {
57     typedef typename T::key_type K;
58     typedef typename T::mapped_type V;
59     static V& get(T const& x, K const& i)
60     {
61         if( x.find(i) != x.end() ) return x[i];
62         KeyError();
63     }
64     static void set(T const& x, K const& i, V const& v)
65     {
66         x[i]=v; // use map autocreation feature
67     }
68     static void del(T const& x, K const& i)
69     {
70         if( x.find(i) != x.end() ) x.erase(i);
71         else KeyError();
72     }
73     static bool in(T const& x, K const& i)
74     {
75         return x.find(i) != x.end();
76     }
77     static boost::python::list keys(T const& x)
78     {
79         boost::python::list t;
80         for(typename T::const_iterator it=x.begin; it!=x.end(); ++it)
81           t.append(it->first);
82         return t;
83     }
84     static boost::python::list values(T const& x)
85     {
86         boost::python::list t;
87         for(typename T::const_iterator it=x.begin; it!=x.end(); ++it)
88           t.append(it->second);
89         return t;
90     }
91     static boost::python::list items(T const& x)
92     {
93         boost::python::list t;
94         for(typename T::const_iterator it=x.begin; it!=x.end(); ++it)
95           t.append(boost::python::make_tuple(it->first,it->second));
96         return t;
97     }
98     static int index(T const& x,  K const& k)
99     {
100         int i=0;
101         for(typename T::const_iterator it=x.begin; it!=x.end(); ++it,++i)
102           if( it->first == k ) return i;
103         return -1;
104     }
105 };
106
107
108 #endif /*STL_CONTAINER_ADAPTER_HPP_*/