{ _VSTD::to_address(__i) } -> same_as<add_pointer_t<iter_reference_t<_Ip>>>;
};
-
template<class _Ip>
concept __has_arrow = input_iterator<_Ip> && (is_pointer_v<_Ip> || requires(_Ip __i) { __i.operator->(); });
requires (indirectly_readable<_Its> && ...) && invocable<_Fp, iter_reference_t<_Its>...>
using indirect_result_t = invoke_result_t<_Fp, iter_reference_t<_Its>...>;
+template<class _In, class _Out>
+concept indirectly_movable =
+ indirectly_readable<_In> &&
+ indirectly_writable<_Out, iter_rvalue_reference_t<_In>>;
+
+template<class _In, class _Out>
+concept indirectly_movable_storable =
+ indirectly_movable<_In, _Out> &&
+ indirectly_writable<_Out, iter_value_t<_In>> &&
+ movable<iter_value_t<_In>> &&
+ constructible_from<iter_value_t<_In>, iter_rvalue_reference_t<_In>> &&
+ assignable_from<iter_value_t<_In>&, iter_rvalue_reference_t<_In>>;
+
// clang-format on
#endif // !defined(_LIBCPP_HAS_NO_RANGES)
template<weakly_incrementable I, indirectly_regular_unary_invocable<I> Proj>
struct incrementable_traits<projected<I, Proj>>; // since C++20
+// [alg.req.ind.move], concept indirectly_movable
+template<class In, class Out>
+ concept indirectly_movable = see below; // since C++20
+
+template<class In, class Out>
+ concept indirectly_movable_storable = see below; // since C++20
+
template<class Category, class T, class Distance = ptrdiff_t,
class Pointer = T*, class Reference = T&>
struct iterator // deprecated in C++17
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert( std::indirectly_movable<iterator, std::pair<int, int>*>);
+static_assert(!std::indirectly_movable_storable<iterator, std::pair<int, int>*>);
static_assert(std::bidirectional_iterator<const_iterator>);
static_assert(!std::random_access_iterator<const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert( std::indirectly_movable<iterator, std::pair<int, int>*>);
+static_assert(!std::indirectly_movable_storable<iterator, std::pair<int, int>*>);
static_assert(std::bidirectional_iterator<const_iterator>);
static_assert(!std::random_access_iterator<const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert(std::indirectly_movable<iterator, int*>);
+static_assert(std::indirectly_movable_storable<iterator, int*>);
static_assert(std::bidirectional_iterator<const_iterator>);
static_assert(!std::random_access_iterator<const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert(std::indirectly_movable<iterator, int*>);
+static_assert(std::indirectly_movable_storable<iterator, int*>);
static_assert(std::bidirectional_iterator<const_iterator>);
static_assert(!std::random_access_iterator<const_iterator>);
static_assert(std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert( std::indirectly_movable<iterator, iterator>);
+static_assert( std::indirectly_movable_storable<iterator, iterator>);
+static_assert(!std::indirectly_movable<iterator, const_iterator>);
+static_assert(!std::indirectly_movable_storable<iterator, const_iterator>);
+static_assert( std::indirectly_movable<iterator, reverse_iterator>);
+static_assert( std::indirectly_movable_storable<iterator, reverse_iterator>);
+static_assert(!std::indirectly_movable<iterator, const_reverse_iterator>);
+static_assert(!std::indirectly_movable_storable<iterator, const_reverse_iterator>);
static_assert(std::contiguous_iterator<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, int>);
static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert( std::indirectly_movable<const_iterator, iterator>);
+static_assert( std::indirectly_movable_storable<const_iterator, iterator>);
+static_assert(!std::indirectly_movable<const_iterator, const_iterator>);
+static_assert(!std::indirectly_movable_storable<const_iterator, const_iterator>);
+static_assert( std::indirectly_movable<const_iterator, reverse_iterator>);
+static_assert( std::indirectly_movable_storable<const_iterator, reverse_iterator>);
+static_assert(!std::indirectly_movable<const_iterator, const_reverse_iterator>);
+static_assert(!std::indirectly_movable_storable<const_iterator, const_reverse_iterator>);
static_assert(std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert( std::indirectly_movable<iterator, iterator>);
+static_assert( std::indirectly_movable_storable<iterator, iterator>);
+static_assert(!std::indirectly_movable<iterator, const_iterator>);
+static_assert(!std::indirectly_movable_storable<iterator, const_iterator>);
+static_assert( std::indirectly_movable<iterator, reverse_iterator>);
+static_assert( std::indirectly_movable_storable<iterator, reverse_iterator>);
+static_assert(!std::indirectly_movable<iterator, const_reverse_iterator>);
+static_assert(!std::indirectly_movable_storable<iterator, const_reverse_iterator>);
static_assert(std::random_access_iterator<const_iterator>);
static_assert(!std::contiguous_iterator<const_iterator>);
static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert( std::indirectly_movable<const_iterator, iterator>);
+static_assert( std::indirectly_movable_storable<const_iterator, iterator>);
+static_assert(!std::indirectly_movable<const_iterator, const_iterator>);
+static_assert(!std::indirectly_movable_storable<const_iterator, const_iterator>);
+static_assert( std::indirectly_movable<const_iterator, reverse_iterator>);
+static_assert( std::indirectly_movable_storable<const_iterator, reverse_iterator>);
+static_assert(!std::indirectly_movable<const_iterator, const_reverse_iterator>);
+static_assert(!std::indirectly_movable_storable<const_iterator, const_reverse_iterator>);
static_assert(std::sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
+static_assert( std::indirectly_movable<iterator, iterator>);
+static_assert( std::indirectly_movable_storable<iterator, iterator>);
+static_assert(!std::indirectly_movable<iterator, const_iterator>);
+static_assert(!std::indirectly_movable_storable<iterator, const_iterator>);
static_assert(std::forward_iterator<const_iterator>);
static_assert(!std::bidirectional_iterator<const_iterator>);
static_assert(std::sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
+static_assert( std::indirectly_movable<const_iterator, iterator>);
+static_assert( std::indirectly_movable_storable<const_iterator, iterator>);
+static_assert(!std::indirectly_movable<const_iterator, const_iterator>);
+static_assert(!std::indirectly_movable_storable<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert( std::indirectly_movable<iterator, iterator>);
+static_assert( std::indirectly_movable_storable<iterator, iterator>);
+static_assert(!std::indirectly_movable<iterator, const_iterator>);
+static_assert(!std::indirectly_movable_storable<iterator, const_iterator>);
+static_assert( std::indirectly_movable<iterator, reverse_iterator>);
+static_assert( std::indirectly_movable_storable<iterator, reverse_iterator>);
+static_assert(!std::indirectly_movable<iterator, const_reverse_iterator>);
+static_assert(!std::indirectly_movable_storable<iterator, const_reverse_iterator>);
static_assert(std::bidirectional_iterator<const_iterator>);
static_assert(!std::random_access_iterator<const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert( std::indirectly_movable<const_iterator, iterator>);
+static_assert( std::indirectly_movable_storable<const_iterator, iterator>);
+static_assert(!std::indirectly_movable<const_iterator, const_iterator>);
+static_assert(!std::indirectly_movable_storable<const_iterator, const_iterator>);
+static_assert( std::indirectly_movable<const_iterator, reverse_iterator>);
+static_assert( std::indirectly_movable_storable<const_iterator, reverse_iterator>);
+static_assert(!std::indirectly_movable<const_iterator, const_reverse_iterator>);
+static_assert(!std::indirectly_movable_storable<const_iterator, const_reverse_iterator>);
using const_reverse_iterator = std::vector<bool>::const_reverse_iterator;
using value_type = bool;
-static_assert(std::random_access_iterator<iterator>);
-static_assert(std::random_access_iterator<reverse_iterator>);
+static_assert( std::random_access_iterator<iterator>);
+static_assert( std::random_access_iterator<reverse_iterator>);
static_assert(!std::contiguous_iterator<iterator>);
static_assert(!std::contiguous_iterator<reverse_iterator>);
static_assert(!std::indirectly_writable<iterator, value_type>);
-static_assert(std::sentinel_for<iterator, iterator>);
-static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert( std::sentinel_for<iterator, iterator>);
+static_assert( std::sentinel_for<iterator, const_iterator>);
static_assert(!std::sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
-static_assert(std::sized_sentinel_for<iterator, iterator>);
-static_assert(std::sized_sentinel_for<iterator, const_iterator>);
+static_assert( std::sized_sentinel_for<iterator, iterator>);
+static_assert( std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert(std::indirectly_movable<iterator, bool*>);
+static_assert(std::indirectly_movable_storable<iterator, bool*>);
-static_assert(std::random_access_iterator<const_iterator>);
-static_assert(std::random_access_iterator<const_reverse_iterator>);
+static_assert( std::random_access_iterator<const_iterator>);
+static_assert( std::random_access_iterator<const_reverse_iterator>);
static_assert(!std::contiguous_iterator<const_iterator>);
static_assert(!std::contiguous_iterator<const_reverse_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);
-static_assert(std::sentinel_for<const_iterator, iterator>);
-static_assert(std::sentinel_for<const_iterator, const_iterator>);
+static_assert( std::sentinel_for<const_iterator, iterator>);
+static_assert( std::sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);
-static_assert(std::sized_sentinel_for<const_iterator, iterator>);
-static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
+static_assert( std::sized_sentinel_for<const_iterator, iterator>);
+static_assert( std::sized_sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
using const_reverse_iterator = std::vector<int>::const_reverse_iterator;
using value_type = int;
-static_assert(std::contiguous_iterator<iterator>);
-static_assert(std::random_access_iterator<reverse_iterator>);
+static_assert( std::contiguous_iterator<iterator>);
+static_assert( std::random_access_iterator<reverse_iterator>);
static_assert(!std::contiguous_iterator<reverse_iterator>);
-static_assert(std::indirectly_writable<iterator, value_type>);
-static_assert(std::sentinel_for<iterator, iterator>);
-static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert( std::indirectly_writable<iterator, value_type>);
+static_assert( std::sentinel_for<iterator, iterator>);
+static_assert( std::sentinel_for<iterator, const_iterator>);
static_assert(!std::sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
-static_assert(std::sized_sentinel_for<iterator, iterator>);
-static_assert(std::sized_sentinel_for<iterator, const_iterator>);
+static_assert( std::sized_sentinel_for<iterator, iterator>);
+static_assert( std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert( std::indirectly_movable<iterator, iterator>);
+static_assert( std::indirectly_movable_storable<iterator, iterator>);
+static_assert(!std::indirectly_movable<iterator, const_iterator>);
+static_assert(!std::indirectly_movable_storable<iterator, const_iterator>);
+static_assert( std::indirectly_movable<iterator, reverse_iterator>);
+static_assert( std::indirectly_movable_storable<iterator, reverse_iterator>);
+static_assert(!std::indirectly_movable<iterator, const_reverse_iterator>);
+static_assert(!std::indirectly_movable_storable<iterator, const_reverse_iterator>);
-static_assert(std::contiguous_iterator<const_iterator>);
-static_assert(std::random_access_iterator<const_reverse_iterator>);
+static_assert( std::contiguous_iterator<const_iterator>);
+static_assert( std::random_access_iterator<const_reverse_iterator>);
static_assert(!std::contiguous_iterator<const_reverse_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);
-static_assert(std::sentinel_for<const_iterator, iterator>);
-static_assert(std::sentinel_for<const_iterator, const_iterator>);
+static_assert( std::sentinel_for<const_iterator, iterator>);
+static_assert( std::sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);
-static_assert(std::sized_sentinel_for<const_iterator, iterator>);
-static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
+static_assert( std::sized_sentinel_for<const_iterator, iterator>);
+static_assert( std::sized_sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert( std::indirectly_movable<const_iterator, iterator>);
+static_assert( std::indirectly_movable_storable<const_iterator, iterator>);
+static_assert(!std::indirectly_movable<const_iterator, const_iterator>);
+static_assert(!std::indirectly_movable_storable<const_iterator, const_iterator>);
+static_assert( std::indirectly_movable<const_iterator, reverse_iterator>);
+static_assert( std::indirectly_movable_storable<const_iterator, reverse_iterator>);
+static_assert(!std::indirectly_movable<const_iterator, const_reverse_iterator>);
+static_assert(!std::indirectly_movable_storable<const_iterator, const_reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_local_iterator>);
+static_assert(std::indirectly_movable<iterator, std::pair<int, int>*>);
+static_assert(!std::indirectly_movable_storable<iterator, std::pair<int, int>*>);
static_assert(std::forward_iterator<const_iterator>);
static_assert(!std::bidirectional_iterator<const_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, const_local_iterator>);
+static_assert(std::indirectly_movable<local_iterator, std::pair<int, int>*>);
+static_assert(!std::indirectly_movable_storable<local_iterator, std::pair<int, int>*>);
static_assert(std::forward_iterator<const_local_iterator>);
static_assert(!std::bidirectional_iterator<const_local_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_local_iterator>);
+static_assert(std::indirectly_movable<iterator, std::pair<int, int>*>);
+static_assert(!std::indirectly_movable_storable<iterator, std::pair<int, int>*>);
static_assert(std::forward_iterator<const_iterator>);
static_assert(!std::bidirectional_iterator<const_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, const_local_iterator>);
+static_assert(std::indirectly_movable<local_iterator, std::pair<int, int>*>);
+static_assert(!std::indirectly_movable_storable<local_iterator, std::pair<int, int>*>);
static_assert(std::forward_iterator<const_local_iterator>);
static_assert(!std::bidirectional_iterator<const_local_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_local_iterator>);
+static_assert(std::indirectly_movable<iterator, int*>);
+static_assert(std::indirectly_movable_storable<iterator, int*>);
static_assert(std::forward_iterator<const_iterator>);
static_assert(!std::bidirectional_iterator<const_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, const_local_iterator>);
+static_assert(std::indirectly_movable<local_iterator, int*>);
+static_assert(std::indirectly_movable_storable<local_iterator, int*>);
static_assert(std::forward_iterator<const_local_iterator>);
static_assert(!std::bidirectional_iterator<const_local_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_local_iterator>);
+static_assert(std::indirectly_movable<iterator, int*>);
+static_assert(std::indirectly_movable_storable<iterator, int*>);
static_assert(std::forward_iterator<const_iterator>);
static_assert(!std::bidirectional_iterator<const_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, const_local_iterator>);
+static_assert(std::indirectly_movable<local_iterator, int*>);
+static_assert(std::indirectly_movable_storable<local_iterator, int*>);
static_assert(std::forward_iterator<const_local_iterator>);
static_assert(!std::bidirectional_iterator<const_local_iterator>);
static_assert(!std::sentinel_for<iterator, reverse_iterator>);
static_assert(std::sized_sentinel_for<iterator, iterator>);
static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
+static_assert(std::indirectly_movable<iterator, int*>);
+static_assert(std::indirectly_movable_storable<iterator, int*>);
static_assert(!std::incrementable<fs::directory_iterator>);
static_assert(std::sentinel_for<fs::directory_iterator, fs::directory_iterator>);
static_assert(!std::sized_sentinel_for<fs::directory_iterator, fs::directory_iterator>);
+static_assert(!std::indirectly_movable<fs::directory_iterator, fs::directory_iterator>);
+static_assert(!std::indirectly_movable_storable<fs::directory_iterator, fs::directory_iterator>);
static_assert(std::input_iterator<fs::recursive_directory_iterator>);
static_assert(!std::forward_iterator<fs::recursive_directory_iterator>);
static_assert(!std::incrementable<fs::recursive_directory_iterator>);
static_assert(std::sentinel_for<fs::recursive_directory_iterator, fs::recursive_directory_iterator>);
static_assert(!std::sized_sentinel_for<fs::recursive_directory_iterator, fs::recursive_directory_iterator>);
+static_assert(!std::indirectly_movable<fs::recursive_directory_iterator, fs::recursive_directory_iterator>);
+static_assert(!std::indirectly_movable_storable<fs::recursive_directory_iterator, fs::recursive_directory_iterator>);
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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<class In, class Out>
+// concept indirectly_movable;
+
+#include <iterator>
+
+#include "test_macros.h"
+
+struct IndirectlyMovableWithInt {
+ int& operator*() const;
+};
+
+struct Empty {};
+
+struct MoveOnly {
+ MoveOnly(MoveOnly&&) = default;
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly&&) = default;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+ MoveOnly() = default;
+};
+
+template<class T>
+struct PointerTo {
+ using value_type = T;
+ T& operator*() const;
+};
+
+static_assert( std::indirectly_movable<int*, int*>);
+static_assert( std::indirectly_movable<const int*, int *>);
+static_assert(!std::indirectly_movable<int*, const int *>);
+static_assert(!std::indirectly_movable<const int*, const int *>);
+static_assert( std::indirectly_movable<int*, int[2]>);
+static_assert(!std::indirectly_movable<int[2], int*>);
+static_assert(!std::indirectly_movable<int[2], int[2]>);
+static_assert(!std::indirectly_movable<int(&)[2], int(&)[2]>);
+static_assert(!std::indirectly_movable<int, int*>);
+static_assert(!std::indirectly_movable<int, int>);
+static_assert( std::indirectly_movable<Empty*, Empty*>);
+static_assert( std::indirectly_movable<int*, IndirectlyMovableWithInt>);
+static_assert(!std::indirectly_movable<Empty*, IndirectlyMovableWithInt>);
+static_assert( std::indirectly_movable<int*, IndirectlyMovableWithInt>);
+static_assert( std::indirectly_movable<MoveOnly*, MoveOnly*>);
+static_assert(!std::indirectly_movable<MoveOnly*, const MoveOnly*>);
+static_assert(!std::indirectly_movable<const MoveOnly*, const MoveOnly*>);
+static_assert(!std::indirectly_movable<const MoveOnly*, MoveOnly*>);
+static_assert( std::indirectly_movable<PointerTo<MoveOnly>, PointerTo<MoveOnly>>);
+static_assert( std::indirectly_movable<MoveOnly*, PointerTo<MoveOnly>>);
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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<class In, class Out>
+// concept indirectly_movable;
+
+#include <iterator>
+
+#include <concepts>
+
+template<std::indirectly_readable I, class O>
+constexpr bool indirectly_movable_subsumption() {
+ return false;
+}
+
+template<class I, class O>
+ requires std::indirectly_movable<I, O>
+constexpr bool indirectly_movable_subsumption() {
+ return true;
+}
+
+static_assert(indirectly_movable_subsumption<int*, int*>());
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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<class In, class Out>
+// concept indirectly_movable_storable;
+
+#include <iterator>
+
+#include "test_macros.h"
+
+struct Empty {};
+
+struct MoveOnlyConvertible;
+struct AssignableToMoveOnly;
+
+struct MoveOnly {
+ MoveOnly(MoveOnly&&) = default;
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly&&) = default;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+ MoveOnly() = default;
+
+ MoveOnly& operator=(MoveOnlyConvertible const&) = delete;
+ MoveOnly& operator=(AssignableToMoveOnly const&);
+};
+
+template<class T, class ValueType = T>
+struct PointerTo {
+ using value_type = ValueType;
+ T& operator*() const;
+};
+
+// MoveOnlyConvertible is convertible to MoveOnly, but not assignable to it. This is
+// implemented by explicitly deleting "operator=(MoveOnlyConvertible)" in MoveOnly.
+struct MoveOnlyConvertible {
+ operator MoveOnly&() const;
+};
+
+// This type can be constructed with a MoveOnly and assigned to a MoveOnly, so it does
+// model indirectly_movable_storable.
+struct AssignableToMoveOnly {
+ AssignableToMoveOnly() = default;
+ AssignableToMoveOnly(const MoveOnly&);
+};
+
+struct DeletedMoveCtor {
+ DeletedMoveCtor(DeletedMoveCtor&&) = delete;
+ DeletedMoveCtor& operator=(DeletedMoveCtor&&) = default;
+};
+
+struct CommonType { };
+
+struct NotConstructibleFromRefIn {
+ struct ValueType {
+ operator CommonType&() const;
+ };
+
+ struct ReferenceType {
+ operator CommonType&() const;
+ };
+
+ using value_type = ValueType;
+ ReferenceType& operator*() const;
+};
+
+template <template <class> class X, template <class> class Y>
+struct std::basic_common_reference<NotConstructibleFromRefIn::ValueType,
+ NotConstructibleFromRefIn::ReferenceType, X, Y> {
+ using type = CommonType&;
+};
+
+template <template <class> class X, template <class> class Y>
+struct std::basic_common_reference<NotConstructibleFromRefIn::ReferenceType,
+ NotConstructibleFromRefIn::ValueType, X, Y> {
+ using type = CommonType&;
+};
+
+struct NotAssignableFromRefIn {
+ struct ReferenceType;
+
+ struct ValueType {
+ ValueType(ReferenceType);
+ ValueType& operator=(ReferenceType) = delete;
+ operator CommonType&() const;
+ };
+
+ struct ReferenceType {
+ operator CommonType&() const;
+ };
+
+ using value_type = ValueType;
+ ReferenceType& operator*() const;
+};
+
+template <template <class> class X, template <class> class Y>
+struct std::basic_common_reference<NotAssignableFromRefIn::ValueType,
+ NotAssignableFromRefIn::ReferenceType, X, Y> {
+ using type = CommonType&;
+};
+
+template <template <class> class X, template <class> class Y>
+struct std::basic_common_reference<NotAssignableFromRefIn::ReferenceType,
+ NotAssignableFromRefIn::ValueType, X, Y> {
+ using type = CommonType&;
+};
+
+struct AnyWritable {
+ template<class T>
+ AnyWritable& operator=(T&&);
+};
+
+struct AnyOutput {
+ using value_type = AnyWritable;
+ AnyWritable& operator*() const;
+};
+
+static_assert( std::indirectly_movable_storable<int*, int*>);
+static_assert( std::indirectly_movable_storable<const int*, int *>);
+static_assert( std::indirectly_movable_storable<int*, int[2]>);
+static_assert( std::indirectly_movable_storable<Empty*, Empty*>);
+static_assert( std::indirectly_movable_storable<MoveOnly*, MoveOnly*>);
+static_assert( std::indirectly_movable_storable<PointerTo<MoveOnly>, PointerTo<MoveOnly>>);
+// The case when indirectly_writable<iter_rvalue_reference> but not indirectly_writable<iter_value>.
+static_assert( std::indirectly_writable<
+ PointerTo<MoveOnly, MoveOnlyConvertible>,
+ std::iter_rvalue_reference_t<
+ PointerTo<MoveOnly, MoveOnlyConvertible>>>);
+static_assert(!std::indirectly_movable_storable<PointerTo<MoveOnly, MoveOnlyConvertible>,
+ PointerTo<MoveOnly, MoveOnlyConvertible>>);
+static_assert(!std::indirectly_movable_storable<DeletedMoveCtor*, DeletedMoveCtor*>);
+static_assert( std::indirectly_movable_storable<PointerTo<MoveOnly, AssignableToMoveOnly>,
+ PointerTo<MoveOnly, AssignableToMoveOnly>>);
+static_assert(!std::indirectly_movable_storable<NotConstructibleFromRefIn, AnyOutput>);
+static_assert(!std::indirectly_movable_storable<NotAssignableFromRefIn, AnyOutput>);
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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<class In, class Out>
+// concept indirectly_movable_storable;
+
+#include <iterator>
+
+#include <concepts>
+
+template<class I, class O>
+ requires std::indirectly_movable<I, O>
+constexpr bool indirectly_movable_storable_subsumption() {
+ return false;
+}
+
+template<class I, class O>
+ requires std::indirectly_movable_storable<I, O>
+constexpr bool indirectly_movable_storable_subsumption() {
+ return true;
+}
+
+static_assert(indirectly_movable_storable_subsumption<int*, int*>());
static_assert(!std::sentinel_for<iterator, iterator>);
static_assert(!std::sized_sentinel_for<iterator, iterator>);
static_assert(!std::input_iterator<iterator>);
+static_assert(std::indirectly_movable<int*, iterator>);
+static_assert(std::indirectly_movable_storable<int*, iterator>);
static_assert(!std::sentinel_for<iterator, iterator>);
static_assert(!std::sized_sentinel_for<iterator, iterator>);
static_assert(!std::input_iterator<iterator>);
+static_assert(std::indirectly_movable<int*, iterator>);
+static_assert(std::indirectly_movable_storable<int*, iterator>);
static_assert(std::input_or_output_iterator<iterator>);
static_assert(!std::sentinel_for<iterator, iterator>);
static_assert(!std::input_iterator<iterator>);
+static_assert(std::indirectly_movable<int*, iterator>);
+static_assert(std::indirectly_movable_storable<int*, iterator>);
static_assert(std::incrementable<iterator>);
static_assert(std::sentinel_for<iterator, iterator>);
static_assert(std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::indirectly_movable<int*, iterator>);
+static_assert(!std::indirectly_movable_storable<int*, iterator>);
static_assert(std::bidirectional_iterator<reverse_bidirectional_iterator>);
static_assert(!std::random_access_iterator<reverse_bidirectional_iterator>);
static_assert(!std::sized_sentinel_for<reverse_bidirectional_iterator, reverse_bidirectional_iterator>);
+static_assert( std::indirectly_movable<reverse_bidirectional_iterator, reverse_bidirectional_iterator>);
+static_assert( std::indirectly_movable_storable<reverse_bidirectional_iterator, reverse_bidirectional_iterator>);
using reverse_random_access_iterator = std::reverse_iterator<random_access_iterator<int*>>;
static_assert(common_reverse_iterator_checks<reverse_random_access_iterator>());
static_assert(std::random_access_iterator<reverse_random_access_iterator>);
static_assert(!std::contiguous_iterator<reverse_random_access_iterator>);
static_assert(std::sized_sentinel_for<reverse_random_access_iterator, reverse_random_access_iterator>);
+static_assert( std::indirectly_movable<reverse_random_access_iterator, reverse_random_access_iterator>);
+static_assert( std::indirectly_movable_storable<reverse_random_access_iterator, reverse_random_access_iterator>);
using reverse_contiguous_iterator = std::reverse_iterator<contiguous_iterator<int*>>;
static_assert(common_reverse_iterator_checks<reverse_contiguous_iterator>());
static_assert(std::random_access_iterator<reverse_contiguous_iterator>);
static_assert(!std::contiguous_iterator<reverse_contiguous_iterator>);
static_assert(std::sized_sentinel_for<reverse_contiguous_iterator, reverse_contiguous_iterator>);
+static_assert( std::indirectly_movable<reverse_contiguous_iterator, reverse_contiguous_iterator>);
+static_assert( std::indirectly_movable_storable<reverse_contiguous_iterator, reverse_contiguous_iterator>);
static_assert(std::sentinel_for<iterator, iterator>);
static_assert(!std::sized_sentinel_for<iterator, iterator>);
static_assert(std::input_iterator<iterator>);
+static_assert(!std::indirectly_movable<int*, iterator>);
+static_assert(!std::indirectly_movable_storable<int*, iterator>);
static_assert(!std::incrementable<iterator>);
static_assert(std::sentinel_for<iterator, iterator>);
static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(std::indirectly_movable<iterator, char*>);
+static_assert(std::indirectly_movable_storable<iterator, char*>);
static_assert(!std::sentinel_for<iterator, iterator>);
static_assert(!std::sized_sentinel_for<iterator, iterator>);
static_assert(!std::input_iterator<iterator>);
+static_assert(std::indirectly_movable<int*, iterator>);
+static_assert(std::indirectly_movable_storable<int*, iterator>);
static_assert(!std::sentinel_for<iterator, iterator>);
static_assert(!std::sized_sentinel_for<iterator, iterator>);
static_assert(!std::input_iterator<iterator>);
+static_assert(std::indirectly_movable<char*, iterator>);
+static_assert(std::indirectly_movable_storable<char*, iterator>);
static_assert(!std::indirectly_writable<std::cregex_iterator, char>);
static_assert(std::sentinel_for<std::cregex_iterator, std::cregex_iterator>);
static_assert(!std::sized_sentinel_for<std::cregex_iterator, std::cregex_iterator>);
+static_assert(!std::indirectly_movable<std::cregex_iterator, std::cregex_iterator>);
+static_assert(!std::indirectly_movable_storable<std::cregex_iterator, std::cregex_iterator>);
static_assert(!std::indirectly_writable<std::cregex_token_iterator, char>);
static_assert(std::sentinel_for<std::cregex_token_iterator, std::cregex_token_iterator>);
static_assert(!std::sized_sentinel_for<std::cregex_token_iterator, std::cregex_token_iterator>);
+static_assert(!std::indirectly_movable<std::cregex_token_iterator, std::cregex_token_iterator>);
+static_assert(!std::indirectly_movable_storable<std::cregex_token_iterator, std::cregex_token_iterator>);
static_assert(std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert( std::indirectly_movable<iterator, iterator>);
+static_assert( std::indirectly_movable_storable<iterator, iterator>);
+static_assert(!std::indirectly_movable<iterator, const_iterator>);
+static_assert(!std::indirectly_movable_storable<iterator, const_iterator>);
+static_assert( std::indirectly_movable<iterator, reverse_iterator>);
+static_assert( std::indirectly_movable_storable<iterator, reverse_iterator>);
+static_assert(!std::indirectly_movable<iterator, const_reverse_iterator>);
+static_assert(!std::indirectly_movable_storable<iterator, const_reverse_iterator>);
static_assert(std::contiguous_iterator<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);
static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert( std::indirectly_movable<const_iterator, iterator>);
+static_assert( std::indirectly_movable_storable<const_iterator, iterator>);
+static_assert(!std::indirectly_movable<const_iterator, const_iterator>);
+static_assert(!std::indirectly_movable_storable<const_iterator, const_iterator>);
+static_assert( std::indirectly_movable<const_iterator, reverse_iterator>);
+static_assert( std::indirectly_movable_storable<const_iterator, reverse_iterator>);
+static_assert(!std::indirectly_movable<const_iterator, const_reverse_iterator>);
+static_assert(!std::indirectly_movable_storable<const_iterator, const_reverse_iterator>);
static_assert(std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert(std::indirectly_movable<iterator, char*>);
+static_assert(std::indirectly_movable_storable<iterator, char*>);
static_assert(std::contiguous_iterator<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, char>);
static_assert(std::indirectly_readable<std::unique_ptr<int> >);
static_assert(std::indirectly_writable<std::unique_ptr<int>, int>);
static_assert(!std::weakly_incrementable<std::unique_ptr<int> >);
+static_assert(std::indirectly_movable<std::unique_ptr<int>, std::unique_ptr<int>>);
+static_assert(std::indirectly_movable_storable<std::unique_ptr<int>, std::unique_ptr<int>>);
static_assert(!std::indirectly_readable<std::unique_ptr<void> >);
static_assert(!std::indirectly_writable<std::unique_ptr<void>, void>);
static_assert(!std::weakly_incrementable<std::unique_ptr<void> >);
+static_assert(!std::indirectly_movable<std::unique_ptr<void>, std::unique_ptr<void>>);
+static_assert(!std::indirectly_movable_storable<std::unique_ptr<void>, std::unique_ptr<void>>);
static_assert(std::indirectly_readable<std::shared_ptr<int> >);
static_assert(std::indirectly_writable<std::shared_ptr<int>, int>);
static_assert(!std::weakly_incrementable<std::shared_ptr<int> >);
+static_assert(std::indirectly_movable<std::shared_ptr<int>, std::shared_ptr<int>>);
+static_assert(std::indirectly_movable_storable<std::shared_ptr<int>, std::shared_ptr<int>>);
static_assert(!std::indirectly_readable<std::shared_ptr<void> >);
static_assert(!std::indirectly_writable<std::shared_ptr<void>, void>);
static_assert(!std::weakly_incrementable<std::shared_ptr<void> >);
+static_assert(!std::indirectly_movable<std::shared_ptr<void>, std::shared_ptr<void>>);
+static_assert(!std::indirectly_movable_storable<std::shared_ptr<void>, std::shared_ptr<void>>);
static_assert(!std::indirectly_readable<std::optional<int> >);
static_assert(!std::indirectly_writable<std::optional<int>, int>);
static_assert(!std::weakly_incrementable<std::optional<int> >);
+static_assert(!std::indirectly_movable<std::optional<int>, std::optional<int>>);
+static_assert(!std::indirectly_movable_storable<std::optional<int>, std::optional<int>>);