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