diff --git a/libcxx/docs/Cxx2aStatusIssuesStatus.csv b/libcxx/docs/Cxx2aStatusIssuesStatus.csv --- a/libcxx/docs/Cxx2aStatusIssuesStatus.csv +++ b/libcxx/docs/Cxx2aStatusIssuesStatus.csv @@ -297,3 +297,4 @@ "`3396 `__","Clarify point of reference for ``source_location::current()``\ (DE 169)","Prague","","" "`3397 `__","``ranges::basic_istream_view::iterator``\ should not provide ``iterator_category``\ ","Prague","","" "`3398 `__","``tuple_element_t``\ is also wrong for ``const subrange``\ ","Prague","","" +"`3446 `__","``indirectly_readable_traits``\ ambiguity for types with both ``value_type``\ and ``element_type``\ ","November virtual meeting","|Complete|","13.0" diff --git a/libcxx/include/iterator b/libcxx/include/iterator --- a/libcxx/include/iterator +++ b/libcxx/include/iterator @@ -17,7 +17,8 @@ namespace std { -template struct incrementable_traits; // since C++20 +template struct incrementable_traits; // since C++20 +template struct indirectly_readable_traits; // since C++20 template struct iterator_traits @@ -50,6 +51,9 @@ typedef Category iterator_category; }; +template + using iter_reference_t = decltype(*declval()); + struct input_iterator_tag {}; struct output_iterator_tag {}; struct forward_iterator_tag : public input_iterator_tag {}; @@ -472,6 +476,69 @@ }; // TODO(cjdb): add iter_difference_t once iterator_traits is cleaned up. + +// [readable.traits] +template struct __cond_value_type {}; + +template +requires is_object_v<_Tp> +struct __cond_value_type<_Tp> { using value_type = remove_cv_t<_Tp>; }; + +template +concept __has_member_value_type = requires { typename _Tp::value_type; }; + +template +concept __has_member_element_type = requires { typename _Tp::element_type; }; + +template struct indirectly_readable_traits {}; + +template +requires is_array_v<_Ip> +struct indirectly_readable_traits<_Ip> { + using value_type = remove_cv_t>; +}; + +template +struct indirectly_readable_traits : indirectly_readable_traits<_Ip> {}; + +template +struct indirectly_readable_traits<_Tp*> : __cond_value_type<_Tp> {}; + +template<__has_member_value_type _Tp> +struct indirectly_readable_traits<_Tp> + : __cond_value_type {}; + +template<__has_member_element_type _Tp> +struct indirectly_readable_traits<_Tp> + : __cond_value_type {}; + +// Pre-emptively applying LWG3541. +template<__has_member_value_type _Tp> +requires __has_member_element_type<_Tp> +struct indirectly_readable_traits<_Tp> {}; + +template<__has_member_value_type _Tp> +requires __has_member_element_type<_Tp> && + same_as, + remove_cv_t> +struct indirectly_readable_traits<_Tp> + : __cond_value_type {}; + +template +using __with_reference = _Tp&; + +template +concept __referenceable = requires { + typename __with_reference<_Tp>; +}; + +template +concept __dereferenceable = requires(_Tp& __t) { + { *__t } -> __referenceable; // not required to be equality-preserving +}; + +template<__dereferenceable _Tp> +using iter_reference_t = decltype(*declval<_Tp&>()); #endif // !defined(_LIBCPP_HAS_NO_RANGES) template @@ -582,6 +649,71 @@ typedef typename _Iter::iterator_category iterator_category; }; +#if !defined(_LIBCPP_HAS_NO_RANGES) + +// The `cpp17.*-iterator` concepts have been dubbed `__legacy.*_iterator` because the name is both +// clearer (C++98 iterators are still valid `cpp17-iterators`, for example), and because it's the +// term that C++ Reference uses (which is what most users will look to when issued diagnostics). + +template +concept __legacy_iterator = + requires(_Ip __i) { + { *__i } -> __referenceable; + { ++__i } -> same_as<_Ip&>; + { *__i++ } -> __referenceable; + } && + copyable<_Ip>; + +template +concept __legacy_input_iterator = + __legacy_iterator<_Ip> && + equality_comparable<_Ip> && + requires(_Ip __i) { + typename incrementable_traits<_Ip>::difference_type; + typename indirectly_readable_traits<_Ip>::value_type; + typename common_reference_t&&, + typename indirectly_readable_traits<_Ip>::value_type&>; + typename common_reference_t::value_type&>; + requires signed_integral::difference_type>; + }; + +template +concept __legacy_forward_iterator = + __legacy_input_iterator<_Ip> && + constructible_from<_Ip> && + is_lvalue_reference_v> && + same_as>, + typename indirectly_readable_traits<_Ip>::value_type> && + requires(_Ip __i) { + { __i++ } -> convertible_to<_Ip const&>; + { *__i++ } -> same_as>; + }; + +template +concept __legacy_bidirectional_iterator = + __legacy_forward_iterator<_Ip> && + requires(_Ip __i) { + { --__i } -> same_as<_Ip&>; + { __i-- } -> convertible_to<_Ip const&>; + { *__i-- } -> same_as>; + }; + +template +concept __legacy_random_access_iterator = + __legacy_bidirectional_iterator<_Ip> and + totally_ordered<_Ip> and + requires(_Ip __i, typename incrementable_traits<_Ip>::difference_type __n) { + { __i += __n } -> same_as<_Ip&>; + { __i -= __n } -> same_as<_Ip&>; + { __i + __n } -> same_as<_Ip>; + { __n + __i } -> same_as<_Ip>; + { __i - __n } -> same_as<_Ip>; + { __i - __i } -> same_as; + { __i[__n] } -> convertible_to>; + }; +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) + template struct __iterator_traits {}; template diff --git a/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_bidirectional_iterator.compile.pass.cpp b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_bidirectional_iterator.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_bidirectional_iterator.compile.pass.cpp @@ -0,0 +1,151 @@ +//===----------------------------------------------------------------------===// +// +// 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 __legacy_bidirectional_iterator; + +#include + +#include +#include +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static_assert(std::__legacy_bidirectional_iterator); +static_assert(std::__legacy_bidirectional_iterator); +static_assert(std::__legacy_bidirectional_iterator); +static_assert(std::__legacy_bidirectional_iterator); + +// +static_assert(std::__legacy_bidirectional_iterator::iterator>); +static_assert(std::__legacy_bidirectional_iterator::const_iterator>); +static_assert(std::__legacy_bidirectional_iterator::reverse_iterator>); +static_assert(std::__legacy_bidirectional_iterator::const_reverse_iterator>); + +// +static_assert(std::__legacy_bidirectional_iterator::iterator>); +static_assert(std::__legacy_bidirectional_iterator::const_iterator>); +static_assert(std::__legacy_bidirectional_iterator::reverse_iterator>); +static_assert(std::__legacy_bidirectional_iterator::const_reverse_iterator>); + +// +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +static_assert(!std::__legacy_bidirectional_iterator); +static_assert(!std::__legacy_bidirectional_iterator); +#endif + +// +static_assert(!std::__legacy_bidirectional_iterator::iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_iterator>); + +// +static_assert(!std::__legacy_bidirectional_iterator > >); +static_assert(!std::__legacy_bidirectional_iterator > >); +static_assert(!std::__legacy_bidirectional_iterator > >); +static_assert(!std::__legacy_bidirectional_iterator::iterator> >); + +// +static_assert(std::__legacy_bidirectional_iterator::iterator>); +static_assert(std::__legacy_bidirectional_iterator::const_iterator>); +static_assert(std::__legacy_bidirectional_iterator::reverse_iterator>); +static_assert(std::__legacy_bidirectional_iterator::const_reverse_iterator>); + +// +static_assert(std::__legacy_bidirectional_iterator::iterator>); +static_assert(std::__legacy_bidirectional_iterator::const_iterator>); +static_assert(std::__legacy_bidirectional_iterator::reverse_iterator>); +static_assert(std::__legacy_bidirectional_iterator::const_reverse_iterator>); + +static_assert(std::__legacy_bidirectional_iterator::iterator>); +static_assert(std::__legacy_bidirectional_iterator::const_iterator>); +static_assert(std::__legacy_bidirectional_iterator::reverse_iterator>); +static_assert(std::__legacy_bidirectional_iterator::const_reverse_iterator>); + +// +static_assert(std::__legacy_bidirectional_iterator::iterator>); +static_assert(std::__legacy_bidirectional_iterator::const_iterator>); +static_assert(std::__legacy_bidirectional_iterator::reverse_iterator>); +static_assert(std::__legacy_bidirectional_iterator::const_reverse_iterator>); + +static_assert(std::__legacy_bidirectional_iterator::iterator>); +static_assert(std::__legacy_bidirectional_iterator::const_iterator>); +static_assert(std::__legacy_bidirectional_iterator::reverse_iterator>); +static_assert(std::__legacy_bidirectional_iterator::const_reverse_iterator>); + +// +static_assert(std::__legacy_bidirectional_iterator); +static_assert(std::__legacy_bidirectional_iterator); +static_assert(std::__legacy_bidirectional_iterator); +static_assert(std::__legacy_bidirectional_iterator); + +// +static_assert(std::__legacy_bidirectional_iterator); +static_assert(std::__legacy_bidirectional_iterator); +static_assert(std::__legacy_bidirectional_iterator); +static_assert(std::__legacy_bidirectional_iterator); + +// +static_assert(!std::__legacy_bidirectional_iterator::iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +static_assert(!std::__legacy_bidirectional_iterator::iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +// +static_assert(!std::__legacy_bidirectional_iterator::iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +static_assert(!std::__legacy_bidirectional_iterator::iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +// +static_assert(std::__legacy_bidirectional_iterator::iterator>); +static_assert(std::__legacy_bidirectional_iterator::const_iterator>); +static_assert(std::__legacy_bidirectional_iterator::reverse_iterator>); +static_assert(std::__legacy_bidirectional_iterator::const_reverse_iterator>); + +// Not iterators +static_assert(!std::__legacy_bidirectional_iterator); +static_assert(!std::__legacy_bidirectional_iterator); +static_assert(!std::__legacy_bidirectional_iterator); +static_assert(!std::__legacy_bidirectional_iterator::iterator volatile>); +static_assert(!std::__legacy_bidirectional_iterator::iterator&>); +static_assert(!std::__legacy_bidirectional_iterator::iterator&&>); +static_assert(!std::__legacy_bidirectional_iterator); +static_assert(!std::__legacy_bidirectional_iterator); +static_assert(!std::__legacy_bidirectional_iterator); +static_assert(!std::__legacy_bidirectional_iterator); +static_assert(!std::__legacy_bidirectional_iterator); +static_assert(!std::__legacy_bidirectional_iterator); + +struct S {}; +static_assert(!std::__legacy_bidirectional_iterator); +static_assert(!std::__legacy_bidirectional_iterator); +static_assert(!std::__legacy_bidirectional_iterator); diff --git a/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_forward_iterator.compile.pass.cpp b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_forward_iterator.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_forward_iterator.compile.pass.cpp @@ -0,0 +1,151 @@ +//===----------------------------------------------------------------------===// +// +// 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 __legacy_forward_iterator; + +#include + +#include +#include +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static_assert(std::__legacy_forward_iterator); +static_assert(std::__legacy_forward_iterator); +static_assert(std::__legacy_forward_iterator); +static_assert(std::__legacy_forward_iterator); + +// +static_assert(std::__legacy_forward_iterator::iterator>); +static_assert(std::__legacy_forward_iterator::const_iterator>); +static_assert(std::__legacy_forward_iterator::reverse_iterator>); +static_assert(std::__legacy_forward_iterator::const_reverse_iterator>); + +// +static_assert(std::__legacy_forward_iterator::iterator>); +static_assert(std::__legacy_forward_iterator::const_iterator>); +static_assert(std::__legacy_forward_iterator::reverse_iterator>); +static_assert(std::__legacy_forward_iterator::const_reverse_iterator>); + +// +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +static_assert(!std::__legacy_forward_iterator); +static_assert(!std::__legacy_forward_iterator); +#endif + +// +static_assert(std::__legacy_forward_iterator::iterator>); +static_assert(std::__legacy_forward_iterator::const_iterator>); + +// +static_assert(!std::__legacy_forward_iterator > >); +static_assert(!std::__legacy_forward_iterator > >); +static_assert(!std::__legacy_forward_iterator > >); +static_assert(!std::__legacy_forward_iterator::iterator> >); + +// +static_assert(std::__legacy_forward_iterator::iterator>); +static_assert(std::__legacy_forward_iterator::const_iterator>); +static_assert(std::__legacy_forward_iterator::reverse_iterator>); +static_assert(std::__legacy_forward_iterator::const_reverse_iterator>); + +// +static_assert(std::__legacy_forward_iterator::iterator>); +static_assert(std::__legacy_forward_iterator::const_iterator>); +static_assert(std::__legacy_forward_iterator::reverse_iterator>); +static_assert(std::__legacy_forward_iterator::const_reverse_iterator>); + +static_assert(std::__legacy_forward_iterator::iterator>); +static_assert(std::__legacy_forward_iterator::const_iterator>); +static_assert(std::__legacy_forward_iterator::reverse_iterator>); +static_assert(std::__legacy_forward_iterator::const_reverse_iterator>); + +// +static_assert(std::__legacy_forward_iterator::iterator>); +static_assert(std::__legacy_forward_iterator::const_iterator>); +static_assert(std::__legacy_forward_iterator::reverse_iterator>); +static_assert(std::__legacy_forward_iterator::const_reverse_iterator>); + +static_assert(std::__legacy_forward_iterator::iterator>); +static_assert(std::__legacy_forward_iterator::const_iterator>); +static_assert(std::__legacy_forward_iterator::reverse_iterator>); +static_assert(std::__legacy_forward_iterator::const_reverse_iterator>); + +// +static_assert(std::__legacy_forward_iterator); +static_assert(std::__legacy_forward_iterator); +static_assert(std::__legacy_forward_iterator); +static_assert(std::__legacy_forward_iterator); + +// +static_assert(std::__legacy_forward_iterator); +static_assert(std::__legacy_forward_iterator); +static_assert(std::__legacy_forward_iterator); +static_assert(std::__legacy_forward_iterator); + +// +static_assert(std::__legacy_forward_iterator::iterator>); +static_assert(std::__legacy_forward_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +static_assert(std::__legacy_forward_iterator::iterator>); +static_assert(std::__legacy_forward_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +// +static_assert(std::__legacy_forward_iterator::iterator>); +static_assert(std::__legacy_forward_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +static_assert(std::__legacy_forward_iterator::iterator>); +static_assert(std::__legacy_forward_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +// +static_assert(std::__legacy_forward_iterator::iterator>); +static_assert(std::__legacy_forward_iterator::const_iterator>); +static_assert(std::__legacy_forward_iterator::reverse_iterator>); +static_assert(std::__legacy_forward_iterator::const_reverse_iterator>); + +// Not iterators +static_assert(!std::__legacy_forward_iterator); +static_assert(!std::__legacy_forward_iterator); +static_assert(!std::__legacy_forward_iterator); +static_assert(!std::__legacy_forward_iterator::iterator volatile>); +static_assert(!std::__legacy_forward_iterator::iterator&>); +static_assert(!std::__legacy_forward_iterator::iterator&&>); +static_assert(!std::__legacy_forward_iterator); +static_assert(!std::__legacy_forward_iterator); +static_assert(!std::__legacy_forward_iterator); +static_assert(!std::__legacy_forward_iterator); +static_assert(!std::__legacy_forward_iterator); +static_assert(!std::__legacy_forward_iterator); + +struct S {}; +static_assert(!std::__legacy_forward_iterator); +static_assert(!std::__legacy_forward_iterator); +static_assert(!std::__legacy_forward_iterator); diff --git a/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_input_iterator.compile.pass.cpp b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_input_iterator.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_input_iterator.compile.pass.cpp @@ -0,0 +1,151 @@ +//===----------------------------------------------------------------------===// +// +// 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 __legacy_input_iterator; + +#include + +#include +#include +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static_assert(std::__legacy_input_iterator); +static_assert(std::__legacy_input_iterator); +static_assert(std::__legacy_input_iterator); +static_assert(std::__legacy_input_iterator); + +// +static_assert(std::__legacy_input_iterator::iterator>); +static_assert(std::__legacy_input_iterator::const_iterator>); +static_assert(std::__legacy_input_iterator::reverse_iterator>); +static_assert(std::__legacy_input_iterator::const_reverse_iterator>); + +// +static_assert(std::__legacy_input_iterator::iterator>); +static_assert(std::__legacy_input_iterator::const_iterator>); +static_assert(std::__legacy_input_iterator::reverse_iterator>); +static_assert(std::__legacy_input_iterator::const_reverse_iterator>); + +// +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +static_assert(std::__legacy_input_iterator); +static_assert(std::__legacy_input_iterator); +#endif + +// +static_assert(std::__legacy_input_iterator::iterator>); +static_assert(std::__legacy_input_iterator::const_iterator>); + +// +static_assert(!std::__legacy_input_iterator > >); +static_assert(!std::__legacy_input_iterator > >); +static_assert(!std::__legacy_input_iterator > >); +static_assert(std::__legacy_input_iterator::iterator> >); + +// +static_assert(std::__legacy_input_iterator::iterator>); +static_assert(std::__legacy_input_iterator::const_iterator>); +static_assert(std::__legacy_input_iterator::reverse_iterator>); +static_assert(std::__legacy_input_iterator::const_reverse_iterator>); + +// +static_assert(std::__legacy_input_iterator::iterator>); +static_assert(std::__legacy_input_iterator::const_iterator>); +static_assert(std::__legacy_input_iterator::reverse_iterator>); +static_assert(std::__legacy_input_iterator::const_reverse_iterator>); + +static_assert(std::__legacy_input_iterator::iterator>); +static_assert(std::__legacy_input_iterator::const_iterator>); +static_assert(std::__legacy_input_iterator::reverse_iterator>); +static_assert(std::__legacy_input_iterator::const_reverse_iterator>); + +// +static_assert(std::__legacy_input_iterator::iterator>); +static_assert(std::__legacy_input_iterator::const_iterator>); +static_assert(std::__legacy_input_iterator::reverse_iterator>); +static_assert(std::__legacy_input_iterator::const_reverse_iterator>); + +static_assert(std::__legacy_input_iterator::iterator>); +static_assert(std::__legacy_input_iterator::const_iterator>); +static_assert(std::__legacy_input_iterator::reverse_iterator>); +static_assert(std::__legacy_input_iterator::const_reverse_iterator>); + +// +static_assert(std::__legacy_input_iterator); +static_assert(std::__legacy_input_iterator); +static_assert(std::__legacy_input_iterator); +static_assert(std::__legacy_input_iterator); + +// +static_assert(std::__legacy_input_iterator); +static_assert(std::__legacy_input_iterator); +static_assert(std::__legacy_input_iterator); +static_assert(std::__legacy_input_iterator); + +// +static_assert(std::__legacy_input_iterator::iterator>); +static_assert(std::__legacy_input_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +static_assert(std::__legacy_input_iterator::iterator>); +static_assert(std::__legacy_input_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +// +static_assert(std::__legacy_input_iterator::iterator>); +static_assert(std::__legacy_input_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +static_assert(std::__legacy_input_iterator::iterator>); +static_assert(std::__legacy_input_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +// +static_assert(std::__legacy_input_iterator::iterator>); +static_assert(std::__legacy_input_iterator::const_iterator>); +static_assert(std::__legacy_input_iterator::reverse_iterator>); +static_assert(std::__legacy_input_iterator::const_reverse_iterator>); + +// Not iterators +static_assert(!std::__legacy_input_iterator); +static_assert(!std::__legacy_input_iterator); +static_assert(!std::__legacy_input_iterator); +static_assert(!std::__legacy_input_iterator::iterator volatile>); +static_assert(!std::__legacy_input_iterator::iterator&>); +static_assert(!std::__legacy_input_iterator::iterator&&>); +static_assert(!std::__legacy_input_iterator); +static_assert(!std::__legacy_input_iterator); +static_assert(!std::__legacy_input_iterator); +static_assert(!std::__legacy_input_iterator); +static_assert(!std::__legacy_input_iterator); +static_assert(!std::__legacy_input_iterator); + +struct S {}; +static_assert(!std::__legacy_input_iterator); +static_assert(!std::__legacy_input_iterator); +static_assert(!std::__legacy_input_iterator); diff --git a/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_iterator.compile.pass.cpp b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_iterator.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_iterator.compile.pass.cpp @@ -0,0 +1,151 @@ +//===----------------------------------------------------------------------===// +// +// 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 __legacy_iterator; + +#include + +#include +#include +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static_assert(std::__legacy_iterator); +static_assert(std::__legacy_iterator); +static_assert(std::__legacy_iterator); +static_assert(std::__legacy_iterator); + +// +static_assert(std::__legacy_iterator::iterator>); +static_assert(std::__legacy_iterator::const_iterator>); +static_assert(std::__legacy_iterator::reverse_iterator>); +static_assert(std::__legacy_iterator::const_reverse_iterator>); + +// +static_assert(std::__legacy_iterator::iterator>); +static_assert(std::__legacy_iterator::const_iterator>); +static_assert(std::__legacy_iterator::reverse_iterator>); +static_assert(std::__legacy_iterator::const_reverse_iterator>); + +// +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +static_assert(std::__legacy_iterator); +static_assert(std::__legacy_iterator); +#endif + +// +static_assert(std::__legacy_iterator::iterator>); +static_assert(std::__legacy_iterator::const_iterator>); + +// +static_assert(std::__legacy_iterator > >); +static_assert(std::__legacy_iterator > >); +static_assert(std::__legacy_iterator > >); +static_assert(std::__legacy_iterator::iterator> >); + +// +static_assert(std::__legacy_iterator::iterator>); +static_assert(std::__legacy_iterator::const_iterator>); +static_assert(std::__legacy_iterator::reverse_iterator>); +static_assert(std::__legacy_iterator::const_reverse_iterator>); + +// +static_assert(std::__legacy_iterator::iterator>); +static_assert(std::__legacy_iterator::const_iterator>); +static_assert(std::__legacy_iterator::reverse_iterator>); +static_assert(std::__legacy_iterator::const_reverse_iterator>); + +static_assert(std::__legacy_iterator::iterator>); +static_assert(std::__legacy_iterator::const_iterator>); +static_assert(std::__legacy_iterator::reverse_iterator>); +static_assert(std::__legacy_iterator::const_reverse_iterator>); + +// +static_assert(std::__legacy_iterator::iterator>); +static_assert(std::__legacy_iterator::const_iterator>); +static_assert(std::__legacy_iterator::reverse_iterator>); +static_assert(std::__legacy_iterator::const_reverse_iterator>); + +static_assert(std::__legacy_iterator::iterator>); +static_assert(std::__legacy_iterator::const_iterator>); +static_assert(std::__legacy_iterator::reverse_iterator>); +static_assert(std::__legacy_iterator::const_reverse_iterator>); + +// +static_assert(std::__legacy_iterator); +static_assert(std::__legacy_iterator); +static_assert(std::__legacy_iterator); +static_assert(std::__legacy_iterator); + +// +static_assert(std::__legacy_iterator); +static_assert(std::__legacy_iterator); +static_assert(std::__legacy_iterator); +static_assert(std::__legacy_iterator); + +// +static_assert(std::__legacy_iterator::iterator>); +static_assert(std::__legacy_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +static_assert(std::__legacy_iterator::iterator>); +static_assert(std::__legacy_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +// +static_assert(std::__legacy_iterator::iterator>); +static_assert(std::__legacy_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +static_assert(std::__legacy_iterator::iterator>); +static_assert(std::__legacy_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +// +static_assert(std::__legacy_iterator::iterator>); +static_assert(std::__legacy_iterator::const_iterator>); +static_assert(std::__legacy_iterator::reverse_iterator>); +static_assert(std::__legacy_iterator::const_reverse_iterator>); + +// Not iterators +static_assert(!std::__legacy_iterator); +static_assert(!std::__legacy_iterator); +static_assert(!std::__legacy_iterator); +static_assert(!std::__legacy_iterator::iterator volatile>); +static_assert(!std::__legacy_iterator::iterator&>); +static_assert(!std::__legacy_iterator::iterator&&>); +static_assert(!std::__legacy_iterator); +static_assert(!std::__legacy_iterator); +static_assert(!std::__legacy_iterator); +static_assert(!std::__legacy_iterator); +static_assert(!std::__legacy_iterator); +static_assert(!std::__legacy_iterator); + +struct S {}; +static_assert(!std::__legacy_iterator); +static_assert(!std::__legacy_iterator); +static_assert(!std::__legacy_iterator); diff --git a/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_random_access_iterator.compile.pass.cpp b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_random_access_iterator.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_random_access_iterator.compile.pass.cpp @@ -0,0 +1,151 @@ +//===----------------------------------------------------------------------===// +// +// 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 __legacy_random_access_iterator; + +#include + +#include +#include +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static_assert(std::__legacy_random_access_iterator); +static_assert(std::__legacy_random_access_iterator); +static_assert(std::__legacy_random_access_iterator); +static_assert(std::__legacy_random_access_iterator); + +// +static_assert(std::__legacy_random_access_iterator::iterator>); +static_assert(std::__legacy_random_access_iterator::const_iterator>); +static_assert(std::__legacy_random_access_iterator::reverse_iterator>); +static_assert(std::__legacy_random_access_iterator::const_reverse_iterator>); + +// +static_assert(std::__legacy_random_access_iterator::iterator>); +static_assert(std::__legacy_random_access_iterator::const_iterator>); +static_assert(std::__legacy_random_access_iterator::reverse_iterator>); +static_assert(std::__legacy_random_access_iterator::const_reverse_iterator>); + +// +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +static_assert(!std::__legacy_random_access_iterator); +static_assert(!std::__legacy_random_access_iterator); +#endif + +// +static_assert(!std::__legacy_random_access_iterator::iterator>); +static_assert(!std::__legacy_random_access_iterator::const_iterator>); + +// +static_assert(!std::__legacy_random_access_iterator > >); +static_assert(!std::__legacy_random_access_iterator > >); +static_assert(!std::__legacy_random_access_iterator > >); +static_assert(!std::__legacy_random_access_iterator::iterator> >); + +// +static_assert(!std::__legacy_random_access_iterator::iterator>); +static_assert(!std::__legacy_random_access_iterator::const_iterator>); +static_assert(!std::__legacy_random_access_iterator::reverse_iterator>); +static_assert(!std::__legacy_random_access_iterator::const_reverse_iterator>); + +// +static_assert(!std::__legacy_random_access_iterator::iterator>); +static_assert(!std::__legacy_random_access_iterator::const_iterator>); +static_assert(!std::__legacy_random_access_iterator::reverse_iterator>); +static_assert(!std::__legacy_random_access_iterator::const_reverse_iterator>); + +static_assert(!std::__legacy_random_access_iterator::iterator>); +static_assert(!std::__legacy_random_access_iterator::const_iterator>); +static_assert(!std::__legacy_random_access_iterator::reverse_iterator>); +static_assert(!std::__legacy_random_access_iterator::const_reverse_iterator>); + +// +static_assert(!std::__legacy_random_access_iterator::iterator>); +static_assert(!std::__legacy_random_access_iterator::const_iterator>); +static_assert(!std::__legacy_random_access_iterator::reverse_iterator>); +static_assert(!std::__legacy_random_access_iterator::const_reverse_iterator>); + +static_assert(!std::__legacy_random_access_iterator::iterator>); +static_assert(!std::__legacy_random_access_iterator::const_iterator>); +static_assert(!std::__legacy_random_access_iterator::reverse_iterator>); +static_assert(!std::__legacy_random_access_iterator::const_reverse_iterator>); + +// +static_assert(std::__legacy_random_access_iterator); +static_assert(std::__legacy_random_access_iterator); +static_assert(std::__legacy_random_access_iterator); +static_assert(std::__legacy_random_access_iterator); + +// +static_assert(std::__legacy_random_access_iterator); +static_assert(std::__legacy_random_access_iterator); +static_assert(std::__legacy_random_access_iterator); +static_assert(std::__legacy_random_access_iterator); + +// +static_assert(!std::__legacy_random_access_iterator::iterator>); +static_assert(!std::__legacy_random_access_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +static_assert(!std::__legacy_random_access_iterator::iterator>); +static_assert(!std::__legacy_random_access_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +// +static_assert(!std::__legacy_random_access_iterator::iterator>); +static_assert(!std::__legacy_random_access_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +static_assert(!std::__legacy_random_access_iterator::iterator>); +static_assert(!std::__legacy_random_access_iterator::const_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::local_iterator>); +static_assert(!std::__legacy_bidirectional_iterator::const_local_iterator>); + +// +static_assert(std::__legacy_random_access_iterator::iterator>); +static_assert(std::__legacy_random_access_iterator::const_iterator>); +static_assert(std::__legacy_random_access_iterator::reverse_iterator>); +static_assert(std::__legacy_random_access_iterator::const_reverse_iterator>); + +// Not iterators +static_assert(!std::__legacy_random_access_iterator); +static_assert(!std::__legacy_random_access_iterator); +static_assert(!std::__legacy_random_access_iterator); +static_assert(!std::__legacy_random_access_iterator::iterator volatile>); +static_assert(!std::__legacy_random_access_iterator::iterator&>); +static_assert(!std::__legacy_random_access_iterator::iterator&&>); +static_assert(!std::__legacy_random_access_iterator); +static_assert(!std::__legacy_random_access_iterator); +static_assert(!std::__legacy_random_access_iterator); +static_assert(!std::__legacy_random_access_iterator); +static_assert(!std::__legacy_random_access_iterator); +static_assert(!std::__legacy_random_access_iterator); + +struct S {}; +static_assert(!std::__legacy_random_access_iterator); +static_assert(!std::__legacy_random_access_iterator); +static_assert(!std::__legacy_random_access_iterator); diff --git a/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/locale_dependent.compile.pass.cpp b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/locale_dependent.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/locale_dependent.compile.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// REQUIRES: locale.en_US.UTF-8 + +#include + +#include +#include + +static_assert(std::__legacy_iterator >); +static_assert(std::__legacy_iterator >); +static_assert(std::__legacy_iterator >); +static_assert(std::__legacy_iterator >); + +static_assert(std::__legacy_input_iterator >); +static_assert(std::__legacy_input_iterator >); +static_assert(!std::__legacy_input_iterator >); +static_assert(!std::__legacy_input_iterator >); + +// This is because the legacy iterator concepts don't care about iterator_category +static_assert(std::__legacy_forward_iterator >); + +static_assert(!std::__legacy_forward_iterator >); +static_assert(!std::__legacy_forward_iterator >); +static_assert(!std::__legacy_forward_iterator >); + +static_assert(!std::__legacy_bidirectional_iterator >); +static_assert(!std::__legacy_bidirectional_iterator >); +static_assert(!std::__legacy_bidirectional_iterator >); +static_assert(!std::__legacy_bidirectional_iterator >); + +static_assert(!std::__legacy_random_access_iterator >); +static_assert(!std::__legacy_random_access_iterator >); +static_assert(!std::__legacy_random_access_iterator >); +static_assert(!std::__legacy_random_access_iterator >); diff --git a/libcxx/test/std/iterators/iterator.primitives/iterator.traits/iter_reference_t.compile.pass.cpp b/libcxx/test/std/iterators/iterator.primitives/iterator.traits/iter_reference_t.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/iterators/iterator.primitives/iterator.traits/iter_reference_t.compile.pass.cpp @@ -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 + +// template +// using iter_reference_t = decltype(*declval()); + +#include + +#include + +#include "test_iterators.h" + +static_assert(std::same_as >, int&>); +static_assert(std::same_as >, int&>); +static_assert(std::same_as >, int&>); +static_assert(std::same_as >, int&>); diff --git a/libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/readable.traits/indirectly_readable_traits.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/readable.traits/indirectly_readable_traits.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/readable.traits/indirectly_readable_traits.compile.pass.cpp @@ -0,0 +1,187 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// template +// struct indirectly_readable_traits; + +#include + +#include +#include +#include +#include +#include + +// `value_type` and `element_type` member aliases aren't actually used to declare anytihng, so GCC +// thinks they're completely unused. +#pragma GCC diagnostic ignored "-Wunused-local-typedefs" + +// clang-format off +template +concept check_has_value_type = requires { + typename std::indirectly_readable_traits::value_type; +}; + +template +concept check_value_type_matches = + check_has_value_type && + std::same_as::value_type, Expected>; +// clang-format on + +template +constexpr bool check_pointer() { + constexpr bool result = check_value_type_matches; + static_assert(check_value_type_matches == result); + static_assert(check_value_type_matches == result); + static_assert(check_value_type_matches == result); + + static_assert(check_value_type_matches == result); + static_assert(check_value_type_matches == result); + static_assert(check_value_type_matches == result); + static_assert(check_value_type_matches == result); + + return result; +} + +static_assert(!check_pointer()); +static_assert(check_pointer()); +static_assert(check_pointer()); +static_assert(check_pointer()); +static_assert(check_pointer()); + +struct S {}; +static_assert(check_pointer()); + +template +constexpr bool check_array() { + constexpr bool result = check_value_type_matches; + static_assert(check_value_type_matches == result); + static_assert(check_value_type_matches == result); + static_assert(check_value_type_matches == result); + static_assert(check_value_type_matches == result); + static_assert(check_value_type_matches == result); + static_assert(check_value_type_matches == result); + static_assert(check_value_type_matches == result); + return result; +} + +static_assert(check_array()); +static_assert(check_array()); +static_assert(check_array()); +static_assert(check_array()); +static_assert(check_array()); + +template +constexpr bool check_explicit_member() { + constexpr bool result = check_value_type_matches; + static_assert(check_value_type_matches == result); + return result; +} + +struct has_value_type { + using value_type = int; +}; +static_assert(check_explicit_member()); +static_assert(check_explicit_member::iterator, int>()); + +struct has_element_type { + using element_type = S; +}; +static_assert(check_explicit_member()); + +struct has_same_value_and_element_type { + using value_type = int; + using element_type = int; +}; +static_assert(check_explicit_member()); +static_assert(check_explicit_member, long>()); +static_assert(check_explicit_member, long>()); + +// clang-format off +template +requires std::same_as, std::remove_cv_t > +struct possibly_different_cv_qualifiers { + using value_type = T; + using element_type = U; +}; +// clang-format on + +static_assert(check_explicit_member, int>()); +static_assert(check_explicit_member, int>()); +static_assert(check_explicit_member, int>()); +static_assert(check_explicit_member, int>()); +static_assert(check_explicit_member, int>()); +static_assert(check_explicit_member, int>()); +static_assert(check_explicit_member, int>()); +static_assert(check_explicit_member, int>()); +static_assert(check_explicit_member, int>()); +static_assert(check_explicit_member, int>()); +static_assert(check_explicit_member, int>()); +static_assert(check_explicit_member, int>()); +static_assert(check_explicit_member, int>()); +static_assert(check_explicit_member, int>()); +static_assert(check_explicit_member, int>()); +static_assert(check_explicit_member, int>()); + +struct S2 {}; +namespace std { +template <> +struct indirectly_readable_traits { + using value_type = int; +}; +} // namespace std +static_assert(check_value_type_matches); +static_assert(check_value_type_matches, int>); +static_assert(check_value_type_matches::iterator, int>); +static_assert(check_value_type_matches::const_iterator, int>); +static_assert(check_value_type_matches, int>); +static_assert(check_value_type_matches, char>); +static_assert(check_value_type_matches, int>); + +template +constexpr bool check_ref() { + struct ref_value { + using value_type = T&; + }; + constexpr bool result = check_has_value_type; + + struct ref_element { + using element_type = T&; + }; + static_assert(check_has_value_type == result); + + return result; +} + +static_assert(!check_ref()); +static_assert(!check_ref()); +static_assert(!check_ref >()); + +static_assert(!check_has_value_type); +static_assert(!check_has_value_type); +static_assert(!check_has_value_type); +static_assert(!check_has_value_type); + +struct has_different_value_and_element_type { + using value_type = int; + using element_type = long; +}; +static_assert(!check_has_value_type); + +struct void_value { + using value_type = void; +}; +static_assert(!check_has_value_type); + +struct void_element { + using element_type = void; +}; +static_assert(!check_has_value_type);