comparison DEPENDENCIES/generic/include/boost/log/detail/light_function.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
comparison
equal deleted inserted replaced
15:663ca0da4350 16:2665513ce2d3
1 /*
2 * Copyright Andrey Semashev 2007 - 2013.
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 * \file light_function.hpp
9 * \author Andrey Semashev
10 * \date 20.06.2010
11 *
12 * \brief This header is the Boost.Log library impl, see the library documentation
13 * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
14 *
15 * The file contains a lightweight alternative of Boost.Function. It does not provide all
16 * features of Boost.Function but doesn't introduce dependency on Boost.Bind.
17 */
18
19 #ifndef BOOST_LOG_DETAIL_LIGHT_FUNCTION_HPP_INCLUDED_
20 #define BOOST_LOG_DETAIL_LIGHT_FUNCTION_HPP_INCLUDED_
21
22 #include <cstddef>
23 #include <boost/move/core.hpp>
24 #include <boost/move/utility.hpp>
25 #include <boost/log/detail/config.hpp>
26 #include <boost/utility/explicit_operator_bool.hpp>
27 #include <boost/type_traits/remove_cv.hpp>
28 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
29 #include <boost/preprocessor/iteration/iterate.hpp>
30 #include <boost/preprocessor/repetition/enum_params.hpp>
31 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
32 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
33 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
34 #endif
35 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
36 #include <boost/utility/enable_if.hpp>
37 #include <boost/type_traits/is_same.hpp>
38 #include <boost/mpl/or.hpp>
39 #else
40 #include <boost/type_traits/remove_reference.hpp>
41 #endif
42 #if defined(BOOST_NO_CXX11_NULLPTR)
43 #include <boost/assert.hpp>
44 #endif
45 #include <boost/log/detail/header.hpp>
46
47 #ifdef BOOST_HAS_PRAGMA_ONCE
48 #pragma once
49 #endif
50
51 #ifndef BOOST_LOG_LIGHT_FUNCTION_LIMIT
52 #define BOOST_LOG_LIGHT_FUNCTION_LIMIT 2
53 #endif
54
55 namespace boost {
56
57 BOOST_LOG_OPEN_NAMESPACE
58
59 namespace aux {
60
61 template< typename SignatureT >
62 class light_function;
63
64 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
65
66 template< typename ResultT, typename... ArgsT >
67 class light_function< ResultT (ArgsT...) >
68 {
69 typedef light_function this_type;
70 BOOST_COPYABLE_AND_MOVABLE(this_type)
71
72 public:
73 typedef ResultT result_type;
74
75 private:
76 struct impl_base
77 {
78 typedef result_type (*invoke_type)(impl_base*, ArgsT...);
79 const invoke_type invoke;
80
81 typedef impl_base* (*clone_type)(const impl_base*);
82 const clone_type clone;
83
84 typedef void (*destroy_type)(impl_base*);
85 const destroy_type destroy;
86
87 impl_base(invoke_type inv, clone_type cl, destroy_type dstr) : invoke(inv), clone(cl), destroy(dstr)
88 {
89 }
90 };
91
92 #if !defined(BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS)
93 template< typename FunT >
94 class impl;
95 template< typename FunT >
96 friend class impl;
97 #endif
98
99 template< typename FunT >
100 class impl :
101 public impl_base
102 {
103 typedef impl< FunT > this_type;
104
105 FunT m_Function;
106
107 public:
108 explicit impl(FunT const& fun) :
109 impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
110 m_Function(fun)
111 {
112 }
113
114 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
115 explicit impl(FunT&& fun) :
116 impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
117 m_Function(fun)
118 {
119 }
120 #endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
121
122 static void destroy_impl(impl_base* self)
123 {
124 delete static_cast< impl* >(self);
125 }
126 static impl_base* clone_impl(const impl_base* self)
127 {
128 return new impl(static_cast< const impl* >(self)->m_Function);
129 }
130 static result_type invoke_impl(impl_base* self, ArgsT... args)
131 {
132 return static_cast< impl* >(self)->m_Function(args...);
133 }
134 };
135
136 private:
137 impl_base* m_pImpl;
138
139 public:
140 BOOST_CONSTEXPR light_function() BOOST_NOEXCEPT : m_pImpl(NULL)
141 {
142 }
143 light_function(this_type const& that)
144 {
145 if (that.m_pImpl)
146 m_pImpl = that.m_pImpl->clone(that.m_pImpl);
147 else
148 m_pImpl = NULL;
149 }
150
151 light_function(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
152 {
153 m_pImpl = that.m_pImpl;
154 that.m_pImpl = NULL;
155 }
156
157 light_function(BOOST_RV_REF(const this_type) that) BOOST_NOEXCEPT
158 {
159 m_pImpl = that.m_pImpl;
160 ((this_type&)that).m_pImpl = NULL;
161 }
162
163 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
164 template< typename FunT >
165 light_function(FunT&& fun) :
166 m_pImpl(new impl< typename remove_cv< typename remove_reference< FunT >::type >::type >(boost::forward< FunT >(fun)))
167 {
168 }
169 #else
170 template< typename FunT >
171 light_function(FunT const& fun, typename disable_if< mpl::or_< move_detail::is_rv< FunT >, is_same< FunT, this_type > >, int >::type = 0) :
172 m_pImpl(new impl< FunT >(fun))
173 {
174 }
175 template< typename FunT >
176 light_function(rv< FunT > const& fun, typename disable_if< is_same< typename remove_cv< FunT >::type, this_type >, int >::type = 0) :
177 m_pImpl(new impl< typename remove_cv< FunT >::type >(fun))
178 {
179 }
180 #endif
181
182 //! Constructor from NULL
183 #if !defined(BOOST_NO_CXX11_NULLPTR)
184 BOOST_CONSTEXPR light_function(std::nullptr_t) BOOST_NOEXCEPT
185 #else
186 BOOST_CONSTEXPR light_function(int p) BOOST_NOEXCEPT
187 #endif
188 : m_pImpl(NULL)
189 {
190 #if defined(BOOST_NO_CXX11_NULLPTR)
191 BOOST_ASSERT(p == 0);
192 #endif
193 }
194 ~light_function()
195 {
196 clear();
197 }
198
199 light_function& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
200 {
201 this->swap(that);
202 return *this;
203 }
204 light_function& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
205 {
206 light_function tmp(that);
207 this->swap(tmp);
208 return *this;
209 }
210 //! Assignment of NULL
211 #if !defined(BOOST_NO_CXX11_NULLPTR)
212 light_function& operator= (std::nullptr_t)
213 #else
214 light_function& operator= (int p)
215 #endif
216 {
217 #if defined(BOOST_NO_CXX11_NULLPTR)
218 BOOST_ASSERT(p == 0);
219 #endif
220 clear();
221 return *this;
222 }
223 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
224 template< typename FunT >
225 light_function& operator= (FunT&& fun)
226 {
227 light_function tmp(boost::forward< FunT >(fun));
228 this->swap(tmp);
229 return *this;
230 }
231 #else
232 template< typename FunT >
233 typename disable_if< mpl::or_< move_detail::is_rv< FunT >, is_same< FunT, this_type > >, this_type& >::type
234 operator= (FunT const& fun)
235 {
236 light_function tmp(fun);
237 this->swap(tmp);
238 return *this;
239 }
240 #endif
241
242 result_type operator() (ArgsT... args) const
243 {
244 return m_pImpl->invoke(m_pImpl, args...);
245 }
246
247 BOOST_EXPLICIT_OPERATOR_BOOL()
248 bool operator! () const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
249 bool empty() const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
250 void clear() BOOST_NOEXCEPT
251 {
252 if (m_pImpl)
253 {
254 m_pImpl->destroy(m_pImpl);
255 m_pImpl = NULL;
256 }
257 }
258
259 void swap(this_type& that) BOOST_NOEXCEPT
260 {
261 register impl_base* p = m_pImpl;
262 m_pImpl = that.m_pImpl;
263 that.m_pImpl = p;
264 }
265 };
266
267 template< typename... ArgsT >
268 class light_function< void (ArgsT...) >
269 {
270 typedef light_function this_type;
271 BOOST_COPYABLE_AND_MOVABLE(this_type)
272
273 public:
274 typedef void result_type;
275
276 private:
277 struct impl_base
278 {
279 typedef void (*invoke_type)(impl_base*, ArgsT...);
280 const invoke_type invoke;
281
282 typedef impl_base* (*clone_type)(const impl_base*);
283 const clone_type clone;
284
285 typedef void (*destroy_type)(impl_base*);
286 const destroy_type destroy;
287
288 impl_base(invoke_type inv, clone_type cl, destroy_type dstr) : invoke(inv), clone(cl), destroy(dstr)
289 {
290 }
291 };
292
293 #if !defined(BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS)
294 template< typename FunT >
295 class impl;
296 template< typename FunT >
297 friend class impl;
298 #endif
299
300 template< typename FunT >
301 class impl :
302 public impl_base
303 {
304 typedef impl< FunT > this_type;
305
306 FunT m_Function;
307
308 public:
309 explicit impl(FunT const& fun) :
310 impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
311 m_Function(fun)
312 {
313 }
314
315 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
316 explicit impl(FunT&& fun) :
317 impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
318 m_Function(fun)
319 {
320 }
321 #endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
322
323 static void destroy_impl(impl_base* self)
324 {
325 delete static_cast< impl* >(self);
326 }
327 static impl_base* clone_impl(const impl_base* self)
328 {
329 return new impl(static_cast< const impl* >(self)->m_Function);
330 }
331 static result_type invoke_impl(impl_base* self, ArgsT... args)
332 {
333 static_cast< impl* >(self)->m_Function(args...);
334 }
335 };
336
337 private:
338 impl_base* m_pImpl;
339
340 public:
341 BOOST_CONSTEXPR light_function() BOOST_NOEXCEPT : m_pImpl(NULL)
342 {
343 }
344 light_function(this_type const& that)
345 {
346 if (that.m_pImpl)
347 m_pImpl = that.m_pImpl->clone(that.m_pImpl);
348 else
349 m_pImpl = NULL;
350 }
351 light_function(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
352 {
353 m_pImpl = that.m_pImpl;
354 that.m_pImpl = NULL;
355 }
356
357 light_function(BOOST_RV_REF(const this_type) that) BOOST_NOEXCEPT
358 {
359 m_pImpl = that.m_pImpl;
360 ((this_type&)that).m_pImpl = NULL;
361 }
362
363 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
364 template< typename FunT >
365 light_function(FunT&& fun) :
366 m_pImpl(new impl< typename remove_cv< typename remove_reference< FunT >::type >::type >(boost::forward< FunT >(fun)))
367 {
368 }
369 #else
370 template< typename FunT >
371 light_function(FunT const& fun, typename disable_if< mpl::or_< move_detail::is_rv< FunT >, is_same< FunT, this_type > >, int >::type = 0) :
372 m_pImpl(new impl< FunT >(fun))
373 {
374 }
375 template< typename FunT >
376 light_function(rv< FunT > const& fun, typename disable_if< is_same< typename remove_cv< FunT >::type, this_type >, int >::type = 0) :
377 m_pImpl(new impl< typename remove_cv< FunT >::type >(fun))
378 {
379 }
380 #endif
381
382 //! Constructor from NULL
383 #if !defined(BOOST_NO_CXX11_NULLPTR)
384 BOOST_CONSTEXPR light_function(std::nullptr_t) BOOST_NOEXCEPT
385 #else
386 BOOST_CONSTEXPR light_function(int p) BOOST_NOEXCEPT
387 #endif
388 : m_pImpl(NULL)
389 {
390 #if defined(BOOST_NO_CXX11_NULLPTR)
391 BOOST_ASSERT(p == 0);
392 #endif
393 }
394 ~light_function()
395 {
396 clear();
397 }
398
399 light_function& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
400 {
401 this->swap(that);
402 return *this;
403 }
404 light_function& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
405 {
406 light_function tmp = that;
407 this->swap(tmp);
408 return *this;
409 }
410 //! Assignment of NULL
411 #if !defined(BOOST_NO_CXX11_NULLPTR)
412 light_function& operator= (std::nullptr_t)
413 #else
414 light_function& operator= (int p)
415 #endif
416 {
417 #if defined(BOOST_NO_CXX11_NULLPTR)
418 BOOST_ASSERT(p == 0);
419 #endif
420 clear();
421 return *this;
422 }
423 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
424 template< typename FunT >
425 light_function& operator= (FunT&& fun)
426 {
427 light_function tmp(boost::forward< FunT >(fun));
428 this->swap(tmp);
429 return *this;
430 }
431 #else
432 template< typename FunT >
433 typename disable_if< mpl::or_< move_detail::is_rv< FunT >, is_same< FunT, this_type > >, this_type& >::type
434 operator= (FunT const& fun)
435 {
436 light_function tmp(fun);
437 this->swap(tmp);
438 return *this;
439 }
440 #endif
441
442 result_type operator() (ArgsT... args) const
443 {
444 m_pImpl->invoke(m_pImpl, args...);
445 }
446
447 BOOST_EXPLICIT_OPERATOR_BOOL()
448 bool operator! () const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
449 bool empty() const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
450 void clear() BOOST_NOEXCEPT
451 {
452 if (m_pImpl)
453 {
454 m_pImpl->destroy(m_pImpl);
455 m_pImpl = NULL;
456 }
457 }
458
459 void swap(this_type& that) BOOST_NOEXCEPT
460 {
461 register impl_base* p = m_pImpl;
462 m_pImpl = that.m_pImpl;
463 that.m_pImpl = p;
464 }
465 };
466
467 #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
468
469 #define BOOST_PP_FILENAME_1 <boost/log/detail/light_function_pp.hpp>
470 #define BOOST_PP_ITERATION_LIMITS (0, BOOST_LOG_LIGHT_FUNCTION_LIMIT)
471 #include BOOST_PP_ITERATE()
472
473 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
474
475 template< typename SignatureT >
476 inline void swap(light_function< SignatureT >& left, light_function< SignatureT >& right)
477 {
478 left.swap(right);
479 }
480
481 } // namespace aux
482
483 BOOST_LOG_CLOSE_NAMESPACE // namespace log
484
485 } // namespace boost
486
487 #include <boost/log/detail/footer.hpp>
488
489 #endif // BOOST_LOG_DETAIL_LIGHT_FUNCTION_HPP_INCLUDED_