diff --git a/libcxx/include/concepts b/libcxx/include/concepts --- a/libcxx/include/concepts +++ b/libcxx/include/concepts @@ -194,6 +194,11 @@ concept default_initializable = constructible_from<_Tp> && requires { _Tp{}; } && __default_initializable<_Tp>; +// [concept.moveconstructible] +template +concept move_constructible = + constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>; + #endif //_LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/test/std/concepts/lang/moveconstructible.h b/libcxx/test/std/concepts/lang/moveconstructible.h new file mode 100644 --- /dev/null +++ b/libcxx/test/std/concepts/lang/moveconstructible.h @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +#ifndef MOVECONSTRUCTIBLE_H +#define MOVECONSTRUCTIBLE_H + +struct HasDefaultOps {}; + +struct CustomMoveCtor { + CustomMoveCtor(CustomMoveCtor&&) noexcept; +}; + +struct MoveOnly { + MoveOnly(MoveOnly&&) noexcept = default; + MoveOnly& operator=(MoveOnly&&) noexcept = default; + MoveOnly(const MoveOnly&) = delete; + MoveOnly& operator=(const MoveOnly&) = default; +}; + +struct CustomMoveAssign { + CustomMoveAssign(CustomMoveAssign&&) noexcept; + CustomMoveAssign& operator=(CustomMoveAssign&&) noexcept; +}; + +struct DeletedMoveCtor { + DeletedMoveCtor(DeletedMoveCtor&&) = delete; +}; + +struct ImplicitlyDeletedMoveCtor { + DeletedMoveCtor X; +}; + +struct DeletedMoveAssign { + DeletedMoveAssign& operator=(DeletedMoveAssign&&) = default; +}; + +struct ImplicitlyDeletedMoveAssign { + DeletedMoveAssign X; +}; + +class MemberLvalueReference { +public: + MemberLvalueReference(int&); + +private: + int& X; +}; + +class MemberRvalueReference { +public: + MemberRvalueReference(int&&); + +private: + int&& X; +}; + +#endif // MOVECONSTRUCTIBLE_H \ No newline at end of file diff --git a/libcxx/test/std/concepts/lang/moveconstructible.compile.pass.cpp b/libcxx/test/std/concepts/lang/moveconstructible.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/concepts/lang/moveconstructible.compile.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// 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++98, c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-no-concepts + +// template +// concept move_constructible; + +#include +#include + +#include "moveconstructible.h" + +int main(int, char**) { + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + + static_assert(!std::move_constructible); + static_assert(!std::move_constructible); + static_assert(!std::move_constructible); + static_assert(!std::move_constructible); + static_assert(!std::move_constructible); + static_assert(!std::move_constructible); + static_assert(!std::move_constructible); + static_assert(!std::move_constructible); + static_assert(!std::move_constructible); + static_assert(!std::move_constructible); + + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + static_assert(std::move_constructible); + return 0; +}