diff --git a/libcxx/include/concepts b/libcxx/include/concepts --- a/libcxx/include/concepts +++ b/libcxx/include/concepts @@ -342,6 +342,9 @@ assignable_from<_Tp&, const _Tp&> && assignable_from<_Tp&, const _Tp>; +template +concept semiregular = copyable<_Tp> && default_initializable<_Tp>; + // [concept.invocable] template concept invocable = requires(_Fn&& __fn, _Args&&... __args) { diff --git a/libcxx/test/std/concepts/object/semiregular.compile.pass.cpp b/libcxx/test/std/concepts/object/semiregular.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/concepts/object/semiregular.compile.pass.cpp @@ -0,0 +1,187 @@ +//===----------------------------------------------------------------------===// +// +// 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 semiregular = see below; + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); + +struct S {}; +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); +static_assert(std::semiregular); + +static_assert(std::semiregular >); +static_assert(std::semiregular > >); // IFNDR: doesn't model semiregular +static_assert(std::semiregular >); +static_assert(std::semiregular >); +static_assert(std::semiregular >); +static_assert( + std::semiregular< + std::map, + std::unique_ptr > >); // IFNDR: doesn't model semiregular +static_assert(std::semiregular > >); +static_assert(std::semiregular > >); +static_assert(std::semiregular, + std::unique_ptr > >); // IFNDR: doesn't model semiregular +static_assert(std::semiregular >); +static_assert(std::semiregular > >); +static_assert(std::semiregular >, + std::optional > >); + +// Not objects +static_assert(!std::semiregular); +static_assert(!std::semiregular); +static_assert(!std::semiregular); +static_assert(!std::semiregular); +static_assert(!std::semiregular); +static_assert(!std::semiregular); +static_assert(!std::semiregular); +static_assert(!std::semiregular); +static_assert(!std::semiregular); +static_assert(!std::semiregular); +static_assert(!std::semiregular); +static_assert(!std::semiregular); + +// Not copyable +static_assert(!std::semiregular >); +static_assert(!std::semiregular); +static_assert(!std::semiregular); + +// Not default_initialzable +static_assert(!std::semiregular); +static_assert( + !std::semiregular >); +static_assert(!std::semiregular); + +struct no_copy_constructor { + no_copy_constructor(no_copy_constructor const&) = delete; + no_copy_constructor(no_copy_constructor&&) = default; +}; +static_assert(!std::semiregular); + +struct no_copy_assignment { + no_copy_assignment& operator=(no_copy_assignment const&) = delete; + no_copy_assignment& operator=(no_copy_assignment&&) = default; +}; +static_assert(!std::semiregular); + +struct no_copy_assignment_mutable { + no_copy_assignment_mutable& + operator=(no_copy_assignment_mutable const&) = default; + no_copy_assignment_mutable& operator=(no_copy_assignment_mutable&) = delete; + no_copy_assignment_mutable& operator=(no_copy_assignment_mutable&&) = default; +}; +static_assert(std::is_copy_assignable_v); +static_assert(!std::semiregular); + +struct no_const_value_assignment { + no_const_value_assignment& + operator=(no_const_value_assignment const) = delete; +}; +static_assert(!std::semiregular); + +struct derived_from_noncopyable : std::unique_ptr {}; +static_assert(!std::semiregular); + +struct has_noncopyable { + std::unique_ptr x; +}; +static_assert(!std::semiregular); + +struct derived_from_non_default_initializable : std::nullopt_t {}; +static_assert(!std::semiregular); + +struct has_non_default_initializable { + std::in_place_t x; +}; +static_assert(!std::semiregular); + +struct has_const_member { + int const x; +}; +static_assert(!std::semiregular); + +struct has_volatile_member { + int volatile x; +}; +static_assert(std::semiregular); + +struct has_cv_member { + int const volatile x; +}; +static_assert(!std::semiregular); + +struct has_lvalue_reference_member { + int& x; +}; +static_assert(!std::semiregular); + +struct has_rvalue_reference_member { + int&& x; +}; +static_assert(!std::semiregular); + +struct has_array_member { + int x[5]; +}; +static_assert(std::semiregular); + +struct has_function_ref_member { + int (&f)(); +}; +static_assert(!std::semiregular); + +int main(int, char**) { return 0; }