summaryrefslogtreecommitdiffstats
path: root/libcxx/test/std/utilities/function.objects
diff options
context:
space:
mode:
authorLouis Dionne <ldionne@apple.com>2019-07-18 19:50:56 +0000
committerLouis Dionne <ldionne@apple.com>2019-07-18 19:50:56 +0000
commite1eabcdfad89f67ae575b0c86aa4a72d277378b4 (patch)
tree2c1df81755e10798c225b10e70e027268796e58d /libcxx/test/std/utilities/function.objects
parent0c99d19470bab02158856ac88dc1cc0fb40a4570 (diff)
downloadbcm5719-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')
-rw-r--r--libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/deduct_F.fail.cpp34
-rw-r--r--libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/deduct_F.pass.cpp137
-rw-r--r--libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/deduct_ptr.pass.cpp112
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)>);
+ }
+}
OpenPOWER on IntegriCloud