]> rtime.felk.cvut.cz Git - eurobot/public.git/blob - src/boost/boost/thread/future.hpp
Add subset of boost library headers needed for compilation on PowerPC
[eurobot/public.git] / src / boost / boost / thread / future.hpp
1 //  (C) Copyright 2008-10 Anthony Williams
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See
4 //  accompanying file LICENSE_1_0.txt or copy at
5 //  http://www.boost.org/LICENSE_1_0.txt)
6
7 #ifndef BOOST_THREAD_FUTURE_HPP
8 #define BOOST_THREAD_FUTURE_HPP
9 #include <stdexcept>
10 #include <boost/thread/detail/move.hpp>
11 #include <boost/thread/thread_time.hpp>
12 #include <boost/thread/mutex.hpp>
13 #include <boost/thread/condition_variable.hpp>
14 #include <boost/exception_ptr.hpp>
15 #include <boost/shared_ptr.hpp>
16 #include <boost/scoped_ptr.hpp>
17 #include <boost/type_traits/is_fundamental.hpp>
18 #include <boost/type_traits/is_convertible.hpp>
19 #include <boost/mpl/if.hpp>
20 #include <boost/config.hpp>
21 #include <boost/throw_exception.hpp>
22 #include <algorithm>
23 #include <boost/function.hpp>
24 #include <boost/bind.hpp>
25 #include <boost/ref.hpp>
26 #include <boost/scoped_array.hpp>
27 #include <boost/utility/enable_if.hpp>
28 #include <list>
29 #include <boost/next_prior.hpp>
30 #include <vector>
31
32 namespace boost
33 {
34     class future_uninitialized:
35         public std::logic_error
36     {
37     public:
38         future_uninitialized():
39             std::logic_error("Future Uninitialized")
40         {}
41     };
42     class broken_promise:
43         public std::logic_error
44     {
45     public:
46         broken_promise():
47             std::logic_error("Broken promise")
48         {}
49     };
50     class future_already_retrieved:
51         public std::logic_error
52     {
53     public:
54         future_already_retrieved():
55             std::logic_error("Future already retrieved")
56         {}
57     };
58     class promise_already_satisfied:
59         public std::logic_error
60     {
61     public:
62         promise_already_satisfied():
63             std::logic_error("Promise already satisfied")
64         {}
65     };
66
67     class task_already_started:
68         public std::logic_error
69     {
70     public:
71         task_already_started():
72             std::logic_error("Task already started")
73         {}
74     };
75
76     class task_moved:
77         public std::logic_error
78     {
79     public:
80         task_moved():
81             std::logic_error("Task moved")
82         {}
83     };
84
85     namespace future_state
86     {
87         enum state { uninitialized, waiting, ready, moved };
88     }
89
90     namespace detail
91     {
92         struct future_object_base
93         {
94             boost::exception_ptr exception;
95             bool done;
96             boost::mutex mutex;
97             boost::condition_variable waiters;
98             typedef std::list<boost::condition_variable_any*> waiter_list;
99             waiter_list external_waiters;
100             boost::function<void()> callback;
101
102             future_object_base():
103                 done(false)
104             {}
105             virtual ~future_object_base()
106             {}
107
108             waiter_list::iterator register_external_waiter(boost::condition_variable_any& cv)
109             {
110                 boost::unique_lock<boost::mutex> lock(mutex);
111                 do_callback(lock);
112                 return external_waiters.insert(external_waiters.end(),&cv);
113             }
114
115             void remove_external_waiter(waiter_list::iterator it)
116             {
117                 boost::lock_guard<boost::mutex> lock(mutex);
118                 external_waiters.erase(it);
119             }
120
121             void mark_finished_internal()
122             {
123                 done=true;
124                 waiters.notify_all();
125                 for(waiter_list::const_iterator it=external_waiters.begin(),
126                         end=external_waiters.end();it!=end;++it)
127                 {
128                     (*it)->notify_all();
129                 }
130             }
131
132             struct relocker
133             {
134                 boost::unique_lock<boost::mutex>& lock;
135
136                 relocker(boost::unique_lock<boost::mutex>& lock_):
137                     lock(lock_)
138                 {
139                     lock.unlock();
140                 }
141                 ~relocker()
142                 {
143                     lock.lock();
144                 }
145             private:
146                 relocker& operator=(relocker const&);
147             };
148
149             void do_callback(boost::unique_lock<boost::mutex>& lock)
150             {
151                 if(callback && !done)
152                 {
153                     boost::function<void()> local_callback=callback;
154                     relocker relock(lock);
155                     local_callback();
156                 }
157             }
158
159
160             void wait(bool rethrow=true)
161             {
162                 boost::unique_lock<boost::mutex> lock(mutex);
163                 do_callback(lock);
164                 while(!done)
165                 {
166                     waiters.wait(lock);
167                 }
168                 if(rethrow && exception)
169                 {
170                     boost::rethrow_exception(exception);
171                 }
172             }
173
174             bool timed_wait_until(boost::system_time const& target_time)
175             {
176                 boost::unique_lock<boost::mutex> lock(mutex);
177                 do_callback(lock);
178                 while(!done)
179                 {
180                     bool const success=waiters.timed_wait(lock,target_time);
181                     if(!success && !done)
182                     {
183                         return false;
184                     }
185                 }
186                 return true;
187             }
188
189             void mark_exceptional_finish_internal(boost::exception_ptr const& e)
190             {
191                 exception=e;
192                 mark_finished_internal();
193             }
194             void mark_exceptional_finish()
195             {
196                 boost::lock_guard<boost::mutex> lock(mutex);
197                 mark_exceptional_finish_internal(boost::current_exception());
198             }
199
200             bool has_value()
201             {
202                 boost::lock_guard<boost::mutex> lock(mutex);
203                 return done && !exception;
204             }
205             bool has_exception()
206             {
207                 boost::lock_guard<boost::mutex> lock(mutex);
208                 return done && exception;
209             }
210
211             template<typename F,typename U>
212             void set_wait_callback(F f,U* u)
213             {
214                 callback=boost::bind(f,boost::ref(*u));
215             }
216
217         private:
218             future_object_base(future_object_base const&);
219             future_object_base& operator=(future_object_base const&);
220         };
221
222         template<typename T>
223         struct future_traits
224         {
225             typedef boost::scoped_ptr<T> storage_type;
226 #ifndef BOOST_NO_RVALUE_REFERENCES
227             typedef T const& source_reference_type;
228             struct dummy;
229             typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,T&&>::type rvalue_source_type;
230             typedef typename boost::mpl::if_<boost::is_fundamental<T>,T,T&&>::type move_dest_type;
231 #else
232             typedef T& source_reference_type;
233             typedef typename boost::mpl::if_<boost::is_convertible<T&,boost::detail::thread_move_t<T> >,boost::detail::thread_move_t<T>,T const&>::type rvalue_source_type;
234             typedef typename boost::mpl::if_<boost::is_convertible<T&,boost::detail::thread_move_t<T> >,boost::detail::thread_move_t<T>,T>::type move_dest_type;
235 #endif
236
237             static void init(storage_type& storage,source_reference_type t)
238             {
239                 storage.reset(new T(t));
240             }
241
242             static void init(storage_type& storage,rvalue_source_type t)
243             {
244                 storage.reset(new T(static_cast<rvalue_source_type>(t)));
245             }
246
247             static void cleanup(storage_type& storage)
248             {
249                 storage.reset();
250             }
251         };
252
253         template<typename T>
254         struct future_traits<T&>
255         {
256             typedef T* storage_type;
257             typedef T& source_reference_type;
258             struct rvalue_source_type
259             {};
260             typedef T& move_dest_type;
261
262             static void init(storage_type& storage,T& t)
263             {
264                 storage=&t;
265             }
266
267             static void cleanup(storage_type& storage)
268             {
269                 storage=0;
270             }
271         };
272
273         template<>
274         struct future_traits<void>
275         {
276             typedef bool storage_type;
277             typedef void move_dest_type;
278
279             static void init(storage_type& storage)
280             {
281                 storage=true;
282             }
283
284             static void cleanup(storage_type& storage)
285             {
286                 storage=false;
287             }
288
289         };
290
291         template<typename T>
292         struct future_object:
293             detail::future_object_base
294         {
295             typedef typename future_traits<T>::storage_type storage_type;
296             typedef typename future_traits<T>::source_reference_type source_reference_type;
297             typedef typename future_traits<T>::rvalue_source_type rvalue_source_type;
298             typedef typename future_traits<T>::move_dest_type move_dest_type;
299
300             storage_type result;
301
302             future_object():
303                 result(0)
304             {}
305
306             void mark_finished_with_result_internal(source_reference_type result_)
307             {
308                 future_traits<T>::init(result,result_);
309                 mark_finished_internal();
310             }
311             void mark_finished_with_result_internal(rvalue_source_type result_)
312             {
313                 future_traits<T>::init(result,static_cast<rvalue_source_type>(result_));
314                 mark_finished_internal();
315             }
316
317             void mark_finished_with_result(source_reference_type result_)
318             {
319                 boost::lock_guard<boost::mutex> lock(mutex);
320                 mark_finished_with_result_internal(result_);
321             }
322             void mark_finished_with_result(rvalue_source_type result_)
323             {
324                 boost::lock_guard<boost::mutex> lock(mutex);
325                 mark_finished_with_result_internal(result_);
326             }
327
328             move_dest_type get()
329             {
330                 wait();
331                 return static_cast<move_dest_type>(*result);
332             }
333
334             future_state::state get_state()
335             {
336                 boost::lock_guard<boost::mutex> guard(mutex);
337                 if(!done)
338                 {
339                     return future_state::waiting;
340                 }
341                 else
342                 {
343                     return future_state::ready;
344                 }
345             }
346
347         private:
348             future_object(future_object const&);
349             future_object& operator=(future_object const&);
350         };
351
352         template<>
353         struct future_object<void>:
354             detail::future_object_base
355         {
356           typedef void move_dest_type;
357
358             future_object()
359             {}
360
361             void mark_finished_with_result_internal()
362             {
363                 mark_finished_internal();
364             }
365
366             void mark_finished_with_result()
367             {
368                 boost::lock_guard<boost::mutex> lock(mutex);
369                 mark_finished_with_result_internal();
370             }
371
372             void get()
373             {
374                 wait();
375             }
376
377             future_state::state get_state()
378             {
379                 boost::lock_guard<boost::mutex> guard(mutex);
380                 if(!done)
381                 {
382                     return future_state::waiting;
383                 }
384                 else
385                 {
386                     return future_state::ready;
387                 }
388             }
389
390         private:
391             future_object(future_object const&);
392             future_object& operator=(future_object const&);
393         };
394
395         class future_waiter
396         {
397             struct registered_waiter;
398             typedef std::vector<registered_waiter>::size_type count_type;
399
400             struct registered_waiter
401             {
402                 boost::shared_ptr<detail::future_object_base> future;
403                 detail::future_object_base::waiter_list::iterator wait_iterator;
404                 count_type index;
405
406                 registered_waiter(boost::shared_ptr<detail::future_object_base> const& future_,
407                                   detail::future_object_base::waiter_list::iterator wait_iterator_,
408                                   count_type index_):
409                     future(future_),wait_iterator(wait_iterator_),index(index_)
410                 {}
411
412             };
413
414             struct all_futures_lock
415             {
416 #ifdef _MANAGED
417                 typedef std::ptrdiff_t count_type_portable;
418 #else
419                 typedef count_type count_type_portable;
420 #endif
421                 count_type_portable count;
422
423                 boost::scoped_array<boost::unique_lock<boost::mutex> > locks;
424
425                 all_futures_lock(std::vector<registered_waiter>& futures):
426                     count(futures.size()),locks(new boost::unique_lock<boost::mutex>[count])
427                 {
428                     for(count_type_portable i=0;i<count;++i)
429                     {
430 #if defined __DECCXX || defined __SUNPRO_CC
431                         locks[i]=boost::unique_lock<boost::mutex>(futures[i].future->mutex).move();
432 #else
433                         locks[i]=boost::unique_lock<boost::mutex>(futures[i].future->mutex);
434 #endif
435                     }
436                 }
437
438                 void lock()
439                 {
440                     boost::lock(locks.get(),locks.get()+count);
441                 }
442
443                 void unlock()
444                 {
445                     for(count_type_portable i=0;i<count;++i)
446                     {
447                         locks[i].unlock();
448                     }
449                 }
450             };
451
452             boost::condition_variable_any cv;
453             std::vector<registered_waiter> futures;
454             count_type future_count;
455
456         public:
457             future_waiter():
458                 future_count(0)
459             {}
460
461             template<typename F>
462             void add(F& f)
463             {
464                 if(f.future)
465                 {
466                     futures.push_back(registered_waiter(f.future,f.future->register_external_waiter(cv),future_count));
467                 }
468                 ++future_count;
469             }
470
471             count_type wait()
472             {
473                 all_futures_lock lk(futures);
474                 for(;;)
475                 {
476                     for(count_type i=0;i<futures.size();++i)
477                     {
478                         if(futures[i].future->done)
479                         {
480                             return futures[i].index;
481                         }
482                     }
483                     cv.wait(lk);
484                 }
485             }
486
487             ~future_waiter()
488             {
489                 for(count_type i=0;i<futures.size();++i)
490                 {
491                     futures[i].future->remove_external_waiter(futures[i].wait_iterator);
492                 }
493             }
494
495         };
496
497     }
498
499     template <typename R>
500     class unique_future;
501
502     template <typename R>
503     class shared_future;
504
505     template<typename T>
506     struct is_future_type
507     {
508         BOOST_STATIC_CONSTANT(bool, value=false);
509     };
510
511     template<typename T>
512     struct is_future_type<unique_future<T> >
513     {
514         BOOST_STATIC_CONSTANT(bool, value=true);
515     };
516
517     template<typename T>
518     struct is_future_type<shared_future<T> >
519     {
520         BOOST_STATIC_CONSTANT(bool, value=true);
521     };
522
523     template<typename Iterator>
524     typename boost::disable_if<is_future_type<Iterator>,void>::type wait_for_all(Iterator begin,Iterator end)
525     {
526         for(Iterator current=begin;current!=end;++current)
527         {
528             current->wait();
529         }
530     }
531
532     template<typename F1,typename F2>
533     typename boost::enable_if<is_future_type<F1>,void>::type wait_for_all(F1& f1,F2& f2)
534     {
535         f1.wait();
536         f2.wait();
537     }
538
539     template<typename F1,typename F2,typename F3>
540     void wait_for_all(F1& f1,F2& f2,F3& f3)
541     {
542         f1.wait();
543         f2.wait();
544         f3.wait();
545     }
546
547     template<typename F1,typename F2,typename F3,typename F4>
548     void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4)
549     {
550         f1.wait();
551         f2.wait();
552         f3.wait();
553         f4.wait();
554     }
555
556     template<typename F1,typename F2,typename F3,typename F4,typename F5>
557     void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
558     {
559         f1.wait();
560         f2.wait();
561         f3.wait();
562         f4.wait();
563         f5.wait();
564     }
565
566     template<typename Iterator>
567     typename boost::disable_if<is_future_type<Iterator>,Iterator>::type wait_for_any(Iterator begin,Iterator end)
568     {
569         if(begin==end)
570             return end;
571
572         detail::future_waiter waiter;
573         for(Iterator current=begin;current!=end;++current)
574         {
575             waiter.add(*current);
576         }
577         return boost::next(begin,waiter.wait());
578     }
579
580     template<typename F1,typename F2>
581     typename boost::enable_if<is_future_type<F1>,unsigned>::type wait_for_any(F1& f1,F2& f2)
582     {
583         detail::future_waiter waiter;
584         waiter.add(f1);
585         waiter.add(f2);
586         return waiter.wait();
587     }
588
589     template<typename F1,typename F2,typename F3>
590     unsigned wait_for_any(F1& f1,F2& f2,F3& f3)
591     {
592         detail::future_waiter waiter;
593         waiter.add(f1);
594         waiter.add(f2);
595         waiter.add(f3);
596         return waiter.wait();
597     }
598
599     template<typename F1,typename F2,typename F3,typename F4>
600     unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4)
601     {
602         detail::future_waiter waiter;
603         waiter.add(f1);
604         waiter.add(f2);
605         waiter.add(f3);
606         waiter.add(f4);
607         return waiter.wait();
608     }
609
610     template<typename F1,typename F2,typename F3,typename F4,typename F5>
611     unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
612     {
613         detail::future_waiter waiter;
614         waiter.add(f1);
615         waiter.add(f2);
616         waiter.add(f3);
617         waiter.add(f4);
618         waiter.add(f5);
619         return waiter.wait();
620     }
621
622     template <typename R>
623     class promise;
624
625     template <typename R>
626     class packaged_task;
627
628     template <typename R>
629     class unique_future
630     {
631         unique_future(unique_future & rhs);// = delete;
632         unique_future& operator=(unique_future& rhs);// = delete;
633
634         typedef boost::shared_ptr<detail::future_object<R> > future_ptr;
635
636         future_ptr future;
637
638         friend class shared_future<R>;
639         friend class promise<R>;
640         friend class packaged_task<R>;
641         friend class detail::future_waiter;
642
643         typedef typename detail::future_traits<R>::move_dest_type move_dest_type;
644
645         unique_future(future_ptr future_):
646             future(future_)
647         {}
648
649     public:
650         typedef future_state::state state;
651
652         unique_future()
653         {}
654
655         ~unique_future()
656         {}
657
658 #ifndef BOOST_NO_RVALUE_REFERENCES
659         unique_future(unique_future && other)
660         {
661             future.swap(other.future);
662         }
663         unique_future& operator=(unique_future && other)
664         {
665             future=other.future;
666             other.future.reset();
667             return *this;
668         }
669 #else
670         unique_future(boost::detail::thread_move_t<unique_future> other):
671             future(other->future)
672         {
673             other->future.reset();
674         }
675
676         unique_future& operator=(boost::detail::thread_move_t<unique_future> other)
677         {
678             future=other->future;
679             other->future.reset();
680             return *this;
681         }
682
683         operator boost::detail::thread_move_t<unique_future>()
684         {
685             return boost::detail::thread_move_t<unique_future>(*this);
686         }
687 #endif
688
689         void swap(unique_future& other)
690         {
691             future.swap(other.future);
692         }
693
694         // retrieving the value
695         move_dest_type get()
696         {
697             if(!future)
698             {
699                 boost::throw_exception(future_uninitialized());
700             }
701
702             return future->get();
703         }
704
705         // functions to check state, and wait for ready
706         state get_state() const
707         {
708             if(!future)
709             {
710                 return future_state::uninitialized;
711             }
712             return future->get_state();
713         }
714
715
716         bool is_ready() const
717         {
718             return get_state()==future_state::ready;
719         }
720
721         bool has_exception() const
722         {
723             return future && future->has_exception();
724         }
725
726         bool has_value() const
727         {
728             return future && future->has_value();
729         }
730
731         void wait() const
732         {
733             if(!future)
734             {
735                 boost::throw_exception(future_uninitialized());
736             }
737             future->wait(false);
738         }
739
740         template<typename Duration>
741         bool timed_wait(Duration const& rel_time) const
742         {
743             return timed_wait_until(boost::get_system_time()+rel_time);
744         }
745
746         bool timed_wait_until(boost::system_time const& abs_time) const
747         {
748             if(!future)
749             {
750                 boost::throw_exception(future_uninitialized());
751             }
752             return future->timed_wait_until(abs_time);
753         }
754
755     };
756
757 #ifdef BOOST_NO_RVALUE_REFERENCES
758     template <typename T>
759     struct has_move_emulation_enabled_aux<unique_future<T> >
760       : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
761     {};
762 #endif
763
764     template <typename R>
765     class shared_future
766     {
767         typedef boost::shared_ptr<detail::future_object<R> > future_ptr;
768
769         future_ptr future;
770
771 //         shared_future(const unique_future<R>& other);
772 //         shared_future& operator=(const unique_future<R>& other);
773
774         friend class detail::future_waiter;
775         friend class promise<R>;
776         friend class packaged_task<R>;
777
778         shared_future(future_ptr future_):
779             future(future_)
780         {}
781
782     public:
783         shared_future(shared_future const& other):
784             future(other.future)
785         {}
786
787         typedef future_state::state state;
788
789         shared_future()
790         {}
791
792         ~shared_future()
793         {}
794
795         shared_future& operator=(shared_future const& other)
796         {
797             future=other.future;
798             return *this;
799         }
800 #ifndef BOOST_NO_RVALUE_REFERENCES
801         shared_future(shared_future && other)
802         {
803             future.swap(other.future);
804         }
805         shared_future(unique_future<R> && other)
806         {
807             future.swap(other.future);
808         }
809         shared_future& operator=(shared_future && other)
810         {
811             future.swap(other.future);
812             other.future.reset();
813             return *this;
814         }
815         shared_future& operator=(unique_future<R> && other)
816         {
817             future.swap(other.future);
818             other.future.reset();
819             return *this;
820         }
821 #else
822         shared_future(boost::detail::thread_move_t<shared_future> other):
823             future(other->future)
824         {
825             other->future.reset();
826         }
827 //         shared_future(const unique_future<R> &) = delete;
828         shared_future(boost::detail::thread_move_t<unique_future<R> > other):
829             future(other->future)
830         {
831             other->future.reset();
832         }
833         shared_future& operator=(boost::detail::thread_move_t<shared_future> other)
834         {
835             future.swap(other->future);
836             other->future.reset();
837             return *this;
838         }
839         shared_future& operator=(boost::detail::thread_move_t<unique_future<R> > other)
840         {
841             future.swap(other->future);
842             other->future.reset();
843             return *this;
844         }
845
846         operator boost::detail::thread_move_t<shared_future>()
847         {
848             return boost::detail::thread_move_t<shared_future>(*this);
849         }
850
851 #endif
852
853         void swap(shared_future& other)
854         {
855             future.swap(other.future);
856         }
857
858         // retrieving the value
859         //typename detail::future_object<R>::move_dest_type get()
860         R get()
861         {
862             if(!future)
863             {
864                 boost::throw_exception(future_uninitialized());
865             }
866
867             return future->get();
868         }
869
870         // functions to check state, and wait for ready
871         state get_state() const
872         {
873             if(!future)
874             {
875                 return future_state::uninitialized;
876             }
877             return future->get_state();
878         }
879
880
881         bool is_ready() const
882         {
883             return get_state()==future_state::ready;
884         }
885
886         bool has_exception() const
887         {
888             return future && future->has_exception();
889         }
890
891         bool has_value() const
892         {
893             return future && future->has_value();
894         }
895
896         void wait() const
897         {
898             if(!future)
899             {
900                 boost::throw_exception(future_uninitialized());
901             }
902             future->wait(false);
903         }
904
905         template<typename Duration>
906         bool timed_wait(Duration const& rel_time) const
907         {
908             return timed_wait_until(boost::get_system_time()+rel_time);
909         }
910
911         bool timed_wait_until(boost::system_time const& abs_time) const
912         {
913             if(!future)
914             {
915                 boost::throw_exception(future_uninitialized());
916             }
917             return future->timed_wait_until(abs_time);
918         }
919
920     };
921
922 #ifdef BOOST_NO_RVALUE_REFERENCES
923     template <typename T>
924     struct has_move_emulation_enabled_aux<shared_future<T> >
925       : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
926     {};
927 #endif
928
929     template <typename R>
930     class promise
931     {
932         typedef boost::shared_ptr<detail::future_object<R> > future_ptr;
933
934         future_ptr future;
935         bool future_obtained;
936
937         promise(promise & rhs);// = delete;
938         promise & operator=(promise & rhs);// = delete;
939
940         void lazy_init()
941         {
942             if(!atomic_load(&future))
943             {
944                 future_ptr blank;
945                 atomic_compare_exchange(&future,&blank,future_ptr(new detail::future_object<R>));
946             }
947         }
948
949     public:
950 //         template <class Allocator> explicit promise(Allocator a);
951
952         promise():
953             future(),future_obtained(false)
954         {}
955
956         ~promise()
957         {
958             if(future)
959             {
960                 boost::lock_guard<boost::mutex> lock(future->mutex);
961
962                 if(!future->done)
963                 {
964                     future->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()));
965                 }
966             }
967         }
968
969         // Assignment
970 #ifndef BOOST_NO_RVALUE_REFERENCES
971         promise(promise && rhs):
972             future_obtained(rhs.future_obtained)
973         {
974             future.swap(rhs.future);
975             rhs.future_obtained=false;
976         }
977         promise & operator=(promise&& rhs)
978         {
979             future.swap(rhs.future);
980             future_obtained=rhs.future_obtained;
981             rhs.future.reset();
982             rhs.future_obtained=false;
983             return *this;
984         }
985 #else
986         promise(boost::detail::thread_move_t<promise> rhs):
987             future(rhs->future),future_obtained(rhs->future_obtained)
988         {
989             rhs->future.reset();
990             rhs->future_obtained=false;
991         }
992         promise & operator=(boost::detail::thread_move_t<promise> rhs)
993         {
994             future=rhs->future;
995             future_obtained=rhs->future_obtained;
996             rhs->future.reset();
997             rhs->future_obtained=false;
998             return *this;
999         }
1000
1001         operator boost::detail::thread_move_t<promise>()
1002         {
1003             return boost::detail::thread_move_t<promise>(*this);
1004         }
1005 #endif
1006
1007         void swap(promise& other)
1008         {
1009             future.swap(other.future);
1010             std::swap(future_obtained,other.future_obtained);
1011         }
1012
1013         // Result retrieval
1014         unique_future<R> get_future()
1015         {
1016             lazy_init();
1017             if(future_obtained)
1018             {
1019                 boost::throw_exception(future_already_retrieved());
1020             }
1021             future_obtained=true;
1022             return unique_future<R>(future);
1023         }
1024
1025         void set_value(typename detail::future_traits<R>::source_reference_type r)
1026         {
1027             lazy_init();
1028             boost::lock_guard<boost::mutex> lock(future->mutex);
1029             if(future->done)
1030             {
1031                 boost::throw_exception(promise_already_satisfied());
1032             }
1033             future->mark_finished_with_result_internal(r);
1034         }
1035
1036 //         void set_value(R && r);
1037         void set_value(typename detail::future_traits<R>::rvalue_source_type r)
1038         {
1039             lazy_init();
1040             boost::lock_guard<boost::mutex> lock(future->mutex);
1041             if(future->done)
1042             {
1043                 boost::throw_exception(promise_already_satisfied());
1044             }
1045             future->mark_finished_with_result_internal(static_cast<typename detail::future_traits<R>::rvalue_source_type>(r));
1046         }
1047
1048         void set_exception(boost::exception_ptr p)
1049         {
1050             lazy_init();
1051             boost::lock_guard<boost::mutex> lock(future->mutex);
1052             if(future->done)
1053             {
1054                 boost::throw_exception(promise_already_satisfied());
1055             }
1056             future->mark_exceptional_finish_internal(p);
1057         }
1058
1059         template<typename F>
1060         void set_wait_callback(F f)
1061         {
1062             lazy_init();
1063             future->set_wait_callback(f,this);
1064         }
1065
1066     };
1067
1068     template <>
1069     class promise<void>
1070     {
1071         typedef boost::shared_ptr<detail::future_object<void> > future_ptr;
1072
1073         future_ptr future;
1074         bool future_obtained;
1075
1076         promise(promise & rhs);// = delete;
1077         promise & operator=(promise & rhs);// = delete;
1078
1079         void lazy_init()
1080         {
1081             if(!atomic_load(&future))
1082             {
1083                 future_ptr blank;
1084                 atomic_compare_exchange(&future,&blank,future_ptr(new detail::future_object<void>));
1085             }
1086         }
1087     public:
1088 //         template <class Allocator> explicit promise(Allocator a);
1089
1090         promise():
1091             future(),future_obtained(false)
1092         {}
1093
1094         ~promise()
1095         {
1096             if(future)
1097             {
1098                 boost::lock_guard<boost::mutex> lock(future->mutex);
1099
1100                 if(!future->done)
1101                 {
1102                     future->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()));
1103                 }
1104             }
1105         }
1106
1107         // Assignment
1108 #ifndef BOOST_NO_RVALUE_REFERENCES
1109         promise(promise && rhs):
1110             future_obtained(rhs.future_obtained)
1111         {
1112             future.swap(rhs.future);
1113             rhs.future_obtained=false;
1114         }
1115         promise & operator=(promise&& rhs)
1116         {
1117             future.swap(rhs.future);
1118             future_obtained=rhs.future_obtained;
1119             rhs.future.reset();
1120             rhs.future_obtained=false;
1121             return *this;
1122         }
1123 #else
1124         promise(boost::detail::thread_move_t<promise> rhs):
1125             future(rhs->future),future_obtained(rhs->future_obtained)
1126         {
1127             rhs->future.reset();
1128             rhs->future_obtained=false;
1129         }
1130         promise & operator=(boost::detail::thread_move_t<promise> rhs)
1131         {
1132             future=rhs->future;
1133             future_obtained=rhs->future_obtained;
1134             rhs->future.reset();
1135             rhs->future_obtained=false;
1136             return *this;
1137         }
1138
1139         operator boost::detail::thread_move_t<promise>()
1140         {
1141             return boost::detail::thread_move_t<promise>(*this);
1142         }
1143 #endif
1144
1145         void swap(promise& other)
1146         {
1147             future.swap(other.future);
1148             std::swap(future_obtained,other.future_obtained);
1149         }
1150
1151         // Result retrieval
1152         unique_future<void> get_future()
1153         {
1154             lazy_init();
1155
1156             if(future_obtained)
1157             {
1158                 boost::throw_exception(future_already_retrieved());
1159             }
1160             future_obtained=true;
1161             return unique_future<void>(future);
1162         }
1163
1164         void set_value()
1165         {
1166             lazy_init();
1167             boost::lock_guard<boost::mutex> lock(future->mutex);
1168             if(future->done)
1169             {
1170                 boost::throw_exception(promise_already_satisfied());
1171             }
1172             future->mark_finished_with_result_internal();
1173         }
1174
1175         void set_exception(boost::exception_ptr p)
1176         {
1177             lazy_init();
1178             boost::lock_guard<boost::mutex> lock(future->mutex);
1179             if(future->done)
1180             {
1181                 boost::throw_exception(promise_already_satisfied());
1182             }
1183             future->mark_exceptional_finish_internal(p);
1184         }
1185
1186         template<typename F>
1187         void set_wait_callback(F f)
1188         {
1189             lazy_init();
1190             future->set_wait_callback(f,this);
1191         }
1192
1193     };
1194
1195 #ifdef BOOST_NO_RVALUE_REFERENCES
1196     template <typename T>
1197     struct has_move_emulation_enabled_aux<promise<T> >
1198       : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
1199     {};
1200 #endif
1201
1202     namespace detail
1203     {
1204         template<typename R>
1205         struct task_base:
1206             detail::future_object<R>
1207         {
1208             bool started;
1209
1210             task_base():
1211                 started(false)
1212             {}
1213
1214             void run()
1215             {
1216                 {
1217                     boost::lock_guard<boost::mutex> lk(this->mutex);
1218                     if(started)
1219                     {
1220                         boost::throw_exception(task_already_started());
1221                     }
1222                     started=true;
1223                 }
1224                 do_run();
1225             }
1226
1227             void owner_destroyed()
1228             {
1229                 boost::lock_guard<boost::mutex> lk(this->mutex);
1230                 if(!started)
1231                 {
1232                     started=true;
1233                     this->mark_exceptional_finish_internal(boost::copy_exception(boost::broken_promise()));
1234                 }
1235             }
1236
1237
1238             virtual void do_run()=0;
1239         };
1240
1241
1242         template<typename R,typename F>
1243         struct task_object:
1244             task_base<R>
1245         {
1246             F f;
1247             task_object(F const& f_):
1248                 f(f_)
1249             {}
1250 #ifndef BOOST_NO_RVALUE_REFERENCES
1251             task_object(F&& f_):
1252                 f(f_)
1253             {}
1254 #else
1255             task_object(boost::detail::thread_move_t<F> f_):
1256                 f(f_)
1257             {}
1258 #endif
1259
1260             void do_run()
1261             {
1262                 try
1263                 {
1264                     this->mark_finished_with_result(f());
1265                 }
1266                 catch(...)
1267                 {
1268                     this->mark_exceptional_finish();
1269                 }
1270             }
1271         };
1272
1273         template<typename F>
1274         struct task_object<void,F>:
1275             task_base<void>
1276         {
1277             F f;
1278             task_object(F const& f_):
1279                 f(f_)
1280             {}
1281 #ifndef BOOST_NO_RVALUE_REFERENCES
1282             task_object(F&& f_):
1283                 f(f_)
1284             {}
1285 #else
1286             task_object(boost::detail::thread_move_t<F> f_):
1287                 f(f_)
1288             {}
1289 #endif
1290
1291             void do_run()
1292             {
1293                 try
1294                 {
1295                     f();
1296                     this->mark_finished_with_result();
1297                 }
1298                 catch(...)
1299                 {
1300                     this->mark_exceptional_finish();
1301                 }
1302             }
1303         };
1304
1305     }
1306
1307
1308     template<typename R>
1309     class packaged_task
1310     {
1311         boost::shared_ptr<detail::task_base<R> > task;
1312         bool future_obtained;
1313
1314         packaged_task(packaged_task&);// = delete;
1315         packaged_task& operator=(packaged_task&);// = delete;
1316
1317     public:
1318         packaged_task():
1319             future_obtained(false)
1320         {}
1321
1322         // construction and destruction
1323         template <class F>
1324         explicit packaged_task(F const& f):
1325             task(new detail::task_object<R,F>(f)),future_obtained(false)
1326         {}
1327         explicit packaged_task(R(*f)()):
1328             task(new detail::task_object<R,R(*)()>(f)),future_obtained(false)
1329         {}
1330
1331 #ifndef BOOST_NO_RVALUE_REFERENCES
1332         template <class F>
1333         explicit packaged_task(F&& f):
1334             task(new detail::task_object<R,F>(f)),future_obtained(false)
1335         {}
1336 #else
1337         template <class F>
1338         explicit packaged_task(boost::detail::thread_move_t<F> f):
1339             task(new detail::task_object<R,F>(f)),future_obtained(false)
1340         {}
1341 #endif
1342
1343 //         template <class F, class Allocator>
1344 //         explicit packaged_task(F const& f, Allocator a);
1345 //         template <class F, class Allocator>
1346 //         explicit packaged_task(F&& f, Allocator a);
1347
1348
1349         ~packaged_task()
1350         {
1351             if(task)
1352             {
1353                 task->owner_destroyed();
1354             }
1355         }
1356
1357         // assignment
1358 #ifndef BOOST_NO_RVALUE_REFERENCES
1359         packaged_task(packaged_task&& other):
1360             future_obtained(other.future_obtained)
1361         {
1362             task.swap(other.task);
1363             other.future_obtained=false;
1364         }
1365         packaged_task& operator=(packaged_task&& other)
1366         {
1367             packaged_task temp(static_cast<packaged_task&&>(other));
1368             swap(temp);
1369             return *this;
1370         }
1371 #else
1372         packaged_task(boost::detail::thread_move_t<packaged_task> other):
1373             future_obtained(other->future_obtained)
1374         {
1375             task.swap(other->task);
1376             other->future_obtained=false;
1377         }
1378         packaged_task& operator=(boost::detail::thread_move_t<packaged_task> other)
1379         {
1380             packaged_task temp(other);
1381             swap(temp);
1382             return *this;
1383         }
1384         operator boost::detail::thread_move_t<packaged_task>()
1385         {
1386             return boost::detail::thread_move_t<packaged_task>(*this);
1387         }
1388 #endif
1389
1390     void swap(packaged_task& other)
1391         {
1392             task.swap(other.task);
1393             std::swap(future_obtained,other.future_obtained);
1394         }
1395
1396         // result retrieval
1397         unique_future<R> get_future()
1398         {
1399             if(!task)
1400             {
1401                 boost::throw_exception(task_moved());
1402             }
1403             else if(!future_obtained)
1404             {
1405                 future_obtained=true;
1406                 return unique_future<R>(task);
1407             }
1408             else
1409             {
1410                 boost::throw_exception(future_already_retrieved());
1411             }
1412         }
1413
1414
1415         // execution
1416         void operator()()
1417         {
1418             if(!task)
1419             {
1420                 boost::throw_exception(task_moved());
1421             }
1422             task->run();
1423         }
1424
1425         template<typename F>
1426         void set_wait_callback(F f)
1427         {
1428             task->set_wait_callback(f,this);
1429         }
1430
1431     };
1432
1433 #ifdef BOOST_NO_RVALUE_REFERENCES
1434     template <typename T>
1435     struct has_move_emulation_enabled_aux<packaged_task<T> >
1436       : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
1437     {};
1438 #endif
1439
1440 }
1441
1442
1443 #endif