• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[/
2  (C) Copyright 20012 Vicente J. Botet Escriba.
3  Distributed under the Boost Software License, Version 1.0.
4  (See accompanying file LICENSE_1_0.txt or copy at
5  http://www.boost.org/LICENSE_1_0.txt).
6]
7
8
9[section:emulations Emulations]
10[section:delete `=delete` emulation]
11
12C++11 allows to delete some implicitly generated functions as constructors and assignment using '= delete' as in
13
14  public:
15    thread(thread const&) = delete;
16
17On compilers not supporting this feature, Boost.Thread relays on a partial simulation, it declares the function as private without definition.
18
19  private:
20    thread(thread &);
21
22The emulation is partial as the private function can be used for overload resolution for some compilers and prefer it to other overloads that need a conversion. See below the consequences on the move semantic emulation.
23
24[endsect]
25
26[section:move Move semantics]
27
28In order to implement Movable classes, move parameters and return types Boost.Thread uses the rvalue reference when the compiler support it.
29On 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.
30
31[section:deprecated Deprecated Version 2 interface]
32
33Previous 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.
34
35To preserve backward compatibility at least during some releases, Boost.Thread allows the user to use the deprecated move semantic emulation defining BOOST_THREAD_DONT_USE_MOVE.
36
37Many aspects of move semantics can be emulated for compilers not supporting rvalue references and Boost.Thread legacy offers tools for that purpose.
38
39[section:Helper Helpers class and function]
40
41Next follows the interface of the legacy move semantic helper class and function.
42
43  namespace boost
44  {
45    namespace detail
46    {
47        template<typename T>
48        struct thread_move_t
49        {
50          explicit thread_move_t(T& t_);
51          T& operator*() const;
52          T* operator->() const;
53        private:
54          void operator=(thread_move_t&);
55        };
56    }
57    template<typename T>
58    boost::detail::thread_move_t<T> move(boost::detail::thread_move_t<T> t);
59  }
60[endsect]
61
62[section:movable Movable emulation]
63
64We can write a MovableOny class as follows. You just need to follow these simple steps:
65
66* Add a conversion to the `detail::thread_move_t<classname>`
67* Make the copy constructor private.
68* Write a constructor taking the parameter as `detail::thread_move_t<classname>`
69* Write an assignment taking the parameter as `detail::thread_move_t<classname>`
70
71For example the thread class defines the following:
72
73    class thread
74    {
75      // ...
76    private:
77        thread(thread&);
78        thread& operator=(thread&);
79    public:
80        detail::thread_move_t<thread> move()
81        {
82            detail::thread_move_t<thread> x(*this);
83            return x;
84        }
85        operator detail::thread_move_t<thread>()
86        {
87            return move();
88        }
89        thread(detail::thread_move_t<thread> x)
90        {
91            thread_info=x->thread_info;
92            x->thread_info.reset();
93        }
94        thread& operator=(detail::thread_move_t<thread> x)
95        {
96            thread new_thread(x);
97            swap(new_thread);
98            return *this;
99        }
100      // ...
101
102    };
103
104[endsect]
105
106[endsect]
107
108[section:portable Portable interface]
109
110In 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.
111
112See the Boost.Move documentation for a complete description on how to declare new Movable classes and its limitations.
113
114* `BOOST_THREAD_RV_REF(TYPE)` is the equivalent of `BOOST_RV_REF(TYPE)`
115* `BOOST_THREAD_RV_REF_BEG` is the equivalent of `BOOST_RV_REF_BEG(TYPE)`
116* `BOOST_THREAD_RV_REF_END` is the equivalent of `BOOST_RV_REF_END(TYPE)`
117* `BOOST_THREAD_FWD_REF(TYPE)` is the equivalent of `BOOST_FWD_REF(TYPE)
118
119In addition the following macros are needed to make the code portable:
120
121* `BOOST_THREAD_RV(V)` macro to access the rvalue from a BOOST_THREAD_RV_REF(TYPE),
122* `BOOST_THREAD_MAKE_RV_REF(RVALUE)` makes a rvalue.
123* `BOOST_THREAD_DCL_MOVABLE(CLASS)` to avoid conflicts with Boost.Move
124* `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.
125
126Other macros are provided and must be included on the public section:
127
128* `BOOST_THREAD_NO_COPYABLE` declares a class no-copyable either deleting the copy constructors and copy assignment or moving them to the private section.
129* `BOOST_THREAD_MOVABLE(CLASS)` declares all the implicit conversions to an rvalue-reference.
130* `BOOST_THREAD_MOVABLE_ONLY(CLASS)` is the equivalent of `BOOST_MOVABLE_BUT_NOT_COPYABLE(CLASS)`
131* `BOOST_THREAD_COPYABLE_AND_MOVABLE(CLASS)` is the equivalent of `BOOST_COPYABLE_AND_MOVABLE(CLASS)`
132
133
134[section:NO_COPYABLE `BOOST_THREAD_NO_COPYABLE(CLASS)`]
135
136This macro marks a class as no copyable, disabling copy construction and assignment.
137
138[endsect]
139
140[section:MOVABLE `BOOST_THREAD_MOVABLE(CLASS)`]
141
142This macro marks a class as movable, declaring all the implicit conversions to an rvalue-reference.
143
144[endsect]
145
146[section:MOVABLE_ONLY `BOOST_THREAD_MOVABLE_ONLY(CLASS)`]
147
148This 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.
149
150[endsect]
151
152[section:COPYABLE_AND_MOVABLE `BOOST_THREAD_COPYABLE_AND_MOVABLE(CLASS)`]
153
154This 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.
155
156[endsect]
157
158[section:RV_REF `BOOST_THREAD_RV_REF(TYPE)`, `BOOST_THREAD_RV_REF_BEG` and `BOOST_THREAD_RV_REF_END`]
159
160This 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`.
161
162`BOOST_THREAD_RV_REF_BEG` and `BOOST_THREAD_RV_REF_END` are used when the parameter end with a `>` to avoid the compiler error.
163
164[endsect]
165
166[section:RV `BOOST_THREAD_RV(V)`]
167
168While 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.
169
170        thread(BOOST_THREAD_RV_REF(thread) x)
171        {
172            thread_info=BOOST_THREAD_RV(x).thread_info;
173            BOOST_THREAD_RV(x).thread_info.reset();
174        }
175
176The use of this macros has reduced considerably the size of the Boost.Thread move related code.
177
178[endsect]
179
180[section:MAKE_RV_REF `BOOST_THREAD_MAKE_RV_REF(RVALUE)`]
181
182While Boost.Move is the best C++03 move emulation there are some limitations that impact the way the library can be used.
183For example, with the following declarations
184
185  class thread {
186    // ...
187  private:
188    thread(thread &);
189  public:
190    thread(rv<thread>&);
191    // ...
192  };
193
194This could not work on some compilers even if thread is convertible to `rv<thread>` because the compiler prefers the private copy constructor.
195
196  thread mkth()
197  {
198    return thread(f);
199  }
200
201On these compilers we need to use instead an explicit conversion. The library provides a move member function that allows to workaround the issue.
202
203  thread mkth()
204  {
205    return thread(f).move();
206  }
207
208Note that `::boost::move` can not be used in this case as thread is not implicitly convertible to `thread&`.
209
210  thread mkth()
211  {
212    return ::boost::move(thread(f));
213  }
214
215To make the code portable Boost.Thread the user needs to use a macro `BOOST_THREAD_MAKE_RV_REF` that can be used as in
216
217  thread mkth()
218  {
219    return BOOST_THREAD_MAKE_RV_REF(thread(f));
220  }
221
222Note that this limitation is shared also by the legacy Boost.Thread move emulation.
223
224[endsect]
225
226[section:DCL_MOVABLE `BOOST_THREAD_DCL_MOVABLE`, `BOOST_THREAD_DCL_MOVABLE_BEG(T1)` and `BOOST_THREAD_DCL_MOVABLE_END`]
227
228As Boost.Move defines also the `boost::move` function we need to specialize the `has_move_emulation_enabled_aux` metafunction.
229
230    template <>
231    struct has_move_emulation_enabled_aux<thread>
232      : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
233    {};
234
235so that the following Boost.Move overload is disabled
236
237   template <class T>
238   inline typename BOOST_MOVE_BOOST_NS::disable_if<has_move_emulation_enabled_aux<T>, T&>::type move(T& x);
239
240The 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.
241
242    BOOST_THREAD_DCL_MOVABLE(thread)
243
244and
245
246    BOOST_THREAD_DCL_MOVABLE_BEG(T) promise<T> BOOST_THREAD_DCL_MOVABLE_END
247
248
249[endsect]
250[endsect]
251
252
253[endsect]
254
255[section:bool_explicit_conversion Bool explicit conversion]
256
257Locks provide an explicit bool conversion operator when the compiler provides them.
258
259  explicit operator bool() const;
260
261The library provides un implicit conversion to an undefined type that can be used as a conditional expression.
262
263    #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
264        operator ``['unspecified-bool-type]``() const;
265        bool operator!() const;
266    #else
267        explicit operator bool() const;
268    #endif
269
270The user should use the lock.owns_lock() when an explicit conversion is required.
271
272[section:bool_conversion `operator `['unspecified-bool-type]`() const`]
273
274[variablelist
275
276[[Returns:] [If __owns_lock_ref__ would return `true`, a value that evaluates to
277`true` in boolean contexts, otherwise a value that evaluates to `false` in
278boolean contexts.]]
279
280[[Throws:] [Nothing.]]
281
282]
283
284[endsect]
285
286
287[section:operator_not `bool operator!() const`]
288
289[variablelist
290
291[[Returns:] [`!` __owns_lock_ref__.]]
292
293[[Throws:] [Nothing.]]
294
295]
296
297[endsect]
298
299
300[endsect]
301
302[section:scoped_enums Scoped Enums]
303
304Some of the enumerations defined in the standard library are scoped enums.
305
306On compilers that don't support them, the library uses a class to wrap the underlying type. Instead of
307
308  enum class future_errc
309  {
310      broken_promise,
311      future_already_retrieved,
312      promise_already_satisfied,
313      no_state
314  };
315
316the library declare these types as
317
318  BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_errc)
319  {
320      broken_promise,
321      future_already_retrieved,
322      promise_already_satisfied,
323      no_state
324  }
325  BOOST_SCOPED_ENUM_DECLARE_END(future_errc)
326
327These macros allows to use 'future_errc' in almost all the cases as a scoped enum.
328
329There are however some limitations:
330
331* The type is not a C++ enum, so 'is_enum<future_errc>' will be false_type.
332* The emulated scoped enum can not be used in switch nor in template arguments. For these cases the user needs to use some macros.
333
334Instead of
335
336        switch (ev)
337        {
338        case future_errc::broken_promise:
339	// ...
340
341use
342
343        switch (boost::native_value(ev))
344        {
345        case future_errc::broken_promise:
346
347And instead of
348
349    #ifdef BOOST_NO_CXX11_SCOPED_ENUMS
350    template <>
351    struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc> : public true_type { };
352    #endif
353
354use
355
356    #ifdef BOOST_NO_CXX11_SCOPED_ENUMS
357    template <>
358    struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc::enum_type> : public true_type { };
359    #endif
360
361
362
363[endsect]
364
365[endsect]