3 #include "../enum_class.h"
\r
5 #include <boost/thread/future.hpp>
\r
6 #include <boost/thread/thread.hpp>
\r
7 #include <boost/utility/declval.hpp>
\r
9 #include <functional>
\r
15 struct launch_policy_def
\r
23 typedef enum_class<launch_policy_def> launch;
\r
27 template<typename R, typename F>
\r
28 struct callback_object: public boost::detail::future_object<R>
\r
33 template<typename F2>
\r
34 callback_object(F2&& f)
\r
35 : f(std::forward<F2>(f))
\r
42 boost::lock_guard<boost::mutex> lock2(mutex);
\r
49 this->mark_finished_with_result_internal(f());
\r
53 this->mark_exceptional_finish_internal(boost::current_exception());
\r
60 template<typename F>
\r
61 struct callback_object<void, F> : public boost::detail::future_object<void>
\r
66 template<typename F2>
\r
67 callback_object(F2&& f)
\r
68 : f(std::forward<F2>(f))
\r
75 boost::lock_guard<boost::mutex> lock2(mutex);
\r
83 this->mark_finished_with_result_internal();
\r
87 this->mark_exceptional_finish_internal(boost::current_exception());
\r
96 template<typename F>
\r
97 auto async(launch lp, F&& f) -> boost::unique_future<decltype(f())>
\r
99 typedef decltype(f()) result_type;
\r
101 if(lp == launch::deferred)
\r
103 // HACK: THIS IS A MAYOR HACK!
\r
105 typedef boost::detail::future_object<result_type> future_object_t;
\r
107 auto callback_object = boost::make_shared<detail::callback_object<result_type, F>>(std::forward<F>(f));
\r
108 auto callback_object_raw = callback_object.get();
\r
109 auto future_object = boost::static_pointer_cast<future_object_t>(std::move(callback_object));
\r
112 future_object->set_wait_callback(std::function<void(int)>([callback_object_raw](int) mutable
\r
114 (*callback_object_raw)();
\r
117 boost::unique_future<result_type> future;
\r
118 reinterpret_cast<boost::shared_ptr<future_object_t>&>(future) = std::move(future_object); // Get around the "private" encapsulation.
\r
119 return std::move(future);
\r
123 typedef boost::packaged_task<result_type> task_t;
\r
125 auto task = task_t(std::forward<F>(f));
\r
126 auto future = task.get_future();
\r
128 boost::thread(std::move(task)).detach();
\r
130 return std::move(future);
\r
134 template<typename F>
\r
135 auto async(F&& f) -> boost::unique_future<decltype(f())>
\r
137 return async(launch::async, std::forward<F>(f));
\r
140 template<typename T>
\r
141 auto make_shared(boost::unique_future<T>&& f) -> boost::shared_future<T>
\r
143 return boost::shared_future<T>(std::move(f));
\r
146 template<typename T>
\r
147 auto flatten(boost::unique_future<T>&& f) -> boost::unique_future<decltype(f.get().get())>
\r
149 auto shared_f = make_shared(std::move(f));
\r
150 return async(launch::deferred, [=]() mutable
\r
152 return shared_f.get().get();
\r