Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20

#include <cassert>
#include <functional>

#include "type_algorithms.h"
#include "common.h"

template <class T>
void test() {
{
std::move_only_function<T> f = &call_func;
std::move_only_function<T> f2;
f.swap(f2);
}
{
decltype(&call_func) ptr = nullptr;
std::move_only_function<T> f = ptr;
std::move_only_function<T> f2;
f.swap(f2);
}
{
std::move_only_function<T> f = TriviallyDestructible{};
std::move_only_function<T> f2;
f.swap(f2);
}
{
std::move_only_function<T> f = TriviallyDestructibleTooLarge{};
std::move_only_function<T> f2;
f.swap(f2);
}
{
std::move_only_function<T> f = NonTrivial{};
std::move_only_function<T> f2;
f.swap(f2);
}
}

struct S {
void func() noexcept {}
};

template <class T>
void test_member_function_pointer() {
{
std::move_only_function<T> f = &S::func;
std::move_only_function<T> f2;
f.swap(f2);
}
{
decltype(&S::func) ptr = nullptr;
std::move_only_function<T> f = ptr;
std::move_only_function<T> f2;
f.swap(f2);
}
}

int main(int, char**) {
types::for_each(types::function_noexcept_const_ref_qualified<void()>{}, []<class T> { test<T>(); });
types::for_each(types::function_noexcept_const_ref_qualified<void(S)>{}, []<class T> {
test_member_function_pointer<T>();
});

return 0;
}
36 changes: 36 additions & 0 deletions libcxx/test/support/type_algorithms.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,42 @@ struct type_list_as_pointers<type_list<Types...> > {

template <class T>
using as_pointers = typename type_list_as_pointers<T>::type;
template <class...>
struct function_noexcept_const_lvalue_ref_qualified_impl;

template <class ReturnT, class... Args>
struct function_noexcept_const_lvalue_ref_qualified_impl<ReturnT(Args...)> {
using type =
type_list<ReturnT(Args...),
ReturnT(Args...)&,
ReturnT(Args...) noexcept,
ReturnT(Args...) & noexcept,
ReturnT(Args...) const,
ReturnT(Args...) const&,
ReturnT(Args...) const noexcept,
ReturnT(Args...) const & noexcept>;
};

template <class Func>
using function_noexcept_const_lvalue_ref_qualified =
typename function_noexcept_const_lvalue_ref_qualified_impl<Func>::type;

template <class...>
struct function_noexcept_const_ref_qualified_impl;

template <class ReturnT, class... Args>
struct function_noexcept_const_ref_qualified_impl<ReturnT(Args...)> {
using type =
concatenate_t<function_noexcept_const_lvalue_ref_qualified<ReturnT(Args...)>,
type_list<ReturnT(Args...)&&,
ReturnT(Args...) && noexcept,
ReturnT(Args...) const&&,
ReturnT(Args...) const && noexcept> >;
};

template <class Func>
using function_noexcept_const_ref_qualified = typename function_noexcept_const_ref_qualified_impl<Func>::type;

} // namespace types

#endif // TEST_SUPPORT_TYPE_ALGORITHMS_H
1 change: 0 additions & 1 deletion libcxx/utils/generate_feature_test_macro_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,6 @@ def add_version_header(tc):
"name": "__cpp_lib_move_only_function",
"values": {"c++23": 202110},
"headers": ["functional"],
"unimplemented": True,
},
{
"name": "__cpp_lib_node_extract",
Expand Down