Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81129 - in trunk: boost/thread libs/thread/test libs/thread/test/sync/futures/future libs/thread/test/sync/futures/shared_future
From: vicente.botet_at_[hidden]
Date: 2012-10-31 17:16:02


Author: viboes
Date: 2012-10-31 17:16:00 EDT (Wed, 31 Oct 2012)
New Revision: 81129
URL: http://svn.boost.org/trac/boost/changeset/81129

Log:
Thread: Refactor futures by adding a basic_future common class + added some tests for shared_future
Added:
   trunk/libs/thread/test/sync/futures/shared_future/copy_assign_pass.cpp (contents, props changed)
   trunk/libs/thread/test/sync/futures/shared_future/copy_ctor_pass.cpp (contents, props changed)
   trunk/libs/thread/test/sync/futures/shared_future/default_pass.cpp (contents, props changed)
   trunk/libs/thread/test/sync/futures/shared_future/dtor_pass.cpp (contents, props changed)
   trunk/libs/thread/test/sync/futures/shared_future/get_pass.cpp (contents, props changed)
   trunk/libs/thread/test/sync/futures/shared_future/move_assign_pass.cpp (contents, props changed)
   trunk/libs/thread/test/sync/futures/shared_future/move_ctor_pass.cpp (contents, props changed)
Text files modified:
   trunk/boost/thread/future.hpp | 296 +++++++++++++++++++--------------------
   trunk/libs/thread/test/Jamfile.v2 | 12 +
   trunk/libs/thread/test/sync/futures/future/dtor_pass.cpp | 4
   trunk/libs/thread/test/sync/futures/future/get_pass.cpp | 6
   trunk/libs/thread/test/sync/futures/future/move_assign_pass.cpp | 4
   trunk/libs/thread/test/sync/futures/future/move_ctor_pass.cpp | 4
   6 files changed, 164 insertions(+), 162 deletions(-)

Modified: trunk/boost/thread/future.hpp
==============================================================================
--- trunk/boost/thread/future.hpp (original)
+++ trunk/boost/thread/future.hpp 2012-10-31 17:16:00 EDT (Wed, 31 Oct 2012)
@@ -584,6 +584,7 @@
                 return static_cast<shared_future_get_result_type>(*result);
             }
 
