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,27 +17,18 @@ 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 -{ - typedef typename Iterator::difference_type difference_type; - typedef typename Iterator::value_type value_type; - typedef typename Iterator::pointer pointer; - typedef typename Iterator::reference reference; - typedef typename Iterator::iterator_category iterator_category; -}; +struct iterator_traits; template -struct iterator_traits -{ - typedef ptrdiff_t difference_type; - typedef T value_type; - typedef T* pointer; - typedef T& reference; - typedef random_access_iterator_tag iterator_category; -}; + requires is_object_v // since C++20 +struct iterator_traits; + +template + using iter_reference_t = decltype(*declval()); template @@ -428,7 +419,6 @@ #include <__memory/addressof.h> #include <__memory/pointer_traits.h> #include -#include #include <__debug> @@ -439,6 +429,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if !defined(_LIBCPP_HAS_NO_RANGES) + +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 +}; + // [incrementable.traits] template struct incrementable_traits {}; @@ -472,6 +476,56 @@ }; // 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 applies 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 {}; + +// [iterator.traits] +template<__dereferenceable _Tp> +using iter_reference_t = decltype(*declval<_Tp&>()); #endif // !defined(_LIBCPP_HAS_NO_RANGES) template @@ -570,6 +624,254 @@ static const bool value = sizeof(__test<_Tp>(nullptr)) == 1; }; +#if !defined(_LIBCPP_HAS_NO_RANGES) + +// The `cpp17-*-iterator` exposition-only concepts are easily confused with the Cpp17*Iterator tables, +// so they've been banished to a namespace that makes it obvious they have a niche use-case. +namespace __iterator_traits_detail { +template +concept __cpp17_iterator = + requires(_Ip __i) { + { *__i } -> __referenceable; + { ++__i } -> same_as<_Ip&>; + { *__i++ } -> __referenceable; + } && + copyable<_Ip>; + +template +concept __cpp17_input_iterator = + __cpp17_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 __cpp17_forward_iterator = + __cpp17_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 __cpp17_bidirectional_iterator = + __cpp17_forward_iterator<_Ip> && + requires(_Ip __i) { + { --__i } -> same_as<_Ip&>; + { __i-- } -> convertible_to<_Ip const&>; + { *__i-- } -> same_as>; + }; + +template +concept __cpp17_random_access_iterator = + __cpp17_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>; + }; +} // namespace __iterator_traits_detail + +template struct __iterator_traits; + +template +struct iterator_traits : __iterator_traits<_Ip> { + using __primary_template = iterator_traits; +}; + +template struct __iterator_traits_member_pointer; +template struct __iterator_traits_member_reference; +template struct __iterator_traits_iterator_category; + +template +concept __has_member_reference = requires { typename _Ip::reference; }; + +template +concept __has_member_pointer = requires { typename _Ip::pointer; }; + +template +concept __has_member_iterator_category = requires { typename _Ip::iterator_category; }; + +template +concept __specifies_members = + __has_member_reference<_Ip> && + __has_member_iterator_category<_Ip> && + requires { + typename _Ip::difference_type; + typename _Ip::value_type; + }; + +template +struct __iterator_traits_member_pointer_or_void { + using type = void; +}; + +template<__has_member_pointer _Tp> +struct __iterator_traits_member_pointer_or_void<_Tp> { + using type = typename _Tp::pointer; +}; + +// [iterator.traits]/3.1 +// If `I` has valid ([temp.deduct]) member types `difference_­type`, `value_­type`, `reference`, and +// `iterator_­category`, then `iterator_­traits` has the following publicly accessible members: +template<__specifies_members _Ip> +struct __iterator_traits<_Ip> { + using iterator_category = typename _Ip::iterator_category; + using value_type = typename _Ip::value_type; + using difference_type = typename _Ip::difference_type; + using pointer = typename __iterator_traits_member_pointer_or_void<_Ip>::type; + using reference = typename _Ip::reference; +}; + +namespace __iterator_traits_detail { +template +concept __cpp17_iterator_missing_members = + !__specifies_members<_Tp> && + __cpp17_iterator<_Tp>; + +template +concept __cpp17_input_iterator_missing_members = + __cpp17_iterator_missing_members<_Tp> && + __cpp17_input_iterator<_Tp>; +} // namespace __iterator_traits_detail + +// [iterator.traits]/3.2 +// Otherwise, if `I` satisfies the exposition-only concept `cpp17-input-iterator`, +// `iterator_­traits` has the following publicly accessible members: +template<__iterator_traits_detail::__cpp17_input_iterator_missing_members _Ip> +struct __iterator_traits<_Ip> { + using iterator_category = typename __iterator_traits_iterator_category<_Ip>::type; + using value_type = typename indirectly_readable_traits<_Ip>::value_type; + using difference_type = typename incrementable_traits<_Ip>::difference_type; + using pointer = typename __iterator_traits_member_pointer<_Ip>::type; + using reference = typename __iterator_traits_member_reference<_Ip>::type; +}; + +// [iterator.traits]/3.2.1 +// If the qualified-id `I::pointer` is valid and denotes a type, `pointer` names that type. +template<__has_member_pointer _Ip> +struct __iterator_traits_member_pointer<_Ip> { using type = typename _Ip::pointer; }; + +// Otherwise, if `decltype(declval().operator->())` is well-formed, then `pointer` names that +// type. +template +concept __has_arrow = + !__has_member_pointer<_Ip> && + requires(_Ip& __i) { + __i.operator->(); + }; + +template<__has_arrow _Ip> +struct __iterator_traits_member_pointer<_Ip> { + using type = decltype(declval<_Ip&>().operator->()); +}; + +// Otherwise, `pointer` names `void`. +template +struct __iterator_traits_member_pointer { using type = void; }; + +// [iterator.traits]/3.2.2 +// If the qualified-id `I::reference` is valid and denotes a type, `reference` names that type. +template<__has_member_reference _Ip> +struct __iterator_traits_member_reference<_Ip> { using type = typename _Ip::reference; }; + +// Otherwise, `reference` names `iter_­reference_­t`. +template +struct __iterator_traits_member_reference { using type = iter_reference_t<_Ip>; }; + +// [iterator.traits]/3.2.3 +// If the qualified-id `I::iterator_­category` is valid and denotes a type, `iterator_­category` names +// that type. +template<__has_member_iterator_category _Ip> +struct __iterator_traits_iterator_category<_Ip> { + using type = typename _Ip::iterator_category; +}; + +// Otherwise, iterator_­category names: +template +struct __deduce_iterator_category; + +template +struct __iterator_traits_iterator_category : __deduce_iterator_category<_Ip> {}; + +// [iterator.traits]/3.2.3.1 +// `random_­access_­iterator_­tag` if `I` satisfies `cpp17-random-access-iterator`, or otherwise +template<__iterator_traits_detail::__cpp17_random_access_iterator _Ip> +struct __deduce_iterator_category<_Ip> { + using type = random_access_iterator_tag; +}; + +// [iterator.traits]/3.2.3.2 +// `bidirectional_­iterator_­tag` if `I` satisfies `cpp17-bidirectional-iterator`, or otherwise +template<__iterator_traits_detail::__cpp17_bidirectional_iterator _Ip> +struct __deduce_iterator_category<_Ip> { + using type = bidirectional_iterator_tag; +}; + +// [iterator.traits]/3.2.3.3 +// `forward_­iterator_­tag` if `I` satisfies `cpp17-forward-iterator`, or otherwise +template<__iterator_traits_detail::__cpp17_forward_iterator _Ip> +struct __deduce_iterator_category<_Ip> { + using type = forward_iterator_tag; +}; + +// [iterator.traits]/3.2.3.4 +// input_­iterator_­tag +template +struct __deduce_iterator_category { + using type = input_iterator_tag; +}; + + +// [iterator.traits]/3.3 +template struct __iterator_traits_difference_type; + +// Otherwise, if `I` satisfies the exposition-only concept `cpp17-iterator`, then +// `iterator_­traits` has the following publicly accessible members: +template<__iterator_traits_detail::__cpp17_iterator_missing_members _Ip> +struct __iterator_traits<_Ip> { + using iterator_category = output_iterator_tag; + using value_type = void; + using difference_type = typename __iterator_traits_difference_type<_Ip>::type; + using pointer = void; + using reference = void; +}; + +// If the qualified-id `incrementable_­traits::difference_­type` is valid and denotes a type, then +// `difference_­type` names that type; +template +requires requires { typename incrementable_traits<_Ip>::difference_type; } +struct __iterator_traits_difference_type<_Ip> { + using type = typename incrementable_traits<_Ip>::difference_type; +}; + +// otherwise, it names void. +template +struct __iterator_traits_difference_type { using type = void; }; + +// [iterator.traits]/3.4 +// Otherwise, `iterator_­traits` has no members by any of the above names. +template +struct __iterator_traits {}; +#else +template struct __iterator_traits {}; + template struct __iterator_traits_impl {}; template @@ -582,8 +884,6 @@ typedef typename _Iter::iterator_category iterator_category; }; -template struct __iterator_traits {}; - template struct __iterator_traits<_Iter, true> : __iterator_traits_impl @@ -605,8 +905,12 @@ using __primary_template = iterator_traits; }; +#endif // !defined(_LIBCPP_HAS_NO_RANGES) template +#if !defined(_LIBCPP_HAS_NO_RANGES) +requires is_object_v<_Tp> +#endif struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> { typedef ptrdiff_t difference_type; diff --git a/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/iterator_traits_cpp17_iterators.h b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/iterator_traits_cpp17_iterators.h new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/iterator_traits_cpp17_iterators.h @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// 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 TEST_LIBCXX_ITERATORS_ITERATOR_REQUIREMENTS_ITERATOR_ASSOC_TYPES_ITERATOR_TRAITS_ITERATOR_TRAITS_CPP17_ITERATORS +#define TEST_LIBCXX_ITERATORS_ITERATOR_REQUIREMENTS_ITERATOR_ASSOC_TYPES_ITERATOR_TRAITS_ITERATOR_TRAITS_CPP17_ITERATORS + +struct iterator_traits_cpp17_iterator { + int& operator*(); + iterator_traits_cpp17_iterator& operator++(); + iterator_traits_cpp17_iterator operator++(int); +}; + +struct iterator_traits_cpp17_proxy_iterator { + int operator*(); + iterator_traits_cpp17_proxy_iterator& operator++(); + + // this returns legcay_iterator, not iterator_traits_cpp17_proxy_iterator + iterator_traits_cpp17_iterator operator++(int); +}; + +struct iterator_traits_cpp17_input_iterator { + using difference_type = int; + using value_type = long; + + int& operator*(); + iterator_traits_cpp17_input_iterator& operator++(); + iterator_traits_cpp17_input_iterator operator++(int); + + bool operator==(iterator_traits_cpp17_input_iterator const&) const; +}; + +struct iterator_traits_cpp17_proxy_input_iterator { + using difference_type = int; + using value_type = long; + + int operator*(); + iterator_traits_cpp17_proxy_input_iterator& operator++(); + + // this returns legcay_input_iterator, not iterator_traits_cpp17_proxy_input_iterator + iterator_traits_cpp17_input_iterator operator++(int); + + bool operator==(iterator_traits_cpp17_proxy_input_iterator const&) const; +}; + +struct iterator_traits_cpp17_forward_iterator { + using difference_type = int; + using value_type = int; + + int& operator*(); + iterator_traits_cpp17_forward_iterator& operator++(); + iterator_traits_cpp17_forward_iterator operator++(int); + + bool operator==(iterator_traits_cpp17_forward_iterator const&) const; +}; + +struct iterator_traits_cpp17_bidirectional_iterator { + using difference_type = int; + using value_type = int; + + int& operator*(); + iterator_traits_cpp17_bidirectional_iterator& operator++(); + iterator_traits_cpp17_bidirectional_iterator operator++(int); + iterator_traits_cpp17_bidirectional_iterator& operator--(); + iterator_traits_cpp17_bidirectional_iterator operator--(int); + + bool operator==(iterator_traits_cpp17_bidirectional_iterator const&) const; +}; + +struct iterator_traits_cpp17_random_access_iterator { + using difference_type = int; + using value_type = int; + + int& operator*(); + int& operator[](difference_type); + iterator_traits_cpp17_random_access_iterator& operator++(); + iterator_traits_cpp17_random_access_iterator operator++(int); + iterator_traits_cpp17_random_access_iterator& operator--(); + iterator_traits_cpp17_random_access_iterator operator--(int); + + bool operator==(iterator_traits_cpp17_random_access_iterator const&) const; + bool operator<(iterator_traits_cpp17_random_access_iterator const&) const; + bool operator>(iterator_traits_cpp17_random_access_iterator const&) const; + bool operator<=(iterator_traits_cpp17_random_access_iterator const&) const; + bool operator>=(iterator_traits_cpp17_random_access_iterator const&) const; + + iterator_traits_cpp17_random_access_iterator& operator+=(difference_type); + iterator_traits_cpp17_random_access_iterator& operator-=(difference_type); + + friend iterator_traits_cpp17_random_access_iterator operator+(iterator_traits_cpp17_random_access_iterator, + difference_type); + friend iterator_traits_cpp17_random_access_iterator operator+(difference_type, + iterator_traits_cpp17_random_access_iterator); + friend iterator_traits_cpp17_random_access_iterator operator-(iterator_traits_cpp17_random_access_iterator, + difference_type); + friend difference_type operator-(iterator_traits_cpp17_random_access_iterator, + iterator_traits_cpp17_random_access_iterator); +}; + +#endif // TEST_LIBCXX_ITERATORS_ITERATOR_REQUIREMENTS_ITERATOR_ASSOC_TYPES_ITERATOR_TRAITS_ITERATOR_TRAITS_CPP17_ITERATORS 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,183 @@ +//===----------------------------------------------------------------------===// +// +// 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 __iterator_traits_detail::__cpp17_bidirectional_iterator; + +#include + +#include +#include +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iterator_traits_cpp17_iterators.h" + +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert( + std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert( + std::__iterator_traits_detail::__cpp17_bidirectional_iterator); + +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator); + +// +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::reverse_iterator>); +static_assert( + std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_reverse_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_reverse_iterator>); + +// +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +#endif + +// +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator::iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_iterator>); + +// +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator > >); +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator > >); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator > >); +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator::iterator> >); + +// +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_reverse_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::reverse_iterator>); +static_assert( + std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_reverse_iterator>); + +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::reverse_iterator>); +static_assert( + std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_reverse_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_reverse_iterator>); + +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::reverse_iterator>); +static_assert( + std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_reverse_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator); + +// +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator); + +// +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator::iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator::local_iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_local_iterator>); + +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator::iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator::local_iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator< + std::unordered_multimap::const_local_iterator>); + +// +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator::iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator::local_iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_local_iterator>); + +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator::iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator::local_iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_local_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator::const_reverse_iterator>); + +// Not iterators +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator::iterator volatile>); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator::iterator&>); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator::iterator&&>); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator); + +struct S {}; +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_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,167 @@ +//===----------------------------------------------------------------------===// +// +// 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 __iterator_traits_detail::__cpp17_forward_iterator; + +#include + +#include +#include +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iterator_traits_cpp17_iterators.h" + +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator); + +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator); + +// +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_reverse_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_reverse_iterator>); + +// +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator); +#endif + +// +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_iterator>); + +// +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator > >); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator > >); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator > >); +static_assert( + !std::__iterator_traits_detail::__cpp17_forward_iterator::iterator> >); + +// +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_reverse_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_reverse_iterator>); + +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_reverse_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_reverse_iterator>); + +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_reverse_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator); + +// +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator); + +// +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::local_iterator>); +static_assert( + std::__iterator_traits_detail::__cpp17_forward_iterator::const_local_iterator>); + +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::iterator>); +static_assert( + std::__iterator_traits_detail::__cpp17_forward_iterator::const_iterator>); +static_assert( + std::__iterator_traits_detail::__cpp17_forward_iterator::local_iterator>); +static_assert( + std::__iterator_traits_detail::__cpp17_forward_iterator::const_local_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::local_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_local_iterator>); + +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::local_iterator>); +static_assert( + std::__iterator_traits_detail::__cpp17_forward_iterator::const_local_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator::const_reverse_iterator>); + +// Not iterators +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator::iterator volatile>); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator::iterator&>); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator::iterator&&>); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator); + +struct S {}; +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_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,164 @@ +//===----------------------------------------------------------------------===// +// +// 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 __iterator_traits_detail::__cpp17_input_iterator; + +#include + +#include +#include +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iterator_traits_cpp17_iterators.h" + +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); + +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); + +// +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_reverse_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_reverse_iterator>); + +// +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); +#endif + +// +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_iterator>); + +// +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator > >); +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator > >); +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator > >); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::iterator> >); + +// +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_reverse_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_reverse_iterator>); + +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_reverse_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_reverse_iterator>); + +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_reverse_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); + +// +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator); + +// +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::local_iterator>); +static_assert( + std::__iterator_traits_detail::__cpp17_input_iterator::const_local_iterator>); + +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::local_iterator>); +static_assert( + std::__iterator_traits_detail::__cpp17_input_iterator::const_local_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::local_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_local_iterator>); + +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::local_iterator>); +static_assert( + std::__iterator_traits_detail::__cpp17_input_iterator::const_local_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator::const_reverse_iterator>); + +// Not iterators +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator::iterator volatile>); +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator::iterator&>); +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator::iterator&&>); +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator); + +struct S {}; +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_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,161 @@ +//===----------------------------------------------------------------------===// +// +// 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 __iterator_traits_detail::__cpp17_iterator; + +#include + +#include +#include +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iterator_traits_cpp17_iterators.h" + +static_assert(std::__iterator_traits_detail::__cpp17_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_iterator); + +static_assert(std::__iterator_traits_detail::__cpp17_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_iterator); + +// +static_assert(std::__iterator_traits_detail::__cpp17_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_reverse_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_reverse_iterator>); + +// +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +static_assert(std::__iterator_traits_detail::__cpp17_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_iterator); +#endif + +// +static_assert(std::__iterator_traits_detail::__cpp17_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_iterator > >); +static_assert(std::__iterator_traits_detail::__cpp17_iterator > >); +static_assert(std::__iterator_traits_detail::__cpp17_iterator > >); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::iterator> >); + +// +static_assert(std::__iterator_traits_detail::__cpp17_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_reverse_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_reverse_iterator>); + +static_assert(std::__iterator_traits_detail::__cpp17_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_reverse_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_reverse_iterator>); + +static_assert(std::__iterator_traits_detail::__cpp17_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_reverse_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_iterator); + +// +static_assert(std::__iterator_traits_detail::__cpp17_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_iterator); + +// +static_assert(std::__iterator_traits_detail::__cpp17_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::local_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_local_iterator>); + +static_assert(std::__iterator_traits_detail::__cpp17_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::local_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_local_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::local_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_local_iterator>); + +static_assert(std::__iterator_traits_detail::__cpp17_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::local_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_local_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_iterator::const_reverse_iterator>); + +// Not iterators +static_assert(!std::__iterator_traits_detail::__cpp17_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_iterator::iterator volatile>); +static_assert(!std::__iterator_traits_detail::__cpp17_iterator::iterator&>); +static_assert(!std::__iterator_traits_detail::__cpp17_iterator::iterator&&>); +static_assert(!std::__iterator_traits_detail::__cpp17_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_iterator); + +struct S {}; +static_assert(!std::__iterator_traits_detail::__cpp17_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_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,184 @@ +//===----------------------------------------------------------------------===// +// +// 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 __iterator_traits_detail::__cpp17_random_access_iterator; + +#include + +#include +#include +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iterator_traits_cpp17_iterators.h" + +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert( + std::__iterator_traits_detail::__cpp17_random_access_iterator); + +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator); + +// +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator::reverse_iterator>); +static_assert( + std::__iterator_traits_detail::__cpp17_random_access_iterator::const_reverse_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator::const_reverse_iterator>); + +// +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator); +#endif + +// +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::const_iterator>); + +// +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator > >); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator > >); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator > >); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator::iterator> >); + +// +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::const_iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::reverse_iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::const_reverse_iterator>); + +// +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::const_iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::reverse_iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator::const_reverse_iterator>); + +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::const_iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator::reverse_iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator::const_reverse_iterator>); + +// +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::const_iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::reverse_iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::const_reverse_iterator>); + +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::const_iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::reverse_iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator::const_reverse_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator); + +// +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator); + +// +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator::const_iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator::local_iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator::const_local_iterator>); + +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator::iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator::const_iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator::local_iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator< + std::unordered_multimap::const_local_iterator>); + +// +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::const_iterator>); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::local_iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator::const_local_iterator>); + +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator::const_iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator::local_iterator>); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator::const_local_iterator>); + +// +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator::iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator::const_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator::reverse_iterator>); +static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator::const_reverse_iterator>); + +// Not iterators +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::iterator volatile>); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::iterator&>); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator::iterator&&>); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator); + +struct S {}; +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator); +static_assert(!std::__iterator_traits_detail::__cpp17_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,53 @@ +//===----------------------------------------------------------------------===// +// +// 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::__iterator_traits_detail::__cpp17_iterator >); +static_assert(std::__iterator_traits_detail::__cpp17_iterator >); +static_assert(std::__iterator_traits_detail::__cpp17_iterator >); +static_assert(std::__iterator_traits_detail::__cpp17_iterator >); + +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator >); +static_assert(std::__iterator_traits_detail::__cpp17_input_iterator >); +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator >); +static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator >); + +// This is because the legacy iterator concepts don't care about iterator_category +static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator >); + +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator >); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator >); +static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator >); + +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator >); +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator >); +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator >); +static_assert( + !std::__iterator_traits_detail::__cpp17_bidirectional_iterator >); + +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator >); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator >); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator >); +static_assert( + !std::__iterator_traits_detail::__cpp17_random_access_iterator >); diff --git a/libcxx/test/std/iterators/iterator.primitives/iterator.traits/cxx20_iterator_traits.compile.pass.cpp b/libcxx/test/std/iterators/iterator.primitives/iterator.traits/cxx20_iterator_traits.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/iterators/iterator.primitives/iterator.traits/cxx20_iterator_traits.compile.pass.cpp @@ -0,0 +1,478 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// struct iterator_traits; + +#include + +#include "test_macros.h" +#include "test_iterators.h" +#include "legacy_iterator_wrappers.h" + +template +constexpr bool has_iterator_concept_v = requires { + typename Traits::iterator_concept; +}; + +using PointerIteratorTraits = std::iterator_traits; +static_assert(std::same_as); +static_assert(std::same_as); +static_assert( + std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); + +using ConstPointerIteratorTraits = std::iterator_traits; +static_assert(std::same_as); +static_assert(std::same_as); +static_assert( + std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); + +struct AllMembers { + struct iterator_category {}; + struct value_type {}; + struct difference_type {}; + struct reference {}; + struct pointer {}; +}; +using AllMembersTraits = std::iterator_traits; +static_assert(std::same_as); +static_assert( + std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +struct NoPointerMember { + struct iterator_category {}; + struct value_type {}; + struct difference_type {}; + struct reference {}; + // TODO + value_type* + operator->() const; // ignored, because B is not a LegacyInputIterator +}; +using NoPointerMemberTraits = std::iterator_traits; +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert( + std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +struct IterConcept { + struct iterator_category {}; + struct iterator_concept {}; // ignored + struct value_type {}; + struct difference_type {}; + struct reference {}; + struct pointer {}; +}; +using IterConceptTraits = std::iterator_traits; +static_assert(std::same_as); +static_assert( + std::same_as); +static_assert(std::same_as); +static_assert( + std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +struct LegacyInput { + struct iterator_category {}; + struct value_type {}; + struct reference { + operator value_type() const; + }; + + friend bool operator==(LegacyInput, LegacyInput); + reference operator*() const; + LegacyInput& operator++(); + LegacyInput operator++(int); +}; +template <> +struct std::incrementable_traits { + using difference_type = short; +}; +using LegacyInputTraits = std::iterator_traits; +static_assert(std::same_as); +static_assert( + std::same_as); +static_assert(std::same_as); +static_assert( + std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +struct LegacyInputNoValueType { + struct not_value_type {}; + using difference_type = int; // or any signed integral type + struct reference { + operator not_value_type() const; + }; + + friend bool operator==(LegacyInputNoValueType, LegacyInputNoValueType); + reference operator*() const; + LegacyInputNoValueType& operator++(); + LegacyInputNoValueType operator++(int); +}; +template <> +struct std::indirectly_readable_traits { + using value_type = LegacyInputNoValueType::not_value_type; +}; +using LegacyInputNoValueTypeTraits = + std::iterator_traits; +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +struct LegacyForward { + struct not_value_type {}; + + friend bool operator==(LegacyForward, LegacyForward); + const not_value_type& operator*() const; + LegacyForward& operator++(); + LegacyForward operator++(int); +}; +template <> +struct std::indirectly_readable_traits { + using value_type = LegacyForward::not_value_type; +}; +template <> +struct std::incrementable_traits { + using difference_type = short; // or any signed integral type +}; +using LegacyForwardTraits = std::iterator_traits; +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +struct LegacyBidirectional { + struct value_type {}; + + friend bool operator==(LegacyBidirectional, LegacyBidirectional); + const value_type& operator*() const; + LegacyBidirectional& operator++(); + LegacyBidirectional operator++(int); + LegacyBidirectional& operator--(); + LegacyBidirectional operator--(int); + friend short operator-(LegacyBidirectional, LegacyBidirectional); +}; +using LegacyBidirectionalTraits = std::iterator_traits; +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +// Almost a random access iterator except it is missing operator-(It, It). +struct MissingMinusIterIter { + struct value_type {}; + + friend auto operator<=>(MissingMinusIterIter, MissingMinusIterIter) = default; + const value_type& operator*() const; + const value_type& operator[](long) const; + MissingMinusIterIter& operator++(); + MissingMinusIterIter operator++(int); + MissingMinusIterIter& operator--(); + MissingMinusIterIter operator--(int); + MissingMinusIterIter& operator+=(long); + MissingMinusIterIter& operator-=(long); + + // Providing difference_type does not fully compensate for missing operator-(It, It). + friend MissingMinusIterIter operator-(MissingMinusIterIter, int); + friend MissingMinusIterIter operator+(MissingMinusIterIter, int); + friend MissingMinusIterIter operator+(int, MissingMinusIterIter); +}; +template <> +struct std::incrementable_traits { + using difference_type = short; +}; +using MissingMinusIterIterTraits = std::iterator_traits; +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +struct WrongSubscriptReturnType { + struct value_type {}; + + friend auto operator<=>(WrongSubscriptReturnType, + WrongSubscriptReturnType) = default; + // The type of it[n] is not convertible to the type of *it; therefore, this is not random-access. + value_type& operator*() const; + const value_type& operator[](long) const; + WrongSubscriptReturnType& operator++(); + WrongSubscriptReturnType operator++(int); + WrongSubscriptReturnType& operator--(); + WrongSubscriptReturnType operator--(int); + WrongSubscriptReturnType& operator+=(long); + WrongSubscriptReturnType& operator-=(long); + friend short operator-(WrongSubscriptReturnType, WrongSubscriptReturnType); + friend WrongSubscriptReturnType operator-(WrongSubscriptReturnType, int); + friend WrongSubscriptReturnType operator+(WrongSubscriptReturnType, int); + friend WrongSubscriptReturnType operator+(int, WrongSubscriptReturnType); +}; +using WrongSubscriptReturnTypeTraits = + std::iterator_traits; +static_assert(std::same_as); +static_assert(std::same_as); +static_assert( + std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +struct LegacyRandomAccess { + struct value_type {}; + + friend bool operator==(LegacyRandomAccess, LegacyRandomAccess); + friend bool operator<(LegacyRandomAccess, LegacyRandomAccess); + friend bool operator<=(LegacyRandomAccess, LegacyRandomAccess); + friend bool operator>(LegacyRandomAccess, LegacyRandomAccess); + friend bool operator>=(LegacyRandomAccess, LegacyRandomAccess); + const value_type& operator*() const; + const value_type& operator[](long) const; + LegacyRandomAccess& operator++(); + LegacyRandomAccess operator++(int); + LegacyRandomAccess& operator--(); + LegacyRandomAccess operator--(int); + LegacyRandomAccess& operator+=(long); + LegacyRandomAccess& operator-=(long); + friend short operator-(LegacyRandomAccess, LegacyRandomAccess); + friend LegacyRandomAccess operator-(LegacyRandomAccess, int); + friend LegacyRandomAccess operator+(LegacyRandomAccess, int); + friend LegacyRandomAccess operator+(int, LegacyRandomAccess); +}; +using LegacyRandomAccessTraits = std::iterator_traits; +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +struct LegacyRandomAccessSpaceship { + struct not_value_type {}; + struct ReferenceConvertible { + operator not_value_type&() const; + }; + + friend auto operator<=>(LegacyRandomAccessSpaceship, + LegacyRandomAccessSpaceship) = default; + not_value_type& operator*() const; + ReferenceConvertible operator[](long) const; + LegacyRandomAccessSpaceship& operator++(); + LegacyRandomAccessSpaceship operator++(int); + LegacyRandomAccessSpaceship& operator--(); + LegacyRandomAccessSpaceship operator--(int); + LegacyRandomAccessSpaceship& operator+=(long); + LegacyRandomAccessSpaceship& operator-=(long); + friend short operator-(LegacyRandomAccessSpaceship, + LegacyRandomAccessSpaceship); + friend LegacyRandomAccessSpaceship operator-(LegacyRandomAccessSpaceship, + int); + friend LegacyRandomAccessSpaceship operator+(LegacyRandomAccessSpaceship, + int); + friend LegacyRandomAccessSpaceship operator+(int, + LegacyRandomAccessSpaceship); +}; +template <> +struct std::indirectly_readable_traits { + using value_type = LegacyRandomAccessSpaceship::not_value_type; +}; +template <> +struct std::incrementable_traits { + using difference_type = short; // or any signed integral type +}; +using LegacyRandomAccessSpaceshipTraits = + std::iterator_traits; +static_assert(std::same_as); +static_assert(std::same_as); +static_assert( + std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +// For output iterators, value_type, difference_type, and reference may be void. +struct BareLegacyOutput { + struct Empty {}; + Empty operator*() const; + BareLegacyOutput& operator++(); + BareLegacyOutput operator++(int); +}; +using BareLegacyOutputTraits = std::iterator_traits; +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +// The operator- means we get difference_type. +struct LegacyOutputWithMinus { + struct Empty {}; + Empty operator*() const; + LegacyOutputWithMinus& operator++(); + LegacyOutputWithMinus operator++(int); + friend short operator-(LegacyOutputWithMinus, LegacyOutputWithMinus); + // Lacking operator==, this is a LegacyIterator but not a LegacyInputIterator. +}; +using LegacyOutputWithMinusTraits = std::iterator_traits; +static_assert(std::same_as); +static_assert(std::same_as); +static_assert( + std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +struct LegacyOutputWithMemberTypes { + struct value_type {}; // ignored + struct reference {}; // ignored + using difference_type = long; + + friend bool operator==(LegacyOutputWithMemberTypes, + LegacyOutputWithMemberTypes); + reference operator*() const; + LegacyOutputWithMemberTypes& operator++(); + LegacyOutputWithMemberTypes operator++(int); + friend short operator-(LegacyOutputWithMemberTypes, + LegacyOutputWithMemberTypes); // ignored + // Since (*it) is not convertible to value_type, this is not a LegacyInputIterator. +}; +using LegacyOutputWithMemberTypesTraits = + std::iterator_traits; +static_assert(std::same_as); +static_assert( + std::same_as); +static_assert( + std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +using InputTestItereatorTraits = std::iterator_traits >; +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +using OutputTestItereatorTraits = std::iterator_traits >; +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +using ForwardTestIteratorTraits = std::iterator_traits >; +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +using BidirectionalTestIteratorTraits = + std::iterator_traits >; +static_assert(std::same_as); +static_assert(std::same_as); +static_assert( + std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +using RandomAccessTestIteratorTraits = + std::iterator_traits >; +static_assert(std::same_as); +static_assert(std::same_as); +static_assert( + std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +using ContiguousTestIteratorTraits = + std::iterator_traits >; +static_assert(std::same_as); +static_assert(std::same_as); +static_assert( + std::same_as); +static_assert(std::same_as); +static_assert(std::same_as); +static_assert(!has_iterator_concept_v); + +// TODO: add back tests for standard types. + diff --git a/libcxx/test/std/iterators/iterator.primitives/iterator.traits/empty.fail.cpp b/libcxx/test/std/iterators/iterator.primitives/iterator.traits/empty.fail.cpp --- a/libcxx/test/std/iterators/iterator.primitives/iterator.traits/empty.fail.cpp +++ b/libcxx/test/std/iterators/iterator.primitives/iterator.traits/empty.fail.cpp @@ -91,7 +91,7 @@ typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std:{{.*}}:iterator_traits<{{.+}}>}} typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std:{{.*}}:iterator_traits<{{.+}}>}} } - +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_HAS_NO_CONCEPTS) { typedef std::iterator_traits T; typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std:{{.*}}:iterator_traits<{{.+}}>}} @@ -100,7 +100,7 @@ typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std:{{.*}}:iterator_traits<{{.+}}>}} typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std:{{.*}}:iterator_traits<{{.+}}>}} } - +#endif { typedef std::iterator_traits T; typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std:{{.*}}:iterator_traits<{{.+}}>}} diff --git a/libcxx/test/std/iterators/iterator.primitives/iterator.traits/empty.pass.cpp b/libcxx/test/std/iterators/iterator.primitives/iterator.traits/empty.pass.cpp --- a/libcxx/test/std/iterators/iterator.primitives/iterator.traits/empty.pass.cpp +++ b/libcxx/test/std/iterators/iterator.primitives/iterator.traits/empty.pass.cpp @@ -36,6 +36,9 @@ { typedef std::iterator_traits It; static_assert(!(has_value_type::value), ""); +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) + static_assert(!(has_value_type >::value)); +#endif - return 0; + return 0; } 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.primitives/iterator.traits/legacy_iterator_wrappers.h b/libcxx/test/std/iterators/iterator.primitives/iterator.traits/legacy_iterator_wrappers.h new file mode 100644 --- /dev/null +++ b/libcxx/test/std/iterators/iterator.primitives/iterator.traits/legacy_iterator_wrappers.h @@ -0,0 +1,125 @@ +//===----------------------------------------------------------------------===// +// +// 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 STD_ITERATORS_ITERATOR_PRIMITIVES_ITERATOR_TRAITS_LEGACY_ITERATORS_H +#define STD_ITERATORS_ITERATOR_PRIMITIVES_ITERATOR_TRAITS_LEGACY_ITERATORS_H + +template +concept has_arrow = requires(I& i) { + i.operator->(); +}; + +// Extension point for `legacy_iterator_wrapper` to support `operator->`. +template +struct arrow_extension { + decltype(std::declval().operator->()) operator->() const; +}; + +// Wrapper around a legacy C++ iterator to give it a minimal interface. +// +// The key difference between these `legacy.*_iterator` types and those found in +// `support/test_iterators.h` is that the legacy iterator class are designed to support mixins and +// specifically test C++20's changes to `iterator_traits`. Namely, the absence of members and the +// arrow operator is important. +template class... Args> +class legacy_iterator : public Args... { +public: + legacy_iterator() = default; + explicit legacy_iterator(I i) : base_(i) {} + + decltype(auto) operator*() const { return *base_; } + + legacy_iterator& operator++(); + legacy_iterator operator++(int); + +private: + I base_ = I(); +}; + +// Wrapper around a legacy C++ input iterator to give it a minimal interface. +template class... Args> +class legacy_input_iterator : public legacy_iterator { +public: + using iterator_category = std::input_iterator_tag; + using difference_type = typename std::incrementable_traits::difference_type; + using value_type = typename std::indirectly_readable_traits::value_type; + + using legacy_iterator::legacy_iterator; + bool operator==(legacy_input_iterator const&) const; + legacy_input_iterator& operator++(); + legacy_input_iterator operator++(int); +}; + +// Wrapper around a legacy C++ forward iterator to give it a minimal interface. +template class... Args> +class legacy_forward_iterator : public legacy_input_iterator { +public: + using iterator_category = std::forward_iterator_tag; + using legacy_input_iterator::legacy_input_iterator; + + legacy_forward_iterator& operator++(); + legacy_forward_iterator operator++(int); +}; + +// Wrapper around a legacy C++ bidirectional iterator to give it a minimal interface. +template class... Args> +class legacy_bidirectional_iterator : public legacy_forward_iterator { +public: + using iterator_category = std::bidirectional_iterator_tag; + using legacy_forward_iterator::legacy_forward_iterator; + + legacy_bidirectional_iterator& operator++(); + legacy_bidirectional_iterator operator++(int); + legacy_bidirectional_iterator& operator--(); + legacy_bidirectional_iterator operator--(int); +}; + +// Wrapper around a legacy C++ random-access iterator to give it a minimal interface. +template class... Args> +class legacy_random_access_iterator : public legacy_bidirectional_iterator { +public: + using iterator_category = std::random_access_iterator_tag; + using legacy_bidirectional_iterator::legacy_bidirectional_iterator; + using typename legacy_bidirectional_iterator::difference_type; + + legacy_random_access_iterator& operator++(); + legacy_random_access_iterator operator++(int); + legacy_random_access_iterator& operator--(); + legacy_random_access_iterator operator--(int); + legacy_random_access_iterator& operator+=(difference_type); + legacy_random_access_iterator& operator-=(difference_type); + + friend legacy_random_access_iterator operator+(legacy_random_access_iterator, difference_type); + friend legacy_random_access_iterator operator+(difference_type, legacy_random_access_iterator); + friend legacy_random_access_iterator operator-(legacy_random_access_iterator, difference_type); + + difference_type operator-(legacy_random_access_iterator) const; + decltype(auto) operator[](difference_type const n) const { return *(*this + n); } + bool operator<(legacy_random_access_iterator) const; + bool operator>(legacy_random_access_iterator) const; + bool operator<=(legacy_random_access_iterator) const; + bool operator>=(legacy_random_access_iterator) const; +}; + +// Extension point for reference member. +template +struct reference_extension { + using reference = typename I::reference; +}; + +// Extension point for pointer member. +template +struct pointer_extension { + using pointer = typename I::pointer; +}; + +// Extension point to indicate no extension points. +// This is used for function overloading when there isn't a better name for two overloads. +template +struct empty_extension {}; + +#endif // STD_ITERATORS_ITERATOR_PRIMITIVES_ITERATOR_TRAITS_LEGACY_ITERATORS_H 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);