Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r78123 - in trunk: boost/thread boost/thread/detail libs/thread/doc libs/thread/test
From: vicente.botet_at_[hidden]
Date: 2012-04-22 04:12:37


Author: viboes
Date: 2012-04-22 04:12:27 EDT (Sun, 22 Apr 2012)
New Revision: 78123
URL: http://svn.boost.org/trac/boost/changeset/78123

Log:
Thread: Added macro BOOST_THREAD_DCL_MOVABLE to mask has_move_emulation_enabled_aux specialization
Text files modified:
   trunk/boost/thread/detail/move.hpp | 47 +++++++++
   trunk/boost/thread/detail/thread.hpp | 9 -
   trunk/boost/thread/future.hpp | 31 -----
   trunk/boost/thread/locks.hpp | 30 -----
   trunk/libs/thread/doc/emulations.qbk | 205 +++++++++++++++++++++++++++++----------
   trunk/libs/thread/test/test_move_function.cpp | 7 -
   6 files changed, 209 insertions(+), 120 deletions(-)

Modified: trunk/boost/thread/detail/move.hpp
==============================================================================
--- trunk/boost/thread/detail/move.hpp (original)
+++ trunk/boost/thread/detail/move.hpp 2012-04-22 04:12:27 EDT (Sun, 22 Apr 2012)
@@ -23,6 +23,8 @@
 
     namespace detail
     {
+ template <typename T>
+ struct has_move_emulation_enabled_aux_dummy_specialization;
         template<typename T>
         struct thread_move_t
         {
@@ -69,6 +71,16 @@
 #define BOOST_THREAD_RV(V) V
 #define BOOST_THREAD_MAKE_RV_REF(RVALUE) RVALUE
 #define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE)
+#define BOOST_THREAD_DCL_MOVABLE(TYPE)
+#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \
+ namespace detail { \
+ template <typename T> \
+ struct has_move_emulation_enabled_aux_dummy_specialization<
+
+#define BOOST_THREAD_DCL_MOVABLE_END > \
+ : integral_constant<bool, true> \
+ {}; \
+ }
 
 #elif ! defined BOOST_NO_RVALUE_REFERENCES && defined BOOST_MSVC
 
@@ -78,6 +90,16 @@
 #define BOOST_THREAD_RV(V) V
 #define BOOST_THREAD_MAKE_RV_REF(RVALUE) RVALUE
 #define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE)
+#define BOOST_THREAD_DCL_MOVABLE(TYPE)
+#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \
+ namespace detail { \
+ template <typename T> \
+ struct has_move_emulation_enabled_aux_dummy_specialization<
+
+#define BOOST_THREAD_DCL_MOVABLE_END > \
+ : integral_constant<bool, true> \
+ {}; \
+ }
 
 #else
 
@@ -87,6 +109,16 @@
 #define BOOST_THREAD_RV_REF_END BOOST_RV_REF_END
 #define BOOST_THREAD_RV(V) V
 #define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE)
+#define BOOST_THREAD_DCL_MOVABLE(TYPE)
+#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \
+ namespace detail { \
+ template <typename T> \
+ struct has_move_emulation_enabled_aux_dummy_specialization<
+
+#define BOOST_THREAD_DCL_MOVABLE_END > \
+ : integral_constant<bool, true> \
+ {}; \
+ }
 
 #else
 
@@ -95,6 +127,21 @@
 #define BOOST_THREAD_RV_REF_END >
 #define BOOST_THREAD_RV(V) (*V)
 #define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE)
+
+#define BOOST_THREAD_DCL_MOVABLE(TYPE) \
+template <> \
+struct has_move_emulation_enabled_aux< TYPE > \
+ : BOOST_MOVE_BOOST_NS::integral_constant<bool, true> \
+{};
+
+#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \
+template <typename T> \
+struct has_move_emulation_enabled_aux<
+
+#define BOOST_THREAD_DCL_MOVABLE_END > \
+ : BOOST_MOVE_BOOST_NS::integral_constant<bool, true> \
+{};
+
 #endif
 
 namespace boost

Modified: trunk/boost/thread/detail/thread.hpp
==============================================================================
--- trunk/boost/thread/detail/thread.hpp (original)
+++ trunk/boost/thread/detail/thread.hpp 2012-04-22 04:12:27 EDT (Sun, 22 Apr 2012)
@@ -442,14 +442,7 @@
     }
 #endif
 
-#ifdef BOOST_NO_RVALUE_REFERENCES
-#if !defined BOOST_THREAD_USES_MOVE
- template <>
- struct has_move_emulation_enabled_aux<thread>
- : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
- {};
-#endif
-#endif
+ BOOST_THREAD_DCL_MOVABLE(thread)
 
     namespace this_thread
     {

Modified: trunk/boost/thread/future.hpp
==============================================================================
--- trunk/boost/thread/future.hpp (original)
+++ trunk/boost/thread/future.hpp 2012-04-22 04:12:27 EDT (Sun, 22 Apr 2012)
@@ -935,12 +935,7 @@
 #endif
     };
 
-#ifdef BOOST_NO_RVALUE_REFERENCES
- template <typename T>
- struct has_move_emulation_enabled_aux<BOOST_THREAD_FUTURE<T> >
- : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
- {};
-#endif
+ BOOST_THREAD_DCL_MOVABLE_BEG(T) BOOST_THREAD_FUTURE<T> BOOST_THREAD_DCL_MOVABLE_END
 
     template <typename R>
     class shared_future
@@ -1102,12 +1097,7 @@
 #endif
     };
 
