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...));
135a83710eSEric Fiselier
145a83710eSEric Fiselier #include <functional>
155a83710eSEric Fiselier #include <cassert>
165a83710eSEric Fiselier
17f2f2a639SEric Fiselier #include "test_macros.h"
18f2f2a639SEric Fiselier
195a83710eSEric Fiselier struct A
205a83710eSEric Fiselier {
test0A21*7b00e9faSArthur O'Dwyer TEST_CONSTEXPR_CXX14 char test0() {return 'a';}
test1A22*7b00e9faSArthur O'Dwyer TEST_CONSTEXPR_CXX14 char test1(int) {return 'b';}
test2A23*7b00e9faSArthur O'Dwyer TEST_CONSTEXPR_CXX14 char test2(int, double) {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 F& cf = f;
365a83710eSEric Fiselier assert(cf(ap) == 'a');
375a83710eSEric Fiselier }
38*7b00e9faSArthur O'Dwyer return true;
395a83710eSEric Fiselier }
405a83710eSEric Fiselier
415a83710eSEric Fiselier template <class F>
42*7b00e9faSArthur O'Dwyer TEST_CONSTEXPR_CXX20 bool
test1(F f)435a83710eSEric Fiselier test1(F f)
445a83710eSEric Fiselier {
455a83710eSEric Fiselier {
465a83710eSEric Fiselier A a;
475a83710eSEric Fiselier assert(f(a, 1) == 'b');
485a83710eSEric Fiselier A* ap = &a;
495a83710eSEric Fiselier assert(f(ap, 2) == 'b');
505a83710eSEric Fiselier const F& cf = f;
515a83710eSEric Fiselier assert(cf(ap, 2) == 'b');
525a83710eSEric Fiselier }
53*7b00e9faSArthur O'Dwyer return true;
545a83710eSEric Fiselier }
555a83710eSEric Fiselier
565a83710eSEric Fiselier template <class F>
57*7b00e9faSArthur O'Dwyer TEST_CONSTEXPR_CXX20 bool
test2(F f)585a83710eSEric Fiselier test2(F f)
595a83710eSEric Fiselier {
605a83710eSEric Fiselier {
615a83710eSEric Fiselier A a;
625a83710eSEric Fiselier assert(f(a, 1, 2) == 'c');
635a83710eSEric Fiselier A* ap = &a;
645a83710eSEric Fiselier assert(f(ap, 2, 3.5) == 'c');
655a83710eSEric Fiselier const F& cf = f;
665a83710eSEric Fiselier assert(cf(ap, 2, 3.5) == 'c');
675a83710eSEric Fiselier }
68*7b00e9faSArthur O'Dwyer return true;
695a83710eSEric Fiselier }
705a83710eSEric Fiselier
main(int,char **)712df59c50SJF Bastien int main(int, char**)
725a83710eSEric Fiselier {
735a83710eSEric Fiselier test0(std::mem_fn(&A::test0));
745a83710eSEric Fiselier test1(std::mem_fn(&A::test1));
755a83710eSEric Fiselier test2(std::mem_fn(&A::test2));
76f2f2a639SEric Fiselier #if TEST_STD_VER >= 11
773b72a6efSMarshall Clow static_assert((noexcept(std::mem_fn(&A::test0))), ""); // LWG#2489
783b72a6efSMarshall Clow #endif
792df59c50SJF Bastien
80*7b00e9faSArthur O'Dwyer #if TEST_STD_VER >= 20
81*7b00e9faSArthur O'Dwyer static_assert(test0(std::mem_fn(&A::test0)));
82*7b00e9faSArthur O'Dwyer static_assert(test1(std::mem_fn(&A::test1)));
83*7b00e9faSArthur O'Dwyer static_assert(test2(std::mem_fn(&A::test2)));
84*7b00e9faSArthur O'Dwyer #endif
85*7b00e9faSArthur O'Dwyer
862df59c50SJF Bastien return 0;
875a83710eSEric Fiselier }
88