+ // todo move this to detail::future_object_base
             future_state::state get_state()
             {
                 boost::lock_guard<boost::mutex> guard(mutex);
@@ -630,6 +631,7 @@
             {
                 wait();
             }
+ // todo move this to detail::future_object_base
             future_state::state get_state()
             {
                 boost::lock_guard<boost::mutex> guard(mutex);
@@ -889,86 +891,55 @@
     template <typename R>
     class packaged_task;
 
- template <typename R>
- class BOOST_THREAD_FUTURE
+ namespace detail
     {
- private:
+ /// Common implementation for all the futures independently of the return type
+ class base_future
+ {
+
+ };
+ /// Common implementation for future and shared_future.
+ template <typename R>
+ class basic_future : public base_future
+ {
+ protected:
 
         typedef boost::shared_ptr<detail::future_object<R> > future_ptr;
 
         future_ptr future_;
 
- friend class shared_future<R>;
- friend class promise<R>;
-#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
- template <typename, typename, typename>
- friend struct detail::future_continuation;
-#endif
-#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
- template <class> friend class packaged_task; // todo check if this works in windows
-#else
- friend class packaged_task<R>;
-#endif
- friend class detail::future_waiter;
-
- typedef typename detail::future_traits<R>::move_dest_type move_dest_type;
-
- BOOST_THREAD_FUTURE(future_ptr a_future):
- future_(a_future)
+ basic_future(future_ptr a_future):
+ future_(a_future)
         {
         }
+ // Copy construction from a shared_future
+ explicit basic_future(const shared_future<R>&) BOOST_NOEXCEPT;
 
- public:
- BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
+ public:
         typedef future_state::state state;
 
- BOOST_THREAD_FUTURE()
+ BOOST_THREAD_MOVABLE(basic_future)
+ basic_future()
         {
         }
-
- ~BOOST_THREAD_FUTURE()
+ ~basic_future()
         {
         }
-
- BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
- future_(BOOST_THREAD_RV(other).future_)
+ basic_future(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT:
+ future_(BOOST_THREAD_RV(other).future_)
         {
             BOOST_THREAD_RV(other).future_.reset();
         }
-
- BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
+ basic_future& operator=(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT
         {
             future_=BOOST_THREAD_RV(other).future_;
             BOOST_THREAD_RV(other).future_.reset();
             return *this;
         }
-
- shared_future<R> share()
+ void swap(basic_future& that) BOOST_NOEXCEPT
         {
- return shared_future<R>(::boost::move(*this));
- }
-
- void swap(BOOST_THREAD_FUTURE& other)
- {
- future_.swap(other.future_);
- }
-
- // retrieving the value
- move_dest_type get()
- {
- if(!future_)
- {
- boost::throw_exception(future_uninitialized());
- }
-#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
- future_ptr fut_=future_;
- future_.reset();
- return fut_->get();
-#else
- return future_->get();
-#endif
+ future_.swap(that.future_);
         }
-
         // functions to check state, and wait for ready
         state get_state() const BOOST_NOEXCEPT
         {
@@ -1045,6 +1016,85 @@
         }
 #endif
 
+ };
+
+ } // detail
+ BOOST_THREAD_DCL_MOVABLE_BEG(R) detail::basic_future<R> BOOST_THREAD_DCL_MOVABLE_END
+
+ template <typename R>
+ class BOOST_THREAD_FUTURE : public detail::basic_future<R>
+ {
+ private:
+ typedef detail::basic_future<R> base_type;
+ typedef typename base_type::future_ptr future_ptr;
+
+ friend class shared_future<R>;
+ friend class promise<R>;
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+ template <typename, typename, typename>
+ friend struct detail::future_continuation;
+#endif
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ template <class> friend class packaged_task; // todo check if this works in windows
+#else
+ friend class packaged_task<R>;
+#endif
+ friend class detail::future_waiter;
+
+ typedef typename detail::future_traits<R>::move_dest_type move_dest_type;
+
+ BOOST_THREAD_FUTURE(future_ptr a_future):
+ base_type(a_future)
+ {
+ }
+
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
+ typedef future_state::state state;
+
+ BOOST_THREAD_FUTURE() {}
+
+ ~BOOST_THREAD_FUTURE() {}
+
+ BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
+ base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
+ {
+ }
+
+ BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
+ {
+
+ base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
+ return *this;
+ }
+
+ shared_future<R> share()
+ {
+ return shared_future<R>(::boost::move(*this));
+ }
+
+ void swap(BOOST_THREAD_FUTURE& other)
+ {
+ static_cast<base_type*>(this)->swap(other);
+ }
+
+ // retrieving the value
+ move_dest_type get()
+ {
+ if(!this->future_)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ future_ptr fut_=this->future_;
+ this->future_.reset();
+ return fut_->get();
+#else
+ return this->future_->get();
+#endif
+ }
+
+
 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
 
 // template<typename F>
@@ -1062,11 +1112,11 @@
     BOOST_THREAD_DCL_MOVABLE_BEG(T) BOOST_THREAD_FUTURE<T> BOOST_THREAD_DCL_MOVABLE_END
 
     template <typename R>
- class shared_future
+ class shared_future : public detail::basic_future<R>
     {
- typedef boost::shared_ptr<detail::future_object<R> > future_ptr;
 
- future_ptr future_;
+ typedef detail::basic_future<R> base_type;
+ typedef typename base_type::future_ptr future_ptr;
 
         friend class detail::future_waiter;
         friend class promise<R>;
@@ -1077,14 +1127,14 @@
         friend class packaged_task<R>;
 #endif
         shared_future(future_ptr a_future):
- future_(a_future)
+ base_type(a_future)
         {}
 
     public:
         BOOST_THREAD_MOVABLE(shared_future)
 
         shared_future(shared_future const& other):
- future_(other.future_)
+ base_type(other)
         {}
 
         typedef future_state::state state;
@@ -1097,127 +1147,63 @@
 
         shared_future& operator=(shared_future const& other)
         {
- future_=other.future_;
+ shared_future(other).swap(*this);
             return *this;
         }
         shared_future(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT :
- future_(BOOST_THREAD_RV(other).future_)
+ base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
         {
             BOOST_THREAD_RV(other).future_.reset();
         }
- shared_future(BOOST_THREAD_RV_REF_BEG BOOST_THREAD_FUTURE<R> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT :
- future_(BOOST_THREAD_RV(other).future_)
+ shared_future(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT :
+ base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
         {
- BOOST_THREAD_RV(other).future_.reset();
         }
+
         shared_future& operator=(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT
         {
- future_.swap(BOOST_THREAD_RV(other).future_);
- BOOST_THREAD_RV(other).future_.reset();
+ base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
             return *this;
         }
- shared_future& operator=(BOOST_THREAD_RV_REF_BEG BOOST_THREAD_FUTURE<R> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT
+ shared_future& operator=(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT
         {
- future_.swap(BOOST_THREAD_RV(other).future_);
- BOOST_THREAD_RV(other).future_.reset();
+ base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
+ //shared_future(boost::move(other)).swap(*this);
+ //this->future_.swap(BOOST_THREAD_RV(other).future_);
+ //BOOST_THREAD_RV(other).future_.reset();
             return *this;
         }
 
         void swap(shared_future& other) BOOST_NOEXCEPT
         {
- future_.swap(other.future_);
+ static_cast<base_type*>(this)->swap(other);
         }
 
         // retrieving the value
         typename detail::future_object<R>::shared_future_get_result_type get()
         {
- if(!future_)
+ if(!this->future_)
             {
                 boost::throw_exception(future_uninitialized());
             }
 
- return future_->get_sh();
+ return this->future_->get_sh();
         }
 
- // functions to check state, and wait for ready
- state get_state() const BOOST_NOEXCEPT
- {
- if(!future_)
- {
- return future_state::uninitialized;
- }
- return future_->get_state();
- }
-
- bool valid() const BOOST_NOEXCEPT
- {
- return future_ != 0;
- }
-
- bool is_ready() const BOOST_NOEXCEPT
- {
- return get_state()==future_state::ready;
- }
-
- bool has_exception() const BOOST_NOEXCEPT
- {
- return future_ && future_->has_exception();
- }
-
- bool has_value() const BOOST_NOEXCEPT
- {
- return future_ && future_->has_value();
- }
-
- void wait() const
- {
- if(!future_)
- {
- boost::throw_exception(future_uninitialized());
- }
- future_->wait(false);
- }
-
-#if defined BOOST_THREAD_USES_DATETIME
- template<typename Duration>
- bool timed_wait(Duration const& rel_time) const
- {
- return timed_wait_until(boost::get_system_time()+rel_time);
- }
-
- bool timed_wait_until(boost::system_time const& abs_time) const
- {
- if(!future_)
- {
- boost::throw_exception(future_uninitialized());
- }
- return future_->timed_wait_until(abs_time);
- }
-#endif
-#ifdef BOOST_THREAD_USES_CHRONO
-
- template <class Rep, class Period>
- future_status
- wait_for(const chrono::duration<Rep, Period>& rel_time) const
- {
- return wait_until(chrono::steady_clock::now() + rel_time);
-
- }
- template <class Clock, class Duration>
- future_status
- wait_until(const chrono::time_point<Clock, Duration>& abs_time) const
- {
- if(!future_)
- {
- boost::throw_exception(future_uninitialized());
- }
- return future_->wait_until(abs_time);
- }
-#endif
     };
 
     BOOST_THREAD_DCL_MOVABLE_BEG(T) shared_future<T> BOOST_THREAD_DCL_MOVABLE_END
 
+ namespace detail
+ {
+ /// Copy construction from a shared_future
+ template <typename R>
+ inline basic_future<R>::basic_future(const shared_future<R>& other) BOOST_NOEXCEPT
+ : future_(other.future_)
+ {
+ }
+ }
+
     template <typename R>
     class promise
     {
@@ -2025,6 +2011,8 @@
         }
         packaged_task& operator=(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT
         {
+
+ // todo use forward
             packaged_task temp(static_cast<BOOST_THREAD_RV_REF(packaged_task)>(other));
             swap(temp);
             return *this;
@@ -2344,16 +2332,16 @@
 
     typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>&)>::type future_type;
 
- if (future_)
+ if (this->future_)
     {
- boost::unique_lock<boost::mutex> lock(future_->mutex);
+ boost::unique_lock<boost::mutex> lock(this->future_->mutex);
       detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, F > *ptr =
           new detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, F>(*this, boost::forward<F>(func));
       if (ptr==0)
       {
         return BOOST_THREAD_FUTURE<future_type>();
       }
- future_->set_continuation_ptr(ptr, lock);
+ this->future_->set_continuation_ptr(ptr, lock);
       return ptr->next.get_future();
     } else {
       return BOOST_THREAD_FUTURE<future_type>();
@@ -2370,16 +2358,16 @@
 
     typedef RF future_type;
 
- if (future_)
+ if (this->future_)
     {
- boost::unique_lock<boost::mutex> lock(future_->mutex);
+ boost::unique_lock<boost::mutex> lock(this->future_->mutex);
       detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&) > *ptr =
           new detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&)>(*this, func);
       if (ptr==0)
       {
         return BOOST_THREAD_FUTURE<future_type>();
       }
- future_->set_continuation_ptr(ptr, lock);
+ this->future_->set_continuation_ptr(ptr, lock);
       return ptr->next.get_future();
     } else {
       return BOOST_THREAD_FUTURE<future_type>();

Modified: trunk/libs/thread/test/Jamfile.v2
==============================================================================
--- trunk/libs/thread/test/Jamfile.v2 (original)
+++ trunk/libs/thread/test/Jamfile.v2 2012-10-31 17:16:00 EDT (Wed, 31 Oct 2012)
@@ -280,6 +280,18 @@
           [ thread-run2 ./sync/futures/future/share_pass.cpp : future__share_p ]
     ;
 
+ #explicit ts_shared_future ;
+ test-suite ts_shared_future
+ :
+ [ thread-run2 ./sync/futures/shared_future/copy_assign_pass.cpp : shared_future__copy_assign_p ]
+ [ thread-run2 ./sync/futures/shared_future/copy_ctor_pass.cpp : shared_future__copy_ctor_p ]
+ [ thread-run2 ./sync/futures/shared_future/default_pass.cpp : shared_future__default_p ]
+ [ thread-run2 ./sync/futures/shared_future/dtor_pass.cpp : shared_future__dtor_p ]
+ [ thread-run2 ./sync/futures/shared_future/get_pass.cpp : shared_future__get_p ]
+ [ thread-run2 ./sync/futures/shared_future/move_ctor_pass.cpp : shared_future__move_ctor_p ]
+ [ thread-run2 ./sync/futures/shared_future/move_assign_pass.cpp : shared_future__move_asign_p ]
+ ;
+
     #explicit ts_packaged_task ;
     test-suite ts_packaged_task
     :

Modified: trunk/libs/thread/test/sync/futures/future/dtor_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/future/dtor_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/future/dtor_pass.cpp 2012-10-31 17:16:00 EDT (Wed, 31 Oct 2012)
@@ -14,9 +14,9 @@
 
 // <boost/thread/future.hpp>
 
-// class promise<R>
+// class future<R>
 
-// ~promise();
+// ~future();
 
 #define BOOST_THREAD_VERSION 3
 #include <boost/exception/exception.hpp>

Modified: trunk/libs/thread/test/sync/futures/future/get_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/future/get_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/future/get_pass.cpp 2012-10-31 17:16:00 EDT (Wed, 31 Oct 2012)
@@ -14,9 +14,11 @@
 
 // <boost/thread/future.hpp>
 
-// class promise<R>
+// class future<R>
 
-// future<R> get_future();
+// const R& future::get();
+// R& future<R&>::get();
+// void future<void>::get();
 
 //#define BOOST_THREAD_VERSION 3
 #define BOOST_THREAD_VERSION 4

Modified: trunk/libs/thread/test/sync/futures/future/move_assign_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/future/move_assign_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/future/move_assign_pass.cpp 2012-10-31 17:16:00 EDT (Wed, 31 Oct 2012)
@@ -14,9 +14,9 @@
 
 // <future>
 
-// class promise<R>
+// class future<R>
 
-// promise& operator=(promise&& rhs);
+// future& operator=(future&& rhs);
 
 #define BOOST_THREAD_VERSION 3
 

Modified: trunk/libs/thread/test/sync/futures/future/move_ctor_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/future/move_ctor_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/future/move_ctor_pass.cpp 2012-10-31 17:16:00 EDT (Wed, 31 Oct 2012)
@@ -14,9 +14,9 @@
 
 // <future>
 
-// class promise<R>
+// class future<R>
 
-// promise(promise&& rhs);
+// future(future&& rhs);
 
 #define BOOST_THREAD_VERSION 3
 

Added: trunk/libs/thread/test/sync/futures/shared_future/copy_assign_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/futures/shared_future/copy_assign_pass.cpp 2012-10-31 17:16:00 EDT (Wed, 31 Oct 2012)
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class shared_future<R>
+
+// shared_future& operator=(const shared_future&);
+
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0((p.get_future()));
+ boost::shared_future<T> f;
+ f = f0;
+ BOOST_TEST(f0.valid());
+ BOOST_TEST(f.valid());
+
+ }
+ {
+ typedef int T;
+ boost::shared_future<T> f0;
+ boost::shared_future<T> f;
+ f = f0;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0((p.get_future()));
+ boost::shared_future<T> f;
+ f = f0;
+ BOOST_TEST(f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int& T;
+ boost::shared_future<T> f0;
+ boost::shared_future<T> f;
+ f = f0;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0((p.get_future()));
+ boost::shared_future<T> f;
+ f = f0;
+ BOOST_TEST(f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef void T;
+ boost::shared_future<T> f0;
+ boost::shared_future<T> f;
+ f = f0;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+
+ return boost::report_errors();
+}
+
+//#include "../../../remove_error_code_unused_warning.hpp"
+

Added: trunk/libs/thread/test/sync/futures/shared_future/copy_ctor_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/futures/shared_future/copy_ctor_pass.cpp 2012-10-31 17:16:00 EDT (Wed, 31 Oct 2012)
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class shared_future<R>
+
+// shared_future(const future&);
+
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0((p.get_future()));
+ boost::shared_future<T> f = f0;
+ BOOST_TEST(f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int T;
+ boost::shared_future < T > f0;
+ boost::shared_future<T> f = f0;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0((p.get_future()));
+ boost::shared_future<T> f = f0;
+ BOOST_TEST(f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int& T;
+ boost::shared_future < T > f0;
+ boost::shared_future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0((p.get_future()));
+ boost::shared_future<T> f = f0;
+ BOOST_TEST(f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef void T;
+ boost::shared_future < T > f0;
+ boost::shared_future<T> f = f0;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+
+ return boost::report_errors();
+}
+
+//#include "../../../remove_error_code_unused_warning.hpp"
+

Added: trunk/libs/thread/test/sync/futures/shared_future/default_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/futures/shared_future/default_pass.cpp 2012-10-31 17:16:00 EDT (Wed, 31 Oct 2012)
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class shared_future<R>
+
+// shared_future();
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ boost::shared_future<int> f;
+ BOOST_TEST(!f.valid());
+ }
+ {
+ boost::shared_future<int&> f;
+ BOOST_TEST(!f.valid());
+ }
+ {
+ boost::shared_future<void> f;
+ BOOST_TEST(!f.valid());
+ }
+
+
+ return boost::report_errors();
+}
+

Added: trunk/libs/thread/test/sync/futures/shared_future/dtor_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/futures/shared_future/dtor_pass.cpp 2012-10-31 17:16:00 EDT (Wed, 31 Oct 2012)
@@ -0,0 +1,109 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class shared_future<R>
+
+// ~shared_future();
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/exception/exception.hpp>
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#include "../test_allocator.hpp"
+#endif
+
+int main()
+{
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ typedef int T;
+ boost::shared_future<T> f;
+ {
+ boost::promise<T> p(boost::allocator_arg, test_allocator<T>());
+ BOOST_TEST(test_alloc_base::count == 1);
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ typedef int& T;
+ boost::shared_future<T> f;
+ {
+ boost::promise<T> p(boost::allocator_arg, test_allocator<int>());
+ BOOST_TEST(test_alloc_base::count == 1);
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ typedef void T;
+ boost::shared_future<T> f;
+ {
+ boost::promise<T> p(boost::allocator_arg, test_allocator<T>());
+ BOOST_TEST(test_alloc_base::count == 1);
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+#endif
+ {
+ typedef int T;
+ boost::shared_future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int& T;
+ boost::shared_future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef void T;
+ boost::shared_future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(f.valid());
+ }
+ return boost::report_errors();
+}
+

Added: trunk/libs/thread/test/sync/futures/shared_future/get_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/futures/shared_future/get_pass.cpp 2012-10-31 17:16:00 EDT (Wed, 31 Oct 2012)
@@ -0,0 +1,208 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_future.hpp>
+
+// class shared_future<R>
+
+// const R& shared_future::get();
+// R& shared_future<R&>::get();
+// void shared_future<void>::get();
+//#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+namespace boost
+{
+template <typename T>
+struct wrap
+{
+ wrap(T const& v) : value(v){}
+ T value;
+
+};
+
+template <typename T>
+exception_ptr make_exception_ptr(T v) {
+ return copy_exception(wrap<T>(v));
+}
+}
+
+void func1(boost::promise<int> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_value(3);
+}
+
+void func2(boost::promise<int> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_exception(boost::make_exception_ptr(3));
+}
+
+int j = 0;
+
+void func3(boost::promise<int&> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func4(boost::promise<int&> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_exception(boost::make_exception_ptr(3.5));
+}
+
+void func5(boost::promise<void> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_value();
+}
+
+void func6(boost::promise<void> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_exception(boost::make_exception_ptr(4));
+}
+
+
+int main()
+{
+ {
+ typedef int T;
+ {
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func1, boost::move(p)).detach();
+#else
+ p.set_value(3);
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST(f.get() == 3);
+ BOOST_TEST(f.valid());
+ }
+ {
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func2, boost::move(p)).detach();
+#else
+ p.set_exception(boost::make_exception_ptr(3));
+#endif
+ try
+ {
+ BOOST_TEST(f.valid());
+ BOOST_TEST(f.get() == 3);
+ BOOST_TEST(false);
+ }
+ catch (boost::wrap<int> const& i)
+ {
+ BOOST_TEST(i.value == 3);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ BOOST_TEST(f.valid());
+ }
+ }
+ {
+ typedef int& T;
+ {
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func3, boost::move(p)).detach();
+#else
+ int j=5;
+ p.set_value(j);
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST(f.get() == 5);
+ BOOST_TEST(f.valid());
+ }
+ {
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func4, boost::move(p)).detach();
+#else
+ p.set_exception(boost::make_exception_ptr(3.5));
+#endif
+ try
+ {
+ BOOST_TEST(f.valid());
+ BOOST_TEST(f.get() == 3);
+ BOOST_TEST(false);
+ }
+ catch (boost::wrap<double> const& i)
+ {
+ BOOST_TEST(i.value == 3.5);
+ }
+ BOOST_TEST(f.valid());
+ }
+ }
+
+ typedef void T;
+ {
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func5, boost::move(p)).detach();
+#else
+ p.set_value();
+#endif
+ BOOST_TEST(f.valid());
+ f.get();
+ BOOST_TEST(f.valid());
+ }
+ {
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func6, boost::move(p)).detach();
+#else
+ p.set_exception(boost::make_exception_ptr(4));
+#endif
+ try
+ {
+ BOOST_TEST(f.valid());
+ f.get();
+ BOOST_TEST(false);
+ }
+ catch (boost::wrap<int> const& i)
+ {
+ BOOST_TEST(i.value == 4);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ BOOST_TEST(f.valid());
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif

Added: trunk/libs/thread/test/sync/futures/shared_future/move_assign_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/futures/shared_future/move_assign_pass.cpp 2012-10-31 17:16:00 EDT (Wed, 31 Oct 2012)
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <future>
+
+// class shared_future<R>
+
+// shared_future& shared_future=(shared_future&& rhs);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::shared_future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int T;
+ boost::shared_future<T> f0;
+ boost::shared_future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::shared_future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int& T;
+ boost::shared_future<T> f0;
+ boost::shared_future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::shared_future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef void T;
+ boost::shared_future<T> f0;
+ boost::shared_future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+
+
+ return boost::report_errors();
+
+}
+

Added: trunk/libs/thread/test/sync/futures/shared_future/move_ctor_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/futures/shared_future/move_ctor_pass.cpp 2012-10-31 17:16:00 EDT (Wed, 31 Oct 2012)
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <future>
+
+// class shared_future<R>
+
+// shared_future(shared_future&& rhs);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m;
+
+int main()
+{
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::shared_future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int T;
+ boost::shared_future<T> f0;
+ boost::shared_future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::shared_future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int& T;
+ boost::shared_future<T> f0;
+ boost::shared_future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::shared_future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef void T;
+ boost::shared_future<T> f0;
+ boost::shared_future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+
+ return boost::report_errors();
+}
+


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk