Index: libcxx/include/concepts =================================================================== --- libcxx/include/concepts +++ libcxx/include/concepts @@ -151,6 +151,12 @@ template concept same_as = __same_as_impl && __same_as_impl; +// [concept.derived] +template +concept derived_from = + is_base_of_v && + is_convertible_v; + #endif //_LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD Index: libcxx/test/std/concepts/lang/derived_from.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/concepts/lang/derived_from.pass.cpp @@ -0,0 +1,111 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include + +struct Base1 {}; +struct Derived1 : Base1 {}; +struct Derived2 : Base1 {}; + +struct Base2 : private Base1 {}; +struct Derived3 : Base2 {}; + +struct Base3 : protected Base2 {}; +struct Derived4 : Base3 {}; +struct Derived5 : Derived4 {}; + +int main() { + { // Base1 is the subject. + static_assert(std::derived_from); + static_assert(!std::derived_from); + static_assert(!std::derived_from); + + static_assert(!std::derived_from); + static_assert(!std::derived_from); + static_assert(!std::derived_from); + static_assert(!std::derived_from); + } + + { // Derived1 is the subject. + static_assert(std::derived_from); + static_assert(!std::derived_from); + static_assert(!std::derived_from); + + static_assert(std::derived_from); + static_assert(!std::derived_from); + static_assert(!std::derived_from); + static_assert(!std::derived_from); + } + + { // Derived2 is the subject. + static_assert(std::derived_from); + static_assert(!std::derived_from); + static_assert(!std::derived_from); + + static_assert(!std::derived_from); + static_assert(std::derived_from); + static_assert(!std::derived_from); + static_assert(!std::derived_from); + } + + { // Base2 is the subject. + static_assert(!std::derived_from); + static_assert(std::derived_from); + static_assert(!std::derived_from); + + static_assert(!std::derived_from); + static_assert(!std::derived_from); + static_assert(!std::derived_from); + static_assert(!std::derived_from); + } + + { // Derived3 is the subject. + static_assert(!std::derived_from); + static_assert(std::derived_from); + static_assert(!std::derived_from); + + static_assert(!std::derived_from); + static_assert(!std::derived_from); + static_assert(std::derived_from); + static_assert(!std::derived_from); + } + + { // Base3 is the subject. + static_assert(!std::derived_from); + static_assert(!std::derived_from); + static_assert(std::derived_from); + + static_assert(!std::derived_from); + static_assert(!std::derived_from); + static_assert(!std::derived_from); + static_assert(!std::derived_from); + } + + { // Derived4 is the subject. + static_assert(!std::derived_from); + static_assert(!std::derived_from); + static_assert(std::derived_from); + + static_assert(!std::derived_from); + static_assert(!std::derived_from); + static_assert(!std::derived_from); + static_assert(std::derived_from); + } + + { // Derived5 is the subject. + static_assert(!std::derived_from); + static_assert(!std::derived_from); + static_assert(std::derived_from); + + static_assert(!std::derived_from); + static_assert(!std::derived_from); + static_assert(!std::derived_from); + static_assert(std::derived_from); + static_assert(std::derived_from); + } +}