-#ifdef BOOST_NO_RVALUE_REFERENCES
- template <typename T>
- struct has_move_emulation_enabled_aux<shared_future<T> >
- : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
- {};
-#endif
+ BOOST_THREAD_DCL_MOVABLE_BEG(T) shared_future<T> BOOST_THREAD_DCL_MOVABLE_END
 
     template <typename R>
     class promise
@@ -1405,12 +1395,7 @@
     }
 #endif
 
-#ifdef BOOST_NO_RVALUE_REFERENCES
- template <typename T>
- struct has_move_emulation_enabled_aux<promise<T> >
- : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
- {};
-#endif
+ BOOST_THREAD_DCL_MOVABLE_BEG(T) promise<T> BOOST_THREAD_DCL_MOVABLE_END
 
     namespace detail
     {
@@ -1736,14 +1721,8 @@
     }
 #endif
 
-#ifdef BOOST_NO_RVALUE_REFERENCES
-#if ! defined BOOST_THREAD_USES_MOVE
- template <typename T>
- struct has_move_emulation_enabled_aux<packaged_task<T> >
- : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
- {};
-#endif
-#endif
+ BOOST_THREAD_DCL_MOVABLE_BEG(T) packaged_task<T> BOOST_THREAD_DCL_MOVABLE_END
+
 
 }
 

Modified: trunk/boost/thread/locks.hpp
==============================================================================
--- trunk/boost/thread/locks.hpp (original)
+++ trunk/boost/thread/locks.hpp 2012-04-22 04:12:27 EDT (Sun, 22 Apr 2012)
@@ -652,12 +652,7 @@
         lhs.swap(rhs);
     }
 
-#if defined BOOST_NO_RVALUE_REFERENCES && ! defined BOOST_THREAD_USES_MOVE
- template <typename Mutex>
- struct has_move_emulation_enabled_aux<unique_lock<Mutex> >
- : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
- {};
-#endif
+ BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
 
     template<typename Mutex>
     class shared_lock
@@ -907,13 +902,7 @@
 
     };
 
-#if defined BOOST_NO_RVALUE_REFERENCES && ! defined BOOST_THREAD_USES_MOVE
- template <typename Mutex>
- struct has_move_emulation_enabled_aux<shared_lock<Mutex> >
- : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
- {};
-#endif
-
+ BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) shared_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
 
     template<typename Mutex>
     void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs) BOOST_NOEXCEPT
@@ -1180,13 +1169,7 @@
         lhs.swap(rhs);
     }
 
