// { dg-options "-std=gnu++23" } // { dg-do compile { target c++23 } } // { dg-require-effective-target hosted } #include #ifndef __cpp_lib_move_only_function # error "Feature-test macro for move_only_function missing in " #elif __cpp_lib_move_only_function != 202110L # error "Feature-test macro for move_only_function has wrong value in " #endif using std::move_only_function; using std::is_constructible_v; using std::is_copy_constructible_v; using std::is_nothrow_default_constructible_v; using std::is_nothrow_move_constructible_v; using std::is_nothrow_constructible_v; using std::nullptr_t; using std::in_place_type_t; static_assert( is_nothrow_default_constructible_v> ); static_assert( is_nothrow_constructible_v, nullptr_t> ); static_assert( is_nothrow_move_constructible_v> ); static_assert( ! is_copy_constructible_v> ); static_assert( is_constructible_v, void()> ); static_assert( is_constructible_v, void(&)()> ); static_assert( is_constructible_v, void(*)()> ); static_assert( is_constructible_v, int()> ); static_assert( is_constructible_v, int(&)()> ); static_assert( is_constructible_v, int(*)()> ); static_assert( ! is_constructible_v, void(int)> ); static_assert( is_constructible_v, void(int)> ); static_assert( is_constructible_v, in_place_type_t, void(int)> ); static_assert( is_constructible_v, void() noexcept> ); static_assert( is_constructible_v, void() noexcept> ); static_assert( ! is_constructible_v, void() > ); struct Q { void operator()() const &; void operator()() &&; }; static_assert( is_constructible_v, Q> ); static_assert( is_constructible_v, Q> ); static_assert( is_constructible_v, Q> ); static_assert( is_constructible_v, Q> ); static_assert( is_constructible_v, Q> ); static_assert( is_constructible_v, Q> ); struct R { void operator()() &; void operator()() &&; }; static_assert( is_constructible_v, R> ); static_assert( is_constructible_v, R> ); static_assert( is_constructible_v, R> ); static_assert( ! is_constructible_v, R> ); static_assert( ! is_constructible_v, R> ); static_assert( ! is_constructible_v, R> ); // The following nothrow-constructible guarantees are a GCC extension, // not required by the standard. static_assert( is_nothrow_constructible_v, void()> ); static_assert( is_nothrow_constructible_v, in_place_type_t, void(int)> ); // These types are all small and nothrow move constructible struct F { void operator()(); }; struct G { void operator()() const; }; static_assert( is_nothrow_constructible_v, F> ); static_assert( is_nothrow_constructible_v, G> ); static_assert( is_nothrow_constructible_v, G> ); struct H { H(int); H(int, int) noexcept; void operator()() noexcept; }; static_assert( is_nothrow_constructible_v, H> ); static_assert( is_nothrow_constructible_v, H> ); static_assert( ! is_nothrow_constructible_v, in_place_type_t, int> ); static_assert( is_nothrow_constructible_v, in_place_type_t, int, int> ); struct I { I(int, const char*); I(std::initializer_list); int operator()() const noexcept; }; static_assert( is_constructible_v, std::in_place_type_t, int, const char*> ); static_assert( is_constructible_v, std::in_place_type_t, std::initializer_list> ); void test_instantiation() { // Instantiate the constructor bodies move_only_function f0; move_only_function f1(nullptr); move_only_function f2( I(1, "two") ); move_only_function f3(std::in_place_type, 3, "four"); move_only_function f4(std::in_place_type, // PR libstdc++/102825 { 'P', 'R', '1', '0', '2', '8', '2', '5'}); auto f5 = std::move(f4); f4 = std::move(f5); }