QSpan: make adl_begin() etc SFINAE-friendly
The definition of iterator_t, and, therefore, of is_compatible_range depends on this, otherwise say, 0, is being treated as a valid range and hits a hard error in adl_begin() when trying to call begin(int&). TIL: decltype(auto) does _not_ SFINAE. Fix by calculating the return type manually, re-enabing SFINAE. Pick-to: 6.6 Change-Id: Icacd70554f4050ecaeb396c9ae60bc4f21a220c9 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> (cherry picked from commit 94e122c594a3697b98dcc99a9e332b0f5e816d2d) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
346b5931a7
commit
1b559b25a6
@ -76,14 +76,25 @@ using is_qualification_conversion =
|
||||
template <typename From, typename To>
|
||||
constexpr inline bool is_qualification_conversion_v = is_qualification_conversion<From, To>::value;
|
||||
|
||||
namespace AdlTester {
|
||||
#define MAKE_ADL_TEST(what) \
|
||||
using std:: what; /* bring into scope */ \
|
||||
template <typename T> using what ## _result = decltype( what (std::declval<T&&>())); \
|
||||
/* end */
|
||||
MAKE_ADL_TEST(begin)
|
||||
MAKE_ADL_TEST(data)
|
||||
MAKE_ADL_TEST(size)
|
||||
#undef MAKE_ADL_TEST
|
||||
}
|
||||
|
||||
// Replacements for std::ranges::XXX(), but only bringing in ADL XXX()s,
|
||||
// not doing the extra work C++20 requires
|
||||
template <typename Range>
|
||||
decltype(auto) adl_begin(Range &&r) { using std::begin; return begin(r); }
|
||||
AdlTester::begin_result<Range> adl_begin(Range &&r) { using std::begin; return begin(r); }
|
||||
template <typename Range>
|
||||
decltype(auto) adl_data(Range &&r) { using std::data; return data(r); }
|
||||
AdlTester::data_result<Range> adl_data(Range &&r) { using std::data; return data(r); }
|
||||
template <typename Range>
|
||||
decltype(auto) adl_size(Range &&r) { using std::size; return size(r); }
|
||||
AdlTester::size_result<Range> adl_size(Range &&r) { using std::size; return size(r); }
|
||||
|
||||
// Replacement for std::ranges::iterator_t (which depends on C++20 std::ranges::begin)
|
||||
// This one uses adl_begin() instead.
|
||||
|
@ -96,6 +96,9 @@ static_assert(!std::is_convertible_v<QSpan<const int, 42>, std::span<int, 42>>);
|
||||
static_assert(!std::is_convertible_v<QSpan<const int, 0>, std::span<int, 0>>);
|
||||
#endif // __cpp_lib_span
|
||||
|
||||
// Spans don't convert from nonsense:
|
||||
static_assert(!std::is_constructible_v<QSpan<const int>, int&&>);
|
||||
|
||||
class tst_QSpan : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
Loading…
x
Reference in New Issue
Block a user