Skip to content

Commit

Permalink
Deduce T& when the make_ready_future parameter is reference_wrapper<T…
Browse files Browse the repository at this point in the history
…>. Relates to #10979.
  • Loading branch information
viboes committed Feb 1, 2015
1 parent 095b53b commit cf53906
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 8 deletions.
3 changes: 1 addition & 2 deletions doc/changes.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ There are some severe bugs that prevent the use of the library on concrete conte

[*Fixed Bugs:]

* [@http://svn.boost.org/trac/boost/ticket/9600 #9600] Async: Add task_region


* [@http://svn.boost.org/trac/boost/ticket/10734 #10734] Submit method work differently on different executors, some throw exception and some silently ignore error (thread_executor and inline_executor)
* [@http://svn.boost.org/trac/boost/ticket/10736 #10736] Task exceptions silently ignored. I think std::terminate solution from N3785 and std::thread is better choice and more consistent.
Expand All @@ -59,6 +57,7 @@ There are some severe bugs that prevent the use of the library on concrete conte
* [@http://svn.boost.org/trac/boost/ticket/10963 #10963] future<future<T>>::then Has No Implementation
* [@http://svn.boost.org/trac/boost/ticket/10964 #10964] future<future<T>>::unwrap().then() Deadlocks
* [@http://svn.boost.org/trac/boost/ticket/10971 #10971] shared_future::get()/get_or() must be const
* [@http://svn.boost.org/trac/boost/ticket/10979 #10979] Support T& type deduction when the make_ready_future parameter is reference_wrapper<T>


[heading Version 4.4.0 - boost 1.57]
Expand Down
12 changes: 8 additions & 4 deletions doc/future_ref.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -2362,7 +2362,7 @@ All `R` types must be the same. If any of the `future<R>` or `shared_future<R>`
[section:make_ready_future Non-member function `make_ready_future()` EXTENSION]

template <typename T>
future<typename decay<T>::type> make_ready_future(T&& value); // EXTENSION
future<V> make_ready_future(T&& value); // EXTENSION
future<void> make_ready_future(); // EXTENSION
template <typename T>
future<T> make_ready_future(exception_ptr ex); // DEPRECATED
Expand All @@ -2371,11 +2371,15 @@ All `R` types must be the same. If any of the `future<R>` or `shared_future<R>`

[variablelist

[[Remark:][
where `V` is determined as follows: Let `U` be `decay_t<T>`. Then `V` is `X&`
if `U` equals `reference_wrapper<X>`, otherwise `V` is `U`.
]]
[[Effects:] [
- value prototype: The value that is passed into the function is moved to the shared state of the returned function if it is an rvalue.
Otherwise the value is copied to the shared state of the returned function.
- value prototype: The value that is passed into the function is moved to the shared state of the returned future if it is an rvalue.
Otherwise the value is copied to the shared state of the returned future.

- exception: The exception that is passed into the function is copied to the shared state of the returned function.
- exception: The exception that is passed into the function is copied to the shared state of the returned future.

.]]

Expand Down
20 changes: 20 additions & 0 deletions example/make_future.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,26 @@ int main()
boost::future<int&> f = compute_ref(0);
std::cout << f.get() << std::endl;
}
#if __cplusplus > 201103L
{
std::cout << __FILE__ << " "<< __LINE__ << std::endl;
int i = 0;
boost::future<int&> f = boost::make_ready_future(std::ref(i));
std::cout << f.get() << std::endl;
}
#endif
{
std::cout << __FILE__ << " "<< __LINE__ << std::endl;
int i = 0;
boost::future<int&> f = boost::make_ready_future(boost::ref(i));
std::cout << f.get() << std::endl;
}
{
std::cout << __FILE__ << " "<< __LINE__ << std::endl;
const int i = 0;
boost::future<int const&> f = boost::make_ready_future(boost::cref(i));
std::cout << f.get() << std::endl;
}
// {
// std::cout << __FILE__ << " "<< __LINE__ << std::endl;
// boost::future<int> f = compute(2);
Expand Down
38 changes: 36 additions & 2 deletions include/boost/thread/future.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
#include <algorithm>
#include <list>
#include <vector>
#include <utility>

#if defined BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_FUTURE future
Expand Down Expand Up @@ -3702,13 +3703,46 @@ namespace detail {
////////////////////////////////
// make_ready_future
////////////////////////////////
namespace detail {
template <class T>
struct deduced_type_impl
{
typedef T type;
};

template <class T>
struct deduced_type_impl<reference_wrapper<T> const>
{
typedef T& type;
};
template <class T>
struct deduced_type_impl<reference_wrapper<T> >
{
typedef T& type;
};
#if __cplusplus > 201103L
template <class T>
struct deduced_type_impl<std::reference_wrapper<T> >
{
typedef T& type;
};
#endif
template <class T>
struct deduced_type
{
typedef typename detail::deduced_type_impl<typename decay<T>::type>::type type;
};

}


#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <int = 0, int..., class T>
#else
template <class T>
#endif
BOOST_THREAD_FUTURE<typename decay<T>::type> make_ready_future(BOOST_THREAD_FWD_REF(T) value) {
typedef typename decay<T>::type future_value_type;
BOOST_THREAD_FUTURE<typename detail::deduced_type<T>::type> make_ready_future(BOOST_THREAD_FWD_REF(T) value) {
typedef typename detail::deduced_type<T>::type future_value_type;
promise<future_value_type> p;
p.set_value(boost::forward<future_value_type>(value));
return BOOST_THREAD_MAKE_RV_REF(p.get_future());
Expand Down

0 comments on commit cf53906

Please sign in to comment.