blob: 9b02dc49c2a302875adb337de97a916b4ba27c83 [file] [log] [blame]
// { dg-do compile { target c++26 } }
#include <functional>
#ifndef __cpp_lib_function_ref
# error "Feature-test macro for function_ref missing in <functional>"
#elif __cpp_lib_function_ref != 202306L
# error "Feature-test macro for function_ref has wrong value in <functional>"
#endif
using std::nontype;
using std::nontype_t;
using std::function_ref;
using std::is_nothrow_move_assignable_v;
using std::is_nothrow_copy_assignable_v;
using std::is_nothrow_assignable_v;
using std::is_assignable_v;
using std::is_nothrow_swappable_v;
using std::is_trivially_copyable_v;
static_assert( is_nothrow_move_assignable_v<function_ref<void()>> );
static_assert( is_nothrow_copy_assignable_v<function_ref<void()>> );
static_assert( is_nothrow_swappable_v<function_ref<void()>> );
static_assert( ! is_assignable_v<function_ref<void()>, std::nullptr_t> );
static_assert( is_nothrow_assignable_v<function_ref<void()>, void()> );
static_assert( is_nothrow_assignable_v<function_ref<void()>, void(&)()> );
static_assert( is_nothrow_assignable_v<function_ref<void()>, void(*)()> );
static_assert( is_nothrow_assignable_v<function_ref<void()>, int()> );
static_assert( is_nothrow_assignable_v<function_ref<void()>, int(&)()> );
static_assert( is_nothrow_assignable_v<function_ref<void()>, int(*)()> );
static_assert( ! is_nothrow_assignable_v<function_ref<void()>, void(int)> );
static_assert( is_nothrow_assignable_v<function_ref<void(int)>, void(int)> );
static_assert( is_nothrow_assignable_v<function_ref<void()>,
void() noexcept> );
static_assert( is_nothrow_assignable_v<function_ref<void() noexcept>,
void() noexcept> );
static_assert( ! is_assignable_v<function_ref<void() noexcept>, void() > );
struct S
{
int x;
int f();
};
int funS(S);
static_assert( is_nothrow_assignable_v<function_ref<int(S)>,
decltype(funS)> );
static_assert( is_nothrow_assignable_v<function_ref<int(S)>,
decltype(&funS)> );
static_assert( ! is_assignable_v<function_ref<int(S)>, decltype(&S::x)> );
static_assert( ! is_assignable_v<function_ref<int(S)>, decltype(&S::f)> );
static_assert( is_nothrow_assignable_v<function_ref<int(S)>,
nontype_t<funS>> );
static_assert( is_nothrow_assignable_v<function_ref<int(S)>,
nontype_t<&funS>> );
static_assert( is_nothrow_assignable_v<function_ref<int(S)>,
nontype_t<&S::x>> );
static_assert( is_nothrow_assignable_v<function_ref<int(S)>,
nontype_t<&S::f>> );
struct Q
{
void operator()() const;
};
static_assert( ! is_assignable_v<function_ref<void()>, Q> );
static_assert( ! is_assignable_v<function_ref<void()>, Q&> );
static_assert( ! is_assignable_v<function_ref<void()>, const Q&> );
static_assert( ! is_assignable_v<function_ref<void() const>, Q> );
static_assert( ! is_assignable_v<function_ref<void() const>, Q&> );
static_assert( ! is_assignable_v<function_ref<void() const>, const Q&> );
static_assert( is_nothrow_assignable_v<function_ref<void()>,
nontype_t<Q{}>> );
static_assert( is_nothrow_assignable_v<function_ref<void() const>,
nontype_t<Q{}>> );
constexpr bool
test_constexpr()
{
function_ref<void(S)> fp(nontype<funS>);
fp = nontype<funS>;
fp = nontype<&funS>;
fp = nontype<&S::x>;
fp = nontype<&S::f>;
constexpr Q cq;
function_ref<void() const> fq(cq);
fq = nontype<cq>;
return true;
}
static_assert( test_constexpr() );
void func();
void
test_instantiation()
{
function_ref<void(S)> fp(funS);
fp = funS;
fp = &funS;
test_constexpr();
}