From cfc9a6c1911de705857764d7c79bed1842a990cf Mon Sep 17 00:00:00 2001 From: Michael Schatzow <michael.schatzow@gmail.com> Date: Fri, 13 Oct 2017 13:42:44 -0400 Subject: [PATCH] BF: closes 1484 for unordered map --- Cython/Includes/libcpp/unordered_map.pxd | 4 +- runtests.py | 47 ++++++++++++++++++------ tests/run/cpp_stl_cpp11.pyx | 36 ++++++++++++++++++ 3 files changed, 73 insertions(+), 14 deletions(-) create mode 100644 tests/run/cpp_stl_cpp11.pyx diff --git a/Cython/Includes/libcpp/unordered_map.pxd b/Cython/Includes/libcpp/unordered_map.pxd index 1b02a4fe6..a6e95eb57 100644 --- a/Cython/Includes/libcpp/unordered_map.pxd +++ b/Cython/Includes/libcpp/unordered_map.pxd @@ -42,8 +42,8 @@ cdef extern from "<unordered_map>" namespace "std" nogil: const_iterator const_end "end"() pair[iterator, iterator] equal_range(T&) #pair[const_iterator, const_iterator] equal_range(key_type&) - void erase(iterator) - void erase(iterator, iterator) + iterator erase(iterator) + iterator erase(iterator, iterator) size_t erase(T&) iterator find(T&) const_iterator const_find "find"(T&) diff --git a/runtests.py b/runtests.py index ed5f13f9b..c8c137b16 100755 --- a/runtests.py +++ b/runtests.py @@ -71,7 +71,7 @@ CY3_DIR = None from distutils.command.build_ext import build_ext as _build_ext from distutils import sysconfig - +from distutils import ccompiler _to_clean = [] @atexit.register @@ -240,7 +240,6 @@ def update_openmp_extension(ext): if flags: compile_flags, link_flags = flags - ext.extra_compile_args.extend(compile_flags.split()) ext.extra_link_args.extend(link_flags.split()) return ext @@ -249,21 +248,32 @@ def update_openmp_extension(ext): return EXCLUDE_EXT -def get_openmp_compiler_flags(language): +def update_cpp11_extension(ext): """ - As of gcc 4.2, it supports OpenMP 2.5. Gcc 4.4 implements 3.0. We don't - (currently) check for other compilers. + update cpp11 extensions that will run on versions of gcc >4.8 + """ + gcc_version = get_gcc_version(ext.language) + compiler_version = gcc_version.group(1) + if gcc_version is not None: + compiler_version = gcc_version.group(1) + if float(compiler_version) > 4.8: + ext.extra_compile_args.extend("-std=c++11") + return ext + return EXCLUDE_EXT - returns a two-tuple of (CFLAGS, LDFLAGS) to build the OpenMP extension + +def get_gcc_version(language): + """ + finds gcc version using Popen """ if language == 'cpp': cc = sysconfig.get_config_var('CXX') else: cc = sysconfig.get_config_var('CC') + if not cc: + cc = ccompiler.get_default_compiler() if not cc: - if sys.platform == 'win32': - return '/openmp', '' return None # For some reason, cc can be e.g. 'gcc -pthread' @@ -272,7 +282,6 @@ def get_openmp_compiler_flags(language): # Force english output env = os.environ.copy() env['LC_MESSAGES'] = 'C' - matcher = re.compile(r"gcc version (\d+\.\d+)").search try: p = subprocess.Popen([cc, "-v"], stderr=subprocess.PIPE, env=env) @@ -282,12 +291,25 @@ def get_openmp_compiler_flags(language): (language, os.strerror(sys.exc_info()[1].errno), cc)) return None _, output = p.communicate() - output = output.decode(locale.getpreferredencoding() or 'ASCII', 'replace') - gcc_version = matcher(output) + return gcc_version + + +def get_openmp_compiler_flags(language): + """ + As of gcc 4.2, it supports OpenMP 2.5. Gcc 4.4 implements 3.0. We don't + (currently) check for other compilers. + + returns a two-tuple of (CFLAGS, LDFLAGS) to build the OpenMP extension + """ + gcc_version = get_gcc_version(language) + if not gcc_version: - return None # not gcc - FIXME: do something about other compilers + if sys.platform == 'win32': + return '/openmp', '' + else: + return None # not gcc - FIXME: do something about other compilers # gcc defines "__int128_t", assume that at least all 64 bit architectures have it global COMPILER_HAS_INT128 @@ -313,6 +335,7 @@ EXCLUDE_EXT = object() EXT_EXTRAS = { 'tag:numpy' : update_numpy_extension, 'tag:openmp': update_openmp_extension, + 'tag:cpp11': update_cpp11_extension, 'tag:trace' : update_linetrace_extension, } diff --git a/tests/run/cpp_stl_cpp11.pyx b/tests/run/cpp_stl_cpp11.pyx new file mode 100644 index 000000000..e24c7b0dc --- /dev/null +++ b/tests/run/cpp_stl_cpp11.pyx @@ -0,0 +1,36 @@ +# mode: run +# tag: cpp, werror, cpp11 +# distutils: extra_compile_args=-std=c++0x + +import sys +from libcpp.unordered_map cimport unordered_map +from libcpp.pair cimport pair + +py_set = set +py_xrange = xrange +py_unicode = unicode + + + +def test_unordered_map_functionality(): + """ + >>> test_unordered_map_functionality() + 'pass' + """ + cdef: + unordered_map[int, int] int_map = unordered_map[int,int]() + pair[int, int] pair_insert = pair[int, int](1, 2) + unordered_map[int,int].iterator iterator = int_map.begin() + pair[unordered_map[int,int].iterator, bint] pair_iter = int_map.insert(pair_insert) + assert int_map[1] == 2 + assert int_map.size() == 1 + assert int_map.erase(1) == 1 # returns number of elements erased + assert int_map.size() == 0 + int_map[1] = 2 + assert int_map.size() == 1 + assert int_map[1] == 2 + iterator = int_map.find(1) + assert int_map.erase(iterator) == int_map.end() + return "pass" + + -- 2.30.9