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 // template<Returnable R, class T, CopyConstructible... Args>
125a83710eSEric Fiselier //   unspecified mem_fn(R (T::* pm)(Args...) const);
135a83710eSEric Fiselier 
145a83710eSEric Fiselier #include <functional>
155a83710eSEric Fiselier #include <cassert>
165a83710eSEric Fiselier 
177fc6a556SMarshall Clow #include "test_macros.h"
187fc6a556SMarshall Clow 
195a83710eSEric Fiselier struct A
205a83710eSEric Fiselier {
test0A21*7b00e9faSArthur O'Dwyer     TEST_CONSTEXPR char test0() const {return 'a';}
test1A22*7b00e9faSArthur O'Dwyer     TEST_CONSTEXPR char test1(int) const {return 'b';}
test2A23*7b00e9faSArthur O'Dwyer     TEST_CONSTEXPR char test2(int, double) const {return 'c';}
245a83710eSEric Fiselier };
255a83710eSEric Fiselier 
265a83710eSEric Fiselier template <class F>
27*7b00e9faSArthur O'Dwyer TEST_CONSTEXPR_CXX20 bool
test0(F f)285a83710eSEric Fiselier test0(F f)
295a83710eSEric Fiselier {
305a83710eSEric Fiselier     {
315a83710eSEric Fiselier     A a;
325a83710eSEric Fiselier     assert(f(a) == 'a');
335a83710eSEric Fiselier     A* ap = &a;
345a83710eSEric Fiselier     assert(f(ap) == 'a');
355a83710eSEric Fiselier     const A* cap = &a;
365a83710eSEric Fiselier     assert(f(cap) == 'a');
375a83710eSEric Fiselier     const F& cf = f;
385a83710eSEric Fiselier     assert(cf(ap) == 'a');
395a83710eSEric Fiselier     }
40*7b00e9faSArthur O'Dwyer     return true;
415a83710eSEric Fiselier }
425a83710eSEric Fiselier 
435a83710eSEric Fiselier template <class F>
44*7b00e9faSArthur O'Dwyer TEST_CONSTEXPR_CXX20 bool
test1(F f)455a83710eSEric Fiselier test1(F f)
465a83710eSEric Fiselier {
475a83710eSEric Fiselier     {
485a83710eSEric Fiselier     A a;
495a83710eSEric Fiselier     assert(f(a, 1) == 'b');
505a83710eSEric Fiselier     A* ap = &a;
515a83710eSEric Fiselier     assert(f(ap, 2) == 'b');
525a83710eSEric Fiselier     const A* cap = &a;
535a83710eSEric Fiselier     assert(f(cap, 2) == 'b');
545a83710eSEric Fiselier     const F& cf = f;
555a83710eSEric Fiselier     assert(cf(ap, 2) == 'b');
565a83710eSEric Fiselier     }
57*7b00e9faSArthur O'Dwyer     return true;
585a83710eSEric Fiselier }
595a83710eSEric Fiselier 
605a83710eSEric Fiselier template <class F>
61*7b00e9faSArthur O'Dwyer TEST_CONSTEXPR_CXX20 bool
test2(F f)625a83710eSEric Fiselier test2(F f)
635a83710eSEric Fiselier {
645a83710eSEric Fiselier     {
655a83710eSEric Fiselier     A a;
665a83710eSEric Fiselier     assert(f(a, 1, 2) == 'c');
675a83710eSEric Fiselier     A* ap = &a;
685a83710eSEric Fiselier     assert(f(ap, 2, 3.5) == 'c');
695a83710eSEric Fiselier     const A* cap = &a;
705a83710eSEric Fiselier     assert(f(cap, 2, 3.5) == 'c');
715a83710eSEric Fiselier     const F& cf = f;
725a83710eSEric Fiselier     assert(cf(ap, 2, 3.5) == 'c');
735a83710eSEric Fiselier     }
74*7b00e9faSArthur O'Dwyer     return true;
755a83710eSEric Fiselier }
765a83710eSEric Fiselier 
main(int,char **)772df59c50SJF Bastien int main(int, char**)
785a83710eSEric Fiselier {
795a83710eSEric Fiselier     test0(std::mem_fn(&A::test0));
805a83710eSEric Fiselier     test1(std::mem_fn(&A::test1));
815a83710eSEric Fiselier     test2(std::mem_fn(&A::test2));
822df59c50SJF Bastien 
83*7b00e9faSArthur O'Dwyer #if TEST_STD_VER >= 20
84*7b00e9faSArthur O'Dwyer     static_assert(test0(std::mem_fn(&A::test0)));
85*7b00e9faSArthur O'Dwyer     static_assert(test1(std::mem_fn(&A::test1)));
86*7b00e9faSArthur O'Dwyer     static_assert(test2(std::mem_fn(&A::test2)));
87*7b00e9faSArthur O'Dwyer #endif
88*7b00e9faSArthur O'Dwyer 
892df59c50SJF Bastien     return 0;
905a83710eSEric Fiselier }
91