Commit 1b3fad81 by Jonathan Wakely Committed by Jonathan Wakely

re PR libstdc++/45893 ([C++0x] [DR 817] Finish updating std::bind to rvalue refs)

2010-10-08  Jonathan Wakely  <jwakely.gcc@gmail.com>

	PR libstdc++/45893
	* include/std/functional (bind): Implement DR 817 and add support
	for volatile-qualified call wrappers.
	* include/std/mutex (call_once): Implement DR 891.
	* include/std/thread (thread::thread): Implement DR 929.
	* include/std/future: Optimise use of std::bind.
	* testsuite/20_util/bind/cv_quals.cc: Test volatile-qualification.
	* testsuite/20_util/bind/move.cc: New.

From-SVN: r165144
parent 65d09bfe
2010-10-08 Jonathan Wakely <jwakely.gcc@gmail.com>
PR libstdc++/45893
* include/std/functional (bind): Implement DR 817 and add support
for volatile-qualified call wrappers.
* include/std/mutex (call_once): Implement DR 891.
* include/std/thread (thread::thread): Implement DR 929.
* include/std/future: Optimise use of std::bind.
* testsuite/20_util/bind/cv_quals.cc: Test volatile-qualification.
* testsuite/20_util/bind/move.cc: New.
2010-10-07 Hans-Peter Nilsson <hp@axis.com>
PR libstdc++/45841
......
......@@ -309,7 +309,7 @@ namespace std
bool __set = __ignore_failure;
// all calls to this function are serialized,
// side-effects of invoking __res only happen once
call_once(_M_once, mem_fn(&_State::_M_do_set), this, ref(__res),
call_once(_M_once, &_State::_M_do_set, this, ref(__res),
ref(__set));
if (!__set)
__throw_future_error(int(future_errc::promise_already_satisfied));
......@@ -1155,7 +1155,7 @@ namespace std
_M_run(_Args... __args)
{
// bound arguments decay so wrap lvalue references
auto __bound = std::bind<_Res>(_M_task,
auto __bound = std::bind<_Res>(std::ref(_M_task),
_S_maybe_wrap_ref(std::forward<_Args>(__args))...);
_Task_setter<_Task_state> __setter{ this, std::move(__bound) };
_M_set_result(std::move(__setter));
......
......@@ -690,7 +690,7 @@ namespace std
template<typename _Callable, typename... _Args>
friend void
call_once(once_flag& __once, _Callable __f, _Args&&... __args);
call_once(once_flag& __once, _Callable&& __f, _Args&&... __args);
};
#ifdef _GLIBCXX_HAVE_TLS
......@@ -718,15 +718,17 @@ namespace std
/// call_once
template<typename _Callable, typename... _Args>
void
call_once(once_flag& __once, _Callable __f, _Args&&... __args)
call_once(once_flag& __once, _Callable&& __f, _Args&&... __args)
{
#ifdef _GLIBCXX_HAVE_TLS
auto __bound_functor = std::bind<void>(__f, __args...);
auto __bound_functor = std::bind<void>(std::forward<_Callable>(__f),
std::forward<_Args>(__args)...);
__once_callable = &__bound_functor;
__once_call = &__once_call_impl<decltype(__bound_functor)>;
#else
unique_lock<mutex> __functor_lock(__get_once_mutex());
__once_functor = std::bind<void>(__f, __args...);
__once_functor = std::bind<void>(std::forward<_Callable>(__f),
std::forward<_Args>(__args)...);
__set_once_functor_lock_ptr(&__functor_lock);
#endif
......
......@@ -126,16 +126,14 @@ namespace std
thread(thread&& __t)
{ swap(__t); }
template<typename _Callable>
explicit thread(_Callable __f)
{
_M_start_thread(_M_make_routine<_Callable>
(std::forward<_Callable>(__f)));
}
template<typename _Callable, typename... _Args>
explicit
thread(_Callable&& __f, _Args&&... __args)
{ _M_start_thread(_M_make_routine(std::bind(__f, __args...))); }
{
_M_start_thread(_M_make_routine(std::bind<void>(
std::forward<_Callable>(__f),
std::forward<_Args>(__args)...)));
}
~thread()
{
......
......@@ -22,14 +22,24 @@
#include <functional>
#include <testsuite_hooks.h>
// target must be invoked with cv-quals of call wrapper
struct X
{
int operator()() { return 0; }
int operator()() const { return 1; }
// int operator()() volatile { return 2; }
// int operator()() const volatile { return 3; }
int operator()() volatile { return 2; }
int operator()() const volatile { return 3; }
int operator()(int, int, int) { return 0; }
int operator()(int, int, int) const { return 1; }
int operator()(int, int, int) volatile { return 2; }
int operator()(int, int, int) const volatile { return 3; }
};
using std::placeholders::_1;
using std::placeholders::_2;
void test01()
{
bool test __attribute__((unused)) = true;
......@@ -40,15 +50,70 @@ void test01()
const auto b1 = std::bind(X());
VERIFY( b1() == 1 );
// volatile auto b2 = std::bind(X());
// VERIFY( b2() == 2 );
volatile auto b2 = std::bind(X());
VERIFY( b2() == 2 );
const volatile auto b3 = std::bind(X());
VERIFY( b3() == 3 );
}
void test02()
{
bool test __attribute__((unused)) = true;
auto b0 = std::bind<int>(X());
VERIFY( b0() == 0 );
const auto b1 = std::bind<int>(X());
VERIFY( b1() == 1 );
volatile auto b2 = std::bind<int>(X());
VERIFY( b2() == 2 );
const volatile auto b3 = std::bind<int>(X());
VERIFY( b3() == 3 );
}
void test03()
{
bool test __attribute__((unused)) = true;
auto b0 = std::bind(X(), 0, _1, _2);
VERIFY( b0(0, 0) == 0 );
// const volatile auto b3 = std::bind(X());
// VERIFY( b3() == 3 );
const auto b1 = std::bind(X(), _1, 0, _2);
VERIFY( b1(0, 0) == 1 );
volatile auto b2 = std::bind(X(), _1, _2, 0);
VERIFY( b2(0, 0) == 2 );
const volatile auto b3 = std::bind(X(), _1, 0, _2);
VERIFY( b3(0, 0) == 3 );
}
void test04()
{
bool test __attribute__((unused)) = true;
auto b0 = std::bind<int>(X(), 0, _1, _2);
VERIFY( b0(0, 0) == 0 );
const auto b1 = std::bind<int>(X(), _1, 0, _2);
VERIFY( b1(0, 0) == 1 );
volatile auto b2 = std::bind<int>(X(), _1, _2, 0);
VERIFY( b2(0, 0) == 2 );
const volatile auto b3 = std::bind<int>(X(), _1, 0, _2);
VERIFY( b3(0, 0) == 3 );
}
int main()
{
test01();
test02();
test03();
test04();
return 0;
}
// { dg-options "-std=gnu++0x" }
// Copyright (C) 2010 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#include <functional>
#include <testsuite_hooks.h>
// PR libstdc++/45924
struct f
{
f() : i(0) { }
f(f&& r) : i(1) { r.i = -1; }
f(const f&) = delete;
int operator()() { return i; }
int i;
};
void test01()
{
auto b = std::bind(f());
VERIFY( b() == 1 );
auto bc(std::move(b));
VERIFY( bc() == 1 );
VERIFY( b() == -1 );
}
void test02()
{
auto b = std::bind<int>(f());
VERIFY( b() == 1 );
auto bc(std::move(b));
VERIFY( bc() == 1 );
VERIFY( b() == -1 );
}
int main()
{
test01();
test02();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment