diff options
author | Louis Dionne <ldionne@apple.com> | 2019-07-18 19:50:56 +0000 |
---|---|---|
committer | Louis Dionne <ldionne@apple.com> | 2019-07-18 19:50:56 +0000 |
commit | e1eabcdfad89f67ae575b0c86aa4a72d277378b4 (patch) | |
tree | 2c1df81755e10798c225b10e70e027268796e58d /libcxx/test/std/utilities/function.objects | |
parent | 0c99d19470bab02158856ac88dc1cc0fb40a4570 (diff) | |
download | bcm5719-llvm-e1eabcdfad89f67ae575b0c86aa4a72d277378b4.tar.gz bcm5719-llvm-e1eabcdfad89f67ae575b0c86aa4a72d277378b4.zip |
[libc++] Add C++17 deduction guides for std::function
Summary: http://llvm.org/PR39606
Reviewers: Quuxplusone
Subscribers: christof, dexonsmith, libcxx-commits
Differential Revision: https://reviews.llvm.org/D54410
llvm-svn: 366484
Diffstat (limited to 'libcxx/test/std/utilities/function.objects')
3 files changed, 283 insertions, 0 deletions
diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/deduct_F.fail.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/deduct_F.fail.cpp new file mode 100644 index 00000000000..cb1c5635c78 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/deduct_F.fail.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <functional> + +// template<class F> +// function(F) -> function<see-below>; + +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// UNSUPPORTED: libcpp-no-deduction-guides + +// The deduction guides for std::function do not handle rvalue-ref qualified +// call operators and C-style variadics. It also doesn't deduce from nullptr_t. +// Make sure we stick to the specification. + +#include <functional> +#include <type_traits> + + +struct R { }; +struct f0 { R operator()() && { return {}; } }; +struct f1 { R operator()(int, ...) { return {}; } }; + +int main() { + std::function f = f0{}; // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'function'}} + std::function g = f1{}; // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'function'}} + std::function h = nullptr; // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'function'}} +} diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/deduct_F.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/deduct_F.pass.cpp new file mode 100644 index 00000000000..e39675a65f5 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/deduct_F.pass.cpp @@ -0,0 +1,137 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <functional> + +// template<class F> +// function(F) -> function<see-below>; + +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// UNSUPPORTED: libcpp-no-deduction-guides + +#include <functional> +#include <type_traits> +#include <utility> + +#include "test_macros.h" + + +struct R { }; +struct A1 { }; +struct A2 { }; +struct A3 { }; + +#define DECLARE_FUNCTIONS_WITH_QUALS(N, ...) \ + struct f0_##N { R operator()() __VA_ARGS__ { return {}; } }; \ + struct f1_##N { R operator()(A1) __VA_ARGS__ { return {}; } }; \ + struct f2_##N { R operator()(A1, A2) __VA_ARGS__ { return {}; } }; \ + struct f3_##N { R operator()(A1, A2, A3) __VA_ARGS__ { return {}; } } \ +/**/ + +DECLARE_FUNCTIONS_WITH_QUALS(0, /* nothing */); +DECLARE_FUNCTIONS_WITH_QUALS(1, const); +DECLARE_FUNCTIONS_WITH_QUALS(2, volatile); +DECLARE_FUNCTIONS_WITH_QUALS(3, const volatile); +DECLARE_FUNCTIONS_WITH_QUALS(4, &); +DECLARE_FUNCTIONS_WITH_QUALS(5 , const &); +DECLARE_FUNCTIONS_WITH_QUALS(6 , volatile &); +DECLARE_FUNCTIONS_WITH_QUALS(7 , const volatile &); +DECLARE_FUNCTIONS_WITH_QUALS(8 , noexcept); +DECLARE_FUNCTIONS_WITH_QUALS(9 , const noexcept); +DECLARE_FUNCTIONS_WITH_QUALS(10, volatile noexcept); +DECLARE_FUNCTIONS_WITH_QUALS(11, const volatile noexcept); +DECLARE_FUNCTIONS_WITH_QUALS(12, & noexcept); +DECLARE_FUNCTIONS_WITH_QUALS(13, const & noexcept); +DECLARE_FUNCTIONS_WITH_QUALS(14, volatile & noexcept); +DECLARE_FUNCTIONS_WITH_QUALS(15, const volatile & noexcept); + +int main() { +#define CHECK_FUNCTIONS(N) \ + do { \ + /* implicit */ \ + std::function g0 = f0_##N{}; \ + ASSERT_SAME_TYPE(decltype(g0), std::function<R()>); \ + \ + std::function g1 = f1_##N{}; \ + ASSERT_SAME_TYPE(decltype(g1), std::function<R(A1)>); \ + \ + std::function g2 = f2_##N{}; \ + ASSERT_SAME_TYPE(decltype(g2), std::function<R(A1, A2)>); \ + \ + std::function g3 = f3_##N{}; \ + ASSERT_SAME_TYPE(decltype(g3), std::function<R(A1, A2, A3)>); \ + \ + /* explicit */ \ + std::function g4{f0_##N{}}; \ + ASSERT_SAME_TYPE(decltype(g4), std::function<R()>); \ + \ + std::function g5{f1_##N{}}; \ + ASSERT_SAME_TYPE(decltype(g5), std::function<R(A1)>); \ + \ + std::function g6{f2_##N{}}; \ + ASSERT_SAME_TYPE(decltype(g6), std::function<R(A1, A2)>); \ + \ + std::function g7{f3_##N{}}; \ + ASSERT_SAME_TYPE(decltype(g7), std::function<R(A1, A2, A3)>); \ + \ + /* from std::function */ \ + std::function<R(A1)> unary; \ + std::function g8 = unary; \ + ASSERT_SAME_TYPE(decltype(g8), std::function<R(A1)>); \ + \ + std::function g9 = std::move(unary); \ + ASSERT_SAME_TYPE(decltype(g9), std::function<R(A1)>); \ + \ + std::function<R(A1&&)> unary_ref; \ + std::function g10 = unary_ref; \ + ASSERT_SAME_TYPE(decltype(g10), std::function<R(A1&&)>); \ + \ + std::function g11 = std::move(unary_ref); \ + ASSERT_SAME_TYPE(decltype(g11), std::function<R(A1&&)>); \ + } while (false) \ +/**/ + + // Make sure we can deduce from function objects with valid call operators + CHECK_FUNCTIONS(0); + CHECK_FUNCTIONS(1); + CHECK_FUNCTIONS(2); + CHECK_FUNCTIONS(3); + CHECK_FUNCTIONS(4); + CHECK_FUNCTIONS(5); + CHECK_FUNCTIONS(6); + CHECK_FUNCTIONS(7); + CHECK_FUNCTIONS(8); + CHECK_FUNCTIONS(9); + CHECK_FUNCTIONS(10); + CHECK_FUNCTIONS(11); + CHECK_FUNCTIONS(12); + CHECK_FUNCTIONS(13); + CHECK_FUNCTIONS(14); + CHECK_FUNCTIONS(15); +} + +// Make sure we fail in a SFINAE-friendly manner when we try to deduce +// from a type without a valid call operator. +template <typename F, typename = decltype(std::function{std::declval<F>()})> +constexpr bool can_deduce() { return true; } +template <typename F> +constexpr bool can_deduce(...) { return false; } + +struct invalid1 { }; +struct invalid2 { + template <typename ...Args> + void operator()(Args ...); +}; +struct invalid3 { + void operator()(int); + void operator()(long); +}; +static_assert(!can_deduce<invalid1>()); +static_assert(!can_deduce<invalid2>()); +static_assert(!can_deduce<invalid3>()); diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/deduct_ptr.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/deduct_ptr.pass.cpp new file mode 100644 index 00000000000..5f5c1ee2ce0 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/deduct_ptr.pass.cpp @@ -0,0 +1,112 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <functional> + +// template<class R, class ...Args> +// function(R(*)(Args...)) -> function<R(Args...)>; + +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// UNSUPPORTED: libcpp-no-deduction-guides + +#include <functional> +#include <type_traits> + +#include "test_macros.h" + + +struct R { }; +struct A1 { }; +struct A2 { }; +struct A3 { }; + +R f0() { return {}; } +R f1(A1) { return {}; } +R f2(A1, A2) { return {}; } +R f3(A1, A2, A3) { return {}; } +R f4(A1 = {}) { return {}; } + +int main() { + { + // implicit + std::function a = f0; + ASSERT_SAME_TYPE(decltype(a), std::function<R()>); + + std::function b = &f0; + ASSERT_SAME_TYPE(decltype(b), std::function<R()>); + + // explicit + std::function c{f0}; + ASSERT_SAME_TYPE(decltype(c), std::function<R()>); + + std::function d{&f0}; + ASSERT_SAME_TYPE(decltype(d), std::function<R()>); + } + { + // implicit + std::function a = f1; + ASSERT_SAME_TYPE(decltype(a), std::function<R(A1)>); + + std::function b = &f1; + ASSERT_SAME_TYPE(decltype(b), std::function<R(A1)>); + + // explicit + std::function c{f1}; + ASSERT_SAME_TYPE(decltype(c), std::function<R(A1)>); + + std::function d{&f1}; + ASSERT_SAME_TYPE(decltype(d), std::function<R(A1)>); + } + { + // implicit + std::function a = f2; + ASSERT_SAME_TYPE(decltype(a), std::function<R(A1, A2)>); + + std::function b = &f2; + ASSERT_SAME_TYPE(decltype(b), std::function<R(A1, A2)>); + + // explicit + std::function c{f2}; + ASSERT_SAME_TYPE(decltype(c), std::function<R(A1, A2)>); + + std::function d{&f2}; + ASSERT_SAME_TYPE(decltype(d), std::function<R(A1, A2)>); + } + { + // implicit + std::function a = f3; + ASSERT_SAME_TYPE(decltype(a), std::function<R(A1, A2, A3)>); + + std::function b = &f3; + ASSERT_SAME_TYPE(decltype(b), std::function<R(A1, A2, A3)>); + + // explicit + std::function c{f3}; + ASSERT_SAME_TYPE(decltype(c), std::function<R(A1, A2, A3)>); + + std::function d{&f3}; + ASSERT_SAME_TYPE(decltype(d), std::function<R(A1, A2, A3)>); + } + // Make sure defaulted arguments don't mess up the deduction + { + // implicit + std::function a = f4; + ASSERT_SAME_TYPE(decltype(a), std::function<R(A1)>); + + std::function b = &f4; + ASSERT_SAME_TYPE(decltype(b), std::function<R(A1)>); + + // explicit + std::function c{f4}; + ASSERT_SAME_TYPE(decltype(c), std::function<R(A1)>); + + std::function d{&f4}; + ASSERT_SAME_TYPE(decltype(d), std::function<R(A1)>); + } +} |