Commit b1f6f207 authored by Jonathan Helgert's avatar Jonathan Helgert Committed by GitHub

Add merge and set operations of the C++ algorithm library (GH-4462)

Disable on macOS due to bug in Apple clang++. See https://github.com/cython/cython/pull/4448#issuecomment-964405071
parent e9503188
......@@ -226,8 +226,45 @@ cdef extern from "<algorithm>" namespace "std" nogil:
bool binary_search[ExecutionPolicy, Iter, T, Compare](ExecutionPolicy&& policy, Iter first, Iter last, const T& value, Compare comp) except +
# Other operations on sorted ranges
OutputIt merge[InputIt1, InputIt2, OutputIt](
InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt out) except +
OutputIt merge[InputIt1, InputIt2, OutputIt, Compare](
InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt out, Compare comp) except +
void inplace_merge[BidirIt](BidirIt first, BidirIt middle, BidirIt last) except +
void inplace_merge[BidirIt, Compare](BidirIt first, BidirIt middle, BidirIt last, Compare comp) except +
# Set operations (on sorted ranges)
bool includes[InputIt1, InputIt2](
InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2) except +
bool includes[InputIt1, InputIt2, Compare](
InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Compare comp) except +
OutputIt set_difference[InputIt1, InputIt2, OutputIt](
InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt out) except +
OutputIt set_difference[InputIt1, InputIt2, OutputIt, Compare](
InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2,
OutputIt out, Compare comp) except +
OutputIt set_intersection[InputIt1, InputIt2, OutputIt](
InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt out) except +
OutputIt set_intersection[InputIt1, InputIt2, OutputIt, Compare](
InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt out, Compare comp) except +
OutputIt set_symmetric_difference[InputIt1, InputIt2, OutputIt](
InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt out) except +
OutputIt set_symmetric_difference[InputIt1, InputIt2, OutputIt, Compare](
InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt out, Compare comp) except +
OutputIt set_union[InputIt1, InputIt2, OutputIt](
InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt out) except +
OutputIt set_union[InputIt1, InputIt2, OutputIt, Compare](
InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt out, Compare comp) except +
# Heap operations
void make_heap[Iter](Iter first, Iter last) except +
......
......@@ -9,3 +9,5 @@ cpp_stl_conversion
cpp_stl_function
cpp_stl_algo_comparison_ops
cpp_stl_algo_permutation_ops
cpp_stl_algo_sorted_ranges_set_ops
cpp_stl_algo_sorted_ranges_other_ops
\ No newline at end of file
# mode: run
# tag: cpp, werror, cpp11
from cython.operator cimport dereference as deref
from libcpp cimport bool
from libcpp.algorithm cimport merge, inplace_merge
from libcpp.vector cimport vector
cdef bool less(int a, int b):
return a < b
def test_merge(vector[int] v1, vector[int] v2):
"""
Test merge.
>>> test_merge([1, 3, 5], [2, 4])
[1, 2, 3, 4, 5]
"""
cdef vector[int] out = vector[int](v1.size() + v2.size())
merge(v1.begin(), v1.end(), v2.begin(), v2.end(), out.begin())
return out
def test_merge_with_bin_pred(vector[int] v1, vector[int] v2):
"""
Test merge with binary predicate
>>> test_merge_with_bin_pred([1, 3, 5], [2, 4])
[1, 2, 3, 4, 5]
"""
cdef vector[int] out = vector[int](v1.size() + v2.size())
merge(v1.begin(), v1.end(), v2.begin(), v2.end(), out.begin(), less)
return out
def test_inplace_merge(vector[int] v):
"""
Test inplace_merge.
>>> test_inplace_merge([4, 5, 6, 1, 2, 3])
[1, 2, 3, 4, 5, 6]
"""
inplace_merge(v.begin(), v.begin() + 3, v.end())
return v
def test_inplace_merge_with_bin_pred(vector[int] v):
"""
Test inplace_merge with binary predicate
>>> test_inplace_merge_with_bin_pred([4, 5, 6, 1, 2, 3])
[1, 2, 3, 4, 5, 6]
"""
inplace_merge(v.begin(), v.begin() + 3, v.end(), less)
return v
\ No newline at end of file
# mode: run
# tag: cpp, werror, cpp11
from libcpp cimport bool
from libcpp.algorithm cimport (includes, set_difference, set_intersection,
set_symmetric_difference, set_union)
from libcpp.vector cimport vector
cdef bool less(int a, int b):
return a < b
def test_includes(vector[int] v1, vector[int] v2):
"""
Test includes.
>>> test_includes([1, 2, 3, 4], [1, 2, 3])
True
>>> test_includes([1, 2, 3, 4], [5, 6, 7])
False
"""
return includes(v1.begin(), v1.end(), v2.begin(), v2.end())
def test_includes_with_bin_pred(vector[int] v1, vector[int] v2):
"""
Test includes with binary predicate
>>> test_includes_with_bin_pred([1, 2, 3, 4], [1, 2, 3])
True
>>> test_includes_with_bin_pred([1, 2, 3, 4], [5, 6, 7])
False
"""
return includes(v1.begin(), v1.end(), v2.begin(), v2.end(), less)
def test_set_difference(vector[int] v1, vector[int] v2):
"""
Test set_difference.
>>> test_set_difference([1, 2, 5, 5, 5, 9], [2, 5, 7])
[1, 5, 5, 9]
"""
cdef vector[int] diff = vector[int](4)
set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), diff.begin())
return diff
def test_set_difference_with_bin_pred(vector[int] v1, vector[int] v2):
"""
Test set_difference with binary predicate
>>> test_set_difference_with_bin_pred([1, 2, 5, 5, 5, 9], [2, 5, 7])
[1, 5, 5, 9]
"""
cdef vector[int] diff = vector[int](4)
set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), diff.begin(), less)
return diff
def test_set_intersection(vector[int] v1, vector[int] v2):
"""
Test set_intersection.
>>> test_set_intersection([1, 2, 3, 4, 5, 6, 7, 8], [5, 7, 9, 10])
[5, 7]
"""
cdef vector[int] out = vector[int](2)
set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), out.begin())
return out
def test_set_intersection_with_bin_pred(vector[int] v1, vector[int] v2):
"""
Test set_intersection with binary predicate
>>> test_set_intersection_with_bin_pred([1, 2, 3, 4, 5, 6, 7, 8], [5, 7, 9, 10])
[5, 7]
"""
cdef vector[int] out = vector[int](2)
set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), out.begin(), less)
return out
def test_set_symmetric_difference(vector[int] v1, vector[int] v2):
"""
Test set_symmetric_difference.
>>> test_set_symmetric_difference([1, 2, 3, 4, 5, 6, 7, 8], [5, 7, 9, 10])
[1, 2, 3, 4, 6, 8, 9, 10]
"""
cdef vector[int] out = vector[int](8)
set_symmetric_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), out.begin())
return out
def test_set_symmetric_difference_with_bin_pred(vector[int] v1, vector[int] v2):
"""
Test set_symmetric_difference with binary predicate
>>> test_set_symmetric_difference_with_bin_pred([1, 2, 3, 4, 5, 6, 7, 8], [5, 7, 9, 10])
[1, 2, 3, 4, 6, 8, 9, 10]
"""
cdef vector[int] out = vector[int](8)
set_symmetric_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), out.begin(), less)
return out
def test_set_union(vector[int] v1, vector[int] v2):
"""
Test set_union.
>>> test_set_union([1, 2, 3, 4, 5], [3, 4, 5, 6, 7])
[1, 2, 3, 4, 5, 6, 7]
"""
cdef vector[int] out = vector[int](7)
set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), out.begin())
return out
def test_set_union_with_bin_pred(vector[int] v1, vector[int] v2):
"""
Test set_union with binary predicate
>>> test_set_union_with_bin_pred([1, 2, 3, 4, 5], [3, 4, 5, 6, 7])
[1, 2, 3, 4, 5, 6, 7]
"""
cdef vector[int] out = vector[int](7)
set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), out.begin(), less)
return out
\ No newline at end of file
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