tuple (apply): Handle pointers to member (LWG 2418).

* 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
This commit is contained in:
Jonathan Wakely 2015-05-13 14:12:48 +01:00 committed by Jonathan Wakely
parent 681a3d868d
commit ac68f97cfe
4 changed files with 31 additions and 6 deletions

View File

@ -1,5 +1,11 @@
2015-05-13 Jonathan Wakely <jwakely@redhat.com> 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/random.h (seed_seq): More noexcept (LWG 2440).
* include/bits/alloc_traits.h (_S_max_size): Implement LWG 2466. * include/bits/alloc_traits.h (_S_max_size): Implement LWG 2466.

View File

@ -36,6 +36,7 @@
#else #else
#include <tuple> #include <tuple>
#include <functional>
namespace std _GLIBCXX_VISIBILITY(default) namespace std _GLIBCXX_VISIBILITY(default)
{ {
@ -54,7 +55,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template <typename _Fn, typename _Tuple, std::size_t... _Idx> template <typename _Fn, typename _Tuple, std::size_t... _Idx>
constexpr decltype(auto) constexpr decltype(auto)
__apply_impl(_Fn&& f, _Tuple&& t, std::index_sequence<_Idx...>) __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> template <typename _Fn, typename _Tuple>
constexpr decltype(auto) constexpr decltype(auto)

View File

@ -572,7 +572,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
public: public:
using result_type = typename _Traits::__result_type; 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 // Handle objects
template<typename... _Args, typename _Req template<typename... _Args, typename _Req
@ -671,7 +671,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
friend struct _Bind_check_arity; friend struct _Bind_check_arity;
public: public:
explicit explicit constexpr
_Mem_fn_base(_Res _Class::*__pm) noexcept : _M_pm(__pm) { } _Mem_fn_base(_Res _Class::*__pm) noexcept : _M_pm(__pm) { }
// Handle objects // Handle objects
@ -1002,11 +1002,11 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
{ {
typedef _Tp type; typedef _Tp type;
static const _Tp& static constexpr const _Tp&
__do_wrap(const _Tp& __x) __do_wrap(const _Tp& __x)
{ return __x; } { return __x; }
static _Tp&& static constexpr _Tp&&
__do_wrap(_Tp&& __x) __do_wrap(_Tp&& __x)
{ return static_cast<_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; typedef _Mem_fn<_Tp _Class::*> type;
static type static constexpr type
__do_wrap(_Tp _Class::* __pm) __do_wrap(_Tp _Class::* __pm)
{ return type(__pm); } { return type(__pm); }
}; };

View File

@ -41,9 +41,23 @@ test02()
VERIFY( i == 3 ); 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 int
main() main()
{ {
test01(); test01();
test02(); test02();
test03();
} }