[libcxx-commits] [PATCH] D117396: [RFC][libc++] Allow non-copyable OutputIterators.
Mark de Wever via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Jan 15 06:35:10 PST 2022
Mordante created this revision.
Mordante added reviewers: ldionne, Quuxplusone.
Mordante requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.
Starting with C++20 (input and) output iterators. This patch is a
proof-of-concept only modifying one algorithm.
When we're happy with this patch I want look at similar fixes for the
other iterators. (As seen in the build errors there are quite some
places that need fixes.)
Noticed this while working on LWG3539
format_to must not copy models of output_iterator<const charT&>
Depends on D117395 <https://reviews.llvm.org/D117395>
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D117396
Files:
libcxx/include/__algorithm/fill_n.h
libcxx/include/__config
libcxx/test/support/test_iterators.h
Index: libcxx/test/support/test_iterators.h
===================================================================
--- libcxx/test/support/test_iterators.h
+++ libcxx/test/support/test_iterators.h
@@ -32,6 +32,14 @@
TEST_CONSTEXPR_CXX14 It base() const {return it_;}
TEST_CONSTEXPR_CXX14 output_iterator() {}
+#if TEST_STD_VER > 17
+ // Starting with C++20 an output_iterator must be movable and doesn't
+ // require copyable.
+ output_iterator(const output_iterator&) = delete;
+ output_iterator(output_iterator&&) = default;
+ output_iterator& operator=(const output_iterator&) = delete;
+ output_iterator& operator=(output_iterator&&) = default;
+#endif
explicit TEST_CONSTEXPR_CXX14 output_iterator(It it) : it_(it) {}
template <class U>
TEST_CONSTEXPR_CXX14 output_iterator(const output_iterator<U>& u) :it_(u.it_) {}
Index: libcxx/include/__config
===================================================================
--- libcxx/include/__config
+++ libcxx/include/__config
@@ -1081,6 +1081,18 @@
# define _LIBCPP_CONSTEXPR_AFTER_CXX17
#endif
+// In C++17 (and earlier) an iterator is required to be CopyConstructible and
+// CopyAssignable, but not MoveConstructibe nor MoveAssignable.
+// In C++20 the concepts input_iterator and output_iterator require movable but
+// not copyable. (forward_iterator requires copyable.)
+// Depending on the standard used some algorithms need to be adapted, for
+// example fill_n calls __fill_n with an OutputIterator argument.
+#if _LIBCPP_STD_VER > 17
+# define _LIBCPP_MOVE_AFTER_CXX17(__obj) _VSTD::move(__obj)
+#else
+# define _LIBCPP_MOVE_AFTER_CXX17(__obj) __obj
+#endif
+
#if __has_cpp_attribute(nodiscard) || defined(_LIBCPP_COMPILER_MSVC)
# define _LIBCPP_NODISCARD [[nodiscard]]
#elif defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(_LIBCPP_CXX03_LANG)
Index: libcxx/include/__algorithm/fill_n.h
===================================================================
--- libcxx/include/__algorithm/fill_n.h
+++ libcxx/include/__algorithm/fill_n.h
@@ -9,6 +9,7 @@
#ifndef _LIBCPP___ALGORITHM_FILL_N_H
#define _LIBCPP___ALGORITHM_FILL_N_H
+#include <__algorithm/move.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <type_traits>
@@ -34,7 +35,7 @@
_OutputIterator
fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_)
{
- return _VSTD::__fill_n(__first, _VSTD::__convert_to_integral(__n), __value_);
+ return _VSTD::__fill_n(_LIBCPP_MOVE_AFTER_CXX17(__first), _VSTD::__convert_to_integral(__n), __value_);
}
_LIBCPP_END_NAMESPACE_STD
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D117396.400278.patch
Type: text/x-patch
Size: 2592 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20220115/f5e69872/attachment.bin>
More information about the libcxx-commits
mailing list