diff --git a/libcxx/test/libcxx/ranges/range.access/begin.verify.cpp b/libcxx/test/libcxx/ranges/range.access/begin.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.access/begin.verify.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// 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: libcpp-has-no-incomplete-ranges + +// std::ranges::begin +// Substitution failure should give reasonably nice diagnostics. + +#include +#include + +void f() { + // expected-error@*:* {{no matching function for call}} + // expected-note@*:* {{'is_array_v >' evaluated to false}} + // expected-note@*:* {{does not satisfy '__class_or_enum'}} + // expected-note@*:* {{does not satisfy '__class_or_enum'}} + std::ranges::begin(42); +} + +void g() { + struct S {} s; + // expected-error@*:* {{no matching function for call}} + // expected-note@*:* {{'is_array_v >' evaluated to false}} + // expected-note@*:* {{'std::__1::__decay_copy(__t.begin())' would be invalid}} + // expected-note@*:* {{'std::__1::__decay_copy(begin(__t))' would be invalid}} + std::ranges::begin(s); +} + +void h() { + // expected-error@*:* {{no matching function for call}} + // expected-note@*:* {{call to deleted function '__go'}} + std::ranges::begin(std::string()); +} diff --git a/libcxx/test/libcxx/ranges/range.access/cbegin.verify.cpp b/libcxx/test/libcxx/ranges/range.access/cbegin.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.access/cbegin.verify.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// 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: libcpp-has-no-incomplete-ranges + +// std::ranges::cbegin +// Substitution failure should give reasonably nice diagnostics. + +#include + +void f() { + // expected-error@*:* {{no matching function for call}} + std::ranges::cbegin(42); +} diff --git a/libcxx/test/libcxx/ranges/range.access/cend.verify.cpp b/libcxx/test/libcxx/ranges/range.access/cend.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.access/cend.verify.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// 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: libcpp-has-no-incomplete-ranges + +// std::ranges::cend +// Substitution failure should give reasonably nice diagnostics. + +#include + +void f() { + // expected-error@*:* {{no matching function for call}} + std::ranges::cend(42); +} diff --git a/libcxx/test/libcxx/ranges/range.access/data.verify.cpp b/libcxx/test/libcxx/ranges/range.access/data.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.access/data.verify.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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: libcpp-has-no-incomplete-ranges + +// std::ranges::data +// Substitution failure should give reasonably nice diagnostics. + +#include + +void f() { + // expected-error@*:* {{no matching function for call}} + // expected-note@*:* {{does not satisfy '__class_or_enum'}} + // expected-note@*:* {{'ranges::begin(__t)' would be invalid}} + std::ranges::data(42); +} + +void g() { + struct S {} s; + // expected-error@*:* {{no matching function for call}} + // expected-note@*:* {{'std::__1::__decay_copy(__t.data())' would be invalid}} + // expected-note@*:* {{'ranges::begin(__t)' would be invalid}} + std::ranges::data(s); +} diff --git a/libcxx/test/libcxx/ranges/range.access/empty.verify.cpp b/libcxx/test/libcxx/ranges/range.access/empty.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.access/empty.verify.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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: libcpp-has-no-incomplete-ranges + +// std::ranges::empty +// Substitution failure should give reasonably nice diagnostics. + +#include + +void f() { + // expected-error@*:* {{no matching function for call}} + // expected-note@*:* {{does not satisfy '__class_or_enum'}} + // expected-note@*:* {{'ranges::size(__t) == 0' would be invalid}} + // expected-note@*:* {{'ranges::begin(__t)' would be invalid}} + std::ranges::empty(42); +} + +void g() { + struct S {} s; + // expected-error@*:* {{no matching function for call}} + // expected-note@*:* {{'bool(__t.empty())' would be invalid}} + // expected-note@*:* {{'ranges::size(__t) == 0' would be invalid}} + // expected-note@*:* {{'ranges::begin(__t)' would be invalid}} + std::ranges::empty(s); +} diff --git a/libcxx/test/libcxx/ranges/range.access/end.verify.cpp b/libcxx/test/libcxx/ranges/range.access/end.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.access/end.verify.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// 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: libcpp-has-no-incomplete-ranges + +// std::ranges::end +// Substitution failure should give reasonably nice diagnostics. + +#include +#include + +void f() { + // expected-error@*:* {{no matching function for call}} + // expected-note@*:* {{'is_bounded_array_v >' evaluated to false}} + // expected-note@*:* {{does not satisfy '__class_or_enum'}} + // expected-note@*:* {{does not satisfy '__class_or_enum'}} + std::ranges::end(42); +} + +void g() { + struct S {} s; + // expected-error@*:* {{no matching function for call}} + // expected-note@*:* {{'is_bounded_array_v >' evaluated to false}} + // expected-note@*:* {{'std::__1::__decay_copy(__t.end())' would be invalid}} + // expected-note@*:* {{'std::__1::__decay_copy(end(__t))' would be invalid}} + std::ranges::end(s); +} + +void h() { + // expected-error@*:* {{no matching function for call}} + // expected-note@*:* {{call to deleted function '__go'}} + std::ranges::end(std::string()); +} diff --git a/libcxx/test/libcxx/ranges/range.access/size.verify.cpp b/libcxx/test/libcxx/ranges/range.access/size.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.access/size.verify.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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: libcpp-has-no-incomplete-ranges + +// std::ranges::size +// Substitution failure should give reasonably nice diagnostics. + +#include + +void f() { + // expected-error@*:* {{no matching function for call}} + // expected-note@*:* {{'is_bounded_array_v >' evaluated to false}} + // expected-note@*:* {{does not satisfy '__class_or_enum'}} + // expected-note@*:* {{does not satisfy '__class_or_enum'}} + // expected-note@*:* {{'ranges::end(__t) - ranges::begin(__t)' would be invalid}} + std::ranges::size(42); +} + +void g() { + struct S {} s; + // expected-error@*:* {{no matching function for call}} + // expected-note@*:* {{'is_bounded_array_v >' evaluated to false}} + // expected-note@*:* {{'std::__1::__decay_copy(__t.size())' would be invalid}} + // expected-note@*:* {{'std::__1::__decay_copy(size(__t))' would be invalid}} + // expected-note@*:* {{'ranges::end(__t) - ranges::begin(__t)' would be invalid}} + std::ranges::size(s); +} diff --git a/libcxx/test/libcxx/ranges/range.access/ssize.verify.cpp b/libcxx/test/libcxx/ranges/range.access/ssize.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.access/ssize.verify.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// 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: libcpp-has-no-incomplete-ranges + +// std::ranges::ssize +// Substitution failure should give reasonably nice diagnostics. + +#include + +void f() { + // expected-error@*:* {{no matching function for call}} + std::ranges::ssize(42); +} diff --git a/libcxx/test/std/ranges/range.access/range.access.begin/begin.pass.cpp b/libcxx/test/std/ranges/range.access/range.access.begin/begin.pass.cpp --- a/libcxx/test/std/ranges/range.access/range.access.begin/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.access/range.access.begin/begin.pass.cpp @@ -11,6 +11,7 @@ // UNSUPPORTED: libcpp-has-no-incomplete-ranges // std::ranges::begin +// std::ranges::cbegin #include @@ -18,8 +19,8 @@ #include "test_macros.h" #include "test_iterators.h" -using RangeBeginT = decltype(std::ranges::begin)&; -using RangeCBeginT = decltype(std::ranges::cbegin)&; +using RangeBeginT = decltype(std::ranges::begin); +using RangeCBeginT = decltype(std::ranges::cbegin); static int globalBuff[8]; @@ -114,12 +115,18 @@ BeginMember a; assert(std::ranges::begin(a) == &a.x); assert(std::ranges::cbegin(a) == &a.x); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); NonConstBeginMember b; assert(std::ranges::begin(b) == &b.x); + static_assert(!std::is_invocable_v); EnabledBorrowingBeginMember c; + assert(std::ranges::begin(c) == &globalBuff[0]); + assert(std::ranges::cbegin(c) == &globalBuff[0]); assert(std::ranges::begin(std::move(c)) == &globalBuff[0]); + assert(std::ranges::cbegin(std::move(c)) == &globalBuff[0]); BeginMemberFunction d; assert(std::ranges::begin(d) == &d.x); @@ -198,44 +205,44 @@ constexpr bool testBeginFunction() { BeginFunction a{}; const BeginFunction aa{}; - static_assert(!std::invocable); - assert(std::ranges::begin(aa) == &aa.x); + static_assert(!std::invocable); assert(std::ranges::cbegin(a) == &a.x); + assert(std::ranges::begin(aa) == &aa.x); assert(std::ranges::cbegin(aa) == &aa.x); BeginFunctionByValue b{}; const BeginFunctionByValue bb{}; assert(std::ranges::begin(b) == &globalBuff[1]); - assert(std::ranges::begin(bb) == &globalBuff[1]); assert(std::ranges::cbegin(b) == &globalBuff[1]); + assert(std::ranges::begin(bb) == &globalBuff[1]); assert(std::ranges::cbegin(bb) == &globalBuff[1]); BeginFunctionEnabledBorrowing c{}; const BeginFunctionEnabledBorrowing cc{}; assert(std::ranges::begin(std::move(c)) == &globalBuff[2]); - static_assert(!std::invocable); + assert(std::ranges::cbegin(std::move(c)) == &globalBuff[2]); assert(std::ranges::begin(std::move(cc)) == &globalBuff[2]); assert(std::ranges::cbegin(std::move(cc)) == &globalBuff[2]); BeginFunctionReturnsEmptyPtr d{}; const BeginFunctionReturnsEmptyPtr dd{}; - static_assert(!std::invocable); - assert(std::ranges::begin(dd) == &dd.x); + static_assert(!std::invocable); assert(std::ranges::cbegin(d) == &d.x); + assert(std::ranges::begin(dd) == &dd.x); assert(std::ranges::cbegin(dd) == &dd.x); BeginFunctionWithDataMember e{}; const BeginFunctionWithDataMember ee{}; - static_assert(!std::invocable); + static_assert(!std::invocable); assert(std::ranges::begin(ee) == &ee.x); assert(std::ranges::cbegin(e) == &e.x); assert(std::ranges::cbegin(ee) == &ee.x); BeginFunctionWithPrivateBeginMember f{}; const BeginFunctionWithPrivateBeginMember ff{}; - static_assert(!std::invocable); - assert(std::ranges::begin(ff) == &ff.y); + static_assert(!std::invocable); assert(std::ranges::cbegin(f) == &f.y); + assert(std::ranges::begin(ff) == &ff.y); assert(std::ranges::cbegin(ff) == &ff.y); return true; @@ -264,6 +271,11 @@ ASSERT_NOT_NOEXCEPT(std::ranges::begin(std::declval>&>())); ASSERT_NOT_NOEXCEPT(std::ranges::cbegin(std::declval>&>())); +// Test ADL-proofing. +struct Incomplete; +template struct Holder { T t; }; +static_assert(!std::is_invocable_v*>); +static_assert(!std::is_invocable_v*>); int main(int, char**) { testArray(); diff --git a/libcxx/test/std/ranges/range.access/range.access.end/end.pass.cpp b/libcxx/test/std/ranges/range.access/range.access.end/end.pass.cpp --- a/libcxx/test/std/ranges/range.access/range.access.end/end.pass.cpp +++ b/libcxx/test/std/ranges/range.access/range.access.end/end.pass.cpp @@ -11,6 +11,7 @@ // UNSUPPORTED: libcpp-has-no-incomplete-ranges // std::ranges::end +// std::ranges::cend #include @@ -18,8 +19,8 @@ #include "test_macros.h" #include "test_iterators.h" -using RangeEndT = decltype(std::ranges::end)&; -using RangeCEndT = decltype(std::ranges::cend)&; +using RangeEndT = decltype(std::ranges::end); +using RangeCEndT = decltype(std::ranges::cend); static int globalBuff[8]; @@ -133,9 +134,11 @@ NonConstEndMember b; assert(std::ranges::end(b) == &b.x); + static_assert(!std::is_invocable_v); EnabledBorrowingEndMember c; assert(std::ranges::end(std::move(c)) == &globalBuff[0]); + assert(std::ranges::cend(std::move(c)) == &globalBuff[0]); EndMemberFunction d; assert(std::ranges::end(d) == &d.x); @@ -240,7 +243,9 @@ constexpr bool testEndFunction() { const EndFunction a{}; assert(std::ranges::end(a) == &a.x); + assert(std::ranges::cend(a) == &a.x); EndFunction aa{}; + static_assert(!std::is_invocable_v); assert(std::ranges::cend(aa) == &aa.x); EndFunctionByValue b; @@ -249,25 +254,34 @@ EndFunctionEnabledBorrowing c; assert(std::ranges::end(std::move(c)) == &globalBuff[2]); + assert(std::ranges::cend(std::move(c)) == &globalBuff[2]); const EndFunctionReturnsEmptyPtr d{}; assert(std::ranges::end(d) == &d.x); + assert(std::ranges::cend(d) == &d.x); EndFunctionReturnsEmptyPtr dd{}; + static_assert(!std::is_invocable_v); assert(std::ranges::cend(dd) == &dd.x); const EndFunctionWithDataMember e{}; assert(std::ranges::end(e) == &e.x); + assert(std::ranges::cend(e) == &e.x); EndFunctionWithDataMember ee{}; + static_assert(!std::is_invocable_v); assert(std::ranges::cend(ee) == &ee.x); const EndFunctionWithPrivateEndMember f{}; assert(std::ranges::end(f) == &f.y); + assert(std::ranges::cend(f) == &f.y); EndFunctionWithPrivateEndMember ff{}; + static_assert(!std::is_invocable_v); assert(std::ranges::cend(ff) == &ff.y); const BeginMemberEndFunction g{}; assert(std::ranges::end(g) == &g.x); + assert(std::ranges::cend(g) == &g.x); BeginMemberEndFunction gg{}; + static_assert(!std::is_invocable_v); assert(std::ranges::cend(gg) == &gg.x); return true; @@ -298,6 +312,11 @@ ASSERT_NOT_NOEXCEPT(std::ranges::end(std::declval>&>())); ASSERT_NOT_NOEXCEPT(std::ranges::cend(std::declval>&>())); +// Test ADL-proofing. +struct Incomplete; +template struct Holder { T t; }; +static_assert(!std::is_invocable_v*>); +static_assert(!std::is_invocable_v*>); int main(int, char**) { testArray(); diff --git a/libcxx/test/std/ranges/range.access/range.prim/data.pass.cpp b/libcxx/test/std/ranges/range.access/range.prim/data.pass.cpp --- a/libcxx/test/std/ranges/range.access/range.prim/data.pass.cpp +++ b/libcxx/test/std/ranges/range.access/range.prim/data.pass.cpp @@ -116,9 +116,10 @@ random_access_iterator begin() const; }; -static_assert(!std::is_invocable_v); -static_assert(!std::is_invocable_v); -static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); struct BeginFriendContiguousIterator { int buff[8]; @@ -135,9 +136,10 @@ struct BeginFriendRandomAccess { friend random_access_iterator begin(const BeginFriendRandomAccess iter); }; -static_assert(!std::is_invocable_v); -static_assert(!std::is_invocable_v); -static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); struct BeginMemberRvalue { int buff[8]; @@ -173,6 +175,17 @@ return true; } +// Test ADL-proofing. +struct Incomplete; +template struct Holder { T t; }; +static_assert(!std::is_invocable_v*>); + +struct RandomButNotContiguous { + random_access_iterator begin() const; + random_access_iterator end() const; +}; +static_assert(!std::is_invocable_v); + int main(int, char**) { testDataMember(); static_assert(testDataMember()); diff --git a/libcxx/test/std/ranges/range.access/range.prim/empty.pass.cpp b/libcxx/test/std/ranges/range.access/range.prim/empty.pass.cpp --- a/libcxx/test/std/ranges/range.access/range.prim/empty.pass.cpp +++ b/libcxx/test/std/ranges/range.access/range.prim/empty.pass.cpp @@ -15,11 +15,11 @@ #include #include +#include #include "test_macros.h" #include "test_iterators.h" using RangeEmptyT = decltype(std::ranges::empty); -using RangeSizeT = decltype(std::ranges::size); static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); @@ -30,12 +30,27 @@ static_assert( std::is_invocable_v); static_assert( std::is_invocable_v); -struct NonConstSizeAndEmpty { - int size(); +struct Incomplete; +static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); + +extern Incomplete array_of_incomplete[42]; +static_assert(!std::ranges::empty(array_of_incomplete)); +static_assert(!std::ranges::empty(std::move(array_of_incomplete))); +static_assert(!std::ranges::empty(std::as_const(array_of_incomplete))); +static_assert(!std::ranges::empty(static_cast(array_of_incomplete))); + +struct InputRangeWithoutSize { + cpp17_input_iterator begin() const; + cpp17_input_iterator end() const; +}; +static_assert(!std::is_invocable_v); + +struct NonConstEmpty { bool empty(); }; -static_assert(!std::is_invocable_v); -static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); struct HasMemberAndFunction { constexpr bool empty() const { return true; } @@ -49,7 +64,7 @@ static_assert(!std::is_invocable_v); struct BoolConvertible { - constexpr /*TODO: explicit*/ operator bool() noexcept(false) { return true; } + constexpr explicit operator bool() noexcept(false) { return true; } }; struct BoolConvertibleReturnType { constexpr BoolConvertible empty() noexcept { return {}; } @@ -148,13 +163,16 @@ assert(std::ranges::empty(e) == false); // e.empty() assert(std::ranges::empty(std::as_const(e)) == true); // e.begin() == e.end() -#if 0 // TODO FIXME assert(std::ranges::empty(EvilBeginEnd())); -#endif return true; } +// Test ADL-proofing. +struct Incomplete; +template struct Holder { T t; }; +static_assert(!std::is_invocable_v*>); + int main(int, char**) { testEmptyMember(); static_assert(testEmptyMember()); diff --git a/libcxx/test/std/ranges/range.access/range.prim/size.pass.cpp b/libcxx/test/std/ranges/range.access/range.prim/size.pass.cpp --- a/libcxx/test/std/ranges/range.access/range.prim/size.pass.cpp +++ b/libcxx/test/std/ranges/range.access/range.prim/size.pass.cpp @@ -124,7 +124,7 @@ bool constexpr testHasSizeFunction() { assert(std::ranges::size(SizeFunction()) == 42); ASSERT_SAME_TYPE(decltype(std::ranges::size(SizeFunction())), size_t); - assert(std::ranges::size(MoveOnlySizeFunction()) == 42); + static_assert(!std::is_invocable_v); assert(std::ranges::size(EnumSizeFunction()) == 42); assert(std::ranges::size(SizeFunctionConst()) == 42); @@ -305,6 +305,11 @@ return true; } +// Test ADL-proofing. +struct Incomplete; +template struct Holder { T t; }; +static_assert(!std::is_invocable_v*>); + int main(int, char**) { testArrayType(); static_assert(testArrayType()); diff --git a/libcxx/test/std/ranges/range.access/range.prim/ssize.pass.cpp b/libcxx/test/std/ranges/range.access/range.prim/ssize.pass.cpp --- a/libcxx/test/std/ranges/range.access/range.prim/ssize.pass.cpp +++ b/libcxx/test/std/ranges/range.access/range.prim/ssize.pass.cpp @@ -80,6 +80,11 @@ return true; } +// Test ADL-proofing. +struct Incomplete; +template struct Holder { T t; }; +static_assert(!std::is_invocable_v*>); + int main(int, char**) { test(); static_assert(test()); diff --git a/libcxx/test/std/ranges/range.req/range.range/range.compile.pass.cpp b/libcxx/test/std/ranges/range.req/range.range/range.compile.pass.cpp --- a/libcxx/test/std/ranges/range.req/range.range/range.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.req/range.range/range.compile.pass.cpp @@ -46,3 +46,8 @@ int* end(); }; static_assert(!std::ranges::range); + +// Test ADL-proofing. +struct Incomplete; +template struct Holder { T t; }; +static_assert(!std::ranges::range*>); diff --git a/libcxx/test/std/ranges/range.req/range.sized/sized_range.compile.pass.cpp b/libcxx/test/std/ranges/range.req/range.sized/sized_range.compile.pass.cpp --- a/libcxx/test/std/ranges/range.req/range.sized/sized_range.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.req/range.sized/sized_range.compile.pass.cpp @@ -17,13 +17,14 @@ #include "test_iterators.h" - - static_assert(std::ranges::sized_range); static_assert(std::ranges::sized_range); static_assert(!std::ranges::sized_range); static_assert(!std::ranges::sized_range); +struct Incomplete; +static_assert(!std::ranges::sized_range); + struct range_has_size { bidirectional_iterator begin(); bidirectional_iterator end();