[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