blob: b034c7af07258b6566bdc66564714f34b7b43d1f [file] [log] [blame]
// { dg-do compile { target c++26 } }
#include <functional>
#include <type_traits>
using std::is_same_v;
using std::nontype;
using std::nontype_t;
using std::function_ref;
int i = 0;
template<auto f, class... Args>
concept deductible = requires (Args&... args)
{ std::function_ref(std::nontype<f>, args...); };
static_assert( !deductible<1> );
static_assert( !deductible<1, int> );
void f0();
void f0n() noexcept;
static_assert( is_same_v<decltype(function_ref(f0)),
function_ref<void()>> );
static_assert( is_same_v<decltype(function_ref(f0n)),
function_ref<void() noexcept>> );
static_assert( is_same_v<decltype(function_ref(nontype<f0>)),
function_ref<void()>> );
static_assert( is_same_v<decltype(function_ref(nontype<f0n>)),
function_ref<void() noexcept>> );
static_assert( !deductible<f0, char*> );
static_assert( !deductible<f0n, char*> );
void f1(int);
void f1n(int) noexcept;
static_assert( is_same_v<decltype(function_ref(f1)),
function_ref<void(int)>> );
static_assert( is_same_v<decltype(function_ref(f1n)),
function_ref<void(int) noexcept>> );
static_assert( is_same_v<decltype(function_ref(nontype<f1>)),
function_ref<void(int)>> );
static_assert( is_same_v<decltype(function_ref(nontype<f1n>)),
function_ref<void(int) noexcept>> );
static_assert( is_same_v<decltype(function_ref(nontype<f1>, i)),
function_ref<void()>> );
static_assert( is_same_v<decltype(function_ref(nontype<f1n>, i)),
function_ref<void() noexcept>> );
static_assert( !deductible<f1, char*> );
static_assert( !deductible<f1n, char*> );
void f2(int*, int);
void f2n(int*, int) noexcept;
static_assert( is_same_v<decltype(function_ref(f2)),
function_ref<void(int*, int)>> );
static_assert( is_same_v<decltype(function_ref(f2n)),
function_ref<void(int*, int) noexcept>> );
static_assert( is_same_v<decltype(function_ref(nontype<f2>)),
function_ref<void(int*, int)>> );
static_assert( is_same_v<decltype(function_ref(nontype<f2n>)),
function_ref<void(int*, int) noexcept>> );
static_assert( is_same_v<decltype(function_ref(nontype<f2>, &i)),
function_ref<void(int)>> );
static_assert( is_same_v<decltype(function_ref(nontype<f2n>, &i)),
function_ref<void(int) noexcept>> );
static_assert( !deductible<f2, char*> );
static_assert( !deductible<f2n, char*> );
struct S
{
int mem;
int f();
int fn() noexcept;
int fc(int) const;
int fcn(int) const noexcept;
int fl(int) &;
int fln(int) & noexcept;
int fcl(float) const&;
int fcln(float) const& noexcept;
int fr(int) &&;
int frn(int) && noexcept;
};
S s{};
const S cs{};
static_assert( is_same_v<decltype(function_ref(nontype<&S::mem>, s)),
function_ref<int&() noexcept>> );
static_assert( is_same_v<decltype(function_ref(nontype<&S::mem>, cs)),
function_ref<const int&() noexcept>> );
static_assert( is_same_v<decltype(function_ref(nontype<&S::mem>, &s)),
function_ref<int&() noexcept>> );
static_assert( is_same_v<decltype(function_ref(nontype<&S::mem>, &cs)),
function_ref<const int&() noexcept>> );
static_assert( !deductible<&S::mem, int> );
static_assert( is_same_v<decltype(function_ref(nontype<&S::f>, s)),
function_ref<int()>> );
static_assert( is_same_v<decltype(function_ref(nontype<&S::fn>, &s)),
function_ref<int() noexcept>> );
static_assert( !deductible<&S::f, char*> );
static_assert( !deductible<&S::fn, char*> );
static_assert( !deductible<&S::f, const S> );
static_assert( !deductible<&S::fn, const S> );
static_assert( is_same_v<decltype(function_ref(nontype<&S::fc>, &s)),
function_ref<int(int)>> );
static_assert( is_same_v<decltype(function_ref(nontype<&S::fcn>, s)),
function_ref<int(int) noexcept>> );
static_assert( !deductible<&S::fc, char*> );
static_assert( !deductible<&S::fcn, char*> );
static_assert( is_same_v<decltype(function_ref(nontype<&S::fl>, &s)),
function_ref<int(int)>> );
static_assert( is_same_v<decltype(function_ref(nontype<&S::fln>, s)),
function_ref<int(int) noexcept>> );
static_assert( is_same_v<decltype(function_ref(nontype<&S::fcl>, s)),
function_ref<int(float)>> );
static_assert( is_same_v<decltype(function_ref(nontype<&S::fcln>, &s)),
function_ref<int(float) noexcept>> );
static_assert( !deductible<&S::fr, char*> );
static_assert( !deductible<&S::frn, char*> );
static_assert( !deductible<&S::fr, S> );
static_assert( !deductible<&S::frn, S> );