diff --git a/libcxx/include/iterator b/libcxx/include/iterator --- a/libcxx/include/iterator +++ b/libcxx/include/iterator @@ -64,6 +64,10 @@ template concept indirectly_readable = see below; // since C++20 +// [iterator.concept.writable], concept indirectly_­writable +template + concept indirectly_writable = see below; // since C++20 + template struct iterator @@ -2530,6 +2534,16 @@ template concept indirectly_readable = __indirectly_readable_impl>; +// [iterator.concept.writable] +template +concept indirectly_writable = + requires(_Out&& __o, _Tp&& __t) { + *__o = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving + *_VSTD::forward<_Out>(__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving + const_cast&&>(*__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving + const_cast&&>(*_VSTD::forward<_Out>(__o)) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving + }; + #undef _LIBCPP_NOEXCEPT_RETURN #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.writable/indirectly_writable.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.writable/indirectly_writable.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.writable/indirectly_writable.compile.pass.cpp @@ -0,0 +1,233 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: gcc-10 + +// template +// concept indirectly_writable; + +#include + +#include +#include +#include +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../read_write.h" + +template +[[nodiscard]] constexpr bool check_indirectly_writable() { + constexpr bool result = std::indirectly_writable; + static_assert(std::indirectly_writable == result); + return result; +} + +static_assert(check_indirectly_writable()); +static_assert(check_indirectly_writable()); +static_assert(!check_indirectly_writable()); + +static_assert(!check_indirectly_writable()); +static_assert(!check_indirectly_writable()); + +static_assert(!check_indirectly_writable()); +static_assert(!check_indirectly_writable()); + +namespace standard_types { +static_assert(check_indirectly_writable()); +static_assert(!check_indirectly_writable()); +static_assert(check_indirectly_writable()); +static_assert(!check_indirectly_writable()); +static_assert(check_indirectly_writable()); +static_assert(check_indirectly_writable()); +static_assert(!check_indirectly_writable()); + +static_assert(!check_indirectly_writable()); +static_assert(!check_indirectly_writable()); +static_assert(!check_indirectly_writable()); +static_assert(!check_indirectly_writable()); + +static_assert(!check_indirectly_writable()); +static_assert(!check_indirectly_writable()); +static_assert(!check_indirectly_writable()); +static_assert(!check_indirectly_writable()); +// +static_assert(check_indirectly_writable::iterator, int>()); +static_assert( + !check_indirectly_writable::const_iterator, int>()); +static_assert( + check_indirectly_writable::reverse_iterator, int>()); +static_assert(!check_indirectly_writable< + std::array::const_reverse_iterator, int>()); + +// +static_assert(check_indirectly_writable::iterator, int>()); +static_assert( + !check_indirectly_writable::const_iterator, int>()); +static_assert( + check_indirectly_writable::reverse_iterator, int>()); +static_assert( + !check_indirectly_writable::const_reverse_iterator, int>()); + +// +static_assert( + check_indirectly_writable::iterator, int>()); +static_assert( + !check_indirectly_writable::const_iterator, int>()); + +// +static_assert(std::indirectly_writable< + std::back_insert_iterator >, int>); +static_assert(!std::indirectly_writable< + std::back_insert_iterator > const, int>); +static_assert(std::indirectly_writable< + std::front_insert_iterator >, int>); +static_assert(!std::indirectly_writable< + std::front_insert_iterator > const, int>); +static_assert( + std::indirectly_writable >, int>); +static_assert(!std::indirectly_writable< + std::insert_iterator > const, int>); +static_assert( + !check_indirectly_writable, int>()); +static_assert( + !check_indirectly_writable, int>()); +static_assert(!check_indirectly_writable< + std::move_iterator::iterator>, int>()); +static_assert(std::indirectly_writable, int>); +static_assert( + !std::indirectly_writable const, int>); +static_assert( + std::indirectly_writable, int>); +static_assert( + !std::indirectly_writable const, int>); + +// +static_assert(check_indirectly_writable::iterator, int>()); +static_assert( + !check_indirectly_writable::const_iterator, int>()); +static_assert( + check_indirectly_writable::reverse_iterator, int>()); +static_assert( + !check_indirectly_writable::const_reverse_iterator, int>()); + +// +static_assert(!check_indirectly_writable::iterator, + std::pair >()); +static_assert(!check_indirectly_writable::const_iterator, + std::pair >()); +static_assert(!check_indirectly_writable::reverse_iterator, + std::pair >()); +static_assert( + !check_indirectly_writable::const_reverse_iterator, + std::pair >()); + +static_assert(!check_indirectly_writable::iterator, + std::pair >()); +static_assert(!check_indirectly_writable< + std::multimap::const_iterator, std::pair >()); +static_assert( + !check_indirectly_writable::reverse_iterator, + std::pair >()); +static_assert( + !check_indirectly_writable::const_reverse_iterator, + std::pair >()); + +// +static_assert(check_indirectly_writable, int>()); +static_assert(!check_indirectly_writable, int>()); +static_assert(check_indirectly_writable, int>()); +static_assert(!check_indirectly_writable, int>()); + +// +static_assert(!check_indirectly_writable, int>()); + +// +static_assert(!check_indirectly_writable::iterator, int>()); +static_assert(!check_indirectly_writable::const_iterator, int>()); +static_assert( + !check_indirectly_writable::reverse_iterator, int>()); +static_assert( + !check_indirectly_writable::const_reverse_iterator, int>()); + +static_assert(!check_indirectly_writable::iterator, int>()); +static_assert( + !check_indirectly_writable::const_iterator, int>()); +static_assert( + !check_indirectly_writable::reverse_iterator, int>()); +static_assert(!check_indirectly_writable< + std::multiset::const_reverse_iterator, int>()); + +// +static_assert(check_indirectly_writable()); +static_assert(!check_indirectly_writable()); +static_assert(check_indirectly_writable()); +static_assert( + !check_indirectly_writable()); + +// // +static_assert(!check_indirectly_writable()); +static_assert( + !check_indirectly_writable()); +static_assert( + !check_indirectly_writable()); +static_assert(!check_indirectly_writable< + std::string_view::const_reverse_iterator, char>()); + +// +static_assert(!check_indirectly_writable::iterator, + std::pair >()); +static_assert( + !check_indirectly_writable::const_iterator, + std::pair >()); + +static_assert( + !check_indirectly_writable::iterator, + std::pair >()); +static_assert(!check_indirectly_writable< + std::unordered_multimap::const_iterator, + std::pair >()); + +// +static_assert( + !check_indirectly_writable::iterator, int>()); +static_assert( + !check_indirectly_writable::const_iterator, int>()); + +static_assert(!check_indirectly_writable< + std::unordered_multiset::iterator, int>()); +static_assert(!check_indirectly_writable< + std::unordered_multiset::const_iterator, int>()); + +// +static_assert(check_indirectly_writable::iterator, int>()); +static_assert( + !check_indirectly_writable::const_iterator, int>()); +static_assert( + check_indirectly_writable::reverse_iterator, int>()); +static_assert(!check_indirectly_writable< + std::vector::const_reverse_iterator, int>()); +static_assert(!check_indirectly_writable, int>()); +} // namespace standard_types