brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.9 KiB · 064f7ac Raw
156 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// <functional>10 11// template<class F>12// function(F) -> function<see-below>;13 14// UNSUPPORTED: c++03, c++11, c++1415 16#include <cstddef>17#include <functional>18#include <utility>19 20#include "test_macros.h"21 22struct R { };23struct A1 { };24struct A2 { };25struct A3 { };26 27#define DECLARE_FUNCTIONS_WITH_QUALS(N, ...)                              \28  struct f0_##N  { R operator()() __VA_ARGS__           { return {}; } }; \29  struct f1_##N  { R operator()(A1) __VA_ARGS__         { return {}; } }; \30  struct f2_##N  { R operator()(A1, A2) __VA_ARGS__     { return {}; } }; \31  struct f3_##N  { R operator()(A1, A2, A3) __VA_ARGS__ { return {}; } }  \32/**/33 34DECLARE_FUNCTIONS_WITH_QUALS(0, /* nothing */);35DECLARE_FUNCTIONS_WITH_QUALS(1, const);36DECLARE_FUNCTIONS_WITH_QUALS(2, volatile);37DECLARE_FUNCTIONS_WITH_QUALS(3, const volatile);38DECLARE_FUNCTIONS_WITH_QUALS(4, &);39DECLARE_FUNCTIONS_WITH_QUALS(5 , const &);40DECLARE_FUNCTIONS_WITH_QUALS(6 , volatile &);41DECLARE_FUNCTIONS_WITH_QUALS(7 , const volatile &);42DECLARE_FUNCTIONS_WITH_QUALS(8 , noexcept);43DECLARE_FUNCTIONS_WITH_QUALS(9 , const noexcept);44DECLARE_FUNCTIONS_WITH_QUALS(10, volatile noexcept);45DECLARE_FUNCTIONS_WITH_QUALS(11, const volatile noexcept);46DECLARE_FUNCTIONS_WITH_QUALS(12, & noexcept);47DECLARE_FUNCTIONS_WITH_QUALS(13, const & noexcept);48DECLARE_FUNCTIONS_WITH_QUALS(14, volatile & noexcept);49DECLARE_FUNCTIONS_WITH_QUALS(15, const volatile & noexcept);50 51int main(int, char**) {52#define CHECK_FUNCTIONS(N)                                                    \53  do {                                                                        \54    /* implicit */                                                            \55    std::function g0 = f0_##N{};                                              \56    ASSERT_SAME_TYPE(decltype(g0), std::function<R()>);                       \57                                                                              \58    std::function g1 = f1_##N{};                                              \59    ASSERT_SAME_TYPE(decltype(g1), std::function<R(A1)>);                     \60                                                                              \61    std::function g2 = f2_##N{};                                              \62    ASSERT_SAME_TYPE(decltype(g2), std::function<R(A1, A2)>);                 \63                                                                              \64    std::function g3 = f3_##N{};                                              \65    ASSERT_SAME_TYPE(decltype(g3), std::function<R(A1, A2, A3)>);             \66                                                                              \67    /* explicit */                                                            \68    std::function g4{f0_##N{}};                                               \69    ASSERT_SAME_TYPE(decltype(g4), std::function<R()>);                       \70                                                                              \71    std::function g5{f1_##N{}};                                               \72    ASSERT_SAME_TYPE(decltype(g5), std::function<R(A1)>);                     \73                                                                              \74    std::function g6{f2_##N{}};                                               \75    ASSERT_SAME_TYPE(decltype(g6), std::function<R(A1, A2)>);                 \76                                                                              \77    std::function g7{f3_##N{}};                                               \78    ASSERT_SAME_TYPE(decltype(g7), std::function<R(A1, A2, A3)>);             \79                                                                              \80    /* from std::function */                                                  \81    std::function<R(A1)> unary;                                               \82    std::function g8 = unary;                                                 \83    ASSERT_SAME_TYPE(decltype(g8), std::function<R(A1)>);                     \84                                                                              \85    std::function g9 = std::move(unary);                                      \86    ASSERT_SAME_TYPE(decltype(g9), std::function<R(A1)>);                     \87                                                                              \88    std::function<R(A1&&)> unary_ref;                                         \89    std::function g10 = unary_ref;                                            \90    ASSERT_SAME_TYPE(decltype(g10), std::function<R(A1&&)>);                  \91                                                                              \92    std::function g11 = std::move(unary_ref);                                 \93    ASSERT_SAME_TYPE(decltype(g11), std::function<R(A1&&)>);                  \94  } while (false)                                                             \95/**/96 97  // Make sure we can deduce from function objects with valid call operators98  CHECK_FUNCTIONS(0);99  CHECK_FUNCTIONS(1);100  CHECK_FUNCTIONS(2);101  CHECK_FUNCTIONS(3);102  CHECK_FUNCTIONS(4);103  CHECK_FUNCTIONS(5);104  CHECK_FUNCTIONS(6);105  CHECK_FUNCTIONS(7);106  CHECK_FUNCTIONS(8);107  CHECK_FUNCTIONS(9);108  CHECK_FUNCTIONS(10);109  CHECK_FUNCTIONS(11);110  CHECK_FUNCTIONS(12);111  CHECK_FUNCTIONS(13);112  CHECK_FUNCTIONS(14);113  CHECK_FUNCTIONS(15);114 115  return 0;116}117 118// Make sure we fail in a SFINAE-friendly manner when we try to deduce119// from a type without a valid call operator.120template <typename F, typename = decltype(std::function{std::declval<F>()})>121constexpr bool can_deduce_test(int) { return true; }122template <typename F>123constexpr bool can_deduce_test(...) { return false; }124 125template <typename F>126constexpr bool can_deduce = can_deduce_test<F>(0);127 128struct valid { int operator()() const; };129struct invalid1 { };130struct invalid2 {131  template <typename ...Args>132  void operator()(Args ...);133};134struct invalid3 {135  void operator()(int);136  void operator()(long);137};138static_assert( can_deduce<valid>);139static_assert(!can_deduce<invalid1>);140static_assert(!can_deduce<invalid2>);141static_assert(!can_deduce<invalid3>);142 143 144// LWG 3238. Insufficiently-defined behavior of std::function deduction guides145// https://cplusplus.github.io/LWG/issue3238146// The deduction guides for std::function do not handle rvalue-ref qualified147// call operators and C-style variadics. It also doesn't deduce from nullptr_t.148// Make sure we stick to the specification.149 150struct invalid_rvalue_ref { R operator()() && { return {}; } };151struct invalid_c_vararg { R operator()(int, ...) { return {}; } };152 153static_assert(!can_deduce<invalid_rvalue_ref>);154static_assert(!can_deduce<invalid_c_vararg>);155static_assert(!can_deduce<std::nullptr_t>);156