blob: 730a07202062de69fdb0f1b8ded177da107b725d [file] [edit]
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
// REQUIRES: std-at-least-c++26
// template<class F>
// function_ref(F*) -> function_ref<F>;
//
// template<auto c, class F0>
// function_ref(constant_wrapper<c, F0>) -> function_ref<see below>;
//
// template<auto c, class F, class T>
// function_ref(constant_wrapper<c, F>, T&&) -> function_ref<see below>;
#include <cassert>
#include <functional>
#include <utility>
#include <type_traits>
#include "test_macros.h"
int fn(int, float) { return 42; }
int fn_noexcept(int, float) noexcept { return 42; }
struct S {
int data_mem = 42;
int fn_mem(int, float) { return 42; }
int fn_mem_ref(int, float) & { return 42; }
int fn_mem_const(int, float) const { return 42; }
int fn_mem_const_ref(int, float) const& { return 42; }
int fn_mem_noexcept(int, float) noexcept { return 42; }
};
void test() {
// template<class F>
// function_ref(F*) -> function_ref<F>;
{
std::function_ref fn_ref = fn;
static_assert(std::is_same_v<decltype(fn_ref), std::function_ref<int(int, float)>>);
}
{
std::function_ref fn_ref = fn_noexcept;
static_assert(std::is_same_v<decltype(fn_ref), std::function_ref<int(int, float) noexcept>>);
}
// template<auto c, class F>
// function_ref(constant_wrapper<c, F>) -> function_ref<...>;
{
std::function_ref fn_ref = std::constant_wrapper<fn>();
static_assert(std::is_same_v<decltype(fn_ref), std::function_ref<int(int, float)>>);
}
{
std::function_ref fn_ref = std::constant_wrapper<fn_noexcept>();
static_assert(std::is_same_v<decltype(fn_ref), std::function_ref<int(int, float) noexcept>>);
}
// template<auto c, class F, class T>
// function_ref(constant_wrapper<c, F>, T&&) -> function_ref<...>;
{
int arg = 0;
std::function_ref fn_ref = {std::constant_wrapper<fn>(), arg};
static_assert(std::is_same_v<decltype(fn_ref), std::function_ref<int(float)>>);
}
{
int arg = 0;
std::function_ref fn_ref = {std::constant_wrapper<fn_noexcept>(), arg};
static_assert(std::is_same_v<decltype(fn_ref), std::function_ref<int(float) noexcept>>);
}
{
S s;
std::function_ref fn_ref = {std::constant_wrapper<&S::data_mem>(), s};
static_assert(std::is_same_v<decltype(fn_ref), std::function_ref<int&() noexcept>>);
}
{
const S s;
std::function_ref fn_ref = {std::constant_wrapper<&S::data_mem>(), s};
static_assert(std::is_same_v<decltype(fn_ref), std::function_ref<int const&() noexcept>>);
}
{
S s;
std::function_ref fn_ref = {std::constant_wrapper<&S::fn_mem>(), s};
static_assert(std::is_same_v<decltype(fn_ref), std::function_ref<int(int, float)>>);
}
{
S s;
std::function_ref fn_ref = {std::constant_wrapper<&S::fn_mem_const>(), s};
static_assert(std::is_same_v<decltype(fn_ref), std::function_ref<int(int, float)>>);
}
{
S s;
std::function_ref fn_ref = {std::constant_wrapper<&S::fn_mem_ref>(), s};
static_assert(std::is_same_v<decltype(fn_ref), std::function_ref<int(int, float)>>);
}
{
S s;
std::function_ref fn_ref = {std::constant_wrapper<&S::fn_mem_const_ref>(), s};
static_assert(std::is_same_v<decltype(fn_ref), std::function_ref<int(int, float)>>);
}
{
S s;
std::function_ref fn_ref = {std::constant_wrapper<&S::fn_mem_noexcept>(), s};
static_assert(std::is_same_v<decltype(fn_ref), std::function_ref<int(int, float) noexcept>>);
}
}
int main(int, char**) {
test();
return 0;
}