future (promise): Add constructors for uses-allocator construction from rvalue promise.
* include/std/future (promise): Add constructors for uses-allocator construction from rvalue promise. (packaged_task): Implement LWG 2067. Add additional constructors for uses-allocator construction. * testsuite/30_threads/packaged_task/cons/3.cc: New. * testsuite/30_threads/packaged_task/cons/alloc2.cc: New. * testsuite/30_threads/promise/cons/alloc2.cc: New. From-SVN: r180757
This commit is contained in:
parent
095c8a9466
commit
376d7c51ec
|
@ -1,3 +1,13 @@
|
||||||
|
2011-11-02 Jonathan Wakely <jwakely.gcc@gmail.com>
|
||||||
|
|
||||||
|
* include/std/future (promise): Add constructors for uses-allocator
|
||||||
|
construction from rvalue promise.
|
||||||
|
(packaged_task): Implement LWG 2067. Add additional constructors for
|
||||||
|
uses-allocator construction.
|
||||||
|
* testsuite/30_threads/packaged_task/cons/3.cc: New.
|
||||||
|
* testsuite/30_threads/packaged_task/cons/alloc2.cc: New.
|
||||||
|
* testsuite/30_threads/promise/cons/alloc2.cc: New.
|
||||||
|
|
||||||
2011-10-31 Jason Merrill <jason@redhat.com>
|
2011-10-31 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
* include/Makefile.am (install-freestanding-headers): Install
|
* include/Makefile.am (install-freestanding-headers): Install
|
||||||
|
|
|
@ -955,6 +955,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
_M_storage(__future_base::_S_allocate_result<_Res>(__a))
|
_M_storage(__future_base::_S_allocate_result<_Res>(__a))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
template<typename _Allocator>
|
||||||
|
promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
|
||||||
|
: _M_future(std::move(__rhs._M_future)),
|
||||||
|
_M_storage(std::move(__rhs._M_storage))
|
||||||
|
{ }
|
||||||
|
|
||||||
promise(const promise&) = delete;
|
promise(const promise&) = delete;
|
||||||
|
|
||||||
~promise()
|
~promise()
|
||||||
|
@ -1047,6 +1053,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
_M_storage(__future_base::_S_allocate_result<_Res&>(__a))
|
_M_storage(__future_base::_S_allocate_result<_Res&>(__a))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
template<typename _Allocator>
|
||||||
|
promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
|
||||||
|
: _M_future(std::move(__rhs._M_future)),
|
||||||
|
_M_storage(std::move(__rhs._M_storage))
|
||||||
|
{ }
|
||||||
|
|
||||||
promise(const promise&) = delete;
|
promise(const promise&) = delete;
|
||||||
|
|
||||||
~promise()
|
~promise()
|
||||||
|
@ -1122,6 +1134,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
_M_storage(__future_base::_S_allocate_result<void>(__a))
|
_M_storage(__future_base::_S_allocate_result<void>(__a))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
template<typename _Allocator>
|
||||||
|
promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
|
||||||
|
: _M_future(std::move(__rhs._M_future)),
|
||||||
|
_M_storage(std::move(__rhs._M_storage))
|
||||||
|
{ }
|
||||||
|
|
||||||
promise(const promise&) = delete;
|
promise(const promise&) = delete;
|
||||||
|
|
||||||
~promise()
|
~promise()
|
||||||
|
@ -1270,6 +1288,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
{ return std::forward<_Tp>(__t); }
|
{ return std::forward<_Tp>(__t); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename _Task, typename _Fn, bool
|
||||||
|
= is_same<_Task, typename remove_reference<_Fn>::type>::value>
|
||||||
|
struct __is_same_pkgdtask
|
||||||
|
{ typedef void __type; };
|
||||||
|
|
||||||
|
template<typename _Task, typename _Fn>
|
||||||
|
struct __is_same_pkgdtask<_Task, _Fn, true>
|
||||||
|
{ };
|
||||||
|
|
||||||
/// packaged_task
|
/// packaged_task
|
||||||
template<typename _Res, typename... _ArgTypes>
|
template<typename _Res, typename... _ArgTypes>
|
||||||
class packaged_task<_Res(_ArgTypes...)>
|
class packaged_task<_Res(_ArgTypes...)>
|
||||||
|
@ -1281,13 +1308,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
// Construction and destruction
|
// Construction and destruction
|
||||||
packaged_task() noexcept { }
|
packaged_task() noexcept { }
|
||||||
|
|
||||||
template<typename _Fn>
|
template<typename _Allocator>
|
||||||
|
explicit
|
||||||
|
packaged_task(allocator_arg_t, const _Allocator& __a) noexcept
|
||||||
|
{ }
|
||||||
|
|
||||||
|
template<typename _Fn, typename = typename
|
||||||
|
__is_same_pkgdtask<packaged_task, _Fn>::__type>
|
||||||
explicit
|
explicit
|
||||||
packaged_task(_Fn&& __fn)
|
packaged_task(_Fn&& __fn)
|
||||||
: _M_state(std::make_shared<_State_type>(std::forward<_Fn>(__fn)))
|
: _M_state(std::make_shared<_State_type>(std::forward<_Fn>(__fn)))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template<typename _Fn, typename _Allocator>
|
template<typename _Fn, typename _Allocator, typename = typename
|
||||||
|
__is_same_pkgdtask<packaged_task, _Fn>::__type>
|
||||||
explicit
|
explicit
|
||||||
packaged_task(allocator_arg_t, const _Allocator& __a, _Fn&& __fn)
|
packaged_task(allocator_arg_t, const _Allocator& __a, _Fn&& __fn)
|
||||||
: _M_state(std::allocate_shared<_State_type>(__a,
|
: _M_state(std::allocate_shared<_State_type>(__a,
|
||||||
|
@ -1301,13 +1335,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
}
|
}
|
||||||
|
|
||||||
// No copy
|
// No copy
|
||||||
packaged_task(packaged_task&) = delete;
|
packaged_task(const packaged_task&) = delete;
|
||||||
packaged_task& operator=(packaged_task&) = delete;
|
packaged_task& operator=(const packaged_task&) = delete;
|
||||||
|
|
||||||
|
template<typename _Allocator>
|
||||||
|
explicit
|
||||||
|
packaged_task(allocator_arg_t, const _Allocator&,
|
||||||
|
const packaged_task&) = delete;
|
||||||
|
|
||||||
// Move support
|
// Move support
|
||||||
packaged_task(packaged_task&& __other) noexcept
|
packaged_task(packaged_task&& __other) noexcept
|
||||||
{ this->swap(__other); }
|
{ this->swap(__other); }
|
||||||
|
|
||||||
|
template<typename _Allocator>
|
||||||
|
explicit
|
||||||
|
packaged_task(allocator_arg_t, const _Allocator&,
|
||||||
|
packaged_task&& __other) noexcept
|
||||||
|
{ this->swap(__other); }
|
||||||
|
|
||||||
packaged_task& operator=(packaged_task&& __other) noexcept
|
packaged_task& operator=(packaged_task&& __other) noexcept
|
||||||
{
|
{
|
||||||
packaged_task(std::move(__other)).swap(*this);
|
packaged_task(std::move(__other)).swap(*this);
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } }
|
||||||
|
// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } }
|
||||||
|
// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } }
|
||||||
|
// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } }
|
||||||
|
// { dg-require-cstdint "" }
|
||||||
|
// { dg-require-gthreads "" }
|
||||||
|
// { dg-require-atomic-builtins "" }
|
||||||
|
|
||||||
|
// Copyright (C) 2011 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/>.
|
||||||
|
|
||||||
|
// LWG 2067. packaged_task should have deleted copy c'tor with const parameter
|
||||||
|
|
||||||
|
#include <future>
|
||||||
|
#include <thread>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
std::future<typename std::result_of<F()>::type> spawn_task(F f)
|
||||||
|
{
|
||||||
|
typedef typename std::result_of<F()>::type result_type;
|
||||||
|
std::packaged_task<result_type()> task(std::move(f));
|
||||||
|
std::future<result_type> res(task.get_future());
|
||||||
|
std::thread(std::move(task)).detach();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_res()
|
||||||
|
{
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test01()
|
||||||
|
{
|
||||||
|
auto f = spawn_task(get_res);
|
||||||
|
VERIFY( f.get() == get_res() );
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test01();
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
// { dg-do compile }
|
||||||
|
// { dg-options "-std=gnu++0x" }
|
||||||
|
// { dg-require-cstdint "" }
|
||||||
|
// { dg-require-gthreads "" }
|
||||||
|
// { dg-require-atomic-builtins "" }
|
||||||
|
|
||||||
|
// Copyright (C) 2011 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/>.
|
||||||
|
|
||||||
|
// Test that packaged_task can be default-constructed or move-constructed
|
||||||
|
// in a context that does uses-allocator construction.
|
||||||
|
|
||||||
|
#include <future>
|
||||||
|
#include <memory>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
using std::packaged_task;
|
||||||
|
using std::allocator_arg;
|
||||||
|
using std::allocator;
|
||||||
|
using std::tuple;
|
||||||
|
|
||||||
|
typedef packaged_task<void()> task;
|
||||||
|
allocator<task> a;
|
||||||
|
|
||||||
|
tuple<task> t1{ allocator_arg, a };
|
||||||
|
tuple<task> t2{ allocator_arg, a, task{} };
|
|
@ -0,0 +1,42 @@
|
||||||
|
// { dg-do compile }
|
||||||
|
// { dg-options "-std=gnu++0x" }
|
||||||
|
// { dg-require-cstdint "" }
|
||||||
|
// { dg-require-gthreads "" }
|
||||||
|
// { dg-require-atomic-builtins "" }
|
||||||
|
|
||||||
|
// Copyright (C) 2011 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/>.
|
||||||
|
|
||||||
|
// Test that promise can be default-constructed or move-constructed
|
||||||
|
// in a context that does uses-allocator construction.
|
||||||
|
|
||||||
|
#include <future>
|
||||||
|
#include <memory>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
using std::promise;
|
||||||
|
using std::allocator_arg;
|
||||||
|
using std::allocator;
|
||||||
|
using std::tuple;
|
||||||
|
|
||||||
|
typedef promise<int> p;
|
||||||
|
typedef promise<int&> pr;
|
||||||
|
typedef promise<void> pv;
|
||||||
|
allocator<p> a;
|
||||||
|
|
||||||
|
tuple<p, pr, pv> t1{ allocator_arg, a };
|
||||||
|
tuple<p, pr, pv> t2{ allocator_arg, a, p{}, pr{}, pv{} };
|
Loading…
Reference in New Issue