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

Add most of the C++17 numeric functions to libcpp.numeric (GH-4423)

Some overloaded methods are commented out as they currently result in incorrect C++ code.
See https://github.com/cython/cython/pull/4423#issuecomment-953685310
parent 376efe17
......@@ -21,3 +21,104 @@ cdef extern from "<numeric>" namespace "std" nogil:
void partial_sum[InputIt, OutputIt, BinaryOperation](InputIt in_first, InputIt in_last, OutputIt out_first,
BinaryOperation op)
T reduce[InputIt, T](InputIt first, InputIt last, T init)
# ambiguous with next overload
#T reduce[ExecutionPolicy, ForwardIt, T](ExecutionPolicy&& policy,
# ForwardIt first, ForwardIt last, T init)
T reduce[InputIt, T, BinaryOp](InputIt first, InputIt last, T init, BinaryOp binary_op)
T reduce[ExecutionPolicy, ForwardIt, T, BinaryOp](ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last, T init, BinaryOp binary_op)
T transform_reduce[InputIt1, InputIt2, T](InputIt1 first1, InputIt1 last1,
InputIt2 first2, T init)
T transform_reduce[InputIt1, InputIt2, T, BinaryReductionOp, BinaryTransformOp](
InputIt1 first1, InputIt1 last1, InputIt2 first2, T init,
BinaryReductionOp reduce, BinaryTransformOp transform)
T transform_reduce[InputIt, T, BinaryReductionOp, UnaryTransformOp](
InputIt first, InputIt last, T init, BinaryReductionOp reduce,
UnaryTransformOp transform)
# ambiguous with previous overload
#T transform_reduce[ExecutionPolicy, ForwardIt1, ForwardIt2, T](
# ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1,
# ForwardIt2 first2, T init)
T transform_reduce[ExecutionPolicy, ForwardIt1, ForwardIt2, T, BinaryReductionOp, BinaryTransformOp](
ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2, T init,
BinaryReductionOp reduce, BinaryTransformOp transform)
# ambiguous with second overload
#T transform_reduce[ExecutionPolicy, ForwardIt, T, BinaryReductionOp, UnaryTransformOp](
# ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, T init, BinaryReductionOp reduce,
# UnaryTransformOp transform)
OutputIt inclusive_scan[InputIt, OutputIt](InputIt first, InputIt last, OutputIt d_first)
# ambiguous with next overload
# ForwardIt2 inclusive_scan[ExecutionPolicy, ForwardIt1, ForwardIt2](
# ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last,
# ForwardIt2 d_first)
OutputIt inclusive_scan[InputIt, OutputIt, BinaryOperation](
InputIt first, InputIt last, OutputIt d_first, BinaryOperation binary_op)
# ambiguous with next overload
# ForwardIt2 inclusive_scan[ExecutionPolicy, ForwardIt1, ForwardIt2, BinaryOperation](
# ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
# BinaryOperation binary_op)
OutputIt inclusive_scan[InputIt, OutputIt, BinaryOperation, T](
InputIt first, InputIt last, OutputIt d_first, BinaryOperation binary_op,
T init)
#
# ForwardIt2 inclusive_scan[ExecutionPolicy, ForwardIt1, ForwardIt2, BinaryOperation, T](
# ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
# BinaryOperation binary_op, T init)
OutputIt exclusive_scan[InputIt, OutputIt, T](InputIt first, InputIt last,
OutputIt d_first, T init)
# ambiguous with next overload
#ForwardIt2 exclusive_scan[ExecutionPolicy, ForwardIt1, ForwardIt2, T](
# ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last,
# ForwardIt2 d_first, T init)
OutputIt exclusive_scan[InputIt, OutputIt, T, BinaryOperation](
InputIt first, InputIt last, OutputIt d_first, T init, BinaryOperation binary_op)
ForwardIt2 exclusive_scan[ExecutionPolicy, ForwardIt1, ForwardIt2, T, BinaryOperation](
ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
T init, BinaryOperation binary_op)
OutputIt transform_inclusive_scan[InputIt, OutputIt, BinaryOperation, UnaryOperation](
InputIt first, InputIt last, OutputIt d_first, BinaryOperation binary_op,
UnaryOperation unary_op)
# ambiguous with next overload
# ForwardIt2 transform_inclusive_scan[ExecutionPolicy, ForwardIt1, ForwardIt2, BinaryOperation, UnaryOperation](
# ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
# BinaryOperation binary_op, UnaryOperation unary_op)
OutputIt transform_inclusive_scan[InputIt, OutputIt, BinaryOperation, UnaryOperation, T](
InputIt first, InputIt last, OutputIt d_first, BinaryOperation binary_op,
UnaryOperation unary_op, T init)
ForwardIt2 transform_inclusive_scan[ExecutionPolicy, ForwardIt1, ForwardIt2, BinaryOperation, UnaryOperation, T](
ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
BinaryOperation binary_op, UnaryOperation unary_op, T init)
OutputIt transform_exclusive_scan[InputIt, OutputIt, T, BinaryOperation, UnaryOperation](
InputIt first, InputIt last, OutputIt d_first, T init, BinaryOperation binary_op,
UnaryOperation unary_op)
ForwardIt2 transform_exclusive_scan[ExecutionPolicy, ForwardIt1, ForwardIt2, T, BinaryOperation, UnaryOperation](
ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
T init, BinaryOperation binary_op, UnaryOperation unary_op)
# mode: run
# tag: cpp, werror, cpp17, cppexecpolicies
from libcpp.numeric cimport (reduce, transform_reduce, inclusive_scan,
exclusive_scan, transform_inclusive_scan,
transform_exclusive_scan)
from libcpp.execution cimport seq
from libcpp.vector cimport vector
# Subtracts two integers.
cdef int subtract_integers(int lhs, int rhs):
return lhs - rhs
# Adds two integers.
cdef int add_integers(int lhs, int rhs):
return lhs + rhs
# Multiplies two integers.
cdef int multiply_integers(int lhs, int rhs):
return lhs * rhs
# Multiplies a integer with 2
cdef int multiply_with_2(int val):
return 2*val
def test_reduce(vector[int] v, int init):
"""
Test reduce.
0 + 1 = 1
1 + 2 = 3
3 + 3 = 6
>>> test_reduce([1, 2, 3], 0)
6
"""
return reduce(v.begin(), v.end(), init)
def test_reduce_with_bin_op(vector[int] v, int init):
"""
Test reduce with a binary operation (subtraction).
0 - 1 = -1
-1 - 2 = -3
-3 - 3 = -6
>>> test_reduce_with_bin_op([1, 2, 3], 0)
-6
"""
return reduce(v.begin(), v.end(), init, subtract_integers)
# def test_reduce_with_execpolicy(vector[int] v, int init):
# """
# Test reduce with execution policy.
# 0 + 1 = 1
# 1 + 2 = 3
# 3 + 3 = 6
# >>> test_reduce_with_execpolicy([1, 2, 3], 0)
# 6
# """
# return reduce(seq, v.begin(), v.end(), init)
def test_reduce_with_bin_op_and_execpolicy(vector[int] v, int init):
"""
Test reduce with execution policy and a binary operation (subtraction).
0 - 1 = -1
-1 - 2 = -3
-3 - 3 = -6
>>> test_reduce_with_bin_op_and_execpolicy([1, 2, 3], 0)
-6
"""
return reduce(seq, v.begin(), v.end(), init, subtract_integers)
def test_transform_reduce(vector[int] v1, vector[int] v2, int init):
"""
Test transform_reduce
>>> test_transform_reduce([1, 2, 3], [1, 2, 3], 0)
14
"""
return transform_reduce(v1.begin(), v1.end(), v2.begin(), init)
def test_transform_reduce_with_bin_red_op_and_bin_tran_op(vector[int] v1, vector[int] v2, int init):
"""
Test transform_reduce with a binary reduce and transform operations
>>> test_transform_reduce_with_bin_red_op_and_bin_tran_op([1, 2, 3], [1, 2, 3], 0)
14
"""
return transform_reduce(v1.begin(), v1.end(), v2.begin(), init, add_integers, multiply_integers)
def test_transform_reduce_with_bin_op_and_unary_op(vector[int] v1, vector[int] v2, int init):
"""
Test transform_reduce with a binary reduction and a unary transform operation
>>> test_transform_reduce_with_bin_op_and_unary_op([1, 2, 3], [1, 2, 3], 0)
12
"""
return transform_reduce(v1.begin(), v1.end(), init, add_integers, multiply_with_2)
# def test_transform_reduce_with_execpolicy(vector[int] v1, vector[int] v2, int init):
# """
# Test transform_reduce with a execution policy
# >>> test_transform_reduce_with_execpolicy([1, 2, 3], [1, 2, 3], 0)
# 14
# """
# return transform_reduce(seq, v1.begin(), v1.end(), v2.begin(), init)
def test_transform_reduce_with_execpolicy_bin_red_op_and_bin_tran_op(vector[int] v1, vector[int] v2, int init):
"""
Test transform_reduce with a execution policy and binary reduce and transform operations
>>> test_transform_reduce_with_execpolicy_bin_red_op_and_bin_tran_op([1, 2, 3], [1, 2, 3], 0)
14
"""
return transform_reduce(seq, v1.begin(), v1.end(), v2.begin(), init, add_integers, multiply_integers)
# def test_transform_reduce_with_execpolicy_bin_op_and_unary_op(vector[int] v1, vector[int] v2, int init):
# """
# Test transform_reduce with a execution policy and binary reduction and a unary transform operation
# >>> test_transform_reduce_with_execpolicy_bin_op_and_unary_op([1, 2, 3], [1, 2, 3], 0)
# 12
# """
# return transform_reduce(seq, v1.begin(), v1.end(), v2.begin(), init, add_integers, multiply_with_2)
def test_inclusive_scan(vector[int] v):
"""
Test inclusive_scan
>>> test_inclusive_scan([1, 2, 3, 4])
[1, 3, 6, 10]
"""
cdef vector[int] out = vector[int](v.size())
inclusive_scan(v.begin(), v.end(), out.begin())
return out
# def test_inclusive_scan_with_execpolicy(vector[int] v):
# """
# Test inclusive_scan with a execution policy
# >>> test_inclusive_scan_with_execpolicy([1, 2, 3, 4])
# [1, 3, 6, 10]
# """
# cdef vector[int] out
# inclusive_scan(seq, v.begin(), v.end(), out.begin())
# return out
def test_inclusive_scan_with_bin_op(vector[int] v):
"""
Test inclusive_scan with a binary operation
>>> test_inclusive_scan_with_bin_op([1, 2, 3, 4])
[1, 3, 6, 10]
"""
cdef vector[int] out = vector[int](v.size())
inclusive_scan(v.begin(), v.end(), out.begin(), add_integers)
return out
# def test_inclusive_scan_with_execpolicy_and_bin_op(vector[int] v):
# """
# Test inclusive_scan with a execution policy and a binary operation
# >>> test_inclusive_scan_with_execpolicy_and_bin_op([1, 2, 3, 4])
# [1, 3, 6, 10]
# """
# cdef vector[int] out
# inclusive_scan(seq, v.begin(), v.end(), out.begin(), add_integers)
# return out
def test_inclusive_scan_with_bin_op_and_init(vector[int] v, int init):
"""
Test inclusive_scan with a binary operation and a initial value
>>> test_inclusive_scan_with_bin_op_and_init([1, 2, 3, 4], 0)
[1, 3, 6, 10]
"""
cdef vector[int] out = vector[int](v.size())
inclusive_scan(v.begin(), v.end(), out.begin(), add_integers, init)
return out
# def test_inclusive_scan_with_execpolicy_bin_op_and_init(vector[int] v, int init):
# """
# Test inclusive_scan with a execution policy, a binary operation and a initial value
# >>> test_inclusive_scan_with_execpolicy_bin_op_and_init([1, 2, 3, 4], 0)
# [1, 3, 6, 10]
# """
# cdef vector[int] out = vector[int](v.size())
# inclusive_scan(seq, v.begin(), v.end(), out.begin(), add_integers, init)
# return out
def test_transform_inclusive_scan(vector[int] v):
"""
Test transform inclusive_scan
>>> test_transform_inclusive_scan([1, 2, 3, 4])
[2, 6, 12, 20]
"""
cdef vector[int] out = vector[int](v.size())
transform_inclusive_scan(v.begin(), v.end(), out.begin(), add_integers, multiply_with_2)
return out
# def test_transform_inclusive_scan_with_execpolicy(vector[int] v):
# """
# Test transform inclusive_scan with a execution policy
# >>> test_transform_inclusive_scan_with_execpolicy([1, 2, 3, 4])
# [2, 6, 12, 20 ]
# """
# cdef vector[int] out
# transform_inclusive_scan(seq, v.begin(), v.end(), out.begin(), add_integers, multiply_with_2)
# return out
def test_transform_inclusive_scan_with_init(vector[int] v, int init):
"""
Test transform inclusive_scan with an initial value
>>> test_transform_inclusive_scan_with_init([1, 2, 3, 4], 0)
[2, 6, 12, 20]
"""
cdef vector[int] out = vector[int](v.size())
transform_inclusive_scan(v.begin(), v.end(), out.begin(), add_integers, multiply_with_2, init)
return out
def test_transform_inclusive_scan_with_execpolicy_and_init(vector[int] v, int init):
"""
Test transform inclusive_scan with an initial value
>>> test_transform_inclusive_scan_with_execpolicy_and_init([1, 2, 3, 4], 0)
[2, 6, 12, 20]
"""
cdef vector[int] out = vector[int](v.size())
transform_inclusive_scan(seq, v.begin(), v.end(), out.begin(), add_integers, multiply_with_2, init)
return out
def test_exclusive_scan(vector[int] v, int init):
"""
Test exclusive_scan
>>> test_exclusive_scan([1, 2, 3, 4], 0)
[0, 1, 3, 6]
"""
cdef vector[int] out = vector[int](v.size())
exclusive_scan(v.begin(), v.end(), out.begin(), init)
return out
# def test_exclusive_scan_with_execpolicy(vector[int] v, int init):
# """
# Test exclusive_scan with a execution policy
# >>> test_exclusive_scan_with_execpolicy([1, 2, 3, 4], 0)
# [0, 1, 3, 6]
# """
# cdef vector[int] out
# exclusive_scan(seq, v.begin(), v.end(), out.begin(), init)
# return out
def test_exclusive_scan_with_bin_op(vector[int] v, int init):
"""
Test exclusive_scan with a binary operation
>>> test_exclusive_scan_with_bin_op([1, 2, 3, 4], 0)
[0, 1, 3, 6]
"""
cdef vector[int] out = vector[int](v.size())
exclusive_scan(v.begin(), v.end(), out.begin(), init, add_integers)
return out
def test_exclusive_scan_with_execpolicy_and_bin_op(vector[int] v, int init):
"""
Test exclusive_scan with a execution policy and a binary operation
>>> test_exclusive_scan_with_execpolicy_and_bin_op([1, 2, 3, 4], 0)
[0, 1, 3, 6]
"""
cdef vector[int] out = vector[int](v.size())
exclusive_scan(seq, v.begin(), v.end(), out.begin(), init, add_integers)
return out
def test_transform_exclusive_scan_with_execpolicy(vector[int] v, int init):
"""
Test transform_exclusive_scan
>>> test_transform_exclusive_scan_with_execpolicy([1, 2, 3, 4], 0)
[0, 2, 6, 12]
"""
cdef vector[int] out = vector[int](v.size())
transform_exclusive_scan(seq, v.begin(), v.end(), out.begin(), init, add_integers, multiply_with_2)
return out
def test_transform_exclusive_scan_with_execpolicy(vector[int] v, int init):
"""
Test transform_exclusive_scan with a execution policy
>>> test_transform_exclusive_scan_with_execpolicy([1, 2, 3, 4], 0)
[0, 2, 6, 12]
"""
cdef vector[int] out = vector[int](v.size())
transform_exclusive_scan(seq, v.begin(), v.end(), out.begin(), init, add_integers, multiply_with_2)
return out
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