Chris@102
|
1 // Copyright (C) 2013 Vicente J. Botet Escriba
|
Chris@102
|
2 //
|
Chris@102
|
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@102
|
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
5 //
|
Chris@102
|
6 // 2013/09 Vicente J. Botet Escriba
|
Chris@102
|
7 // Adapt to boost from CCIA C++11 implementation
|
Chris@102
|
8 // Make use of Boost.Move
|
Chris@102
|
9
|
Chris@102
|
10 #ifndef BOOST_THREAD_DETAIL_NULLARY_FUNCTION_HPP
|
Chris@102
|
11 #define BOOST_THREAD_DETAIL_NULLARY_FUNCTION_HPP
|
Chris@102
|
12
|
Chris@102
|
13 #include <boost/config.hpp>
|
Chris@102
|
14 #include <boost/thread/detail/memory.hpp>
|
Chris@102
|
15 #include <boost/thread/detail/move.hpp>
|
Chris@102
|
16 #include <boost/thread/csbl/memory/shared_ptr.hpp>
|
Chris@102
|
17 #include <boost/type_traits/decay.hpp>
|
Chris@102
|
18
|
Chris@102
|
19 namespace boost
|
Chris@102
|
20 {
|
Chris@102
|
21 namespace detail
|
Chris@102
|
22 {
|
Chris@102
|
23
|
Chris@102
|
24 template <typename F>
|
Chris@102
|
25 class nullary_function;
|
Chris@102
|
26 template <>
|
Chris@102
|
27 class nullary_function<void()>
|
Chris@102
|
28 {
|
Chris@102
|
29 struct impl_base
|
Chris@102
|
30 {
|
Chris@102
|
31 virtual void call()=0;
|
Chris@102
|
32 virtual ~impl_base()
|
Chris@102
|
33 {
|
Chris@102
|
34 }
|
Chris@102
|
35 };
|
Chris@102
|
36 csbl::shared_ptr<impl_base> impl;
|
Chris@102
|
37 template <typename F>
|
Chris@102
|
38 struct impl_type: impl_base
|
Chris@102
|
39 {
|
Chris@102
|
40 F f;
|
Chris@102
|
41 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@102
|
42 impl_type(F &f_)
|
Chris@102
|
43 : f(f_)
|
Chris@102
|
44 {}
|
Chris@102
|
45 #endif
|
Chris@102
|
46 impl_type(BOOST_THREAD_RV_REF(F) f_)
|
Chris@102
|
47 : f(boost::move(f_))
|
Chris@102
|
48 {}
|
Chris@102
|
49
|
Chris@102
|
50 void call()
|
Chris@102
|
51 {
|
Chris@102
|
52 f();
|
Chris@102
|
53 }
|
Chris@102
|
54 };
|
Chris@102
|
55 struct impl_type_ptr: impl_base
|
Chris@102
|
56 {
|
Chris@102
|
57 void (*f)();
|
Chris@102
|
58 impl_type_ptr(void (*f_)())
|
Chris@102
|
59 : f(f_)
|
Chris@102
|
60 {}
|
Chris@102
|
61 void call()
|
Chris@102
|
62 {
|
Chris@102
|
63 f();
|
Chris@102
|
64 }
|
Chris@102
|
65 };
|
Chris@102
|
66 public:
|
Chris@102
|
67 BOOST_THREAD_COPYABLE_AND_MOVABLE(nullary_function)
|
Chris@102
|
68
|
Chris@102
|
69 explicit nullary_function(void (*f)()):
|
Chris@102
|
70 impl(new impl_type_ptr(f))
|
Chris@102
|
71 {}
|
Chris@102
|
72
|
Chris@102
|
73 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@102
|
74 template<typename F>
|
Chris@102
|
75 explicit nullary_function(F& f):
|
Chris@102
|
76 impl(new impl_type<F>(f))
|
Chris@102
|
77 {}
|
Chris@102
|
78 #endif
|
Chris@102
|
79 template<typename F>
|
Chris@102
|
80 nullary_function(BOOST_THREAD_RV_REF(F) f):
|
Chris@102
|
81 impl(new impl_type<typename decay<F>::type>(thread_detail::decay_copy(boost::forward<F>(f))))
|
Chris@102
|
82 {}
|
Chris@102
|
83
|
Chris@102
|
84 nullary_function()
|
Chris@102
|
85 : impl()
|
Chris@102
|
86 {
|
Chris@102
|
87 }
|
Chris@102
|
88 nullary_function(nullary_function const& other) BOOST_NOEXCEPT :
|
Chris@102
|
89 impl(other.impl)
|
Chris@102
|
90 {
|
Chris@102
|
91 }
|
Chris@102
|
92 nullary_function(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT :
|
Chris@102
|
93 #if defined BOOST_NO_CXX11_SMART_PTR
|
Chris@102
|
94 impl(BOOST_THREAD_RV(other).impl)
|
Chris@102
|
95 {
|
Chris@102
|
96 BOOST_THREAD_RV(other).impl.reset();
|
Chris@102
|
97 }
|
Chris@102
|
98 #else
|
Chris@102
|
99 impl(boost::move(other.impl))
|
Chris@102
|
100 {
|
Chris@102
|
101 }
|
Chris@102
|
102 #endif
|
Chris@102
|
103 ~nullary_function()
|
Chris@102
|
104 {
|
Chris@102
|
105 }
|
Chris@102
|
106
|
Chris@102
|
107 nullary_function& operator=(BOOST_THREAD_COPY_ASSIGN_REF(nullary_function) other) BOOST_NOEXCEPT
|
Chris@102
|
108 {
|
Chris@102
|
109 impl=other.impl;
|
Chris@102
|
110 return *this;
|
Chris@102
|
111 }
|
Chris@102
|
112 nullary_function& operator=(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT
|
Chris@102
|
113 {
|
Chris@102
|
114 #if defined BOOST_NO_CXX11_SMART_PTR
|
Chris@102
|
115 impl=BOOST_THREAD_RV(other).impl;
|
Chris@102
|
116 BOOST_THREAD_RV(other).impl.reset();
|
Chris@102
|
117 #else
|
Chris@102
|
118 impl = boost::move(other.impl);
|
Chris@102
|
119 #endif
|
Chris@102
|
120 return *this;
|
Chris@102
|
121 }
|
Chris@102
|
122
|
Chris@102
|
123
|
Chris@102
|
124 void operator()()
|
Chris@102
|
125 { if (impl) impl->call();}
|
Chris@102
|
126
|
Chris@102
|
127 };
|
Chris@102
|
128
|
Chris@102
|
129 template <typename R>
|
Chris@102
|
130 class nullary_function<R()>
|
Chris@102
|
131 {
|
Chris@102
|
132 struct impl_base
|
Chris@102
|
133 {
|
Chris@102
|
134 virtual R call()=0;
|
Chris@102
|
135 virtual ~impl_base()
|
Chris@102
|
136 {
|
Chris@102
|
137 }
|
Chris@102
|
138 };
|
Chris@102
|
139 csbl::shared_ptr<impl_base> impl;
|
Chris@102
|
140 template <typename F>
|
Chris@102
|
141 struct impl_type: impl_base
|
Chris@102
|
142 {
|
Chris@102
|
143 F f;
|
Chris@102
|
144 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@102
|
145 impl_type(F &f_)
|
Chris@102
|
146 : f(f_)
|
Chris@102
|
147 {}
|
Chris@102
|
148 #endif
|
Chris@102
|
149 impl_type(BOOST_THREAD_RV_REF(F) f_)
|
Chris@102
|
150 : f(boost::move(f_))
|
Chris@102
|
151 {}
|
Chris@102
|
152
|
Chris@102
|
153 R call()
|
Chris@102
|
154 {
|
Chris@102
|
155 return f();
|
Chris@102
|
156 }
|
Chris@102
|
157 };
|
Chris@102
|
158 struct impl_type_ptr: impl_base
|
Chris@102
|
159 {
|
Chris@102
|
160 R (*f)();
|
Chris@102
|
161 impl_type_ptr(R (*f_)())
|
Chris@102
|
162 : f(f_)
|
Chris@102
|
163 {}
|
Chris@102
|
164
|
Chris@102
|
165 R call()
|
Chris@102
|
166 {
|
Chris@102
|
167 return f();
|
Chris@102
|
168 }
|
Chris@102
|
169 };
|
Chris@102
|
170 public:
|
Chris@102
|
171 BOOST_THREAD_COPYABLE_AND_MOVABLE(nullary_function)
|
Chris@102
|
172
|
Chris@102
|
173 nullary_function(R (*f)()):
|
Chris@102
|
174 impl(new impl_type_ptr(f))
|
Chris@102
|
175 {}
|
Chris@102
|
176 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@102
|
177 template<typename F>
|
Chris@102
|
178 nullary_function(F& f):
|
Chris@102
|
179 impl(new impl_type<F>(f))
|
Chris@102
|
180 {}
|
Chris@102
|
181 #endif
|
Chris@102
|
182 template<typename F>
|
Chris@102
|
183 nullary_function(BOOST_THREAD_RV_REF(F) f):
|
Chris@102
|
184 impl(new impl_type<typename decay<F>::type>(thread_detail::decay_copy(boost::forward<F>(f))))
|
Chris@102
|
185 {}
|
Chris@102
|
186
|
Chris@102
|
187 nullary_function(nullary_function const& other) BOOST_NOEXCEPT :
|
Chris@102
|
188 impl(other.impl)
|
Chris@102
|
189 {
|
Chris@102
|
190 }
|
Chris@102
|
191 nullary_function(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT :
|
Chris@102
|
192 #if defined BOOST_NO_CXX11_SMART_PTR
|
Chris@102
|
193 impl(BOOST_THREAD_RV(other).impl)
|
Chris@102
|
194 {
|
Chris@102
|
195 BOOST_THREAD_RV(other).impl.reset();
|
Chris@102
|
196 }
|
Chris@102
|
197 #else
|
Chris@102
|
198 impl(boost::move(other.impl))
|
Chris@102
|
199 {
|
Chris@102
|
200 }
|
Chris@102
|
201 #endif
|
Chris@102
|
202 nullary_function()
|
Chris@102
|
203 : impl()
|
Chris@102
|
204 {
|
Chris@102
|
205 }
|
Chris@102
|
206 ~nullary_function()
|
Chris@102
|
207 {
|
Chris@102
|
208 }
|
Chris@102
|
209
|
Chris@102
|
210 nullary_function& operator=(BOOST_THREAD_COPY_ASSIGN_REF(nullary_function) other) BOOST_NOEXCEPT
|
Chris@102
|
211 {
|
Chris@102
|
212 impl=other.impl;
|
Chris@102
|
213 return *this;
|
Chris@102
|
214 }
|
Chris@102
|
215 nullary_function& operator=(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT
|
Chris@102
|
216 {
|
Chris@102
|
217 #if defined BOOST_NO_CXX11_SMART_PTR
|
Chris@102
|
218 impl=BOOST_THREAD_RV(other).impl;
|
Chris@102
|
219 BOOST_THREAD_RV(other).impl.reset();
|
Chris@102
|
220 #else
|
Chris@102
|
221 impl = boost::move(other.impl);
|
Chris@102
|
222 #endif
|
Chris@102
|
223 return *this;
|
Chris@102
|
224 }
|
Chris@102
|
225
|
Chris@102
|
226 R operator()()
|
Chris@102
|
227 { if (impl) return impl->call(); else return R();}
|
Chris@102
|
228
|
Chris@102
|
229 };
|
Chris@102
|
230 }
|
Chris@102
|
231 //BOOST_THREAD_DCL_MOVABLE_BEG(F) detail::nullary_function<F> BOOST_THREAD_DCL_MOVABLE_END
|
Chris@102
|
232 }
|
Chris@102
|
233
|
Chris@102
|
234 #endif // header
|