tuple (apply): Handle pointers to member (LWG 2418).
authorJonathan Wakely <jwakely@redhat.com>
Wed, 13 May 2015 13:12:48 +0000 (14:12 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 13 May 2015 13:12:48 +0000 (14:12 +0100)
* include/experimental/tuple (apply): Handle pointers to member (LWG
2418).
* include/std/functional (_Mem_fn_base): Make constructors constexpr.
(_Maybe_wrap_member_pointer::__do_wrap): Make constexpr.
* testsuite/experimental/tuple/apply.cc: Test pointer to member.

From-SVN: r223158

libstdc++-v3/ChangeLog
libstdc++-v3/include/experimental/tuple
libstdc++-v3/include/std/functional
libstdc++-v3/testsuite/experimental/tuple/apply.cc

index 251948e2c0edbe638fb002464a3e8a944623cc39..a22a56524f88c8369d5dfe969f931690db1dfe0f 100644 (file)
@@ -1,5 +1,11 @@
 2015-05-13  Jonathan Wakely  <jwakely@redhat.com>
 
+       * include/experimental/tuple (apply): Handle pointers to member (LWG
+       2418).
+       * include/std/functional (_Mem_fn_base): Make constructors constexpr.
+       (_Maybe_wrap_member_pointer::__do_wrap): Make constexpr.
+       * testsuite/experimental/tuple/apply.cc: Test pointer to member.
+
        * include/bits/random.h (seed_seq): More noexcept (LWG 2440).
 
        * include/bits/alloc_traits.h (_S_max_size): Implement LWG 2466.
index 4baede4af5d617fdc832fe2f975695f79d8c7d4a..aa25c576f8e42764026a674748d516ab4ddec7d5 100644 (file)
@@ -36,6 +36,7 @@
 #else
 
 #include <tuple>
+#include <functional>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -54,7 +55,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template <typename _Fn, typename _Tuple, std::size_t... _Idx>
     constexpr decltype(auto)
     __apply_impl(_Fn&& f, _Tuple&& t, std::index_sequence<_Idx...>)
-    { return std::forward<_Fn>(f)(get<_Idx>(forward<_Tuple>(t))...); }
+    {
+      using _Wrap = _Maybe_wrap_member_pointer<decay_t<_Fn>>;
+      return _Wrap::__do_wrap(std::forward<_Fn>(f))(
+         get<_Idx>(forward<_Tuple>(t))...);
+    }
 
   template <typename _Fn, typename _Tuple>
     constexpr decltype(auto)
index 946cf63ace2aa7ed49643ddc91a64dedf9572790..7dd149ada0af0ee7976eb5f79705e7df0cadcd12 100644 (file)
@@ -572,7 +572,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
     public:
       using result_type = typename _Traits::__result_type;
 
-      explicit _Mem_fn_base(_Pmf __pmf) : _M_pmf(__pmf) { }
+      explicit constexpr _Mem_fn_base(_Pmf __pmf) : _M_pmf(__pmf) { }
 
       // Handle objects
       template<typename... _Args, typename _Req
@@ -671,7 +671,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
        friend struct _Bind_check_arity;
 
     public:
-      explicit
+      explicit constexpr
       _Mem_fn_base(_Res _Class::*__pm) noexcept : _M_pm(__pm) { }
 
       // Handle objects
@@ -1002,11 +1002,11 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
     {
       typedef _Tp type;
 
-      static const _Tp&
+      static constexpr const _Tp&
       __do_wrap(const _Tp& __x)
       { return __x; }
 
-      static _Tp&&
+      static constexpr _Tp&&
       __do_wrap(_Tp&& __x)
       { return static_cast<_Tp&&>(__x); }
     };
@@ -1021,7 +1021,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
     {
       typedef _Mem_fn<_Tp _Class::*> type;
 
-      static type
+      static constexpr type
       __do_wrap(_Tp _Class::* __pm)
       { return type(__pm); }
     };
index 88e174d6336c5b75dc1448b03fa1d4f8155b7aed..e52962b41772fccb5dd173c501cd990d1cba76a1 100644 (file)
@@ -41,9 +41,23 @@ test02()
   VERIFY( i == 3 );
 }
 
+struct F
+{
+  int f(int i, int j) const { return i + j; }
+};
+
+void
+test03()
+{
+  auto t = std::make_tuple(F{}, 1, 2);
+  int r = std::experimental::apply(&F::f, t);
+  VERIFY( r == 3 );
+}
+
 int
 main()
 {
   test01();
   test02();
+  test03();
 }