[libcxx-commits] [libcxx] bc4d2e7 - [libc++] Fix `_IterOps::__iter_move` to support proxy iterators.
Konstantin Varlamov via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Jul 20 13:19:10 PDT 2022
Author: Konstantin Varlamov
Date: 2022-07-20T13:19:00-07:00
New Revision: bc4d2e70518476f0a445761d43fee8b9e6670368
URL: https://github.com/llvm/llvm-project/commit/bc4d2e70518476f0a445761d43fee8b9e6670368
DIFF: https://github.com/llvm/llvm-project/commit/bc4d2e70518476f0a445761d43fee8b9e6670368.diff
LOG: [libc++] Fix `_IterOps::__iter_move` to support proxy iterators.
The return type was specified incorrectly for proxy iterators that
define `reference` to be a class that implicitly converts to
`value_type`. `__iter_move` would end up returning an object of type
`reference` which would then implicitly convert to `value_type`; thus,
the function will return a `value_type&&` rvalue reference to the local
temporary.
Differential Revision: https://reviews.llvm.org/D130197
Added:
libcxx/test/std/algorithms/alg.sorting/alg.sort/sort/sort_proxy.pass.cpp
Modified:
libcxx/include/__algorithm/iterator_operations.h
Removed:
################################################################################
diff --git a/libcxx/include/__algorithm/iterator_operations.h b/libcxx/include/__algorithm/iterator_operations.h
index 03dd2c41e94af..a3840594b8ae1 100644
--- a/libcxx/include/__algorithm/iterator_operations.h
+++ b/libcxx/include/__algorithm/iterator_operations.h
@@ -66,8 +66,10 @@ struct _IterOps<_ClassicAlgPolicy> {
// iter_move
template <class _Iter>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
- // Declaring the return type is necessary for the C++03 mode (which doesn't support placeholder return types).
- static typename iterator_traits<__uncvref_t<_Iter> >::value_type&& __iter_move(_Iter&& __i) {
+ // Declaring the return type is necessary for C++03, so we basically mirror what `decltype(auto)` would deduce.
+ static typename remove_reference<
+ typename iterator_traits<__uncvref_t<_Iter> >::reference
+ >::type&& __iter_move(_Iter&& __i) {
return std::move(*std::forward<_Iter>(__i));
}
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.sort/sort/sort_proxy.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.sort/sort/sort_proxy.pass.cpp
new file mode 100644
index 0000000000000..4dc872566d923
--- /dev/null
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.sort/sort/sort_proxy.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+#include <algorithm>
+#include <cassert>
+#include <vector>
+
+void test() {
+ // TODO: use a custom proxy iterator instead of (or in addition to) `vector<bool>`.
+ std::vector<bool> v(5, false);
+ v[1] = true; v[3] = true;
+ std::sort(v.begin(), v.end());
+ assert(std::is_sorted(v.begin(), v.end()));
+}
+
+int main(int, char**) {
+ test();
+
+ return 0;
+}
More information about the libcxx-commits
mailing list