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> 258