[libcxx] r239668 - Cleanup result_of tests and fix issues with the C++03 result_of.

Eric Fiselier eric at efcs.ca
Sat Jun 13 01:25:25 PDT 2015


Author: ericwf
Date: Sat Jun 13 03:25:24 2015
New Revision: 239668

URL: http://llvm.org/viewvc/llvm-project?rev=239668&view=rev
Log:
Cleanup result_of tests and fix issues with the C++03 result_of.

The two main fixes this patch contains are:
- use __identity_t instead of common_type. common_type was used as an
  identity metafunction but the decay resulted in incorrect results.
- Pointers to free functions were not counted as functions. Remove the pointer
  before checking if a type is a function.

Added:
    libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp
Modified:
    libcxx/trunk/TODO.TXT
    libcxx/trunk/include/type_traits
    libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp

Modified: libcxx/trunk/TODO.TXT
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/TODO.TXT?rev=239668&r1=239667&r2=239668&view=diff
==============================================================================
--- libcxx/trunk/TODO.TXT (original)
+++ libcxx/trunk/TODO.TXT Sat Jun 13 03:25:24 2015
@@ -38,8 +38,6 @@ Misc Tasks
 ==========
 * Find all sequences of >2 underscores and eradicate them.
 * run clang-tidy on libc++
-* Look at test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp;
-  why are the tests duplicated?
 * Document the "conditionally-supported" bits of libc++
 * Look at basic_string's move assignment operator, re LWG 2063 and POCMA
 * libc++ is missing try_emplace

Modified: libcxx/trunk/include/type_traits
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/type_traits?rev=239668&r1=239667&r2=239668&view=diff
==============================================================================
--- libcxx/trunk/include/type_traits (original)
+++ libcxx/trunk/include/type_traits Sat Jun 13 03:25:24 2015
@@ -219,6 +219,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <class>
 struct __void_t { typedef void type; };
 
+template <class T>
+struct __identity { typedef T type; };
+
 template <class _Tp, bool>
 struct _LIBCPP_TYPE_VIS_ONLY __dependent_type : public _Tp {};
 
@@ -2252,7 +2255,7 @@ struct __result_of_mp;
 
 template <class _MP, class _Tp>
 struct __result_of_mp<_MP, _Tp, true>
-    : public common_type<typename __member_pointer_traits<_MP>::_ReturnType>
+    : public __identity<typename __member_pointer_traits<_MP>::_ReturnType>
 {
 };
 
@@ -2320,7 +2323,7 @@ template <class _Fn>
 class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn()>
     : public __result_of<_Fn(),
                          is_class<typename remove_reference<_Fn>::type>::value ||
-                         is_function<typename remove_reference<_Fn>::type>::value,
+                         is_function<typename remove_pointer<typename remove_reference<_Fn>::type>::type>::value,
                          is_member_pointer<typename remove_reference<_Fn>::type>::value
                         >
 {
@@ -2330,7 +2333,7 @@ template <class _Fn, class _A0>
 class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0)>
     : public __result_of<_Fn(_A0),
                          is_class<typename remove_reference<_Fn>::type>::value ||
-                         is_function<typename remove_reference<_Fn>::type>::value,
+                         is_function<typename remove_pointer<typename remove_reference<_Fn>::type>::type>::value,
                          is_member_pointer<typename remove_reference<_Fn>::type>::value
                         >
 {
@@ -2340,7 +2343,7 @@ template <class _Fn, class _A0, class _A
 class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0, _A1)>
     : public __result_of<_Fn(_A0, _A1),
                          is_class<typename remove_reference<_Fn>::type>::value ||
-                         is_function<typename remove_reference<_Fn>::type>::value,
+                         is_function<typename remove_pointer<typename remove_reference<_Fn>::type>::type>::value,
                          is_member_pointer<typename remove_reference<_Fn>::type>::value
                         >
 {
@@ -2350,7 +2353,7 @@ template <class _Fn, class _A0, class _A
 class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0, _A1, _A2)>
     : public __result_of<_Fn(_A0, _A1, _A2),
                          is_class<typename remove_reference<_Fn>::type>::value ||
