Some types that inherit from view_interface do not meet the
preconditions. This came up during discussion
in https://reviews.llvm.org/D112631. Currently, the behavior is IFNDR,
but the preconditions can be easily checked, so let's do so.
In particular, we know each public member function calls the
__derived() private function, so we can do the check there. We
intentionally do it as a static_assert instead of a requires clause
to avoid hard erroring in some cases, such as with incomplete types. An
example hard error is:
llvm-project/build/include/c++/v1/__ranges/view_interface.h:48:14: note: because 'sizeof(_Tp)' would be invalid: invalid application of 'sizeof' to an incomplete type 'MoveOnlyForwardRange' requires { sizeof(_Tp); } && ^ llvm-project/build/include/c++/v1/__ranges/view_interface.h:73:26: error: no matching member function for call to '__derived' return ranges::begin(__derived()) == ranges::end(__derived()); ^~~~~~~~~ llvm-project/libcxx/test/std/ranges/range.utility/view.interface/view.interface.pass.cpp:187:31: note: in instantiation of function template specialization 'std::ranges::view_interface<MoveOnlyForwardRange>::empty<Mov eOnlyForwardRange>' requested here assert(!std::move(moveOnly).empty());
Flashbacks to "Concepts As She Is Spoke"! :) Remember that view<_Tp> is always well-formed. Sometimes its runtime boolean value will be "false," but it's always well-formed (and has type bool). What you meant was
However, I really don't think this should be a concept, because it depends on a property (completeness) that changes over the lifetime of the TU. I think you should just inline this into the one place it's used: that static_assert.
Collateral bonuses: