1c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant//===----------------------------------------------------------------------===//
2c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant//
3c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant//                     The LLVM Compiler Infrastructure
4c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant//
5b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open
6b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// Source Licenses. See LICENSE.TXT for details.
7c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant//
8c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant//===----------------------------------------------------------------------===//
9c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
10c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// <functional>
11c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
12c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// reference_wrapper
13c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
14c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// has weak result type
15c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
16c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include <functional>
17c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include <type_traits>
18c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
19c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantclass functor1
20c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    : public std::unary_function<int, char>
21c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{
22c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant};
23c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
24c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantclass functor2
25c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    : public std::binary_function<char, int, double>
26c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{
27c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant};
28c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
29c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantclass functor3
30c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    : public std::unary_function<char, int>,
31c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant      public std::binary_function<char, int, double>
32c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{
33c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantpublic:
34c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    typedef float result_type;
35c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant};
36c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
37c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantclass functor4
38c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    : public std::unary_function<char, int>,
39c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant      public std::binary_function<char, int, double>
40c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{
41c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantpublic:
42c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant};
43c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
44c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantclass C {};
45c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
46c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnanttemplate <class T>
47c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantstruct has_result_type
48c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{
49c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantprivate:
50c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    struct two {char _; char __;};
51c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    template <class U> static two test(...);
52c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    template <class U> static char test(typename U::result_type* = 0);
53c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantpublic:
54c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    static const bool value = sizeof(test<T>(0)) == 1;
55c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant};
56c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
57c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantint main()
58c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{
59c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    static_assert((std::is_same<std::reference_wrapper<functor1>::result_type,
60c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant                                char>::value), "");
61c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    static_assert((std::is_same<std::reference_wrapper<functor2>::result_type,
62c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant                                double>::value), "");
63c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    static_assert((std::is_same<std::reference_wrapper<functor3>::result_type,
64c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant                                float>::value), "");
65c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    static_assert((std::is_same<std::reference_wrapper<void()>::result_type,
66c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant                                void>::value), "");
67c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    static_assert((std::is_same<std::reference_wrapper<int*(double*)>::result_type,
68c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant                                int*>::value), "");
69c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    static_assert((std::is_same<std::reference_wrapper<void(*)()>::result_type,
70c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant                                void>::value), "");
71c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    static_assert((std::is_same<std::reference_wrapper<int*(*)(double*)>::result_type,
72c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant                                int*>::value), "");
73c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    static_assert((std::is_same<std::reference_wrapper<int*(C::*)(double*)>::result_type,
74c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant                                int*>::value), "");
75c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    static_assert((std::is_same<std::reference_wrapper<int (C::*)(double*) const volatile>::result_type,
76c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant                                int>::value), "");
77c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    static_assert((std::is_same<std::reference_wrapper<C()>::result_type,
78c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant                                C>::value), "");
79c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    static_assert(has_result_type<std::reference_wrapper<functor3> >::value, "");
80c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    static_assert(!has_result_type<std::reference_wrapper<functor4> >::value, "");
81c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    static_assert(!has_result_type<std::reference_wrapper<C> >::value, "");
82c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant}
83