summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Edwards <mje-nz@users.noreply.github.com>2020-04-12 09:16:18 +1200
committerGitHub <noreply@github.com>2020-04-11 23:16:18 +0200
commit008bc53c45d1131d0eedf5c1fe276f5808911681 (patch)
tree37d6c4255e560c736019a3532957c8905ac2f61d
parent1582d97d44b9dbe9b89e9ec6e7e979ae73e3b583 (diff)
downloadcython-008bc53c45d1131d0eedf5c1fe276f5808911681.tar.gz
Add partitioning and sorting operations to libcpp.algorithm (GH-3202)
* Add is_partitioned and partition to libcpp.algorithm * Add is_sorted and is_sorted_until to libcpp.algorithm * Add partition_copy, stable_partition, and partition_point to libcpp.algorithm * Move tests for sort and partial_sort into cpp_stl_algo_sorting_ops, add greater to libcpp.functional * Add partial_sort_copy to libcpp.algorithm * Add stable_sort to libcpp.algorithm * Add nth_element to libcpp.algorithm * Add missing except specifiers in libcpp.algorithm
-rw-r--r--Cython/Includes/libcpp/algorithm.pxd103
-rw-r--r--Cython/Includes/libcpp/functional.pxd10
-rw-r--r--tests/run/cpp_stl_algo_partitioning_ops.pyx90
-rw-r--r--tests/run/cpp_stl_algo_sorting_ops.pyx187
-rw-r--r--tests/run/libcpp_algo.pyx32
5 files changed, 350 insertions, 72 deletions
diff --git a/Cython/Includes/libcpp/algorithm.pxd b/Cython/Includes/libcpp/algorithm.pxd
index 9829101ef..c07bae139 100644
--- a/Cython/Includes/libcpp/algorithm.pxd
+++ b/Cython/Includes/libcpp/algorithm.pxd
@@ -11,44 +11,45 @@ cdef extern from "<algorithm>" namespace "std" nogil:
void for_each[Iter, UnaryFunction](Iter first, Iter last, UnaryFunction f) except + # actually returns f
- ptrdiff_t count[Iter, T](Iter first, Iter last, const T& value)
+ ptrdiff_t count[Iter, T](Iter first, Iter last, const T& value) except +
ptrdiff_t count_if[Iter, Pred](Iter first, Iter last, Pred pred) except +
- pair[Iter1, Iter2] mismatch[Iter1, Iter2](Iter1 first1, Iter1 last1, Iter2 first2) # other overloads are tricky
+ pair[Iter1, Iter2] mismatch[Iter1, Iter2](
+ Iter1 first1, Iter1 last1, Iter2 first2) except + # other overloads are tricky
- Iter find[Iter, T](Iter first, Iter last, const T& value)
+ Iter find[Iter, T](Iter first, Iter last, const T& value) except +
Iter find_if[Iter, Pred](Iter first, Iter last, Pred pred) except +
Iter find_if_not[Iter, Pred](Iter first, Iter last, Pred pred) except +
- Iter1 find_end[Iter1, Iter2](Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2)
+ Iter1 find_end[Iter1, Iter2](Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2) except +
Iter1 find_end[Iter1, Iter2, BinaryPred](
Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2, BinaryPred pred) except +
- Iter1 find_first_of[Iter1, Iter2](Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2)
+ Iter1 find_first_of[Iter1, Iter2](Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2) except +
Iter1 find_first_of[Iter1, Iter2, BinaryPred](
Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2, BinaryPred pred) except +
- Iter adjacent_find[Iter](Iter first, Iter last)
+ Iter adjacent_find[Iter](Iter first, Iter last) except +
Iter adjacent_find[Iter, BinaryPred](Iter first, Iter last, BinaryPred pred) except +
- Iter1 search[Iter1, Iter2](Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2)
+ Iter1 search[Iter1, Iter2](Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2) except +
Iter1 search[Iter1, Iter2, BinaryPred](
Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2, BinaryPred pred) except +
- Iter search_n[Iter, Size, T](Iter first1, Iter last1, Size count, const T& value)
+ Iter search_n[Iter, Size, T](Iter first1, Iter last1, Size count, const T& value) except +
Iter search_n[Iter, Size, T, BinaryPred](
Iter first1, Iter last1, Size count, const T& value, BinaryPred pred) except +
# Modifying sequence operations
- OutputIt copy[InputIt, OutputIt](InputIt first, InputIt last, OutputIt d_first)
+ OutputIt copy[InputIt, OutputIt](InputIt first, InputIt last, OutputIt d_first) except +
OutputIt copy_if[InputIt, OutputIt, Pred](InputIt first, InputIt last, OutputIt d_first, Pred pred) except +
- OutputIt copy_n[InputIt, Size, OutputIt](InputIt first, Size count, OutputIt result)
- Iter2 copy_backward[Iter1, Iter2](Iter1 first, Iter1 last, Iter2 d_last)
+ OutputIt copy_n[InputIt, Size, OutputIt](InputIt first, Size count, OutputIt result) except +
+ Iter2 copy_backward[Iter1, Iter2](Iter1 first, Iter1 last, Iter2 d_last) except +
- OutputIt move[InputIt, OutputIt](InputIt first, InputIt last, OutputIt d_first)
- Iter2 move_backward[Iter1, Iter2](Iter1 first, Iter1 last, Iter2 d_last)
+ OutputIt move[InputIt, OutputIt](InputIt first, InputIt last, OutputIt d_first) except +
+ Iter2 move_backward[Iter1, Iter2](Iter1 first, Iter1 last, Iter2 d_last) except +
- void fill[Iter, T](Iter first, Iter last, const T& value)
- Iter fill_n[Iter, Size, T](Iter first, Size count, const T& value)
+ void fill[Iter, T](Iter first, Iter last, const T& value) except +
+ Iter fill_n[Iter, Size, T](Iter first, Size count, const T& value) except +
OutputIt transform[InputIt, OutputIt, UnaryOp](
InputIt first1, InputIt last1, OutputIt d_first, UnaryOp unary_op) except +
@@ -58,53 +59,75 @@ cdef extern from "<algorithm>" namespace "std" nogil:
void generate[Iter, Generator](Iter first, Iter last, Generator g) except +
void generate_n[Iter, Size, Generator](Iter first, Size count, Generator g) except +
- Iter remove[Iter, T](Iter first, Iter last, const T& value)
- Iter remove_if[Iter, UnaryPred](Iter first, Iter last, UnaryPred pred)
- OutputIt remove_copy[InputIt, OutputIt, T](InputIt first, InputIt last, OutputIt d_first, const T& value)
+ Iter remove[Iter, T](Iter first, Iter last, const T& value) except +
+ Iter remove_if[Iter, UnaryPred](Iter first, Iter last, UnaryPred pred) except +
+ OutputIt remove_copy[InputIt, OutputIt, T](InputIt first, InputIt last, OutputIt d_first, const T& value) except +
OutputIt remove_copy_if[InputIt, OutputIt, UnaryPred](
InputIt first, InputIt last, OutputIt d_first, UnaryPred pred) except +
- void replace[Iter, T](Iter first, Iter last, const T& old_value, const T& new_value)
+ void replace[Iter, T](Iter first, Iter last, const T& old_value, const T& new_value) except +
void replace_if[Iter, UnaryPred, T](Iter first, Iter last, UnaryPred pred, const T& new_value) except +
OutputIt replace_copy[InputIt, OutputIt, T](
- InputIt first, InputIt last, OutputIt d_first, const T& old_value, const T& new_value)
+ InputIt first, InputIt last, OutputIt d_first, const T& old_value, const T& new_value) except +
OutputIt replace_copy_if[InputIt, OutputIt, UnaryPred, T](
InputIt first, InputIt last, OutputIt d_first, UnaryPred pred, const T& new_value) except +
- void swap[T](T& a, T& b) # array overload also works
- Iter2 swap_ranges[Iter1, Iter2](Iter1 first1, Iter1 last1, Iter2 first2)
- void iter_swap[Iter](Iter a, Iter b)
+ void swap[T](T& a, T& b) except + # array overload also works
+ Iter2 swap_ranges[Iter1, Iter2](Iter1 first1, Iter1 last1, Iter2 first2) except +
+ void iter_swap[Iter](Iter a, Iter b) except +
- void reverse[Iter](Iter first, Iter last)
- OutputIt reverse_copy[InputIt, OutputIt](InputIt first, InputIt last, OutputIt d_first)
+ void reverse[Iter](Iter first, Iter last) except +
+ OutputIt reverse_copy[InputIt, OutputIt](InputIt first, InputIt last, OutputIt d_first) except +
- Iter rotate[Iter](Iter first, Iter n_first, Iter last)
- OutputIt rotate_copy[InputIt, OutputIt](InputIt first, InputIt n_first, InputIt last, OutputIt d_first)
+ Iter rotate[Iter](Iter first, Iter n_first, Iter last) except +
+ OutputIt rotate_copy[InputIt, OutputIt](InputIt first, InputIt n_first, InputIt last, OutputIt d_first) except +
- Iter unique[Iter](Iter first, Iter last)
+ Iter unique[Iter](Iter first, Iter last) except +
Iter unique[Iter, BinaryPred](Iter first, Iter last, BinaryPred p) except +
- OutputIt unique_copy[InputIt, OutputIt](InputIt first, InputIt last, OutputIt d_first)
+ OutputIt unique_copy[InputIt, OutputIt](InputIt first, InputIt last, OutputIt d_first) except +
OutputIt unique_copy[InputIt, OutputIt, BinaryPred](
InputIt first, InputIt last, OutputIt d_first, BinaryPred pred) except +
-
# Partitioning operations
+ bool is_partitioned[Iter, Pred](Iter first, Iter last, Pred p) except +
+ Iter partition[Iter, Pred](Iter first, Iter last, Pred p) except +
+ pair[OutputIt1, OutputIt2] partition_copy[InputIt, OutputIt1, OutputIt2, Pred](
+ InputIt first, InputIt last, OutputIt1 d_first_true, OutputIt2 d_first_false, Pred p) except +
+ Iter stable_partition[Iter, Pred](Iter first, Iter last, Pred p) except +
+ Iter partition_point[Iter, Pred](Iter first, Iter last, Pred p) except +
# Sorting operations
- void sort[Iter](Iter first, Iter last)
+ bool is_sorted[Iter](Iter first, Iter last) except +
+ bool is_sorted[Iter, Compare](Iter first, Iter last, Compare comp) except +
+
+ Iter is_sorted_until[Iter](Iter first, Iter last) except +
+ Iter is_sorted_until[Iter, Compare](Iter first, Iter last, Compare comp) except +
+
+ void sort[Iter](Iter first, Iter last) except +
void sort[Iter, Compare](Iter first, Iter last, Compare comp) except +
- void partial_sort[Iter](Iter first, Iter middle, Iter last)
+ void partial_sort[Iter](Iter first, Iter middle, Iter last) except +
void partial_sort[Iter, Compare](Iter first, Iter middle, Iter last, Compare comp) except +
+ OutputIt partial_sort_copy[InputIt, OutputIt](
+ InputIt first, InputIt last, OutputIt d_first, OutputIt d_last) except +
+ OutputIt partial_sort_copy[InputIt, OutputIt, Compare](
+ InputIt first, InputIt last, OutputIt d_first, OutputIt d_last, Compare comp) except +
+
+ void stable_sort[Iter](Iter first, Iter last) except +
+ void stable_sort[Iter, Compare](Iter first, Iter last, Compare comp) except +
+
+ void nth_element[Iter](Iter first, Iter nth, Iter last) except +
+ void nth_element[Iter, Compare](Iter first, Iter nth, Iter last, Compare comp) except +
+
# Binary search operations (on sorted ranges)
- Iter lower_bound[Iter, T](Iter first, Iter last, const T& value)
+ Iter lower_bound[Iter, T](Iter first, Iter last, const T& value) except +
Iter lower_bound[Iter, T, Compare](Iter first, Iter last, const T& value, Compare comp) except +
- Iter upper_bound[Iter, T](Iter first, Iter last, const T& value)
+ Iter upper_bound[Iter, T](Iter first, Iter last, const T& value) except +
Iter upper_bound[Iter, T, Compare](Iter first, Iter last, const T& value, Compare comp) except +
- bool binary_search[Iter, T](Iter first, Iter last, const T& value)
+ bool binary_search[Iter, T](Iter first, Iter last, const T& value) except +
bool binary_search[Iter, T, Compare](Iter first, Iter last, const T& value, Compare comp) except +
# Other operations on sorted ranges
@@ -112,20 +135,20 @@ cdef extern from "<algorithm>" namespace "std" nogil:
# Set operations (on sorted ranges)
# Heap operations
- void make_heap[Iter](Iter first, Iter last)
+ void make_heap[Iter](Iter first, Iter last) except +
void make_heap[Iter, Compare](Iter first, Iter last, Compare comp) except +
- void push_heap[Iter](Iter first, Iter last)
+ void push_heap[Iter](Iter first, Iter last) except +
void push_heap[Iter, Compare](Iter first, Iter last, Compare comp) except +
- void pop_heap[Iter](Iter first, Iter last)
+ void pop_heap[Iter](Iter first, Iter last) except +
void pop_heap[Iter, Compare](Iter first, Iter last, Compare comp) except +
- void sort_heap[Iter](Iter first, Iter last)
+ void sort_heap[Iter](Iter first, Iter last) except +
void sort_heap[Iter, Compare](Iter first, Iter last, Compare comp) except +
# Minimum/maximum operations
- Iter min_element[Iter](Iter first, Iter last)
+ Iter min_element[Iter](Iter first, Iter last) except +
# Comparison operations
diff --git a/Cython/Includes/libcpp/functional.pxd b/Cython/Includes/libcpp/functional.pxd
index 94cbd9e1d..4786d39eb 100644
--- a/Cython/Includes/libcpp/functional.pxd
+++ b/Cython/Includes/libcpp/functional.pxd
@@ -1,3 +1,5 @@
+from libcpp cimport bool
+
cdef extern from "<functional>" namespace "std" nogil:
cdef cppclass function[T]:
function() except +
@@ -10,4 +12,10 @@ cdef extern from "<functional>" namespace "std" nogil:
function operator=(void*)
function operator=[U](U)
- bint operator bool()
+ bool operator bool()
+
+ # Comparisons
+ cdef cppclass greater[T=*]:
+ # https://github.com/cython/cython/issues/3193
+ greater() except +
+ bool operator()(const T& lhs, const T& rhs) except +
diff --git a/tests/run/cpp_stl_algo_partitioning_ops.pyx b/tests/run/cpp_stl_algo_partitioning_ops.pyx
new file mode 100644
index 000000000..3bdc3d2af
--- /dev/null
+++ b/tests/run/cpp_stl_algo_partitioning_ops.pyx
@@ -0,0 +1,90 @@
+# mode: run
+# tag: cpp, werror, cpp11
+
+from __future__ import print_function
+
+from libcpp cimport bool
+from libcpp.algorithm cimport is_partitioned, partition, partition_copy, stable_partition, partition_point
+from libcpp.algorithm cimport for_each, copy, reverse
+from libcpp.iterator cimport back_inserter
+from libcpp.vector cimport vector
+
+
+cdef bool is_even(int i):
+ return i % 2 == 0
+
+
+def test_is_partitioned():
+ """
+ >>> test_is_partitioned()
+ False
+ True
+ False
+ """
+ cdef vector[int] values = range(10)
+ print(is_partitioned(values.begin(), values.end(), is_even))
+
+ partition(values.begin(), values.end(), &is_even)
+ print(is_partitioned(values.begin(), values.end(), is_even))
+
+ reverse(values.begin(), values.end())
+ print(is_partitioned(values.begin(), values.end(), is_even))
+
+
+cdef int print_int(int v) except -1:
+ print(v, end=" ")
+
+
+def print_partition(vector[int] values):
+ """
+ Test partition.
+
+ >> print_partition(range(10))
+ 0 8 2 6 4 * 5 3 7 1 9
+ """
+ it = partition(values.begin(), values.end(), &is_even)
+ for_each(values.begin(), it, &print_int)
+ print("*", end=" ")
+ for_each(it, values.end(), &print_int)
+ print()
+
+
+def partition_ints_even(vector[int] values):
+ """
+ Test partition_copy.
+
+ >>> partition_ints_even(range(10))
+ ([0, 2, 4, 6, 8], [1, 3, 5, 7, 9])
+ """
+ cdef vector[int] even_values, odd_values
+ partition_copy(values.begin(), values.end(), back_inserter(even_values), back_inserter(odd_values), &is_even)
+ return even_values, odd_values
+
+
+cdef bool is_positive(int v):
+ return v > 0
+
+
+def partition_ints_positive(vector[int] values):
+ """
+ Test stable_partition.
+
+ >>> partition_ints_positive([0, 0, 3, 0, 2, 4, 5, 0, 7])
+ [3, 2, 4, 5, 7, 0, 0, 0, 0]
+ """
+ stable_partition(values.begin(), values.end(), &is_positive)
+ return values
+
+
+def partition_point_ints_even(vector[int] values):
+ """
+ Test partition_point.
+
+ >>> partition_point_ints_even([0, 8, 2, 6, 4, 5, 3, 7, 1, 9])
+ ([0, 8, 2, 6, 4], [5, 3, 7, 1, 9])
+ """
+ it = partition_point(values.begin(), values.end(), is_even)
+ cdef vector[int] even_values, odd_values
+ copy(values.begin(), it, back_inserter(even_values))
+ copy(it, values.end(), back_inserter(odd_values))
+ return even_values, odd_values
diff --git a/tests/run/cpp_stl_algo_sorting_ops.pyx b/tests/run/cpp_stl_algo_sorting_ops.pyx
new file mode 100644
index 000000000..299089c4c
--- /dev/null
+++ b/tests/run/cpp_stl_algo_sorting_ops.pyx
@@ -0,0 +1,187 @@
+# mode: run
+# tag: cpp, werror, cpp11
+
+from __future__ import print_function
+
+from libcpp cimport bool
+from libcpp.algorithm cimport is_sorted, is_sorted_until, sort, partial_sort, partial_sort_copy, stable_sort
+from libcpp.algorithm cimport nth_element
+from libcpp.functional cimport greater
+from libcpp.iterator cimport distance
+from libcpp.string cimport string
+from libcpp.vector cimport vector
+
+
+def is_sorted_ints(vector[int] values):
+ """
+ Test is_sorted.
+
+ >>> is_sorted_ints([3, 1, 4, 1, 5])
+ False
+ >>> is_sorted_ints([1, 1, 3, 4, 5])
+ True
+ """
+ return is_sorted(values.begin(), values.end())
+
+
+def initial_sorted_elements(vector[int] values):
+ """
+ Test is_sorted_until.
+
+ >>> initial_sorted_elements([4, 1, 9, 5, 1, 3])
+ 1
+ >>> initial_sorted_elements([4, 5, 9, 3, 1, 1])
+ 3
+ >>> initial_sorted_elements([9, 3, 1, 4, 5, 1])
+ 1
+ >>> initial_sorted_elements([1, 3, 5, 4, 1, 9])
+ 3
+ >>> initial_sorted_elements([5, 9, 1, 1, 3, 4])
+ 2
+ >>> initial_sorted_elements([4, 9, 1, 5, 1, 3])
+ 2
+ >>> initial_sorted_elements([1, 1, 4, 9, 5, 3])
+ 4
+ """
+ sorted_end = is_sorted_until(values.begin(), values.end())
+ return distance(values.begin(), sorted_end)
+
+
+def sort_ints(vector[int] values):
+ """Test sort using the default operator<.
+
+ >>> sort_ints([5, 7, 4, 2, 8, 6, 1, 9, 0, 3])
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+ """
+ sort(values.begin(), values.end())
+ return values
+
+
+def sort_ints_reverse(vector[int] values):
+ """Test sort using a standard library comparison function object.
+
+ >>> sort_ints_reverse([5, 7, 4, 2, 8, 6, 1, 9, 0, 3])
+ [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
+ """
+ sort(values.begin(), values.end(), greater[int]())
+ return values
+
+
+def partial_sort_ints(vector[int] values, int k):
+ """
+ Test partial_sort using the default operator<.
+
+ >>> partial_sort_ints([4, 2, 3, 1, 5], 2)[:2]
+ [1, 2]
+ """
+ partial_sort(values.begin(), values.begin() + k, values.end())
+ return values
+
+
+def partial_sort_ints_reverse(vector[int] values, int k):
+ """
+ Test partial_sort using a standard library comparison function object.
+
+ >>> partial_sort_ints_reverse([4, 2, 3, 1, 5], 2)[:2]
+ [5, 4]
+ """
+ partial_sort(values.begin(), values.begin() + k, values.end(), greater[int]())
+ return values
+
+
+def partial_sort_ints2(vector[int] values, int k):
+ """
+ Test partial_sort_copy using the default operator<.
+
+ >>> partial_sort_ints2([4, 2, 3, 1, 5], 2)
+ [1, 2]
+ """
+ output = vector[int](2)
+ partial_sort_copy(values.begin(), values.end(), output.begin(), output.end())
+ return output
+
+
+def partial_sort_ints_reverse2(vector[int] values, int k):
+ """
+ Test partial_sort_copy using a standard library comparison function object.
+
+ >>> partial_sort_ints_reverse2([4, 2, 3, 1, 5], 2)
+ [5, 4]
+ """
+ output = vector[int](2)
+ partial_sort_copy(values.begin(), values.end(), output.begin(), output.end(), greater[int]())
+ return output
+
+
+cdef extern from *:
+ """
+ struct Employee
+ {
+ Employee() = default;
+ Employee(int age, std::string name): age(age), name(name) {}
+ int age;
+ std::string name; // Does not participate in comparisons
+ };
+
+ bool operator<(const Employee& lhs, const Employee& rhs)
+ {
+ return lhs.age < rhs.age;
+ }
+ """
+ cppclass Employee:
+ Employee()
+ Employee(int, string)
+ int age
+ string name
+
+cdef bool Employee_greater(const Employee& lhs, const Employee& rhs):
+ return lhs.age > rhs.age
+
+def test_stable_sort():
+ """
+ Test stable_sort using cppreference example.
+
+ >>> test_stable_sort()
+ 32, Arthur
+ 108, Zaphod
+ 108, Ford
+ 108, Zaphod
+ 108, Ford
+ 32, Arthur
+ """
+ cdef vector[Employee] employees
+ employees.push_back(Employee(108, <string>b"Zaphod"))
+ employees.push_back(Employee(32, <string>b"Arthur"))
+ employees.push_back(Employee(108, <string>b"Ford"))
+
+ stable_sort(employees.begin(), employees.end())
+
+ for e in employees:
+ print("%s, %s" % (e.age, <str>(e.name).decode("ascii")))
+
+ stable_sort(employees.begin(), employees.end(), &Employee_greater)
+
+ for e in employees:
+ print("%s, %s" % (e.age, <str>(e.name).decode("ascii")))
+
+
+def second_smallest(vector[int] values):
+ """
+ Test nth_element using the default operator<.
+
+ >>> second_smallest([5, 6, 4, 3, 2, 6, 7, 9, 3])
+ 3
+ """
+ nth_element(values.begin(), values.begin() + 1, values.end())
+ return values[1]
+
+
+def second_largest(vector[int] values):
+ """
+ Test nth_element using a standard library comparison function object.
+
+ >>> second_largest([5, 6, 4, 3, 2, 6, 7, 9, 3])
+ 7
+ """
+ nth_element(values.begin(), values.begin() + 1, values.end(), greater[int]())
+ return values[1]
diff --git a/tests/run/libcpp_algo.pyx b/tests/run/libcpp_algo.pyx
index f969b22a6..758da7705 100644
--- a/tests/run/libcpp_algo.pyx
+++ b/tests/run/libcpp_algo.pyx
@@ -2,7 +2,7 @@
# tag: cpp
from libcpp cimport bool
-from libcpp.algorithm cimport make_heap, sort_heap, sort, partial_sort
+from libcpp.algorithm cimport make_heap, sort_heap
from libcpp.vector cimport vector
@@ -28,33 +28,3 @@ def heapsort(l, bool reverse=False):
sort_heap(v.begin(), v.end())
return v
-
-
-def partialsort(l, int k, reverse=False):
- """
- >>> partialsort([4, 2, 3, 1, 5], k=2)[:2]
- [1, 2]
- >>> partialsort([4, 2, 3, 1, 5], k=2, reverse=True)[:2]
- [5, 4]
- """
- cdef vector[int] v = l
- if reverse:
- partial_sort(v.begin(), v.begin() + k, v.end(), &greater)
- else:
- partial_sort(v.begin(), v.begin() + k, v.end())
- return v
-
-
-def stdsort(l, reverse=False):
- """
- >>> stdsort([3, 2, 1, 4, 5])
- [1, 2, 3, 4, 5]
- >>> stdsort([3, 2, 1, 4, 5], reverse=True)
- [5, 4, 3, 2, 1]
- """
- cdef vector[int] v = l
- if reverse:
- sort(v.begin(), v.end(), &greater)
- else:
- sort(v.begin(), v.end())
- return v