diff --git a/libcxx/docs/Cxx2aStatusPaperStatus.csv b/libcxx/docs/Cxx2aStatusPaperStatus.csv --- a/libcxx/docs/Cxx2aStatusPaperStatus.csv +++ b/libcxx/docs/Cxx2aStatusPaperStatus.csv @@ -61,7 +61,7 @@ "`P0608R3 `__","LWG","A sane variant converting constructor","San Diego","|Complete|","9.0" "`P0655R1 `__","LWG","visit: Explicit Return Type for visit","San Diego","|Complete|","12.0" "`P0771R1 `__","LWG","std::function move constructor should be noexcept","San Diego","|Complete|","6.0" -"`P0896R4 `__","LWG","The One Ranges Proposal","San Diego","* *","" +"`P0896R4 `__","LWG","The One Ranges Proposal","San Diego","|In Progress|","" "`P0899R1 `__","LWG","P0899R1 - LWG 3016 is not a defect","San Diego","|Nothing To Do|","" "`P0919R3 `__","LWG","Heterogeneous lookup for unordered containers","San Diego","|Complete|","12.0" "`P0972R0 `__","LWG"," ``zero()``\ , ``min()``\ , and ``max()``\ should be noexcept","San Diego","|Complete|","8.0" diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -848,6 +848,10 @@ #define _LIBCPP_HAS_NO_CONCEPTS #endif +#if _LIBCPP_STD_VER < 20 || defined(_LIBCPP_HAS_NO_CONCEPTS) +#define _LIBCPP_HAS_NO_RANGES +#endif + #ifdef _LIBCPP_CXX03_LANG # define _LIBCPP_DEFAULT {} #else diff --git a/libcxx/include/iterator b/libcxx/include/iterator --- a/libcxx/include/iterator +++ b/libcxx/include/iterator @@ -13,8 +13,11 @@ /* iterator synopsis +#include + namespace std { +template struct incrementable_traits; // since C++20 template struct iterator_traits @@ -423,6 +426,7 @@ #include <__memory/base.h> #include <__memory/pointer_traits.h> #include +#include #include <__debug> @@ -431,6 +435,43 @@ #endif _LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) +// [incrementable.traits] +template struct incrementable_traits {}; + +template +requires is_object_v<_Tp> +struct incrementable_traits<_Tp*> { + using difference_type = ptrdiff_t; +}; + +template +struct incrementable_traits : incrementable_traits<_Ip> {}; + +template +concept __has_member_difference_type = requires { typename _Tp::difference_type; }; + +template<__has_member_difference_type _Tp> +struct incrementable_traits<_Tp> { + using difference_type = typename _Tp::difference_type; +}; + +template +concept __has_integral_minus = + !__has_member_difference_type<_Tp> && + requires(const _Tp& __x, const _Tp& __y) { + { __x - __y } -> integral; + }; + +template<__has_integral_minus _Tp> +struct incrementable_traits<_Tp> { + using difference_type = make_signed_t() - declval<_Tp>())>; +}; + +// TODO(cjdb): add iter_difference_t once iterator_traits is cleaned up. +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + template struct _LIBCPP_TEMPLATE_VIS iterator_traits; diff --git a/libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/incrementable.traits/incrementable_traits.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/incrementable.traits/incrementable_traits.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/incrementable.traits/incrementable_traits.pass.cpp @@ -0,0 +1,704 @@ +//===----------------------------------------------------------------------===// +// +// 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 incrementable_traits; + +#include + +#include + +// clang-format off +template +concept check_has_difference_type = requires { + typename std::incrementable_traits::difference_type; +}; + +template +concept check_difference_type_matches = + check_has_difference_type && + std::same_as::difference_type, Expected>; +// clang-format on + +template +[[nodiscard]] constexpr bool check_incrementable_traits() noexcept { + constexpr bool result = check_difference_type_matches; + static_assert(check_difference_type_matches == result); + return result; +} + +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); +static_assert( + check_incrementable_traits()); +static_assert(check_incrementable_traits()); + +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); + +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); + +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); + +static_assert(check_incrementable_traits()); +static_assert(check_incrementable_traits()); + +struct integral_difference_type { + using difference_type = int; +}; +static_assert(check_incrementable_traits()); + +struct non_integral_difference_type { + using difference_type = void; +}; +static_assert(check_incrementable_traits()); + +struct int_subtraction { + friend int operator-(int_subtraction, int_subtraction) noexcept; +}; +static_assert(check_incrementable_traits()); +static_assert(!check_incrementable_traits()); +static_assert( + !check_incrementable_traits()); + +struct char_subtraction { + friend char operator-(char_subtraction, char_subtraction) noexcept; +}; +static_assert(check_incrementable_traits()); + +struct unsigned_int_subtraction_with_cv { + friend unsigned int + operator-(unsigned_int_subtraction_with_cv const&, + unsigned_int_subtraction_with_cv const&) noexcept; + friend unsigned int + operator-(unsigned_int_subtraction_with_cv const volatile&, + unsigned_int_subtraction_with_cv const volatile&) noexcept; +}; +static_assert( + check_incrementable_traits()); +static_assert(check_incrementable_traits< + unsigned_int_subtraction_with_cv volatile&, int>()); +static_assert(check_incrementable_traits< + unsigned_int_subtraction_with_cv const volatile&, int>()); + +struct specialised_incrementable_traits {}; +namespace std { +template <> +struct incrementable_traits { + using difference_type = int; +}; +} // namespace std +static_assert( + check_incrementable_traits()); + +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); + +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); + +struct empty {}; +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert( + !check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert( + !check_has_difference_type); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type < int (empty::*)() && noexcept >); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type < int (empty::*)() const&& noexcept >); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type < + int (empty::*)() volatile&& noexcept >); +static_assert(!check_has_difference_type); +static_assert(!check_has_difference_type < int (empty::*)() + const volatile&& noexcept >); + +struct void_subtraction { + friend void operator-(void_subtraction, void_subtraction) noexcept; +}; +static_assert(!check_has_difference_type); + +struct rvalue_ref_subtraction_can_throw { + friend int operator-(rvalue_ref_subtraction_can_throw&&, + rvalue_ref_subtraction_can_throw&&); +}; +static_assert(!check_has_difference_type); + +struct lvalue_ref_lvalue_ref_subtraction { + friend int operator-(lvalue_ref_lvalue_ref_subtraction&, + lvalue_ref_lvalue_ref_subtraction&); +}; +static_assert(!check_has_difference_type); + +struct lvalue_ref_const_lvalue_ref_subtraction { + friend int operator-(lvalue_ref_const_lvalue_ref_subtraction&, + lvalue_ref_const_lvalue_ref_subtraction const&); +}; +static_assert( + !check_has_difference_type); + +struct lvalue_ref_volatile_lvalue_ref_subtraction { + friend int operator-(lvalue_ref_volatile_lvalue_ref_subtraction&, + lvalue_ref_volatile_lvalue_ref_subtraction volatile&); +}; +static_assert( + !check_has_difference_type); + +struct lvalue_ref_cv_lvalue_ref_subtraction { + friend int operator-(lvalue_ref_cv_lvalue_ref_subtraction&, + lvalue_ref_cv_lvalue_ref_subtraction const volatile&); +}; +static_assert(!check_has_difference_type); + +struct lvalue_ref_rvalue_ref_subtraction { + friend int operator-(lvalue_ref_rvalue_ref_subtraction&, + lvalue_ref_rvalue_ref_subtraction&&); +}; +static_assert(!check_has_difference_type); + +struct lvalue_ref_const_rvalue_ref_subtraction { + friend int operator-(lvalue_ref_const_rvalue_ref_subtraction&, + lvalue_ref_const_rvalue_ref_subtraction const&&); +}; +static_assert( + !check_has_difference_type); + +struct lvalue_ref_volatile_rvalue_ref_subtraction { + friend int operator-(lvalue_ref_volatile_rvalue_ref_subtraction&, + lvalue_ref_volatile_rvalue_ref_subtraction volatile&&); +}; +static_assert( + !check_has_difference_type); + +struct lvalue_ref_cv_rvalue_ref_subtraction { + friend int operator-(lvalue_ref_cv_rvalue_ref_subtraction&, + lvalue_ref_cv_rvalue_ref_subtraction const volatile&&); +}; +static_assert(!check_has_difference_type); + +struct const_lvalue_ref_lvalue_ref_subtraction { + friend int operator-(const_lvalue_ref_lvalue_ref_subtraction const&, + const_lvalue_ref_lvalue_ref_subtraction&); +}; +static_assert( + !check_has_difference_type); + +struct const_lvalue_ref_volatile_lvalue_ref_subtraction { + friend int + operator-(const_lvalue_ref_volatile_lvalue_ref_subtraction const&, + const_lvalue_ref_volatile_lvalue_ref_subtraction volatile&); +}; +static_assert(!check_has_difference_type< + const_lvalue_ref_volatile_lvalue_ref_subtraction>); + +struct const_lvalue_ref_rvalue_ref_subtraction { + friend int operator-(const_lvalue_ref_rvalue_ref_subtraction const&, + const_lvalue_ref_rvalue_ref_subtraction&&); +}; +static_assert( + !check_has_difference_type); + +struct const_lvalue_ref_const_rvalue_ref_subtraction { + friend int operator-(const_lvalue_ref_const_rvalue_ref_subtraction const&, + const_lvalue_ref_const_rvalue_ref_subtraction const&&); +}; +static_assert( + !check_has_difference_type); + +struct const_lvalue_ref_volatile_rvalue_ref_subtraction { + friend int + operator-(const_lvalue_ref_volatile_rvalue_ref_subtraction const&, + const_lvalue_ref_volatile_rvalue_ref_subtraction volatile&&); +}; +static_assert(!check_has_difference_type< + const_lvalue_ref_volatile_rvalue_ref_subtraction>); + +struct const_lvalue_ref_cv_rvalue_ref_subtraction { + friend int + operator-(const_lvalue_ref_cv_rvalue_ref_subtraction const&, + const_lvalue_ref_cv_rvalue_ref_subtraction const volatile&&); +}; +static_assert( + !check_has_difference_type); + +struct volatile_lvalue_ref_lvalue_ref_subtraction { + friend int operator-(volatile_lvalue_ref_lvalue_ref_subtraction volatile&, + const_lvalue_ref_lvalue_ref_subtraction&); +}; +static_assert( + !check_has_difference_type); + +struct volatile_lvalue_ref_const_lvalue_ref_subtraction { + friend int + operator-(volatile_lvalue_ref_const_lvalue_ref_subtraction volatile&, + volatile_lvalue_ref_const_lvalue_ref_subtraction const&); +}; +static_assert(!check_has_difference_type< + volatile_lvalue_ref_const_lvalue_ref_subtraction>); + +struct volatile_lvalue_ref_volatile_lvalue_ref_subtraction { + friend int + operator-(volatile_lvalue_ref_volatile_lvalue_ref_subtraction volatile&, + volatile_lvalue_ref_volatile_lvalue_ref_subtraction volatile&); +}; +static_assert(!check_has_difference_type< + volatile_lvalue_ref_volatile_lvalue_ref_subtraction>); + +struct volatile_lvalue_ref_cv_lvalue_ref_subtraction { + friend int + operator-(volatile_lvalue_ref_cv_lvalue_ref_subtraction volatile&, + volatile_lvalue_ref_cv_lvalue_ref_subtraction const volatile&); +}; +static_assert( + !check_has_difference_type); + +struct volatile_lvalue_ref_rvalue_ref_subtraction { + friend int operator-(volatile_lvalue_ref_rvalue_ref_subtraction volatile&, + volatile_lvalue_ref_rvalue_ref_subtraction&&); +}; +static_assert( + !check_has_difference_type); + +struct volatile_lvalue_ref_const_rvalue_ref_subtraction { + friend int + operator-(volatile_lvalue_ref_const_rvalue_ref_subtraction volatile&, + volatile_lvalue_ref_const_rvalue_ref_subtraction const&&); +}; +static_assert(!check_has_difference_type< + volatile_lvalue_ref_const_rvalue_ref_subtraction>); + +struct volatile_lvalue_ref_volatile_rvalue_ref_subtraction { + friend int + operator-(volatile_lvalue_ref_volatile_rvalue_ref_subtraction volatile&, + volatile_lvalue_ref_volatile_rvalue_ref_subtraction volatile&&); +}; +static_assert(!check_has_difference_type< + volatile_lvalue_ref_volatile_rvalue_ref_subtraction>); + +struct volatile_lvalue_ref_cv_rvalue_ref_subtraction { + friend int + operator-(volatile_lvalue_ref_cv_rvalue_ref_subtraction volatile&, + volatile_lvalue_ref_cv_rvalue_ref_subtraction const volatile&&); +}; +static_assert( + !check_has_difference_type); + +struct cv_lvalue_ref_lvalue_ref_subtraction { + friend int operator-(cv_lvalue_ref_lvalue_ref_subtraction const volatile&, + const_lvalue_ref_lvalue_ref_subtraction&); +}; +static_assert(!check_has_difference_type); + +struct cv_lvalue_ref_volatile_lvalue_ref_subtraction { + friend int + operator-(cv_lvalue_ref_volatile_lvalue_ref_subtraction const volatile&, + cv_lvalue_ref_volatile_lvalue_ref_subtraction volatile&); +}; +static_assert( + !check_has_difference_type); + +struct cv_lvalue_ref_rvalue_ref_subtraction { + friend int operator-(cv_lvalue_ref_rvalue_ref_subtraction const volatile&, + cv_lvalue_ref_rvalue_ref_subtraction&&); +}; +static_assert(!check_has_difference_type); + +struct cv_lvalue_ref_const_rvalue_ref_subtraction { + friend int + operator-(cv_lvalue_ref_const_rvalue_ref_subtraction const volatile&, + cv_lvalue_ref_const_rvalue_ref_subtraction const&&); +}; +static_assert( + !check_has_difference_type); + +struct cv_lvalue_ref_volatile_rvalue_ref_subtraction { + friend int + operator-(cv_lvalue_ref_volatile_rvalue_ref_subtraction const volatile&, + cv_lvalue_ref_volatile_rvalue_ref_subtraction volatile&&); +}; +static_assert( + !check_has_difference_type); + +struct cv_lvalue_ref_cv_rvalue_ref_subtraction { + friend int + operator-(cv_lvalue_ref_cv_rvalue_ref_subtraction const volatile&, + cv_lvalue_ref_cv_rvalue_ref_subtraction const volatile&&); +}; +static_assert( + !check_has_difference_type); + +struct rvalue_ref_lvalue_ref_subtraction { + friend int operator-(rvalue_ref_lvalue_ref_subtraction&&, + const_lvalue_ref_lvalue_ref_subtraction&); +}; +static_assert(!check_has_difference_type); + +struct rvalue_ref_const_lvalue_ref_subtraction { + friend int operator-(rvalue_ref_const_lvalue_ref_subtraction&&, + rvalue_ref_const_lvalue_ref_subtraction const&); +}; +static_assert( + !check_has_difference_type); + +struct rvalue_ref_volatile_lvalue_ref_subtraction { + friend int operator-(rvalue_ref_volatile_lvalue_ref_subtraction&&, + rvalue_ref_volatile_lvalue_ref_subtraction volatile&); +}; +static_assert( + !check_has_difference_type); + +struct rvalue_ref_cv_lvalue_ref_subtraction { + friend int operator-(rvalue_ref_cv_lvalue_ref_subtraction&&, + rvalue_ref_cv_lvalue_ref_subtraction const volatile&); +}; +static_assert(!check_has_difference_type); + +struct rvalue_ref_rvalue_ref_subtraction { + friend int operator-(rvalue_ref_rvalue_ref_subtraction&&, + rvalue_ref_rvalue_ref_subtraction&&); +}; +static_assert(!check_has_difference_type); + +struct rvalue_ref_const_rvalue_ref_subtraction { + friend int operator-(rvalue_ref_const_rvalue_ref_subtraction&&, + rvalue_ref_const_rvalue_ref_subtraction const&&); +}; +static_assert( + !check_has_difference_type); + +struct rvalue_ref_volatile_rvalue_ref_subtraction { + friend int operator-(rvalue_ref_volatile_rvalue_ref_subtraction&&, + rvalue_ref_volatile_rvalue_ref_subtraction volatile&&); +}; +static_assert( + !check_has_difference_type); + +struct rvalue_ref_cv_rvalue_ref_subtraction { + friend int operator-(rvalue_ref_cv_rvalue_ref_subtraction&&, + rvalue_ref_cv_rvalue_ref_subtraction const volatile&&); +}; +static_assert(!check_has_difference_type); + +struct const_rvalue_ref_lvalue_ref_subtraction { + friend int operator-(const_rvalue_ref_lvalue_ref_subtraction const&&, + const_lvalue_ref_lvalue_ref_subtraction&); +}; +static_assert( + !check_has_difference_type); + +struct const_rvalue_ref_const_lvalue_ref_subtraction { + friend int operator-(const_rvalue_ref_const_lvalue_ref_subtraction const&&, + const_rvalue_ref_const_lvalue_ref_subtraction const&); +}; +static_assert( + !check_has_difference_type); + +struct const_rvalue_ref_volatile_lvalue_ref_subtraction { + friend int + operator-(const_rvalue_ref_volatile_lvalue_ref_subtraction const&&, + const_rvalue_ref_volatile_lvalue_ref_subtraction volatile&); +}; +static_assert(!check_has_difference_type< + const_rvalue_ref_volatile_lvalue_ref_subtraction>); + +struct const_rvalue_ref_cv_lvalue_ref_subtraction { + friend int + operator-(const_rvalue_ref_cv_lvalue_ref_subtraction const&&, + const_rvalue_ref_cv_lvalue_ref_subtraction const volatile&); +}; +static_assert( + !check_has_difference_type); + +struct const_rvalue_ref_rvalue_ref_subtraction { + friend int operator-(const_rvalue_ref_rvalue_ref_subtraction const&&, + const_rvalue_ref_rvalue_ref_subtraction&&); +}; +static_assert( + !check_has_difference_type); + +struct const_rvalue_ref_const_rvalue_ref_subtraction { + friend int operator-(const_rvalue_ref_const_rvalue_ref_subtraction const&&, + const_rvalue_ref_const_rvalue_ref_subtraction const&&); +}; +static_assert( + !check_has_difference_type); + +struct const_rvalue_ref_volatile_rvalue_ref_subtraction { + friend int + operator-(const_rvalue_ref_volatile_rvalue_ref_subtraction const&&, + const_rvalue_ref_volatile_rvalue_ref_subtraction volatile&&); +}; +static_assert(!check_has_difference_type< + const_rvalue_ref_volatile_rvalue_ref_subtraction>); + +struct const_rvalue_ref_cv_rvalue_ref_subtraction { + friend int + operator-(const_rvalue_ref_cv_rvalue_ref_subtraction const&&, + const_rvalue_ref_cv_rvalue_ref_subtraction const volatile&&); +}; +static_assert( + !check_has_difference_type); + +struct volatile_rvalue_ref_lvalue_ref_subtraction { + friend int operator-(volatile_rvalue_ref_lvalue_ref_subtraction volatile&&, + const_lvalue_ref_lvalue_ref_subtraction&); +}; +static_assert( + !check_has_difference_type); + +struct volatile_rvalue_ref_const_lvalue_ref_subtraction { + friend int + operator-(volatile_rvalue_ref_const_lvalue_ref_subtraction volatile&&, + volatile_rvalue_ref_const_lvalue_ref_subtraction const&); +}; +static_assert(!check_has_difference_type< + volatile_rvalue_ref_const_lvalue_ref_subtraction>); + +struct volatile_rvalue_ref_volatile_lvalue_ref_subtraction { + friend int + operator-(volatile_rvalue_ref_volatile_lvalue_ref_subtraction volatile&&, + volatile_rvalue_ref_volatile_lvalue_ref_subtraction volatile&); +}; +static_assert(!check_has_difference_type< + volatile_rvalue_ref_volatile_lvalue_ref_subtraction>); + +struct volatile_rvalue_ref_cv_lvalue_ref_subtraction { + friend int + operator-(volatile_rvalue_ref_cv_lvalue_ref_subtraction volatile&&, + volatile_rvalue_ref_cv_lvalue_ref_subtraction const volatile&); +}; +static_assert( + !check_has_difference_type); + +struct volatile_rvalue_ref_rvalue_ref_subtraction { + friend int operator-(volatile_rvalue_ref_rvalue_ref_subtraction volatile&&, + volatile_rvalue_ref_rvalue_ref_subtraction&&); +}; +static_assert( + !check_has_difference_type); + +struct volatile_rvalue_ref_const_rvalue_ref_subtraction { + friend int + operator-(volatile_rvalue_ref_const_rvalue_ref_subtraction volatile&&, + volatile_rvalue_ref_const_rvalue_ref_subtraction const&&); +}; +static_assert(!check_has_difference_type< + volatile_rvalue_ref_const_rvalue_ref_subtraction>); + +struct volatile_rvalue_ref_volatile_rvalue_ref_subtraction { + friend int + operator-(volatile_rvalue_ref_volatile_rvalue_ref_subtraction volatile&&, + volatile_rvalue_ref_volatile_rvalue_ref_subtraction volatile&&); +}; +static_assert(!check_has_difference_type< + volatile_rvalue_ref_volatile_rvalue_ref_subtraction>); + +struct volatile_rvalue_ref_cv_rvalue_ref_subtraction { + friend int + operator-(volatile_rvalue_ref_cv_rvalue_ref_subtraction volatile&&, + volatile_rvalue_ref_cv_rvalue_ref_subtraction const volatile&&); +}; +static_assert( + !check_has_difference_type); + +struct cv_rvalue_ref_lvalue_ref_subtraction { + friend int operator-(cv_rvalue_ref_lvalue_ref_subtraction const volatile&&, + const_lvalue_ref_lvalue_ref_subtraction&); +}; +static_assert(!check_has_difference_type); + +struct cv_rvalue_ref_const_lvalue_ref_subtraction { + friend int + operator-(cv_rvalue_ref_const_lvalue_ref_subtraction const volatile&&, + cv_rvalue_ref_const_lvalue_ref_subtraction const&); +}; +static_assert( + !check_has_difference_type); + +struct cv_rvalue_ref_volatile_lvalue_ref_subtraction { + friend int + operator-(cv_rvalue_ref_volatile_lvalue_ref_subtraction const volatile&&, + cv_rvalue_ref_volatile_lvalue_ref_subtraction volatile&); +}; +static_assert( + !check_has_difference_type); + +struct cv_rvalue_ref_cv_lvalue_ref_subtraction { + friend int operator-(cv_rvalue_ref_cv_lvalue_ref_subtraction const volatile&&, + cv_rvalue_ref_cv_lvalue_ref_subtraction const volatile&); +}; +static_assert( + !check_has_difference_type); + +struct cv_rvalue_ref_rvalue_ref_subtraction { + friend int operator-(cv_rvalue_ref_rvalue_ref_subtraction const volatile&&, + cv_rvalue_ref_rvalue_ref_subtraction&&); +}; +static_assert(!check_has_difference_type); + +struct cv_rvalue_ref_const_rvalue_ref_subtraction { + friend int + operator-(cv_rvalue_ref_const_rvalue_ref_subtraction const volatile&&, + cv_rvalue_ref_const_rvalue_ref_subtraction const&&); +}; +static_assert( + !check_has_difference_type); + +struct cv_rvalue_ref_volatile_rvalue_ref_subtraction { + friend int + operator-(cv_rvalue_ref_volatile_rvalue_ref_subtraction const volatile&&, + cv_rvalue_ref_volatile_rvalue_ref_subtraction volatile&&); +}; +static_assert( + !check_has_difference_type); + +struct cv_rvalue_ref_cv_rvalue_ref_subtraction { + friend int + operator-(cv_rvalue_ref_cv_rvalue_ref_subtraction const volatile&&, + cv_rvalue_ref_cv_rvalue_ref_subtraction const volatile&&); +}; +static_assert( + !check_has_difference_type); + +struct lvalue_ref_lvalue_subtraction { + friend int operator-(lvalue_ref_lvalue_subtraction&, + lvalue_ref_lvalue_subtraction); +}; +static_assert(!check_has_difference_type); + +struct const_lvalue_ref_lvalue_subtraction { + friend int operator-(const_lvalue_ref_lvalue_subtraction const&, + const_lvalue_ref_lvalue_subtraction); +}; +static_assert(check_has_difference_type); + +struct volatile_lvalue_ref_lvalue_subtraction { + friend int operator-(volatile_lvalue_ref_lvalue_subtraction volatile&, + volatile_lvalue_ref_lvalue_subtraction); +}; +static_assert( + !check_has_difference_type); + +struct rvalue_ref_lvalue_subtraction { + friend int operator-(rvalue_ref_lvalue_subtraction&&, + rvalue_ref_lvalue_subtraction); +}; +static_assert(!check_has_difference_type); + +struct const_rvalue_ref_lvalue_subtraction { + friend int operator-(const_rvalue_ref_lvalue_subtraction const&&, + const_rvalue_ref_lvalue_subtraction); +}; +static_assert(check_has_difference_type); + +struct volatile_rvalue_ref_lvalue_subtraction { + friend int operator-(volatile_rvalue_ref_lvalue_subtraction volatile&&, + volatile_rvalue_ref_lvalue_subtraction); +}; +static_assert( + !check_has_difference_type); + +struct cv_rvalue_ref_lvalue_subtraction { + friend int operator-(cv_rvalue_ref_lvalue_subtraction const volatile&&, + cv_rvalue_ref_lvalue_subtraction); +}; +static_assert(!check_has_difference_type); + +struct lvalue_lvalue_ref_subtraction { + friend int operator-(lvalue_lvalue_ref_subtraction, + lvalue_lvalue_ref_subtraction&); +}; +static_assert(!check_has_difference_type); + +struct lvalue_const_lvalue_ref_subtraction { + friend int operator-(lvalue_const_lvalue_ref_subtraction, + lvalue_const_lvalue_ref_subtraction const&); +}; +static_assert(check_has_difference_type); + +struct lvalue_volatile_lvalue_ref_subtraction { + friend int operator-(lvalue_volatile_lvalue_ref_subtraction, + lvalue_volatile_lvalue_ref_subtraction volatile&); +}; +static_assert( + !check_has_difference_type); + +struct lvalue_rvalue_ref_subtraction { + friend int operator-(lvalue_rvalue_ref_subtraction, + lvalue_rvalue_ref_subtraction&&); +}; +static_assert(!check_has_difference_type); + +struct lvalue_const_rvalue_ref_subtraction { + friend int operator-(lvalue_const_rvalue_ref_subtraction, + lvalue_const_rvalue_ref_subtraction const&&); +}; +static_assert(!check_has_difference_type); + +struct lvalue_volatile_rvalue_ref_subtraction { + friend int operator-(lvalue_volatile_rvalue_ref_subtraction, + lvalue_volatile_rvalue_ref_subtraction volatile&&); +}; +static_assert( + !check_has_difference_type); + +struct lvalue_cv_rvalue_ref_subtraction { + friend int operator-(lvalue_cv_rvalue_ref_subtraction, + lvalue_cv_rvalue_ref_subtraction const volatile&&); +}; +static_assert(!check_has_difference_type); + +int main(int, char**) { return 0; }