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