[libcxx][iterator] adds `std::indirectly_readable` and `std::indirectly_writable`

Implements parts of:
    * P0896R4 The One Ranges Proposal`

Depends on D99873.

Reviewed By: ldionne, #libc

Differential Revision: https://reviews.llvm.org/D100073
This commit is contained in:
Christopher Di Bella 2021-04-21 16:41:13 +00:00
parent 89b59345ee
commit 04733181b5
41 changed files with 1151 additions and 13 deletions

View File

@ -12,6 +12,10 @@
#include <__config>
#include <concepts>
#include <__iterator/iter_move.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/readable_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@ -24,18 +28,36 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if !defined(_LIBCPP_HAS_NO_RANGES)
template<class _Tp>
using __with_reference = _Tp&;
// clang-format off
template<class _Tp>
concept __referenceable = requires {
typename __with_reference<_Tp>;
};
// [iterator.concept.readable]
template<class _In>
concept __indirectly_readable_impl =
requires(const _In __in) {
typename iter_value_t<_In>;
typename iter_reference_t<_In>;
typename iter_rvalue_reference_t<_In>;
{ *__in } -> same_as<iter_reference_t<_In> >;
{ ranges::iter_move(__in) } -> same_as<iter_rvalue_reference_t<_In> >;
} &&
common_reference_with<iter_reference_t<_In>&&, iter_value_t<_In>&> &&
common_reference_with<iter_reference_t<_In>&&, iter_rvalue_reference_t<_In>&&> &&
common_reference_with<iter_rvalue_reference_t<_In>&&, const iter_value_t<_In>&>;
template<class _Tp>
concept __dereferenceable = requires(_Tp& __t) {
{ *__t } -> __referenceable; // not required to be equality-preserving
};
template<class _In>
concept indirectly_readable = __indirectly_readable_impl<remove_cvref_t<_In> >;
// [iterator.concept.writable]
template<class _Out, class _Tp>
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<const iter_reference_t<_Out>&&>(*__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving
const_cast<const iter_reference_t<_Out>&&>(*_VSTD::forward<_Out>(__o)) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving
};
// clang-format on
#endif // !defined(_LIBCPP_HAS_NO_RANGES)

View File

@ -11,7 +11,7 @@
#define _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H
#include <__config>
#include <__iterator/concepts.h>
#include <concepts>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)

View File

@ -11,7 +11,7 @@
#define _LIBCPP___ITERATOR_ITER_MOVE_H
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
#include <concepts> // __class_or_enum
#include <type_traits>
#include <utility>

View File

@ -27,9 +27,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if !defined(_LIBCPP_HAS_NO_RANGES)
template <class _Tp>
using __with_reference = _Tp&;
template <class _Tp>
concept __referenceable = requires {
typename __with_reference<_Tp>;
};
template <class _Tp>
concept __dereferenceable = requires(_Tp& __t) {
{ *__t } -> __referenceable; // not required to be equality-preserving
};
// [iterator.traits]
template<__dereferenceable _Tp>
using iter_reference_t = decltype(*declval<_Tp&>());
#endif // !defined(_LIBCPP_HAS_NO_RANGES)
template <class _Iter>

View File

@ -11,7 +11,8 @@
#define _LIBCPP___ITERATOR_READABLE_TRAITS_H
#include <__config>
#include <__iterator/concepts.h>
#include <concepts>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header

View File

@ -43,6 +43,15 @@ template<dereferenceable T>
requires ...
using iter_rvalue_reference_t = decltype(ranges::iter_move(declval<T&>())); // since C++20
// [iterator.concepts], iterator concepts
// [iterator.concept.readable], concept indirectly_­readable
template<class In>
concept indirectly_readable = see below; // since C++20
// [iterator.concept.writable], concept indirectly_­writable
template<class Out, class T>
concept indirectly_writable = see below; // since C++20
template<class Category, class T, class Distance = ptrdiff_t,
class Pointer = T*, class Reference = T&>
struct iterator

View File

@ -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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts
// UNSUPPORTED: gcc-10
// iterator, const_iterator, reverse_iterator, const_reverse_iterator
#include <map>
#include <iterator>
using iterator = std::map<int, int>::iterator;
using const_iterator = std::map<int, int>::const_iterator;
using value_type = iterator::value_type;
static_assert(std::indirectly_readable<iterator>);
static_assert(!std::indirectly_writable<iterator, value_type>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);

View File

@ -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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts
// UNSUPPORTED: gcc-10
// iterator, const_iterator, reverse_iterator, const_reverse_iterator
#include <map>
#include <iterator>
using iterator = std::multimap<int, int>::iterator;
using const_iterator = std::multimap<int, int>::const_iterator;
using value_type = iterator::value_type;
static_assert(std::indirectly_readable<iterator>);
static_assert(!std::indirectly_writable<iterator, value_type>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);

View File

@ -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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts
// UNSUPPORTED: gcc-10
// iterator, const_iterator, reverse_iterator, const_reverse_iterator
#include <set>
#include <iterator>
using iterator = std::multiset<int>::iterator;
using const_iterator = std::multiset<int>::const_iterator;
using value_type = iterator::value_type;
static_assert(std::indirectly_readable<iterator>);
static_assert(!std::indirectly_writable<iterator, value_type>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);

View File

@ -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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts
// UNSUPPORTED: gcc-10
// iterator, const_iterator, reverse_iterator, const_reverse_iterator
#include <set>
#include <iterator>
using iterator = std::set<int>::iterator;
using const_iterator = std::set<int>::const_iterator;
using value_type = iterator::value_type;
static_assert(std::indirectly_readable<iterator>);
static_assert(!std::indirectly_writable<iterator, value_type>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);

View File

@ -0,0 +1,26 @@
//===----------------------------------------------------------------------===//
//
// 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
// iterator, const_iterator, reverse_iterator, const_reverse_iterator
#include <array>
#include <iterator>
using iterator = std::array<int, 10>::iterator;
using const_iterator = std::array<int, 10>::const_iterator;
static_assert(std::indirectly_readable<iterator>);
static_assert(std::indirectly_writable<iterator, int>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, int>);

View File

@ -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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts
// UNSUPPORTED: gcc-10
// iterator, const_iterator, reverse_iterator, const_reverse_iterator
#include <deque>
#include <iterator>
using iterator = std::deque<int>::iterator;
using const_iterator = std::deque<int>::const_iterator;
using value_type = iterator::value_type;
static_assert(std::indirectly_readable<iterator>);
static_assert(std::indirectly_writable<iterator, value_type>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);

View File

@ -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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts
// UNSUPPORTED: gcc-10
// iterator, const_iterator
#include <forward_list>
#include <iterator>
using iterator = std::forward_list<int>::iterator;
using const_iterator = std::forward_list<int>::const_iterator;
using value_type = iterator::value_type;
static_assert(std::indirectly_readable<iterator>);
static_assert(std::indirectly_writable<iterator, value_type>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);

View File

@ -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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts
// UNSUPPORTED: gcc-10
// iterator, const_iterator, reverse_iterator, const_reverse_iterator
#include <list>
#include <iterator>
using iterator = std::list<int>::iterator;
using const_iterator = std::list<int>::const_iterator;
using value_type = iterator::value_type;
static_assert(std::indirectly_readable<iterator>);
static_assert(std::indirectly_writable<iterator, value_type>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);

View File

@ -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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts
// UNSUPPORTED: gcc-10
// iterator, const_iterator, reverse_iterator, const_reverse_iterator
#include <vector>
#include <iterator>
using iterator = std::vector<bool>::iterator;
using const_iterator = std::vector<bool>::const_iterator;
using value_type = iterator::value_type;
static_assert(std::indirectly_readable<iterator>);
static_assert(!std::indirectly_writable<iterator, value_type>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);

View File

@ -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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts
// UNSUPPORTED: gcc-10
// iterator, const_iterator, reverse_iterator, const_reverse_iterator
#include <vector>
#include <iterator>
using iterator = std::vector<int>::iterator;
using const_iterator = std::vector<int>::const_iterator;
using value_type = iterator::value_type;
static_assert(std::indirectly_readable<iterator>);
static_assert(std::indirectly_writable<iterator, value_type>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);

View File

@ -0,0 +1,35 @@
//===----------------------------------------------------------------------===//
//
// 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
// iterator, const_iterator, local_iterator, const_local_iterator
#include <unordered_map>
#include <iterator>
using iterator = std::unordered_map<int, int>::iterator;
using const_iterator = std::unordered_map<int, int>::const_iterator;
using local_iterator = std::unordered_map<int, int>::local_iterator;
using const_local_iterator = std::unordered_map<int, int>::const_local_iterator;
using value_type = iterator::value_type;
static_assert(std::indirectly_readable<iterator>);
static_assert(!std::indirectly_writable<iterator, value_type>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);
static_assert(std::indirectly_readable<local_iterator>);
static_assert(!std::indirectly_writable<local_iterator, value_type>);
static_assert(std::indirectly_readable<const_local_iterator>);
static_assert(!std::indirectly_writable<const_local_iterator, value_type>);

View File

@ -0,0 +1,35 @@
//===----------------------------------------------------------------------===//
//
// 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
// iterator, const_iterator, local_iterator, const_local_iterator
#include <unordered_map>
#include <iterator>
using iterator = std::unordered_multimap<int, int>::iterator;
using const_iterator = std::unordered_multimap<int, int>::const_iterator;
using local_iterator = std::unordered_multimap<int, int>::local_iterator;
using const_local_iterator = std::unordered_multimap<int, int>::const_local_iterator;
using value_type = iterator::value_type;
static_assert(std::indirectly_readable<iterator>);
static_assert(!std::indirectly_writable<iterator, value_type>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);
static_assert(std::indirectly_readable<local_iterator>);
static_assert(!std::indirectly_writable<local_iterator, value_type>);
static_assert(std::indirectly_readable<const_local_iterator>);
static_assert(!std::indirectly_writable<const_local_iterator, value_type>);

View File

@ -0,0 +1,35 @@
//===----------------------------------------------------------------------===//
//
// 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
// iterator, const_iterator, local_iterator, const_local_iterator
#include <unordered_set>
#include <iterator>
using iterator = std::unordered_multiset<int>::iterator;
using const_iterator = std::unordered_multiset<int>::const_iterator;
using local_iterator = std::unordered_multiset<int>::local_iterator;
using const_local_iterator = std::unordered_multiset<int>::const_local_iterator;
using value_type = iterator::value_type;
static_assert(std::indirectly_readable<iterator>);
static_assert(!std::indirectly_writable<iterator, value_type>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);
static_assert(std::indirectly_readable<local_iterator>);
static_assert(!std::indirectly_writable<local_iterator, value_type>);
static_assert(std::indirectly_readable<const_local_iterator>);
static_assert(!std::indirectly_writable<const_local_iterator, value_type>);

View File

@ -0,0 +1,35 @@
//===----------------------------------------------------------------------===//
//
// 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
// iterator, const_iterator, local_iterator, const_local_iterator
#include <unordered_set>
#include <iterator>
using iterator = std::unordered_set<int>::iterator;
using const_iterator = std::unordered_set<int>::const_iterator;
using local_iterator = std::unordered_set<int>::local_iterator;
using const_local_iterator = std::unordered_set<int>::const_local_iterator;
using value_type = iterator::value_type;
static_assert(std::indirectly_readable<iterator>);
static_assert(!std::indirectly_writable<iterator, value_type>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);
static_assert(std::indirectly_readable<local_iterator>);
static_assert(!std::indirectly_writable<local_iterator, value_type>);
static_assert(std::indirectly_readable<const_local_iterator>);
static_assert(!std::indirectly_writable<const_local_iterator, value_type>);

View File

@ -0,0 +1,23 @@
//===----------------------------------------------------------------------===//
//
// 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
// iterator, reverse_iterator
#include <span>
#include <iterator>
using iterator = std::span<int>::iterator;
using value_type = iterator::value_type;
static_assert(std::indirectly_readable<iterator>);
static_assert(std::indirectly_writable<iterator, value_type>);

View File

@ -0,0 +1,24 @@
//===----------------------------------------------------------------------===//
//
// 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
// directory_iterator, recursive_directory_iterator
#include "filesystem_include.h"
#include <iterator>
static_assert(std::indirectly_readable<fs::directory_iterator>);
static_assert(!std::indirectly_writable<fs::directory_iterator, fs::directory_iterator::value_type>);
static_assert(std::indirectly_readable<fs::recursive_directory_iterator>);
static_assert(
!std::indirectly_writable<fs::recursive_directory_iterator, fs::recursive_directory_iterator::value_type>);

View File

@ -0,0 +1,199 @@
//===----------------------------------------------------------------------===//
//
// 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>
// concept indirectly_readable;
#include <iterator>
#include <concepts>
#include "read_write.h"
template <class In>
[[nodiscard]] constexpr bool check_indirectly_readable() {
constexpr bool result = std::indirectly_readable<In>;
static_assert(std::indirectly_readable<In const> == result);
static_assert(std::indirectly_readable<In volatile> == result);
static_assert(std::indirectly_readable<In const volatile> == result);
static_assert(std::indirectly_readable<In const&> == result);
static_assert(std::indirectly_readable<In volatile&> == result);
static_assert(std::indirectly_readable<In const volatile&> == result);
static_assert(std::indirectly_readable<In const&&> == result);
static_assert(std::indirectly_readable<In volatile&&> == result);
static_assert(std::indirectly_readable<In const volatile&&> == result);
return result;
}
static_assert(!check_indirectly_readable<void*>());
static_assert(!check_indirectly_readable<void const*>());
static_assert(!check_indirectly_readable<void volatile*>());
static_assert(!check_indirectly_readable<void const volatile*>());
static_assert(check_indirectly_readable<int*>());
static_assert(check_indirectly_readable<int const*>());
static_assert(check_indirectly_readable<int volatile*>());
static_assert(check_indirectly_readable<int const volatile*>());
static_assert(check_indirectly_readable<value_type_indirection>());
static_assert(check_indirectly_readable<element_type_indirection>());
static_assert(check_indirectly_readable<proxy_indirection>());
static_assert(check_indirectly_readable<read_only_indirection>());
struct indirection_mismatch {
using value_type = int;
float& operator*() const;
};
static_assert(!std::same_as<std::iter_value_t<indirection_mismatch>, std::iter_reference_t<indirection_mismatch> > &&
check_indirectly_readable<indirection_mismatch>());
static_assert(!check_indirectly_readable<missing_dereference>());
// `iter_rvalue_reference_t` can't be missing unless the dereference operator is also missing.
struct iter_move_mismatch {
using value_type = int;
value_type& operator*() const;
friend float& iter_move(iter_move_mismatch&);
};
static_assert(!check_indirectly_readable<iter_move_mismatch>());
struct indirection_and_iter_move_mismatch {
using value_type = int;
float& operator*() const;
friend unsigned long long& iter_move(indirection_and_iter_move_mismatch&);
};
static_assert(!check_indirectly_readable<indirection_and_iter_move_mismatch>());
struct missing_iter_value_t {
int operator*() const;
};
static_assert(!check_indirectly_readable<missing_iter_value_t>());
struct unrelated_lvalue_ref_and_rvalue_ref {};
struct iter_ref1 {};
namespace std {
template <>
struct common_reference<iter_ref1&, iter_ref1&&> {};
template <>
struct common_reference<iter_ref1&&, iter_ref1&> {};
} // namespace std
static_assert(!std::common_reference_with<iter_ref1&, iter_ref1&&>);
struct bad_iter_reference_t {
using value_type = int;
iter_ref1& operator*() const;
};
static_assert(!check_indirectly_readable<bad_iter_reference_t>());
struct iter_ref2 {};
struct iter_rvalue_ref {};
struct unrelated_iter_ref_rvalue_and_iter_rvalue_ref_rvalue {
using value_type = iter_ref2;
iter_ref2& operator*() const;
friend iter_rvalue_ref&& iter_move(unrelated_iter_ref_rvalue_and_iter_rvalue_ref_rvalue);
};
static_assert(!check_indirectly_readable<unrelated_iter_ref_rvalue_and_iter_rvalue_ref_rvalue>());
struct iter_ref3 {
operator iter_rvalue_ref() const;
};
namespace std {
template <template <class> class XQual, template <class> class YQual>
struct basic_common_reference<iter_ref3, iter_rvalue_ref, XQual, YQual> {
using type = iter_rvalue_ref;
};
template <template <class> class XQual, template <class> class YQual>
struct basic_common_reference<iter_rvalue_ref, iter_ref3, XQual, YQual> {
using type = iter_rvalue_ref;
};
} // namespace std
static_assert(std::common_reference_with<iter_ref3&&, iter_rvalue_ref&&>);
struct different_reference_types_with_common_reference {
using value_type = iter_ref3;
iter_ref3& operator*() const;
friend iter_rvalue_ref&& iter_move(different_reference_types_with_common_reference);
};
static_assert(check_indirectly_readable<different_reference_types_with_common_reference>());
struct iter_ref4 {
operator iter_rvalue_ref() const;
};
namespace std {
template <template <class> class XQual, template <class> class YQual>
struct basic_common_reference<iter_ref4, iter_rvalue_ref, XQual, YQual> {
using type = iter_rvalue_ref;
};
template <template <class> class XQual, template <class> class YQual>
struct basic_common_reference<iter_rvalue_ref, iter_ref4, XQual, YQual> {
using type = iter_rvalue_ref;
};
template <>
struct common_reference<iter_ref4 const&, iter_rvalue_ref&&> {};
template <>
struct common_reference<iter_rvalue_ref&&, iter_ref4 const&> {};
} // namespace std
static_assert(std::common_reference_with<iter_ref4&&, iter_rvalue_ref&&>);
static_assert(!std::common_reference_with<iter_ref4 const&, iter_rvalue_ref&&>);
struct different_reference_types_without_common_reference_to_const {
using value_type = iter_ref4;
iter_ref4& operator*() const;
friend iter_rvalue_ref&& iter_move(different_reference_types_without_common_reference_to_const);
};
static_assert(!check_indirectly_readable<different_reference_types_without_common_reference_to_const>());
struct non_const_deref {
int& operator*();
};
static_assert(!check_indirectly_readable<non_const_deref>());
struct not_referenceable {
using value_type = void;
void operator*() const;
};
static_assert(!std::indirectly_readable<not_referenceable>);
struct legacy_output_iterator {
using value_type = void;
legacy_output_iterator& operator*();
};
static_assert(!std::indirectly_readable<legacy_output_iterator>);
struct S {};
static_assert(!std::indirectly_readable<S>);
static_assert(!std::indirectly_readable<int S::*>);
static_assert(!std::indirectly_readable<int (S::*)()>);
static_assert(!std::indirectly_readable<int (S::*)() noexcept>);
static_assert(!std::indirectly_readable<int (S::*)() &>);
static_assert(!std::indirectly_readable<int (S::*)() & noexcept>);
static_assert(!std::indirectly_readable<int (S::*)() &&>);
static_assert(!std::indirectly_readable < int (S::*)() && noexcept >);
static_assert(!std::indirectly_readable<int (S::*)() const>);
static_assert(!std::indirectly_readable<int (S::*)() const noexcept>);
static_assert(!std::indirectly_readable<int (S::*)() const&>);
static_assert(!std::indirectly_readable<int (S::*)() const & noexcept>);
static_assert(!std::indirectly_readable<int (S::*)() const&&>);
static_assert(!std::indirectly_readable < int (S::*)() const&& noexcept >);
static_assert(!std::indirectly_readable<int (S::*)() volatile>);
static_assert(!std::indirectly_readable<int (S::*)() volatile noexcept>);
static_assert(!std::indirectly_readable<int (S::*)() volatile&>);
static_assert(!std::indirectly_readable<int (S::*)() volatile & noexcept>);
static_assert(!std::indirectly_readable<int (S::*)() volatile&&>);
static_assert(!std::indirectly_readable < int (S::*)() volatile&& noexcept >);

View File

@ -0,0 +1,55 @@
//===----------------------------------------------------------------------===//
//
// 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>
// concept indirectly_writable;
#include <iterator>
#include <concepts>
#include <memory>
#include <optional>
#include "read_write.h"
template <class Out, class T>
[[nodiscard]] constexpr bool check_indirectly_writable() {
constexpr bool result = std::indirectly_writable<Out, T>;
static_assert(std::indirectly_writable<Out const, T> == result);
return result;
}
static_assert(check_indirectly_writable<value_type_indirection, int>());
static_assert(check_indirectly_writable<value_type_indirection, double>());
static_assert(!check_indirectly_writable<value_type_indirection, double*>());
static_assert(!check_indirectly_writable<read_only_indirection, int>());
static_assert(!check_indirectly_writable<proxy_indirection, int>());
static_assert(!check_indirectly_writable<int, int>());
static_assert(!check_indirectly_writable<missing_dereference, missing_dereference::value_type>());
static_assert(!check_indirectly_writable<void*, int>());
static_assert(!check_indirectly_writable<void const*, int>());
static_assert(!check_indirectly_writable<void volatile*, int>());
static_assert(!check_indirectly_writable<void const volatile*, int>());
static_assert(!check_indirectly_writable<void*, double>());
static_assert(check_indirectly_writable<void**, int*>());
static_assert(!check_indirectly_writable<void**, int>());
static_assert(check_indirectly_writable<int*, int>());
static_assert(!check_indirectly_writable<int const*, int>());
static_assert(check_indirectly_writable<int volatile*, int>());
static_assert(!check_indirectly_writable<int const volatile*, int>());
static_assert(check_indirectly_writable<int*, double>());
static_assert(check_indirectly_writable<int**, int*>());
static_assert(!check_indirectly_writable<int**, int>());

View File

@ -0,0 +1,21 @@
//===----------------------------------------------------------------------===//
//
// 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
// back_insert_iterator
#include <iterator>
#include <vector>
using iterator = std::back_insert_iterator<std::vector<int> >;
static_assert(!std::indirectly_readable<iterator>);
static_assert(std::indirectly_writable<iterator, int>);

View File

@ -0,0 +1,21 @@
//===----------------------------------------------------------------------===//
//
// 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
// front_insert_iterator
#include <iterator>
#include <list>
using iterator = std::front_insert_iterator<std::list<int> >;
static_assert(!std::indirectly_readable<iterator>);
static_assert(std::indirectly_writable<iterator, int>);

View File

@ -0,0 +1,21 @@
//===----------------------------------------------------------------------===//
//
// 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
// insert_iterator
#include <iterator>
#include <vector>
using iterator = std::insert_iterator<std::vector<int> >;
static_assert(!std::indirectly_readable<iterator>);
static_assert(std::indirectly_writable<iterator, int>);

View File

@ -0,0 +1,19 @@
//===----------------------------------------------------------------------===//
//
// 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
// move_iterator
#include <iterator>
using iterator = std::move_iterator<int*>;
static_assert(std::indirectly_readable<iterator>);
static_assert(!std::indirectly_writable<iterator, int>);

View File

@ -0,0 +1,19 @@
//===----------------------------------------------------------------------===//
//
// 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
// reverse_iterator
#include <iterator>
using iterator = std::reverse_iterator<int*>;
static_assert(std::indirectly_readable<iterator>);
static_assert(std::indirectly_writable<iterator, int>);

View File

@ -0,0 +1,21 @@
//===----------------------------------------------------------------------===//
//
// 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
// istream_iterator
#include <iterator>
#include <iosfwd>
using iterator = std::istream_iterator<int, std::istream>;
static_assert(std::indirectly_readable<iterator>);
static_assert(!std::indirectly_writable<iterator, int>);

View File

@ -0,0 +1,22 @@
//===----------------------------------------------------------------------===//
//
// 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
// istreambuf_iterator
#include <iterator>
#include <istream>
#include <string>
using iterator = std::istreambuf_iterator<char>;
static_assert(std::indirectly_readable<iterator>);
static_assert(!std::indirectly_writable<iterator, char>);

View File

@ -0,0 +1,21 @@
//===----------------------------------------------------------------------===//
//
// 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
// ostream_iterator
#include <iterator>
#include <iosfwd>
using iterator = std::ostream_iterator<int, std::ostream>;
static_assert(!std::indirectly_readable<iterator>);
static_assert(std::indirectly_writable<iterator, int>);

View File

@ -0,0 +1,22 @@
//===----------------------------------------------------------------------===//
//
// 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
// ostreambuf_iterator
#include <iterator>
#include <ostream>
#include <string>
using iterator = std::ostreambuf_iterator<char>;
static_assert(!std::indirectly_readable<iterator>);
static_assert(std::indirectly_writable<iterator, char>);

View File

@ -0,0 +1,20 @@
//===----------------------------------------------------------------------===//
//
// 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
// regex_iterator
#include <regex>
#include <iterator>
static_assert(std::indirectly_readable<std::cregex_iterator>);
static_assert(!std::indirectly_writable<std::cregex_iterator, char>);

View File

@ -0,0 +1,20 @@
//===----------------------------------------------------------------------===//
//
// 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
// regex_token_iterator
#include <regex>
#include <iterator>
static_assert(std::indirectly_readable<std::cregex_token_iterator>);
static_assert(!std::indirectly_writable<std::cregex_token_iterator, char>);

View File

@ -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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts
// UNSUPPORTED: gcc-10
// iterator, const_iterator, reverse_iterator, const_reverse_iterator
#include <string>
#include <iterator>
using iterator = std::string::iterator;
using const_iterator = std::string::const_iterator;
using value_type = iterator::value_type;
static_assert(std::indirectly_readable<iterator>);
static_assert(std::indirectly_writable<iterator, value_type>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);

View File

@ -0,0 +1,26 @@
//===----------------------------------------------------------------------===//
//
// 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
// iterator, const_iterator, reverse_iterator, const_reverse_iterator
#include <string_view>
#include <iterator>
using iterator = std::string_view::iterator;
using const_iterator = std::string_view::const_iterator;
static_assert(std::indirectly_readable<iterator>);
static_assert(!std::indirectly_writable<iterator, char>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, char>);

View File

@ -0,0 +1,23 @@
//===----------------------------------------------------------------------===//
//
// 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
// unique_ptr
#include <memory>
#include <iterator>
static_assert(std::indirectly_readable<std::unique_ptr<int> >);
static_assert(std::indirectly_writable<std::unique_ptr<int>, int>);
static_assert(!std::indirectly_readable<std::unique_ptr<void> >);
static_assert(!std::indirectly_writable<std::unique_ptr<void>, void>);

View File

@ -0,0 +1,23 @@
//===----------------------------------------------------------------------===//
//
// 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
// shared_ptr
#include <memory>
#include <iterator>
static_assert(std::indirectly_readable<std::shared_ptr<int> >);
static_assert(std::indirectly_writable<std::shared_ptr<int>, int>);
static_assert(!std::indirectly_readable<std::shared_ptr<void> >);
static_assert(!std::indirectly_writable<std::shared_ptr<void>, void>);

View File

@ -0,0 +1,20 @@
//===----------------------------------------------------------------------===//
//
// 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
// unique_ptr
#include <optional>
#include <iterator>
static_assert(!std::indirectly_readable<std::optional<int> >);
static_assert(!std::indirectly_writable<std::optional<int>, int>);

View File

@ -0,0 +1,36 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef LIBCPP_TEST_SUPPORT_READ_WRITE_H
#define LIBCPP_TEST_SUPPORT_READ_WRITE_H
struct value_type_indirection {
using value_type = int;
value_type& operator*() const;
};
struct element_type_indirection {
using element_type = long;
element_type& operator*() const;
};
struct proxy_indirection {
using value_type = int;
value_type operator*() const;
};
struct read_only_indirection {
using value_type = int const;
value_type& operator*() const;
};
// doubles as missing_iter_reference_t
struct missing_dereference {
using value_type = int;
};
#endif // LIBCPP_TEST_SUPPORT_READ_WRITE_H