-#if defined BOOST_NO_RVALUE_REFERENCES && ! defined BOOST_THREAD_USES_MOVE
- template <typename Mutex>
- struct has_move_emulation_enabled_aux<upgrade_lock<Mutex> >
- : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
- {};
-#endif
-
+ BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
 
     template<typename Mutex>
     unique_lock<Mutex>::unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other):
@@ -1263,12 +1246,7 @@
         }
     };
 
-#if defined BOOST_NO_RVALUE_REFERENCES && ! defined BOOST_THREAD_USES_MOVE
- template <typename Mutex>
- struct has_move_emulation_enabled_aux<upgrade_to_unique_lock<Mutex> >
- : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
- {};
-#endif
+ BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_to_unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
 
     namespace detail
     {

Modified: trunk/libs/thread/doc/emulations.qbk
==============================================================================
--- trunk/libs/thread/doc/emulations.qbk (original)
+++ trunk/libs/thread/doc/emulations.qbk 2012-04-22 04:12:27 EDT (Sun, 22 Apr 2012)
@@ -25,53 +25,10 @@
 
 [section:move Move semantics]
 
-In order to implement MovableOnly classes and move parameters and return types Boost.Thread uses the rvalue reference when the compiler support it.
-On compilers not supporting it Boost.Thread uses the emulation provided by Boost.Move.
+In order to implement Movable classes, move parameters and return types Boost.Thread uses the rvalue reference when the compiler support it.
+On compilers not supporting it Boost.Thread uses either the emulation provided by Boost.Move or the emulation provided by the previous versions of Boost.Thread depending whether `BOOST_THREAD_USES_MOVE` is defined or not. This macros is unset by default when `BOOST_THREAD_VERSION` is 2. Since `BOOST_THREAD_VERSION` 3, `BOOST_THREAD_USES_MOVE` is defined.
 
-
-While Boost.Move is the best C++03 move emulation there are some limitations that impact the way the library can be used.
-For example, with the following declarations
-
- class thread {
- // ...
- private:
- thread(thread &);
- public:
- thread(rv<thread>&);
- // ...
- };
-
-This could not work on some compilers even if thread is convertible to rv<thread> because the compiler prefers the private copy constructor.
-
- thread mkth()
- {
- return thread(f);
- }
-
-On these compilers we need to use instead an explicit conversion. The library provides a move member function that allows to workaround the issue.
-
- thread mkth()
- {
- return thread(f).move();
- }
-
-Note that ::boost::move can not be used in this case as thread is not implicitly convertible to thread&.
-
- thread mkth()
- {
- return ::boost::move(thread(f));
- }
-
-To make the code portable Boost.Thread the user needs to use a macro BOOST_THREAD_MAKE_RV_REF that can be used as in
-
- thread mkth()
- {
- return BOOST_THREAD_MAKE_RV_REF(thread(f));
- }
-
-See the Boost.Move documentation for a complete description on how to declare new Movable classes and its limitations.
-
-[section:deprecated Deprecated]
+[section:deprecated Deprecated Version 2 interface]
 
 Previous to version 1.50, Boost.Thread make use of its own move semantic emulation which had more limitations than the provided by Boost.Move. In addition, it is of interest of the whole Boost community that Boost.Thread uses Boost.Move so that boost::thread can be stored on Movable aware containers.
 
@@ -81,7 +38,7 @@
 
 [section:Helper Helpers class and function]
 
-Next follows the interface of the legacy move semantic helper classes and functions.
+Next follows the interface of the legacy move semantic helper class and function.
 
   namespace boost
   {
@@ -100,16 +57,16 @@
     template<typename T>
     boost::detail::thread_move_t<T> move(boost::detail::thread_move_t<T> t);
   }
+[endsect]
 
 [section:movable Movable emulation]
 
 We can write a MovableOny class as follows. You just need to follow these simple steps:
 
-* Add a conversion to the detail::thread_move_t<classname>
+* Add a conversion to the `detail::thread_move_t<classname>`
 * Make the copy constructor private.
-* Write a constructor taking the parameter as detail::thread_move_t<classname>
-* Write an assignment taking the parameter as detail::thread_move_t<classname>
-
+* Write a constructor taking the parameter as `detail::thread_move_t<classname>`
+* Write an assignment taking the parameter as `detail::thread_move_t<classname>`
 
 For example the thread class defines the following:
 
@@ -144,13 +101,153 @@
 
     };
 
