15a83710eSEric Fiselier //===----------------------------------------------------------------------===//
25a83710eSEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65a83710eSEric Fiselier //
75a83710eSEric Fiselier //===----------------------------------------------------------------------===//
85a83710eSEric Fiselier
95a83710eSEric Fiselier // <functional>
105a83710eSEric Fiselier
115a83710eSEric Fiselier // reference_wrapper
125a83710eSEric Fiselier
135a83710eSEric Fiselier // has weak result type
145a83710eSEric Fiselier
1531cbe0f2SLouis Dionne // REQUIRES: c++03 || c++11 || c++14 || c++17
1685ee4ff4SBilly Robert O'Neal III
17*681cde7dSNikolas Klauser // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
18*681cde7dSNikolas Klauser
195a83710eSEric Fiselier #include <functional>
205a83710eSEric Fiselier #include <type_traits>
215a83710eSEric Fiselier
227fc6a556SMarshall Clow #include "test_macros.h"
237fc6a556SMarshall Clow
24bc933768SStephan T. Lavavej template <class Arg, class Result>
25bc933768SStephan T. Lavavej struct my_unary_function
26bc933768SStephan T. Lavavej { // std::unary_function was removed in C++17
27bc933768SStephan T. Lavavej typedef Arg argument_type;
28bc933768SStephan T. Lavavej typedef Result result_type;
29bc933768SStephan T. Lavavej };
30bc933768SStephan T. Lavavej
31bc933768SStephan T. Lavavej template <class Arg1, class Arg2, class Result>
32bc933768SStephan T. Lavavej struct my_binary_function
33bc933768SStephan T. Lavavej { // std::binary_function was removed in C++17
34bc933768SStephan T. Lavavej typedef Arg1 first_argument_type;
35bc933768SStephan T. Lavavej typedef Arg2 second_argument_type;
36bc933768SStephan T. Lavavej typedef Result result_type;
37bc933768SStephan T. Lavavej };
38bc933768SStephan T. Lavavej
395a83710eSEric Fiselier class functor1
40bc933768SStephan T. Lavavej : public my_unary_function<int, char>
415a83710eSEric Fiselier {
425a83710eSEric Fiselier };
435a83710eSEric Fiselier
445a83710eSEric Fiselier class functor2
45bc933768SStephan T. Lavavej : public my_binary_function<char, int, double>
465a83710eSEric Fiselier {
475a83710eSEric Fiselier };
485a83710eSEric Fiselier
495a83710eSEric Fiselier class functor3
50bc933768SStephan T. Lavavej : public my_unary_function<char, int>,
51bc933768SStephan T. Lavavej public my_binary_function<char, int, double>
525a83710eSEric Fiselier {
535a83710eSEric Fiselier public:
545a83710eSEric Fiselier typedef float result_type;
555a83710eSEric Fiselier };
565a83710eSEric Fiselier
575a83710eSEric Fiselier class functor4
58bc933768SStephan T. Lavavej : public my_unary_function<char, int>,
59bc933768SStephan T. Lavavej public my_binary_function<char, int, double>
605a83710eSEric Fiselier {
615a83710eSEric Fiselier public:
625a83710eSEric Fiselier };
635a83710eSEric Fiselier
645a83710eSEric Fiselier class C {};
655a83710eSEric Fiselier
665a83710eSEric Fiselier template <class T>
675a83710eSEric Fiselier struct has_result_type
685a83710eSEric Fiselier {
695a83710eSEric Fiselier private:
705a83710eSEric Fiselier struct two {char _; char __;};
715a83710eSEric Fiselier template <class U> static two test(...);
725a83710eSEric Fiselier template <class U> static char test(typename U::result_type* = 0);
735a83710eSEric Fiselier public:
745a83710eSEric Fiselier static const bool value = sizeof(test<T>(0)) == 1;
755a83710eSEric Fiselier };
765a83710eSEric Fiselier
main(int,char **)772df59c50SJF Bastien int main(int, char**)
785a83710eSEric Fiselier {
795a83710eSEric Fiselier static_assert((std::is_same<std::reference_wrapper<functor1>::result_type,
805a83710eSEric Fiselier char>::value), "");
815a83710eSEric Fiselier static_assert((std::is_same<std::reference_wrapper<functor2>::result_type,
825a83710eSEric Fiselier double>::value), "");
835a83710eSEric Fiselier static_assert((std::is_same<std::reference_wrapper<functor3>::result_type,
845a83710eSEric Fiselier float>::value), "");
855a83710eSEric Fiselier static_assert((std::is_same<std::reference_wrapper<void()>::result_type,
865a83710eSEric Fiselier void>::value), "");
875a83710eSEric Fiselier static_assert((std::is_same<std::reference_wrapper<int*(double*)>::result_type,
885a83710eSEric Fiselier int*>::value), "");
895a83710eSEric Fiselier static_assert((std::is_same<std::reference_wrapper<void(*)()>::result_type,
905a83710eSEric Fiselier void>::value), "");
915a83710eSEric Fiselier static_assert((std::is_same<std::reference_wrapper<int*(*)(double*)>::result_type,
925a83710eSEric Fiselier int*>::value), "");
935a83710eSEric Fiselier static_assert((std::is_same<std::reference_wrapper<int*(C::*)(double*)>::result_type,
945a83710eSEric Fiselier int*>::value), "");
955a83710eSEric Fiselier static_assert((std::is_same<std::reference_wrapper<int (C::*)(double*) const volatile>::result_type,
965a83710eSEric Fiselier int>::value), "");
975a83710eSEric Fiselier static_assert((std::is_same<std::reference_wrapper<C()>::result_type,
985a83710eSEric Fiselier C>::value), "");
995a83710eSEric Fiselier static_assert(has_result_type<std::reference_wrapper<functor3> >::value, "");
1005a83710eSEric Fiselier static_assert(!has_result_type<std::reference_wrapper<functor4> >::value, "");
1015a83710eSEric Fiselier static_assert(!has_result_type<std::reference_wrapper<C> >::value, "");
1022df59c50SJF Bastien
1032df59c50SJF Bastien return 0;
1045a83710eSEric Fiselier }
105