-                         is_function<typename remove_reference<_Fn>::type>::value,
+                         is_function<typename remove_pointer<typename remove_reference<_Fn>::type>::type>::value,
                          is_member_pointer<typename remove_reference<_Fn>::type>::value
                         >
 {

Modified: libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp?rev=239668&r1=239667&r2=239668&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp Sat Jun 13 03:25:24 2015
@@ -13,83 +13,240 @@
 
 #include <type_traits>
 #include <memory>
-
-typedef bool (&PF1)();
-typedef short (*PF2)(long);
+#include "test_macros.h"
 
 struct S
 {
-    operator PF2() const;
+    typedef short (*FreeFunc)(long);
+    operator FreeFunc() const;
     double operator()(char, int&);
-    void calc(long) const;
-    char data_;
+    double const& operator()(char, int&) const;
+    double volatile& operator()(char, int&) volatile;
+    double const volatile& operator()(char, int&) const volatile;
 };
 
-typedef void (S::*PMS)(long) const;
-typedef char S::*PMD;
-
-struct wat
-{
-    wat& operator*() { return *this; }
-    void foo();
+template <class Tp>
+struct Voider {
+    typedef void type;
 };
 
-struct F {};
+template <class T, class = void>
+struct HasType : std::false_type {};
+
+template <class T>
+struct HasType<T, typename Voider<typename T::type>::type> : std::true_type {};
 
 template <class T, class U>
-void test_result_of_imp()
+void test_result_of()
 {
     static_assert((std::is_same<typename std::result_of<T>::type, U>::value), "");
-#if _LIBCPP_STD_VER > 11
-    static_assert((std::is_same<std::result_of_t<T>, U>::value), "");
-#endif
 }
 
-int main()
+template <class T>
+void test_no_result()
 {
-    test_result_of_imp<S(int), short> ();
-    test_result_of_imp<S&(unsigned char, int&), double> ();
-    test_result_of_imp<PF1(), bool> ();
-    test_result_of_imp<PMS(std::unique_ptr<S>, int), void> ();
-    test_result_of_imp<PMS(S, int), void> ();
-    test_result_of_imp<PMS(const S&, int), void> ();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    test_result_of_imp<PMD(S), char&&> ();
-#endif
-    test_result_of_imp<PMD(const S*), const char&> ();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    test_result_of_imp<int (F::* (F       &)) ()       &, int> ();
-    test_result_of_imp<int (F::* (F       &)) () const &, int> ();
-    test_result_of_imp<int (F::* (F const &)) () const &, int> ();
-    test_result_of_imp<int (F::* (F      &&)) ()      &&, int> ();
-    test_result_of_imp<int (F::* (F      &&)) () const&&, int> ();
-    test_result_of_imp<int (F::* (F const&&)) () const&&, int> ();
-#endif
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-    using type1 = std::result_of<decltype(&wat::foo)(wat)>::type;
-    static_assert(std::is_same<type1, void>::value, "");
-#endif
-#if _LIBCPP_STD_VER > 11
-    using type2 = std::result_of_t<decltype(&wat::foo)(wat)>;
-    static_assert(std::is_same<type2, void>::value, "");
+#if TEST_STD_VER >= 11
+    static_assert((!HasType<std::result_of<T> >::value), "");
 #endif
+}
 
-    static_assert((std::is_same<std::result_of<S(int)>::type, short>::value), "Error!");
-    static_assert((std::is_same<std::result_of<S&(unsigned char, int&)>::type, double>::value), "Error!");
-    static_assert((std::is_same<std::result_of<PF1()>::type, bool>::value), "Error!");
-    static_assert((std::is_same<std::result_of<PMS(std::unique_ptr<S>, int)>::type, void>::value), "Error!");
-    static_assert((std::is_same<std::result_of<PMS(S, int)>::type, void>::value), "Error!");
-    static_assert((std::is_same<std::result_of<PMS(const S&, int)>::type, void>::value), "Error!");
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    static_assert((std::is_same<std::result_of<PMD(S)>::type, char&&>::value), "Error!");
-#endif
-    static_assert((std::is_same<std::result_of<PMD(const S*)>::type, const char&>::value), "Error!");
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    static_assert((std::is_same<std::result_of<int (F::* (F       &)) ()       &>::type, int>::value), "Error!");
-    static_assert((std::is_same<std::result_of<int (F::* (F       &)) () const &>::type, int>::value), "Error!");
-    static_assert((std::is_same<std::result_of<int (F::* (F const &)) () const &>::type, int>::value), "Error!");
-    static_assert((std::is_same<std::result_of<int (F::* (F      &&)) ()      &&>::type, int>::value), "Error!");
-    static_assert((std::is_same<std::result_of<int (F::* (F      &&)) () const&&>::type, int>::value), "Error!");
-    static_assert((std::is_same<std::result_of<int (F::* (F const&&)) () const&&>::type, int>::value), "Error!");
-#endif
+int main()
+{
+    { // functor object
+    test_result_of<S(int), short> ();
+    test_result_of<S&(unsigned char, int&), double> ();
+    test_result_of<S const&(unsigned char, int&), double const &> ();
+    test_result_of<S volatile&(unsigned char, int&), double volatile&> ();
+    test_result_of<S const volatile&(unsigned char, int&), double const volatile&> ();
+    }
+    { // pointer to function
+    typedef bool         (&RF0)();
+    typedef bool*       (&RF1)(int);
+    typedef bool&       (&RF2)(int, int);
+    typedef bool const& (&RF3)(int, int, int);
+    typedef bool        (*PF0)();
+    typedef bool*       (*PF1)(int);
+    typedef bool&       (*PF2)(int, int);
+    typedef bool const& (*PF3)(int, int, int);
+    typedef bool        (*&PRF0)();
+    typedef bool*       (*&PRF1)(int);
+    typedef bool&       (*&PRF2)(int, int);
+    typedef bool const& (*&PRF3)(int, int, int);
+    test_result_of<RF0(), bool>();
+    test_result_of<RF1(int), bool*>();
+    test_result_of<RF2(int, long), bool&>();
+    test_result_of<RF3(int, long, int), bool const&>();
+    test_result_of<PF0(), bool>();
+    test_result_of<PF1(int), bool*>();
+    test_result_of<PF2(int, long), bool&>();
+    test_result_of<PF3(int, long, int), bool const&>();
+    test_result_of<PRF0(), bool>();
+    test_result_of<PRF1(int), bool*>();
+    test_result_of<PRF2(int, long), bool&>();
+    test_result_of<PRF3(int, long, int), bool const&>();
+    }
+    { // pointer to member function
+
+    typedef int         (S::*PMS0)();
+    typedef int*        (S::*PMS1)(long);
+    typedef int&        (S::*PMS2)(long, int);
+    test_result_of<PMS0(               S),   int> ();
+    test_result_of<PMS0(               S&),  int> ();
+    test_result_of<PMS0(               S*),  int> ();
+    test_result_of<PMS0(               S*&), int> ();
+    test_result_of<PMS0(std::unique_ptr<S>), int> ();
+    test_no_result<PMS0(const          S&)>();
+    test_no_result<PMS0(volatile       S&)>();
+    test_no_result<PMS0(const volatile S&)>();
+
+    test_result_of<PMS1(               S,   int), int*> ();
+    test_result_of<PMS1(               S&,  int), int*> ();
+    test_result_of<PMS1(               S*,  int), int*> ();
+    test_result_of<PMS1(               S*&, int), int*> ();
+    test_result_of<PMS1(std::unique_ptr<S>, int), int*> ();
+    test_no_result<PMS1(const          S&, int)>();
+    test_no_result<PMS1(volatile       S&, int)>();
+    test_no_result<PMS1(const volatile S&, int)>();
+
+    test_result_of<PMS2(               S,   int, int), int&> ();
+    test_result_of<PMS2(               S&,  int, int), int&> ();
+    test_result_of<PMS2(               S*,  int, int), int&> ();
+    test_result_of<PMS2(               S*&, int, int), int&> ();
+    test_result_of<PMS2(std::unique_ptr<S>, int, int), int&> ();
+    test_no_result<PMS2(const          S&, int, int)>();
+    test_no_result<PMS2(volatile       S&, int, int)>();
+    test_no_result<PMS2(const volatile S&, int, int)>();
+
+    typedef int        (S::*PMS0C)() const;
+    typedef int*       (S::*PMS1C)(long) const;
+    typedef int&       (S::*PMS2C)(long, int) const;
+    test_result_of<PMS0C(               S),   int> ();
+    test_result_of<PMS0C(               S&),  int> ();
+    test_result_of<PMS0C(const          S&),  int> ();
+    test_result_of<PMS0C(               S*),  int> ();
+    test_result_of<PMS0C(const          S*),  int> ();
+    test_result_of<PMS0C(               S*&), int> ();
+    test_result_of<PMS0C(const          S*&), int> ();
+    test_result_of<PMS0C(std::unique_ptr<S>), int> ();
+    test_no_result<PMS0C(volatile       S&)>();
+    test_no_result<PMS0C(const volatile S&)>();
+
+    test_result_of<PMS1C(               S,   int), int*> ();
+    test_result_of<PMS1C(               S&,  int), int*> ();
+    test_result_of<PMS1C(const          S&,  int), int*> ();
+    test_result_of<PMS1C(               S*,  int), int*> ();
+    test_result_of<PMS1C(const          S*,  int), int*> ();
+    test_result_of<PMS1C(               S*&, int), int*> ();
+    test_result_of<PMS1C(const          S*&, int), int*> ();
+    test_result_of<PMS1C(std::unique_ptr<S>, int), int*> ();
+    test_no_result<PMS1C(volatile       S&, int)>();
+    test_no_result<PMS1C(const volatile S&, int)>();
+
+    test_result_of<PMS2C(               S,   int, int), int&> ();
+    test_result_of<PMS2C(               S&,  int, int), int&> ();
+    test_result_of<PMS2C(const          S&,  int, int), int&> ();
+    test_result_of<PMS2C(               S*,  int, int), int&> ();
+    test_result_of<PMS2C(const          S*,  int, int), int&> ();
+    test_result_of<PMS2C(               S*&, int, int), int&> ();
+    test_result_of<PMS2C(const          S*&, int, int), int&> ();
+    test_result_of<PMS2C(std::unique_ptr<S>, int, int), int&> ();
+    test_no_result<PMS2C(volatile       S&, int, int)>();
+    test_no_result<PMS2C(const volatile S&, int, int)>();
+
+    typedef int       (S::*PMS0V)() volatile;
+    typedef int*       (S::*PMS1V)(long) volatile;
+    typedef int&       (S::*PMS2V)(long, int) volatile;
+    test_result_of<PMS0V(               S),   int> ();
+    test_result_of<PMS0V(               S&),  int> ();
+    test_result_of<PMS0V(volatile       S&),  int> ();
+    test_result_of<PMS0V(               S*),  int> ();
+    test_result_of<PMS0V(volatile       S*),  int> ();
+    test_result_of<PMS0V(               S*&), int> ();
+    test_result_of<PMS0V(volatile       S*&), int> ();
+    test_result_of<PMS0V(std::unique_ptr<S>), int> ();
+    test_no_result<PMS0V(const          S&)>();
+    test_no_result<PMS0V(const volatile S&)>();
+
+    test_result_of<PMS1V(               S,   int), int*> ();
+    test_result_of<PMS1V(               S&,  int), int*> ();
+    test_result_of<PMS1V(volatile       S&,  int), int*> ();
+    test_result_of<PMS1V(               S*,  int), int*> ();
+    test_result_of<PMS1V(volatile       S*,  int), int*> ();
+    test_result_of<PMS1V(               S*&, int), int*> ();
+    test_result_of<PMS1V(volatile       S*&, int), int*> ();
+    test_result_of<PMS1V(std::unique_ptr<S>, int), int*> ();
+    test_no_result<PMS1V(const          S&, int)>();
+    test_no_result<PMS1V(const volatile S&, int)>();
+
+    test_result_of<PMS2V(               S,   int, int), int&> ();
+    test_result_of<PMS2V(               S&,  int, int), int&> ();
+    test_result_of<PMS2V(volatile       S&,  int, int), int&> ();
+    test_result_of<PMS2V(               S*,  int, int), int&> ();
+    test_result_of<PMS2V(volatile       S*,  int, int), int&> ();
+    test_result_of<PMS2V(               S*&, int, int), int&> ();
+    test_result_of<PMS2V(volatile       S*&, int, int), int&> ();
+    test_result_of<PMS2V(std::unique_ptr<S>, int, int), int&> ();
+    test_no_result<PMS2V(const          S&, int, int)>();
+    test_no_result<PMS2V(const volatile S&, int, int)>();
+
+    typedef int        (S::*PMS0CV)() const volatile;
+    typedef int*       (S::*PMS1CV)(long) const volatile;
+    typedef int&       (S::*PMS2CV)(long, int) const volatile;
+    test_result_of<PMS0CV(               S),   int> ();
+    test_result_of<PMS0CV(               S&),  int> ();
+    test_result_of<PMS0CV(const          S&),  int> ();
+    test_result_of<PMS0CV(volatile       S&),  int> ();
+    test_result_of<PMS0CV(const volatile S&),  int> ();
+    test_result_of<PMS0CV(               S*),  int> ();
+    test_result_of<PMS0CV(const          S*),  int> ();
+    test_result_of<PMS0CV(volatile       S*),  int> ();
+    test_result_of<PMS0CV(const volatile S*),  int> ();
+    test_result_of<PMS0CV(               S*&), int> ();
+    test_result_of<PMS0CV(const          S*&), int> ();
+    test_result_of<PMS0CV(volatile       S*&), int> ();
+    test_result_of<PMS0CV(const volatile S*&), int> ();
+    test_result_of<PMS0CV(std::unique_ptr<S>), int> ();
+
+    test_result_of<PMS1CV(               S,   int), int*> ();
+    test_result_of<PMS1CV(               S&,  int), int*> ();
+    test_result_of<PMS1CV(const          S&,  int), int*> ();
+    test_result_of<PMS1CV(volatile       S&,  int), int*> ();
+    test_result_of<PMS1CV(const volatile S&,  int), int*> ();
+    test_result_of<PMS1CV(               S*,  int), int*> ();
+    test_result_of<PMS1CV(const          S*,  int), int*> ();
+    test_result_of<PMS1CV(volatile       S*,  int), int*> ();
+    test_result_of<PMS1CV(const volatile S*,  int), int*> ();
+    test_result_of<PMS1CV(               S*&, int), int*> ();
+    test_result_of<PMS1CV(const          S*&, int), int*> ();
+    test_result_of<PMS1CV(volatile       S*&, int), int*> ();
+    test_result_of<PMS1CV(const volatile S*&, int), int*> ();
+    test_result_of<PMS1CV(std::unique_ptr<S>, int), int*> ();
+
+    test_result_of<PMS2CV(               S,   int, int), int&> ();
+    test_result_of<PMS2CV(               S&,  int, int), int&> ();
+    test_result_of<PMS2CV(const          S&,  int, int), int&> ();
+    test_result_of<PMS2CV(volatile       S&,  int, int), int&> ();
+    test_result_of<PMS2CV(const volatile S&,  int, int), int&> ();
+    test_result_of<PMS2CV(               S*,  int, int), int&> ();
+    test_result_of<PMS2CV(const          S*,  int, int), int&> ();
+    test_result_of<PMS2CV(volatile       S*,  int, int), int&> ();
+    test_result_of<PMS2CV(const volatile S*,  int, int), int&> ();
+    test_result_of<PMS2CV(               S*&, int, int), int&> ();
+    test_result_of<PMS2CV(const          S*&, int, int), int&> ();
+    test_result_of<PMS2CV(volatile       S*&, int, int), int&> ();
+    test_result_of<PMS2CV(const volatile S*&, int, int), int&> ();
+    test_result_of<PMS2CV(std::unique_ptr<S>, int, int), int&> ();
+    }
+    { // pointer to member data
+    typedef char S::*PMD;
+    test_result_of<PMD(S&), char &>();
+    test_result_of<PMD(S*), char &>();
+    test_result_of<PMD(S* const), char &>();
+    test_result_of<PMD(const S&), const char&> ();
+    test_result_of<PMD(const S*), const char&> ();
+    test_result_of<PMD(volatile S&), volatile char&> ();
+    test_result_of<PMD(volatile S*), volatile char&> ();
+    test_result_of<PMD(const volatile S&), const volatile char&> ();
+    test_result_of<PMD(const volatile S*), const volatile char&> ();
+    }
 }

Added: libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp?rev=239668&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp (added)
+++ libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp Sat Jun 13 03:25:24 2015
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: c++98, c++03
+//
+// <functional>
+//
+// result_of<Fn(ArgTypes...)>
+
+#include <type_traits>
+#include "test_macros.h"
+
+struct wat
+{
+    wat& operator*() { return *this; }
+    void foo();
+};
+
+struct F {};
+
+template <class T, class U>
+void test_result_of_imp()
+{
+    static_assert((std::is_same<typename std::result_of<T>::type, U>::value), "");
+#if TEST_STD_VER > 11
+    static_assert((std::is_same<std::result_of_t<T>, U>::value), "");
+#endif
+}
+
+int main()
+{
+    {
+    typedef char F::*PMD;
+    test_result_of_imp<PMD(F                &), char                &>();
+    test_result_of_imp<PMD(F const          &), char const          &>();
+    test_result_of_imp<PMD(F volatile       &), char volatile       &>();
+    test_result_of_imp<PMD(F const volatile &), char const volatile &>();
+
+    test_result_of_imp<PMD(F                &&), char                &&>();
+    test_result_of_imp<PMD(F const          &&), char const          &&>();
+    test_result_of_imp<PMD(F volatile       &&), char volatile       &&>();
+    test_result_of_imp<PMD(F const volatile &&), char const volatile &&>();
+
+    test_result_of_imp<PMD(F                ), char &&>();
+    test_result_of_imp<PMD(F const          ), char &&>();
+    test_result_of_imp<PMD(F volatile       ), char &&>();
+    test_result_of_imp<PMD(F const volatile ), char &&>();
+    }
+    {
+    test_result_of_imp<int (F::* (F       &)) ()                &, int> ();
+    test_result_of_imp<int (F::* (F       &)) () const          &, int> ();
+    test_result_of_imp<int (F::* (F       &)) () volatile       &, int> ();
+    test_result_of_imp<int (F::* (F       &)) () const volatile &, int> ();
+    test_result_of_imp<int (F::* (F const &)) () const          &, int> ();
+    test_result_of_imp<int (F::* (F const &)) () const volatile &, int> ();
+    test_result_of_imp<int (F::* (F volatile &)) () volatile       &, int> ();
+    test_result_of_imp<int (F::* (F volatile &)) () const volatile &, int> ();
+    test_result_of_imp<int (F::* (F const volatile &)) () const volatile &, int> ();
+
+    test_result_of_imp<int (F::* (F       &&)) ()                &&, int> ();
+    test_result_of_imp<int (F::* (F       &&)) () const          &&, int> ();
+    test_result_of_imp<int (F::* (F       &&)) () volatile       &&, int> ();
+    test_result_of_imp<int (F::* (F       &&)) () const volatile &&, int> ();
+    test_result_of_imp<int (F::* (F const &&)) () const          &&, int> ();
+    test_result_of_imp<int (F::* (F const &&)) () const volatile &&, int> ();
+    test_result_of_imp<int (F::* (F volatile &&)) () volatile       &&, int> ();
+    test_result_of_imp<int (F::* (F volatile &&)) () const volatile &&, int> ();
+    test_result_of_imp<int (F::* (F const volatile &&)) () const volatile &&, int> ();
+
+    test_result_of_imp<int (F::* (F       )) ()                &&, int> ();
+    test_result_of_imp<int (F::* (F       )) () const          &&, int> ();
+    test_result_of_imp<int (F::* (F       )) () volatile       &&, int> ();
+    test_result_of_imp<int (F::* (F       )) () const volatile &&, int> ();
+    test_result_of_imp<int (F::* (F const )) () const          &&, int> ();
+    test_result_of_imp<int (F::* (F const )) () const volatile &&, int> ();
+    test_result_of_imp<int (F::* (F volatile )) () volatile       &&, int> ();
+    test_result_of_imp<int (F::* (F volatile )) () const volatile &&, int> ();
+    test_result_of_imp<int (F::* (F const volatile )) () const volatile &&, int> ();
+    }
+
+    test_result_of_imp<decltype(&wat::foo)(wat), void>();
+}





More information about the cfe-commits mailing list