Skip to content

Commit 603285e

Browse files
committed
Python std::unordered_map improvements
Pick up various bug fixes and improvements from the std::map implementation.
1 parent 146998c commit 603285e

File tree

1 file changed

+41
-25
lines changed

1 file changed

+41
-25
lines changed

Lib/python/std_unordered_map.i

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,12 @@
7878
typedef std::unordered_map<K,T> unordered_map_type;
7979
static int asptr(PyObject *obj, unordered_map_type **val) {
8080
int res = SWIG_ERROR;
81+
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
8182
if (PyDict_Check(obj)) {
8283
SwigVar_PyObject items = PyObject_CallMethod(obj,(char *)"items",NULL);
8384
%#if PY_VERSION_HEX >= 0x03000000
84-
/* In Python 3.x the ".items()" method return a dict_items object */
85-
items = PySequence_Fast(items, ".items() haven't returned a sequence!");
85+
/* In Python 3.x the ".items()" method returns a dict_items object */
86+
items = PySequence_Fast(items, ".items() didn't return a sequence!");
8687
%#endif
8788
res = traits_asptr_stdseq<std::unordered_map<K,T>, std::pair<K, T> >::asptr(items, val);
8889
} else {
@@ -91,6 +92,7 @@
9192
res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR;
9293
if (SWIG_IsOK(res) && val) *val = p;
9394
}
95+
SWIG_PYTHON_THREAD_END_BLOCK;
9496
return res;
9597
}
9698
};
@@ -100,27 +102,32 @@
100102
typedef std::unordered_map<K,T> unordered_map_type;
101103
typedef typename unordered_map_type::const_iterator const_iterator;
102104
typedef typename unordered_map_type::size_type size_type;
103-
104-
static PyObject *from(const unordered_map_type& unordered_map) {
105+
106+
static PyObject *asdict(const unordered_map_type& map) {
107+
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
108+
size_type size = map.size();
109+
Py_ssize_t pysize = (size <= (size_type) INT_MAX) ? (Py_ssize_t) size : -1;
110+
if (pysize < 0) {
111+
PyErr_SetString(PyExc_OverflowError, "map size not valid in python");
112+
SWIG_PYTHON_THREAD_END_BLOCK;
113+
return NULL;
114+
}
115+
PyObject *obj = PyDict_New();
116+
for (const_iterator i= map.begin(); i!= map.end(); ++i) {
117+
swig::SwigVar_PyObject key = swig::from(i->first);
118+
swig::SwigVar_PyObject val = swig::from(i->second);
119+
PyDict_SetItem(obj, key, val);
120+
}
121+
SWIG_PYTHON_THREAD_END_BLOCK;
122+
return obj;
123+
}
124+
125+
static PyObject *from(const unordered_map_type& map) {
105126
swig_type_info *desc = swig::type_info<unordered_map_type>();
106127
if (desc && desc->clientdata) {
107-
return SWIG_InternalNewPointerObj(new unordered_map_type(unordered_map), desc, SWIG_POINTER_OWN);
128+
return SWIG_InternalNewPointerObj(new unordered_map_type(map), desc, SWIG_POINTER_OWN);
108129
} else {
109-
size_type size = unordered_map.size();
110-
Py_ssize_t pysize = (size <= (size_type) INT_MAX) ? (Py_ssize_t) size : -1;
111-
if (pysize < 0) {
112-
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
113-
PyErr_SetString(PyExc_OverflowError, "unordered_map size not valid in python");
114-
SWIG_PYTHON_THREAD_END_BLOCK;
115-
return NULL;
116-
}
117-
PyObject *obj = PyDict_New();
118-
for (const_iterator i= unordered_map.begin(); i!= unordered_map.end(); ++i) {
119-
swig::SwigVar_PyObject key = swig::from(i->first);
120-
swig::SwigVar_PyObject val = swig::from(i->second);
121-
PyDict_SetItem(obj, key, val);
122-
}
123-
return obj;
130+
return asdict(map);
124131
}
125132
}
126133
};
@@ -136,14 +143,14 @@
136143
#endif
137144

138145
%extend {
139-
mapped_type __getitem__(const key_type& key) const throw (std::out_of_range) {
146+
mapped_type const & __getitem__(const key_type& key) throw (std::out_of_range) {
140147
Map::const_iterator i = self->find(key);
141148
if (i != self->end())
142149
return i->second;
143150
else
144151
throw std::out_of_range("key not found");
145152
}
146-
153+
147154
void __delitem__(const key_type& key) throw (std::out_of_range) {
148155
Map::iterator i = self->find(key);
149156
if (i != self->end())
@@ -160,8 +167,8 @@
160167
PyObject* keys() {
161168
Map::size_type size = self->size();
162169
Py_ssize_t pysize = (size <= (Map::size_type) INT_MAX) ? (Py_ssize_t) size : -1;
170+
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
163171
if (pysize < 0) {
164-
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
165172
PyErr_SetString(PyExc_OverflowError, "unordered_map size not valid in python");
166173
SWIG_PYTHON_THREAD_END_BLOCK;
167174
return NULL;
@@ -171,14 +178,15 @@
171178
for (Py_ssize_t j = 0; j < pysize; ++i, ++j) {
172179
PyList_SET_ITEM(keyList, j, swig::from(i->first));
173180
}
181+
SWIG_PYTHON_THREAD_END_BLOCK;
174182
return keyList;
175183
}
176184

177185
PyObject* values() {
178186
Map::size_type size = self->size();
179187
Py_ssize_t pysize = (size <= (Map::size_type) INT_MAX) ? (Py_ssize_t) size : -1;
188+
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
180189
if (pysize < 0) {
181-
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
182190
PyErr_SetString(PyExc_OverflowError, "unordered_map size not valid in python");
183191
SWIG_PYTHON_THREAD_END_BLOCK;
184192
return NULL;
@@ -188,14 +196,15 @@
188196
for (Py_ssize_t j = 0; j < pysize; ++i, ++j) {
189197
PyList_SET_ITEM(valList, j, swig::from(i->second));
190198
}
199+
SWIG_PYTHON_THREAD_END_BLOCK;
191200
return valList;
192201
}
193202

194203
PyObject* items() {
195204
Map::size_type size = self->size();
196205
Py_ssize_t pysize = (size <= (Map::size_type) INT_MAX) ? (Py_ssize_t) size : -1;
206+
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
197207
if (pysize < 0) {
198-
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
199208
PyErr_SetString(PyExc_OverflowError, "unordered_map size not valid in python");
200209
SWIG_PYTHON_THREAD_END_BLOCK;
201210
return NULL;
@@ -205,6 +214,7 @@
205214
for (Py_ssize_t j = 0; j < pysize; ++i, ++j) {
206215
PyList_SET_ITEM(itemList, j, swig::from(*i));
207216
}
217+
SWIG_PYTHON_THREAD_END_BLOCK;
208218
return itemList;
209219
}
210220

@@ -249,7 +259,13 @@
249259
void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) {
250260
(*self)[key] = x;
251261
}
262+
263+
PyObject* asdict() {
264+
return swig::traits_from< Map >::asdict(*self);
265+
}
252266
}
267+
268+
253269
%enddef
254270

255271

0 commit comments

Comments
 (0)