diff --git a/libcxx/include/concepts b/libcxx/include/concepts --- a/libcxx/include/concepts +++ b/libcxx/include/concepts @@ -162,6 +162,11 @@ template concept destructible = _VSTD::is_nothrow_destructible_v<_Tp>; +// [concept.constructible] +template +concept constructible_from = + destructible<_Tp> && _VSTD::is_constructible_v<_Tp, _Args...>; + #endif //_LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/test/std/concepts/concept.constructible/constructible_from.compile.pass.cpp b/libcxx/test/std/concepts/concept.constructible/constructible_from.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/concepts/concept.constructible/constructible_from.compile.pass.cpp @@ -0,0 +1,151 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// template +// concept constructible_from; +// destructible && is_constructible_v; + +#include +#include +#include +#include +#include + +struct Empty {}; + +struct Defaulted { + ~Defaulted() = default; +}; +struct Deleted { + ~Deleted() = delete; +}; + +struct Noexcept { + ~Noexcept() noexcept; +}; +struct NoexceptTrue { + ~NoexceptTrue() noexcept(true); +}; +struct NoexceptFalse { + ~NoexceptFalse() noexcept(false); +}; + +struct Protected { +protected: + ~Protected() = default; +}; +struct Private { +private: + ~Private() = default; +}; + +template +struct NoexceptDependant { + ~NoexceptDependant() noexcept(std::is_same_v); +}; + +template +void test() { + static_assert(std::constructible_from == + (std::destructible && std::is_constructible_v)); +} + +void test() { + test(); + test(); + + test(); + test(); + test(); + + test(); + test(); + test(); + + test(); + test(); + test(); + + test(); + test(); + test(); + + test(); + test(); + + test(); + test(); + test(); + test(); + test(); + test(); + + test(); + test(); + test(); + test(); + test(); + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + + test(); + test(); + test(); + test(); + + test(); + + test(); + test(); + + test(); + test(); + test(); + + test(); + test(); + + test >(); + test >(); + + test(); + test(); + test(); + test >(); + + test, std::unique_ptr >(); + test, std::unique_ptr&>(); + test, std::unique_ptr&&>(); + + test >(); + test, int>(); + test, int, int>(); +}