-
-
 [endsect]
 
 [endsect]
 
-[endsect]
+[section:portable Portable interface]
+
+In order to make the library code portable Boost.Thread uses some macros that will use either the ones provided by Boost.Move or the deprecated move semantics provided by previous versions of Boost.Thread.
+
+See the Boost.Move documentation for a complete description on how to declare new Movable classes and its limitations.
+
+* `BOOST_THREAD_RV_REF(TYPE)` is the equivalent of `BOOST_RV_REF(TYPE)`
+* `BOOST_THREAD_RV_REF_BEG` is the equivalent of `BOOST_RV_REF_BEG(TYPE)`
+* `BOOST_THREAD_RV_REF_END` is the equivalent of `BOOST_RV_REF_END(TYPE)`
+* `BOOST_THREAD_FWD_REF(TYPE)` is the equivalent of `BOOST_FWD_REF(TYPE)
+
+In addition the following macros are needed to make the code portable:
+
+* `BOOST_THREAD_RV(V)` macro to access the rvalue from a BOOST_THREAD_RV_REF(TYPE),
+* `BOOST_THREAD_MAKE_RV_REF(RVALUE)` makes a rvalue.
+* `BOOST_THREAD_DCL_MOVABLE(CLASS)` to avoid conflicts with Boost.Move
+* `BOOST_THREAD_DCL_MOVABLE_BEG(T1)` and `BOOST_THREAD_DCL_MOVABLE_END` are variant of `BOOST_THREAD_DCL_MOVABLE` when the parameter is a template instantiation.
+
+Other macros are provided and must be included on the public section:
+
+* `BOOST_THREAD_NO_COPYABLE` declares a class no-copyable either deleting the copy constructors and copy assignment or moving them to the private section.
+* `BOOST_THREAD_MOVABLE(CLASS)` declares all the implicit conversions to an rvalue-reference.
+* `BOOST_THREAD_MOVABLE_ONLY(CLASS)` is the equivalent of `BOOST_MOVABLE_BUT_NOT_COPYABLE(CLASS)`
+* `BOOST_THREAD_COPYABLE_AND_MOVABLE(CLASS)` is the equivalent of `BOOST_COPYABLE_AND_MOVABLE(CLASS)`
+
+
+[section:NO_COPYABLE `BOOST_THREAD_NO_COPYABLE(CLASS)`]
+
+This macro marks a class as no copyable, disabling copy construction and assignment.
+
+[endsect]
+
+[section:MOVABLE `BOOST_THREAD_MOVABLE(CLASS)`]
+
+This macro marks a class as movable, declaring all the implicit conversions to an rvalue-reference.
+
+[endsect]
+
+[section:MOVABLE_ONLY `BOOST_THREAD_MOVABLE_ONLY(CLASS)`]
+
+This macro marks a type as movable but not copyable, disabling copy construction and assignment. The user will need to write a move constructor/assignment to fully write a movable but not copyable class.
+
+[endsect]
+
+[section:COPYABLE_AND_MOVABLE `BOOST_THREAD_COPYABLE_AND_MOVABLE(CLASS)`]
+
+This macro marks a type as copyable and movable. The user will need to write a move constructor/assignment and a copy assignment to fully write a copyable and movable class.
+
+[endsect]
+
+[section:RV_REF `BOOST_THREAD_RV_REF(TYPE)`, `BOOST_THREAD_RV_REF_BEG` and `BOOST_THREAD_RV_REF_END`]
+
+This macro is used to achieve portable syntax in move constructors and assignments for classes marked as `BOOST_THREAD_COPYABLE_AND_MOVABLE` or `BOOST_THREAD_MOVABLE_ONLY`.
+
+`BOOST_THREAD_RV_REF_BEG` and `BOOST_THREAD_RV_REF_END` are used when the parameter end with a `>` to avoid the compiler error.
+
+[endsect]
+
+[section:RV `BOOST_THREAD_RV(V)`]
+
+While Boost.Move emulation allows to access an rvalue reference `BOOST_THREAD_RV_REF(TYPE)` using the dot operator, the legacy defines the `operator->`. We need then a macro `BOOST_THREAD_RV` that mask this difference. E.g.
+
+ thread(BOOST_THREAD_RV_REF(thread) x)
+ {
+ thread_info=BOOST_THREAD_RV(x).thread_info;
+ BOOST_THREAD_RV(x).thread_info.reset();
+ }
+
+The use of this macros has reduced considerably the size of the Boost.Thread move related code.
+
+[endsect]
+
+[section:MAKE_RV_REF `BOOST_THREAD_MAKE_RV_REF(RVALUE)`]
+
+While Boost.Move is the best C++03 move emulation there are some limitations that impact the way the library can be used.
+For example, with the following declarations
+
+ class thread {
+ // ...
+ private:
+ thread(thread &);
+ public:
+ thread(rv<thread>&);
+ // ...
+ };
+
+This could not work on some compilers even if thread is convertible to `rv<thread>` because the compiler prefers the private copy constructor.
+
+ thread mkth()
+ {
+ return thread(f);
+ }
+
+On these compilers we need to use instead an explicit conversion. The library provides a move member function that allows to workaround the issue.
+
+ thread mkth()
+ {
+ return thread(f).move();
+ }
+
+Note that `::boost::move` can not be used in this case as thread is not implicitly convertible to `thread&`.
+
+ thread mkth()
+ {
+ return ::boost::move(thread(f));
+ }
+
+To make the code portable Boost.Thread the user needs to use a macro `BOOST_THREAD_MAKE_RV_REF` that can be used as in
+
+ thread mkth()
+ {
+ return BOOST_THREAD_MAKE_RV_REF(thread(f));
+ }
+
+Note that this limitation is shared also by the legacy Boost.Thread move emulation.
+
+[endsect]
+
+[section:DCL_MOVABLE `BOOST_THREAD_DCL_MOVABLE`, `BOOST_THREAD_DCL_MOVABLE_BEG(T1)` and `BOOST_THREAD_DCL_MOVABLE_END`]
+
+As Boost.Move defines also the `boost::move` function we need to specialize the `has_move_emulation_enabled_aux` metafunction.
+
+ template <>
+ struct has_move_emulation_enabled_aux<thread>
+ : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
+ {};
+
+so that the following Boost.Move overload is disabled
+
+ template <class T>
+ inline typename BOOST_MOVE_BOOST_NS::disable_if<has_move_emulation_enabled_aux<T>, T&>::type move(T& x);
+
+The macros `BOOST_THREAD_DCL_MOVABLE(CLASS)`, `BOOST_THREAD_DCL_MOVABLE_BEG(T1)` and `BOOST_THREAD_DCL_MOVABLE_END` are used for this purpose. E.g.
+
+ BOOST_THREAD_DCL_MOVABLE(thread)
+
+and
+
+ BOOST_THREAD_DCL_MOVABLE_BEG(T) promise<T> BOOST_THREAD_DCL_MOVABLE_END
+
+
+[endsect]
+[endsect]
 
 
 [endsect]

Modified: trunk/libs/thread/test/test_move_function.cpp
==============================================================================
--- trunk/libs/thread/test/test_move_function.cpp (original)
+++ trunk/libs/thread/test/test_move_function.cpp 2012-04-22 04:12:27 EDT (Sun, 22 Apr 2012)
@@ -109,15 +109,10 @@
     };
 }
 
-#ifdef BOOST_NO_RVALUE_REFERENCES
 namespace boost
 {
- template <>
- struct has_move_emulation_enabled_aux<user_test_ns::nc>
- : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
- {};
+ BOOST_THREAD_DCL_MOVABLE(user_test_ns::nc)
 }
-#endif
 
 void test_move_for_user_defined_type_unaffected()
 {


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