Changeset View
Standalone View
libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/incrementable.traits/incrementable_traits.pass.cpp
- This file was added.
//===----------------------------------------------------------------------===// | |||||||||||||||||||
// | |||||||||||||||||||
Mordante: http://eel.is/c++draft/incrementable.traits#3 `Users may specialize incrementable_traits on… | |||||||||||||||||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||||||||||||||||||
// See https://llvm.org/LICENSE.txt for license information. | |||||||||||||||||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||||||||||||||||||
// | |||||||||||||||||||
//===----------------------------------------------------------------------===// | |||||||||||||||||||
// UNSUPPORTED: c++03, c++11, c++14, c++17 | |||||||||||||||||||
// UNSUPPORTED: libcpp-no-concepts | |||||||||||||||||||
// UNSUPPORTED: gcc-10 | |||||||||||||||||||
// template<class T> | |||||||||||||||||||
// struct incrementable_traits; | |||||||||||||||||||
#include <iterator> | |||||||||||||||||||
#include <concepts> | |||||||||||||||||||
// clang-format off | |||||||||||||||||||
template <class T> | |||||||||||||||||||
concept check_has_difference_type = requires { | |||||||||||||||||||
typename std::incrementable_traits<T>::difference_type; | |||||||||||||||||||
Almost all places where you write incrementable_traits, you should be writing difference_type — has_difference_type, difference_type_matches, check_difference_type. Quuxplusone: Almost all places where you write `incrementable_traits`, you should be writing… | |||||||||||||||||||
}; | |||||||||||||||||||
template <class T, class Expected> | |||||||||||||||||||
concept check_difference_type_matches = | |||||||||||||||||||
check_has_difference_type<T> && | |||||||||||||||||||
std::same_as<typename std::incrementable_traits<T>::difference_type, Expected>; | |||||||||||||||||||
// clang-format on | |||||||||||||||||||
template <class T, class Expected> | |||||||||||||||||||
[[nodiscard]] constexpr bool check_incrementable_traits() noexcept { | |||||||||||||||||||
constexpr bool result = check_difference_type_matches<T, Expected>; | |||||||||||||||||||
static_assert(check_difference_type_matches<T const, Expected> == result); | |||||||||||||||||||
QuuxplusoneUnsubmitted Not Done ReplyInline ActionsNote that T const is the same type as T whenever T is a reference type. Therefore, any place in this file that instantiates check_incrementable_traits<Foo&> is suspicious — it's simply static-asserting that the difference type of T is the difference type of T. assert(result); inside this function. (Or is it okay if result is false, sometimes? I didn't closely examine all the call sites.) Quuxplusone: Note that `T const` is the same type as `T` whenever `T` is a reference type. Therefore, any… | |||||||||||||||||||
cjdbAuthorUnsubmitted
Lines 63-70 should already account for this, unless you're asking we check T& against T const& and friends.
Lines 89 and 90-1 expect false. cjdb: > Note that `T const` is the same type as `T` whenever `T` is a reference type. Therefore, any… | |||||||||||||||||||
return result; | |||||||||||||||||||
} | |||||||||||||||||||
Take the suggested edit. Quuxplusone: Take the suggested edit. | |||||||||||||||||||
The suggested edit doesn't add anything constructive and appears to be a stylistic preference, so there's nothing to change. cjdb: The suggested edit doesn't add anything constructive and appears to be a stylistic preference… | |||||||||||||||||||
static_assert(check_incrementable_traits<float*, std::ptrdiff_t>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<float const*, std::ptrdiff_t>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<float volatile*, std::ptrdiff_t>()); | |||||||||||||||||||
static_assert( | |||||||||||||||||||
check_incrementable_traits<float const volatile*, std::ptrdiff_t>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<float**, std::ptrdiff_t>()); | |||||||||||||||||||
This is surprising, but I guess it falls out naturally because int[] is subtractable? Quuxplusone: This is surprising, but I guess it falls out naturally because `int[]` is subtractable?
Please… | |||||||||||||||||||
See below for int(*)() and friends. cjdb: See below for `int(*)()` and friends. | |||||||||||||||||||
Please add int[10]. Quuxplusone: Please add `int[10]`. | |||||||||||||||||||
static_assert(check_incrementable_traits<int[], std::ptrdiff_t>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<int[10], std::ptrdiff_t>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<char, int>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<signed char, int>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<unsigned char, int>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<short, int>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<unsigned short, int>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<int, int>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<unsigned int, int>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<long, long>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<unsigned long, long>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<long long, long long>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<unsigned long long, long long>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<int&, int>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<int const&, int>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<int volatile&, int>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<int const volatile&, int>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<int&&, int>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<int const&&, int>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<int volatile&&, int>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<int const volatile&&, int>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<int volatile, int>()); | |||||||||||||||||||
static_assert(check_incrementable_traits<int* volatile, std::ptrdiff_t>()); | |||||||||||||||||||
struct integral_difference_type { | |||||||||||||||||||
using difference_type = int; | |||||||||||||||||||
}; | |||||||||||||||||||
static_assert(check_incrementable_traits<integral_difference_type, int>()); | |||||||||||||||||||
struct non_integral_difference_type { | |||||||||||||||||||
using difference_type = void; | |||||||||||||||||||
}; | |||||||||||||||||||
static_assert(check_incrementable_traits<non_integral_difference_type, void>()); | |||||||||||||||||||
struct int_subtraction { | |||||||||||||||||||
friend int operator-(int_subtraction, int_subtraction) noexcept; | |||||||||||||||||||
}; | |||||||||||||||||||
static_assert(check_incrementable_traits<int_subtraction, int>()); | |||||||||||||||||||
static_assert(!check_incrementable_traits<int_subtraction volatile&, int>()); | |||||||||||||||||||
static_assert( | |||||||||||||||||||
!check_incrementable_traits<int_subtraction const volatile&, int>()); | |||||||||||||||||||
struct char_subtraction { | |||||||||||||||||||
friend char operator-(char_subtraction, char_subtraction) noexcept; | |||||||||||||||||||
}; | |||||||||||||||||||
static_assert(check_incrementable_traits<char_subtraction, signed char>()); | |||||||||||||||||||
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<unsigned_int_subtraction_with_cv, int>()); | |||||||||||||||||||
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<specialised_incrementable_traits> { | |||||||||||||||||||
using difference_type = int; | |||||||||||||||||||
}; | |||||||||||||||||||
} // namespace std | |||||||||||||||||||
static_assert( | |||||||||||||||||||
check_incrementable_traits<specialised_incrementable_traits, int>()); | |||||||||||||||||||
static_assert(!check_has_difference_type<void>); | |||||||||||||||||||
static_assert(!check_has_difference_type<float>); | |||||||||||||||||||
static_assert(!check_has_difference_type<double>); | |||||||||||||||||||
static_assert(!check_has_difference_type<long double>); | |||||||||||||||||||
static_assert(!check_has_difference_type<float&>); | |||||||||||||||||||
static_assert(!check_has_difference_type<float const&>); | |||||||||||||||||||
static_assert(!check_has_difference_type<void*>); | |||||||||||||||||||
static_assert(!check_has_difference_type<std::nullptr_t>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int()>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int() noexcept>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (*)()>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (*)() noexcept>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (&)()>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (&)() noexcept>); | |||||||||||||||||||
struct empty {}; | |||||||||||||||||||
static_assert(!check_has_difference_type<empty>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int empty::*>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (empty::*)()>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (empty::*)() noexcept>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (empty::*)() const>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (empty::*)() const noexcept>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (empty::*)() volatile>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (empty::*)() volatile noexcept>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (empty::*)() const volatile>); | |||||||||||||||||||
static_assert( | |||||||||||||||||||
!check_has_difference_type<int (empty::*)() const volatile noexcept>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (empty::*)() &>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (empty::*)() & noexcept>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (empty::*)() const&>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (empty::*)() const & noexcept>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (empty::*)() volatile&>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (empty::*)() volatile & noexcept>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (empty::*)() const volatile&>); | |||||||||||||||||||
static_assert( | |||||||||||||||||||
!check_has_difference_type<int (empty::*)() const volatile & noexcept>); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (empty::*)() &&>); | |||||||||||||||||||
static_assert(!check_has_difference_type < int (empty::*)() && noexcept >); | |||||||||||||||||||
"with_cv"? I see no cv-qualifiers here. Quuxplusone: "with_cv"? I see no cv-qualifiers here.
Also, my usual opinion on `noexcept` here: `noexcept`… | |||||||||||||||||||
static_assert(!check_has_difference_type<int (empty::*)() const&&>); | |||||||||||||||||||
static_assert(!check_has_difference_type < int (empty::*)() const&& noexcept >); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (empty::*)() volatile&&>); | |||||||||||||||||||
static_assert(!check_has_difference_type < | |||||||||||||||||||
int (empty::*)() volatile&& noexcept >); | |||||||||||||||||||
static_assert(!check_has_difference_type<int (empty::*)() const volatile&&>); | |||||||||||||||||||
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<void_subtraction>); | |||||||||||||||||||
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<rvalue_ref_subtraction_can_throw>); | |||||||||||||||||||
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<lvalue_ref_lvalue_ref_subtraction>); | |||||||||||||||||||
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<lvalue_ref_const_lvalue_ref_subtraction>); | |||||||||||||||||||
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<lvalue_ref_volatile_lvalue_ref_subtraction>); | |||||||||||||||||||
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<lvalue_ref_cv_lvalue_ref_subtraction>); | |||||||||||||||||||
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<lvalue_ref_rvalue_ref_subtraction>); | |||||||||||||||||||
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<lvalue_ref_const_rvalue_ref_subtraction>); | |||||||||||||||||||
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( | |||||||||||||||||||
Not Done ReplyInline ActionsMy usual complaints about hundreds of lines of tests, which test very little.
Quuxplusone: My usual complaints about hundreds of lines of tests, which test very little.
Please remove //a… | |||||||||||||||||||
As mentioned in previous patches: I have been asked to add tests, and my comprehensive coverage has been encouraged by several others, including two maintainers. There are many lines, yes, but each of these tests ensures that cv-qualifiers and reference qualifiers are correctly handled.
I have added these three and more. cjdb: > My usual complaints about hundreds of lines of tests, which test very little.
> Please remove… | |||||||||||||||||||
Not Done ReplyInline ActionsI don't feel opposition to lots of tests, even if they might seem excessive. Though, it might be good to have a few simple tests at the top or bottom that are easily verifiable and human-readable that just show "this works right in the common case". That being said, this patch LGTM (but let's make sure Arthur is also OK with it). zoecarver: I don't feel opposition to lots of tests, even if they might seem excessive. Though, it might… | |||||||||||||||||||
Not Done ReplyInline ActionsWell, I wouldn't say I'm "OK" with it; but I agree I haven't got the clout to block this patch series until it looks the way I think it should. The number of tests in a patch should generally be proportional to the number of lines-of-code changed: here Chris is adding 24 LOC, so the tests should be on that order of magnitude. Another way to put it is, test-code is just like ordinary code. Writing hundreds of lines of code can be useful, but it can also indicate that you need to take a step back to look at the problem you're trying to solve. Once you understand the problem being solved, you might find that an elegant fix is available. The hundred-line rough draft can still be useful! Looking at Chris's "rough draft" with its hundreds of lines of const_lvalue_ref_volatile_rvalue_ref_subtraction gave me the clue "okay, cvref-qualifiers are important to this code somehow." Then I looked at the problem being solved — "okay, we need to test that something might bit-rot in this code, in the area of cvref-qualifiers specifically." That's how I found that none of these tests were testing what they intended. The next step is to write a surgical patch that solves the problem; I think I can write the new test for each of the three bullet points above in about 5 lines each. With the smaller patch in hand, the big patch is no longer technically necessary — and therefore I personally wouldn't check it in. (Although, again, I understand that I'm not the gatekeeper here, and the big patch is quite likely to get checked in regardless.) Quuxplusone: Well, I wouldn't say I'm "OK" with it; but I agree I haven't got the clout to block this patch… | |||||||||||||||||||
Not Done ReplyInline ActionsI'm personally also not too fond of the amount of tests and I agree with @Quuxplusone. However some maintainers have asked for verbose tests for some of the concepts in earlier reviews. Maybe we should discuss on discord what we expect of unit tests and how verbose. I don't like to block this review on that discussion; the tests aren't wrong and we can always reduce the number of tests later. Mordante: I'm personally also not too fond of the amount of tests and I agree with @Quuxplusone. However… | |||||||||||||||||||
!check_has_difference_type<lvalue_ref_volatile_rvalue_ref_subtraction>); | |||||||||||||||||||
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<lvalue_ref_cv_rvalue_ref_subtraction>); | |||||||||||||||||||
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<const_lvalue_ref_lvalue_ref_subtraction>); | |||||||||||||||||||
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<const_lvalue_ref_rvalue_ref_subtraction>); | |||||||||||||||||||
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<const_lvalue_ref_const_rvalue_ref_subtraction>); | |||||||||||||||||||
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<const_lvalue_ref_cv_rvalue_ref_subtraction>); | |||||||||||||||||||
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<volatile_lvalue_ref_lvalue_ref_subtraction>); | |||||||||||||||||||
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<volatile_lvalue_ref_cv_lvalue_ref_subtraction>); | |||||||||||||||||||
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<volatile_lvalue_ref_rvalue_ref_subtraction>); | |||||||||||||||||||
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<volatile_lvalue_ref_cv_rvalue_ref_subtraction>); | |||||||||||||||||||
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<cv_lvalue_ref_lvalue_ref_subtraction>); | |||||||||||||||||||
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<cv_lvalue_ref_volatile_lvalue_ref_subtraction>); | |||||||||||||||||||
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<cv_lvalue_ref_rvalue_ref_subtraction>); | |||||||||||||||||||
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<cv_lvalue_ref_const_rvalue_ref_subtraction>); | |||||||||||||||||||
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<cv_lvalue_ref_volatile_rvalue_ref_subtraction>); | |||||||||||||||||||
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<cv_lvalue_ref_cv_rvalue_ref_subtraction>); | |||||||||||||||||||
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<rvalue_ref_lvalue_ref_subtraction>); | |||||||||||||||||||
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<rvalue_ref_const_lvalue_ref_subtraction>); | |||||||||||||||||||
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<rvalue_ref_volatile_lvalue_ref_subtraction>); | |||||||||||||||||||
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<rvalue_ref_cv_lvalue_ref_subtraction>); | |||||||||||||||||||
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<rvalue_ref_rvalue_ref_subtraction>); | |||||||||||||||||||
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<rvalue_ref_const_rvalue_ref_subtraction>); | |||||||||||||||||||
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<rvalue_ref_volatile_rvalue_ref_subtraction>); | |||||||||||||||||||
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<rvalue_ref_cv_rvalue_ref_subtraction>); | |||||||||||||||||||
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<const_rvalue_ref_lvalue_ref_subtraction>); | |||||||||||||||||||
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<const_rvalue_ref_const_lvalue_ref_subtraction>); | |||||||||||||||||||
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<const_rvalue_ref_cv_lvalue_ref_subtraction>); | |||||||||||||||||||
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<const_rvalue_ref_rvalue_ref_subtraction>); | |||||||||||||||||||
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<const_rvalue_ref_const_rvalue_ref_subtraction>); | |||||||||||||||||||
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<const_rvalue_ref_cv_rvalue_ref_subtraction>); | |||||||||||||||||||
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<volatile_rvalue_ref_lvalue_ref_subtraction>); | |||||||||||||||||||
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<volatile_rvalue_ref_cv_lvalue_ref_subtraction>); | |||||||||||||||||||
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<volatile_rvalue_ref_rvalue_ref_subtraction>); | |||||||||||||||||||
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<volatile_rvalue_ref_cv_rvalue_ref_subtraction>); | |||||||||||||||||||
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<cv_rvalue_ref_lvalue_ref_subtraction>); | |||||||||||||||||||
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<cv_rvalue_ref_const_lvalue_ref_subtraction>); | |||||||||||||||||||
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<cv_rvalue_ref_volatile_lvalue_ref_subtraction>); | |||||||||||||||||||
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<cv_rvalue_ref_cv_lvalue_ref_subtraction>); | |||||||||||||||||||
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<cv_rvalue_ref_rvalue_ref_subtraction>); | |||||||||||||||||||
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<cv_rvalue_ref_const_rvalue_ref_subtraction>); | |||||||||||||||||||
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<cv_rvalue_ref_volatile_rvalue_ref_subtraction>); | |||||||||||||||||||
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<cv_rvalue_ref_cv_rvalue_ref_subtraction>); | |||||||||||||||||||
struct lvalue_ref_lvalue_subtraction { | |||||||||||||||||||
friend int operator-(lvalue_ref_lvalue_subtraction&, | |||||||||||||||||||
lvalue_ref_lvalue_subtraction); | |||||||||||||||||||
}; | |||||||||||||||||||
static_assert(!check_has_difference_type<lvalue_ref_lvalue_subtraction>); | |||||||||||||||||||
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<const_lvalue_ref_lvalue_subtraction>); | |||||||||||||||||||
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<volatile_lvalue_ref_lvalue_subtraction>); | |||||||||||||||||||
struct rvalue_ref_lvalue_subtraction { | |||||||||||||||||||
friend int operator-(rvalue_ref_lvalue_subtraction&&, | |||||||||||||||||||
rvalue_ref_lvalue_subtraction); | |||||||||||||||||||
}; | |||||||||||||||||||
static_assert(!check_has_difference_type<lvalue_ref_lvalue_subtraction>); | |||||||||||||||||||
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<const_lvalue_ref_lvalue_subtraction>); | |||||||||||||||||||
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<volatile_lvalue_ref_lvalue_subtraction>); | |||||||||||||||||||
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<cv_rvalue_ref_lvalue_subtraction>); | |||||||||||||||||||
struct lvalue_lvalue_ref_subtraction { | |||||||||||||||||||
friend int operator-(lvalue_lvalue_ref_subtraction, | |||||||||||||||||||
lvalue_lvalue_ref_subtraction&); | |||||||||||||||||||
}; | |||||||||||||||||||
static_assert(!check_has_difference_type<lvalue_ref_lvalue_subtraction>); | |||||||||||||||||||
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<const_lvalue_ref_lvalue_subtraction>); | |||||||||||||||||||
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<volatile_lvalue_ref_lvalue_subtraction>); | |||||||||||||||||||
struct lvalue_rvalue_ref_subtraction { | |||||||||||||||||||
friend int operator-(lvalue_rvalue_ref_subtraction, | |||||||||||||||||||
lvalue_rvalue_ref_subtraction&&); | |||||||||||||||||||
}; | |||||||||||||||||||
static_assert(!check_has_difference_type<lvalue_ref_lvalue_subtraction>); | |||||||||||||||||||
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<lvalue_const_rvalue_ref_subtraction>); | |||||||||||||||||||
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<volatile_lvalue_ref_lvalue_subtraction>); | |||||||||||||||||||
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<lvalue_cv_rvalue_ref_subtraction>); | |||||||||||||||||||
int main(int, char**) { return 0; } |
http://eel.is/c++draft/incrementable.traits#3 Users may specialize incrementable_traits on program-defined types.
can you add a test for this?