1 /*
2   Unordered Multimaps
3 */
4 %include <std_unordered_map.i>
5 
6 %fragment("StdUnorderedMultimapTraits","header",fragment="StdMapCommonTraits",fragment="StdUnorderedMapForwardIteratorTraits")
7 {
8   namespace swig {
9     template <class SwigPySeq, class K, class T, class Hash, class Compare, class Alloc>
10     inline void
assign(const SwigPySeq & swigpyseq,std::unordered_multimap<K,T,Hash,Compare,Alloc> * unordered_multimap)11     assign(const SwigPySeq& swigpyseq, std::unordered_multimap<K,T,Hash,Compare,Alloc> *unordered_multimap) {
12       typedef typename std::unordered_multimap<K,T,Hash,Compare,Alloc>::value_type value_type;
13       typename SwigPySeq::const_iterator it = swigpyseq.begin();
14       for (;it != swigpyseq.end(); ++it) {
15 	unordered_multimap->insert(value_type(it->first, it->second));
16       }
17     }
18 
19     template <class K, class T, class Hash, class Compare, class Alloc>
20     struct traits_reserve<std::unordered_multimap<K,T,Hash,Compare,Alloc> >  {
21       static void reserve(std::unordered_multimap<K,T,Hash,Compare,Alloc> &seq, typename std::unordered_multimap<K,T,Hash,Compare,Alloc>::size_type n) {
22         seq.reserve(n);
23       }
24     };
25 
26     template <class K, class T, class Hash, class Compare, class Alloc>
27     struct traits_asptr<std::unordered_multimap<K,T,Hash,Compare,Alloc> >  {
28       typedef std::unordered_multimap<K,T,Hash,Compare,Alloc> unordered_multimap_type;
29       static int asptr(PyObject *obj, std::unordered_multimap<K,T,Hash,Compare,Alloc> **val) {
30 	int res = SWIG_ERROR;
31 	if (PyDict_Check(obj)) {
32 	  SwigVar_PyObject items = PyObject_CallMethod(obj,(char *)"items",NULL);
33 %#if PY_VERSION_HEX >= 0x03000000
34           /* In Python 3.x the ".items()" method returns a dict_items object */
35           items = PySequence_Fast(items, ".items() didn't return a sequence!");
36 %#endif
37 	  res = traits_asptr_stdseq<std::unordered_multimap<K,T,Hash,Compare,Alloc>, std::pair<K, T> >::asptr(items, val);
38 	} else {
39 	  unordered_multimap_type *p = 0;
40 	  swig_type_info *descriptor = swig::type_info<unordered_multimap_type>();
41 	  res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR;
42 	  if (SWIG_IsOK(res) && val)  *val = p;
43 	}
44 	return res;
45       }
46     };
47 
48     template <class K, class T, class Hash, class Compare, class Alloc>
49     struct traits_from<std::unordered_multimap<K,T,Hash,Compare,Alloc> >  {
50       typedef std::unordered_multimap<K,T,Hash,Compare,Alloc> unordered_multimap_type;
51       typedef typename unordered_multimap_type::const_iterator const_iterator;
52       typedef typename unordered_multimap_type::size_type size_type;
53 
54       static PyObject *from(const unordered_multimap_type& unordered_multimap) {
55 	swig_type_info *desc = swig::type_info<unordered_multimap_type>();
56 	if (desc && desc->clientdata) {
57 	  return SWIG_InternalNewPointerObj(new unordered_multimap_type(unordered_multimap), desc, SWIG_POINTER_OWN);
58 	} else {
59 	  size_type size = unordered_multimap.size();
60 	  Py_ssize_t pysize = (size <= (size_type) INT_MAX) ? (Py_ssize_t) size : -1;
61 	  if (pysize < 0) {
62 	    SWIG_PYTHON_THREAD_BEGIN_BLOCK;
63 	    PyErr_SetString(PyExc_OverflowError, "unordered_multimap size not valid in python");
64 	    SWIG_PYTHON_THREAD_END_BLOCK;
65 	    return NULL;
66 	  }
67 	  PyObject *obj = PyDict_New();
68 	  for (const_iterator i= unordered_multimap.begin(); i!= unordered_multimap.end(); ++i) {
69 	    swig::SwigVar_PyObject key = swig::from(i->first);
70 	    swig::SwigVar_PyObject val = swig::from(i->second);
71 	    PyDict_SetItem(obj, key, val);
72 	  }
73 	  return obj;
74 	}
75       }
76     };
77   }
78 }
79 
80 %define %swig_unordered_multimap_methods(Type...)
81   %swig_unordered_map_common(Type);
82 
83 #if defined(SWIGPYTHON_BUILTIN)
84   %feature("python:slot", "mp_ass_subscript", functype="objobjargproc") __setitem__;
85 #endif
86 
87   %extend {
88     // This will be called through the mp_ass_subscript slot to delete an entry.
89     void __setitem__(const key_type& key) {
90       self->erase(key);
91     }
92 
93     void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) {
94       self->insert(Type::value_type(key,x));
95     }
96   }
97 %enddef
98 
99 %include <std/std_unordered_multimap.i>
100 
101