Commit bda90138 authored by Robert Bradshaw's avatar Robert Bradshaw

Support for C++ unordered sets and maps.

parent 3a6674df
...@@ -7,7 +7,13 @@ Latest ...@@ -7,7 +7,13 @@ Latest
======= =======
=================== Features added
--------------
* Support for C++ unordered_set and unordered_map.
0.20.1 (2014-02-11) 0.20.1 (2014-02-11)
=================== ===================
......
...@@ -2976,7 +2976,11 @@ class CStructOrUnionType(CType): ...@@ -2976,7 +2976,11 @@ class CStructOrUnionType(CType):
return super(CStructOrUnionType, self).cast_code(expr_code) return super(CStructOrUnionType, self).cast_code(expr_code)
builtin_cpp_conversions = ("std::string", "std::vector", "std::list", "std::set", "std::map", "std::pair") builtin_cpp_conversions = ("std::string",
"std::pair",
"std::vector", "std::list",
"std::set", "std::unordered_set",
"std::map", "std::unordered_map")
class CppClassType(CType): class CppClassType(CType):
# name string # name string
...@@ -3010,6 +3014,12 @@ class CppClassType(CType): ...@@ -3010,6 +3014,12 @@ class CppClassType(CType):
def use_conversion_utility(self, from_or_to): def use_conversion_utility(self, from_or_to):
pass pass
def maybe_unordered(self):
if 'unordered' in self.cname:
return 'unordered_'
else:
return ''
def create_from_py_utility_code(self, env): def create_from_py_utility_code(self, env):
if self.from_py_function is not None: if self.from_py_function is not None:
return True return True
...@@ -3040,10 +3050,11 @@ class CppClassType(CType): ...@@ -3040,10 +3050,11 @@ class CppClassType(CType):
cname = '__pyx_convert_%s_from_py_%s' % (cls, '____'.join(tags)) cname = '__pyx_convert_%s_from_py_%s' % (cls, '____'.join(tags))
context = { context = {
'template_type_declarations': '\n'.join(declarations), 'template_type_declarations': '\n'.join(declarations),
'cname': cname 'cname': cname,
'maybe_unordered': self.maybe_unordered(),
} }
from UtilityCode import CythonUtilityCode from UtilityCode import CythonUtilityCode
env.use_utility_code(CythonUtilityCode.load(cls + ".from_py", "CppConvert.pyx", context=context)) env.use_utility_code(CythonUtilityCode.load(cls.replace('unordered_', '') + ".from_py", "CppConvert.pyx", context=context))
self.from_py_function = cname self.from_py_function = cname
return True return True
...@@ -3068,10 +3079,11 @@ class CppClassType(CType): ...@@ -3068,10 +3079,11 @@ class CppClassType(CType):
cname = "__pyx_convert_%s_to_py_%s" % (cls, "____".join(tags)) cname = "__pyx_convert_%s_to_py_%s" % (cls, "____".join(tags))
context = { context = {
'template_type_declarations': '\n'.join(declarations), 'template_type_declarations': '\n'.join(declarations),
'cname': cname 'cname': cname,
'maybe_unordered': self.maybe_unordered(),
} }
from UtilityCode import CythonUtilityCode from UtilityCode import CythonUtilityCode
env.use_utility_code(CythonUtilityCode.load(cls + ".to_py", "CppConvert.pyx", context=context)) env.use_utility_code(CythonUtilityCode.load(cls.replace('unordered_', '') + ".to_py", "CppConvert.pyx", context=context))
self.to_py_function = cname self.to_py_function = cname
return True return True
......
from utility cimport pair
cdef extern from "<unordered_map>" namespace "std":
cdef cppclass unordered_map[T, U]:
cppclass iterator:
pair[T, U]& operator*() nogil
iterator operator++() nogil
iterator operator--() nogil
bint operator==(iterator) nogil
bint operator!=(iterator) nogil
cppclass reverse_iterator:
pair[T, U]& operator*() nogil
iterator operator++() nogil
iterator operator--() nogil
bint operator==(reverse_iterator) nogil
bint operator!=(reverse_iterator) nogil
#cppclass const_iterator(iterator):
# pass
#cppclass const_reverse_iterator(reverse_iterator):
# pass
unordered_map() nogil except +
unordered_map(unordered_map&) nogil except +
#unordered_map(key_compare&)
U& operator[](T&) nogil
#unordered_map& operator=(unordered_map&)
bint operator==(unordered_map&, unordered_map&) nogil
bint operator!=(unordered_map&, unordered_map&) nogil
bint operator<(unordered_map&, unordered_map&) nogil
bint operator>(unordered_map&, unordered_map&) nogil
bint operator<=(unordered_map&, unordered_map&) nogil
bint operator>=(unordered_map&, unordered_map&) nogil
U& at(T&) nogil
iterator begin() nogil
#const_iterator begin()
void clear() nogil
size_t count(T&) nogil
bint empty() nogil
iterator end() nogil
#const_iterator end()
pair[iterator, iterator] equal_range(T&) nogil
#pair[const_iterator, const_iterator] equal_range(key_type&)
void erase(iterator) nogil
void erase(iterator, iterator) nogil
size_t erase(T&) nogil
iterator find(T&) nogil
#const_iterator find(key_type&)
pair[iterator, bint] insert(pair[T, U]) nogil # XXX pair[T,U]&
iterator insert(iterator, pair[T, U]) nogil # XXX pair[T,U]&
#void insert(input_iterator, input_iterator)
#key_compare key_comp()
iterator lower_bound(T&) nogil
#const_iterator lower_bound(key_type&)
size_t max_size() nogil
reverse_iterator rbegin() nogil
#const_reverse_iterator rbegin()
reverse_iterator rend() nogil
#const_reverse_iterator rend()
size_t size() nogil
void swap(unordered_map&) nogil
iterator upper_bound(T&) nogil
#const_iterator upper_bound(key_type&)
#value_compare value_comp()
from pair cimport pair
cdef extern from "<unordered_set>" namespace "std":
cdef cppclass unordered_set[T]:
cppclass iterator:
T& operator*()
iterator operator++() nogil
iterator operator--() nogil
bint operator==(iterator) nogil
bint operator!=(iterator) nogil
cppclass reverse_iterator:
T& operator*() nogil
iterator operator++() nogil
iterator operator--() nogil
bint operator==(reverse_iterator) nogil
bint operator!=(reverse_iterator) nogil
#cppclass const_iterator(iterator):
# pass
#cppclass const_reverse_iterator(reverse_iterator):
# pass
unordered_set() nogil except +
unordered_set(unordered_set&) nogil except +
#unordered_set(key_compare&)
#unordered_set& operator=(unordered_set&)
bint operator==(unordered_set&, unordered_set&) nogil
bint operator!=(unordered_set&, unordered_set&) nogil
bint operator<(unordered_set&, unordered_set&) nogil
bint operator>(unordered_set&, unordered_set&) nogil
bint operator<=(unordered_set&, unordered_set&) nogil
bint operator>=(unordered_set&, unordered_set&) nogil
iterator begin() nogil
#const_iterator begin()
void clear() nogil
size_t count(T&) nogil
bint empty() nogil
iterator end() nogil
#const_iterator end()
pair[iterator, iterator] equal_range(T&) nogil
#pair[const_iterator, const_iterator] equal_range(T&)
void erase(iterator) nogil
void erase(iterator, iterator) nogil
size_t erase(T&) nogil
iterator find(T&) nogil
#const_iterator find(T&)
pair[iterator, bint] insert(T&) nogil
iterator insert(iterator, T&) nogil
#void insert(input_iterator, input_iterator)
#key_compare key_comp()
iterator lower_bound(T&) nogil
#const_iterator lower_bound(T&)
size_t max_size() nogil
reverse_iterator rbegin() nogil
#const_reverse_iterator rbegin()
reverse_iterator rend() nogil
#const_reverse_iterator rend()
size_t size() nogil
void swap(unordered_set&) nogil
iterator upper_bound(T&) nogil
#const_iterator upper_bound(T&)
#value_compare value_comp()
...@@ -109,7 +109,7 @@ cdef object {{cname}}(const_cpp_list[X]& v): ...@@ -109,7 +109,7 @@ cdef object {{cname}}(const_cpp_list[X]& v):
{{template_type_declarations}} {{template_type_declarations}}
cdef extern from *: cdef extern from *:
cdef cppclass set "std::set" [T]: cdef cppclass set "std::{{maybe_unordered}}set" [T]:
void insert(T&) void insert(T&)
@cname("{{cname}}") @cname("{{cname}}")
...@@ -127,14 +127,14 @@ cimport cython ...@@ -127,14 +127,14 @@ cimport cython
{{template_type_declarations}} {{template_type_declarations}}
cdef extern from *: cdef extern from *:
cdef cppclass cpp_set "std::set" [T]: cdef cppclass cpp_set "std::{{maybe_unordered}}set" [T]:
cppclass const_iterator: cppclass const_iterator:
T& operator*() T& operator*()
const_iterator operator++() const_iterator operator++()
bint operator!=(const_iterator) bint operator!=(const_iterator)
const_iterator begin() const_iterator begin()
const_iterator end() const_iterator end()
cdef cppclass const_cpp_set "const std::set" [T](cpp_set): cdef cppclass const_cpp_set "const std::{{maybe_unordered}}set" [T](cpp_set):
pass pass
@cname("{{cname}}") @cname("{{cname}}")
...@@ -182,7 +182,7 @@ cdef object {{cname}}(pair[X,Y]& p): ...@@ -182,7 +182,7 @@ cdef object {{cname}}(pair[X,Y]& p):
cdef extern from *: cdef extern from *:
cdef cppclass pair "std::pair" [T, U]: cdef cppclass pair "std::pair" [T, U]:
pair(T&, U&) pair(T&, U&)
cdef cppclass map "std::map" [T, U]: cdef cppclass map "std::{{maybe_unordered}}map" [T, U]:
void insert(pair[T, U]&) void insert(pair[T, U]&)
cdef cppclass pair "std::pair" [T, U]: cdef cppclass pair "std::pair" [T, U]:
...@@ -209,7 +209,7 @@ cimport cython ...@@ -209,7 +209,7 @@ cimport cython
{{template_type_declarations}} {{template_type_declarations}}
cdef extern from *: cdef extern from *:
cdef cppclass map "std::map" [T, U]: cdef cppclass map "std::{{maybe_unordered}}map" [T, U]:
cppclass value_type: cppclass value_type:
T first T first
U second U second
......
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
import sys import sys
from libcpp.map cimport map from libcpp.map cimport map
from libcpp.unordered_map cimport unordered_map
from libcpp.set cimport set as cpp_set from libcpp.set cimport set as cpp_set
from libcpp.unordered_set cimport unordered_set
from libcpp.string cimport string from libcpp.string cimport string
from libcpp.pair cimport pair from libcpp.pair cimport pair
from libcpp.vector cimport vector from libcpp.vector cimport vector
...@@ -140,6 +142,18 @@ def test_set(o): ...@@ -140,6 +142,18 @@ def test_set(o):
cdef cpp_set[long] s = o cdef cpp_set[long] s = o
return s return s
def test_unordered_set(o):
"""
>>> sorted(test_unordered_set([1, 2, 3]))
[1, 2, 3]
>>> sorted(test_unordered_set([1, 2, 3, 3]))
[1, 2, 3]
>>> type(test_unordered_set([])) is py_set
True
"""
cdef unordered_set[long] s = o
return s
def test_map(o): def test_map(o):
""" """
>>> test_map({1: 1.0, 2: 0.5, 3: 0.25}) >>> test_map({1: 1.0, 2: 0.5, 3: 0.25})
...@@ -148,6 +162,14 @@ def test_map(o): ...@@ -148,6 +162,14 @@ def test_map(o):
cdef map[int, double] m = o cdef map[int, double] m = o
return m return m
def test_unordered_map(o):
"""
>>> test_map({1: 1.0, 2: 0.5, 3: 0.25})
{1: 1.0, 2: 0.5, 3: 0.25}
"""
cdef unordered_map[int, double] m = o
return m
def test_nested(o): def test_nested(o):
""" """
>>> test_nested({}) >>> test_nested({})
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment