import source from 1.3.40
[external/swig.git] / Lib / python / std_map.i
1 /*
2   Maps
3 */
4
5 %fragment("StdMapTraits","header",fragment="StdSequenceTraits")
6 {
7   namespace swig {
8     template <class SwigPySeq, class K, class T >
9     inline void
10     assign(const SwigPySeq& swigpyseq, std::map<K,T > *map) {
11       typedef typename std::map<K,T>::value_type value_type;
12       typename SwigPySeq::const_iterator it = swigpyseq.begin();
13       for (;it != swigpyseq.end(); ++it) {
14         map->insert(value_type(it->first, it->second));
15       }
16     }
17
18     template <class K, class T>
19     struct traits_asptr<std::map<K,T> >  {
20       typedef std::map<K,T> map_type;
21       static int asptr(PyObject *obj, map_type **val) {
22         int res = SWIG_ERROR;
23         SWIG_PYTHON_THREAD_BEGIN_BLOCK;
24         if (PyDict_Check(obj)) {
25           SwigVar_PyObject items = PyObject_CallMethod(obj,(char *)"items",NULL);
26 %#if PY_VERSION_HEX >= 0x03000000
27           /* In Python 3.x the ".items()" method returns a dict_items object */
28           items = PySequence_Fast(items, ".items() didn't return a sequence!");
29 %#endif
30           res = traits_asptr_stdseq<std::map<K,T>, std::pair<K, T> >::asptr(items, val);
31         } else {
32           map_type *p;
33           res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info<map_type>(),0);
34           if (SWIG_IsOK(res) && val)  *val = p;
35         }
36         SWIG_PYTHON_THREAD_END_BLOCK;
37         return res;
38       }      
39     };
40       
41     template <class K, class T >
42     struct traits_from<std::map<K,T> >  {
43       typedef std::map<K,T> map_type;
44       typedef typename map_type::const_iterator const_iterator;
45       typedef typename map_type::size_type size_type;
46             
47       static PyObject *from(const map_type& map) {
48         swig_type_info *desc = swig::type_info<map_type>();
49         if (desc && desc->clientdata) {
50           return SWIG_NewPointerObj(new map_type(map), desc, SWIG_POINTER_OWN);
51         } else {
52           SWIG_PYTHON_THREAD_BEGIN_BLOCK;
53           size_type size = map.size();
54           int pysize = (size <= (size_type) INT_MAX) ? (int) size : -1;
55           if (pysize < 0) {
56             PyErr_SetString(PyExc_OverflowError,
57                             "map size not valid in python");
58             SWIG_PYTHON_THREAD_END_BLOCK;
59             return NULL;
60           }
61           PyObject *obj = PyDict_New();
62           for (const_iterator i= map.begin(); i!= map.end(); ++i) {
63             swig::SwigVar_PyObject key = swig::from(i->first);
64             swig::SwigVar_PyObject val = swig::from(i->second);
65             PyDict_SetItem(obj, key, val);
66           }
67           SWIG_PYTHON_THREAD_END_BLOCK;
68           return obj;
69         }
70       }
71     };
72
73     template <class ValueType>
74     struct from_key_oper 
75     {
76       typedef const ValueType& argument_type;
77       typedef  PyObject *result_type;
78       result_type operator()(argument_type v) const
79       {
80         return swig::from(v.first);
81       }
82     };
83
84     template <class ValueType>
85     struct from_value_oper 
86     {
87       typedef const ValueType& argument_type;
88       typedef  PyObject *result_type;
89       result_type operator()(argument_type v) const
90       {
91         return swig::from(v.second);
92       }
93     };
94
95     template<class OutIterator, class FromOper, class ValueType = typename OutIterator::value_type>
96     struct SwigPyMapIterator_T : SwigPyIteratorClosed_T<OutIterator, ValueType, FromOper>
97     {
98       SwigPyMapIterator_T(OutIterator curr, OutIterator first, OutIterator last, PyObject *seq)
99         : SwigPyIteratorClosed_T<OutIterator,ValueType,FromOper>(curr, first, last, seq)
100       {
101       }
102     };
103
104
105     template<class OutIterator,
106              class FromOper = from_key_oper<typename OutIterator::value_type> >
107     struct SwigPyMapKeyIterator_T : SwigPyMapIterator_T<OutIterator, FromOper>
108     {
109       SwigPyMapKeyIterator_T(OutIterator curr, OutIterator first, OutIterator last, PyObject *seq)
110         : SwigPyMapIterator_T<OutIterator, FromOper>(curr, first, last, seq)
111       {
112       }
113     };
114
115     template<typename OutIter>
116     inline SwigPyIterator*
117     make_output_key_iterator(const OutIter& current, const OutIter& begin, const OutIter& end, PyObject *seq = 0)
118     {
119       return new SwigPyMapKeyIterator_T<OutIter>(current, begin, end, seq);
120     }
121
122     template<class OutIterator,
123              class FromOper = from_value_oper<typename OutIterator::value_type> >
124     struct SwigPyMapValueITerator_T : SwigPyMapIterator_T<OutIterator, FromOper>
125     {
126       SwigPyMapValueITerator_T(OutIterator curr, OutIterator first, OutIterator last, PyObject *seq)
127         : SwigPyMapIterator_T<OutIterator, FromOper>(curr, first, last, seq)
128       {
129       }
130     };
131     
132
133     template<typename OutIter>
134     inline SwigPyIterator*
135     make_output_value_iterator(const OutIter& current, const OutIter& begin, const OutIter& end, PyObject *seq = 0)
136     {
137       return new SwigPyMapValueITerator_T<OutIter>(current, begin, end, seq);
138     }
139   }
140 }
141
142 %define %swig_map_common(Map...)
143   %swig_sequence_iterator(Map);
144   %swig_container_methods(Map)
145
146   %extend {
147     mapped_type __getitem__(const key_type& key) const throw (std::out_of_range) {
148       Map::const_iterator i = self->find(key);
149       if (i != self->end())
150         return i->second;
151       else
152         throw std::out_of_range("key not found");
153     }
154     
155     void __delitem__(const key_type& key) throw (std::out_of_range) {
156       Map::iterator i = self->find(key);
157       if (i != self->end())
158         self->erase(i);
159       else
160         throw std::out_of_range("key not found");
161     }
162     
163     bool has_key(const key_type& key) const {
164       Map::const_iterator i = self->find(key);
165       return i != self->end();
166     }
167     
168     PyObject* keys() {
169       Map::size_type size = self->size();
170       int pysize = (size <= (Map::size_type) INT_MAX) ? (int) size : -1;
171       SWIG_PYTHON_THREAD_BEGIN_BLOCK;
172       if (pysize < 0) {
173         PyErr_SetString(PyExc_OverflowError,
174                         "map size not valid in python");
175         SWIG_PYTHON_THREAD_END_BLOCK;
176         return NULL;
177       }
178       PyObject* keyList = PyList_New(pysize);
179       Map::const_iterator i = self->begin();
180       for (int j = 0; j < pysize; ++i, ++j) {
181         PyList_SET_ITEM(keyList, j, swig::from(i->first));
182       }
183       SWIG_PYTHON_THREAD_END_BLOCK;
184       return keyList;
185     }
186     
187     PyObject* values() {
188       Map::size_type size = self->size();
189       int pysize = (size <= (Map::size_type) INT_MAX) ? (int) size : -1;
190       SWIG_PYTHON_THREAD_BEGIN_BLOCK;
191       if (pysize < 0) {
192         PyErr_SetString(PyExc_OverflowError,
193                         "map size not valid in python");
194         SWIG_PYTHON_THREAD_END_BLOCK;
195         return NULL;
196       }
197       PyObject* valList = PyList_New(pysize);
198       Map::const_iterator i = self->begin();
199       for (int j = 0; j < pysize; ++i, ++j) {
200         PyList_SET_ITEM(valList, j, swig::from(i->second));
201       }
202       SWIG_PYTHON_THREAD_END_BLOCK;
203       return valList;
204     }
205     
206     PyObject* items() {
207       Map::size_type size = self->size();
208       int pysize = (size <= (Map::size_type) INT_MAX) ? (int) size : -1;
209       SWIG_PYTHON_THREAD_BEGIN_BLOCK;
210       if (pysize < 0) {
211         PyErr_SetString(PyExc_OverflowError,
212                         "map size not valid in python");
213         SWIG_PYTHON_THREAD_END_BLOCK;
214         return NULL;
215       }    
216       PyObject* itemList = PyList_New(pysize);
217       Map::const_iterator i = self->begin();
218       for (int j = 0; j < pysize; ++i, ++j) {
219         PyList_SET_ITEM(itemList, j, swig::from(*i));
220       }
221       SWIG_PYTHON_THREAD_END_BLOCK;
222       return itemList;
223     }
224     
225     // Python 2.2 methods
226     bool __contains__(const key_type& key) {
227       return self->find(key) != self->end();
228     }
229
230     %newobject key_iterator(PyObject **PYTHON_SELF);
231     swig::SwigPyIterator* key_iterator(PyObject **PYTHON_SELF) {
232       return swig::make_output_key_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
233     }
234
235     %newobject value_iterator(PyObject **PYTHON_SELF);
236     swig::SwigPyIterator* value_iterator(PyObject **PYTHON_SELF) {
237       return swig::make_output_value_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
238     }
239
240     %pythoncode {def __iter__(self): return self.key_iterator()}    
241     %pythoncode {def iterkeys(self): return self.key_iterator()}
242     %pythoncode {def itervalues(self): return self.value_iterator()}
243     %pythoncode {def iteritems(self): return self.iterator()}
244   }
245 %enddef
246
247 %define %swig_map_methods(Map...)
248   %swig_map_common(Map)
249   %extend {
250     void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) {
251       (*self)[key] = x;
252     }
253   }
254 %enddef
255
256
257 %include <std/std_map.i>