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