File indexing completed on 2025-01-18 09:39:21
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef BOOST_LOG_DETAIL_LIGHT_FUNCTION_HPP_INCLUDED_
0020 #define BOOST_LOG_DETAIL_LIGHT_FUNCTION_HPP_INCLUDED_
0021
0022 #include <cstddef>
0023 #include <boost/move/core.hpp>
0024 #include <boost/move/utility_core.hpp>
0025 #include <boost/core/explicit_operator_bool.hpp>
0026 #include <boost/log/detail/config.hpp>
0027 #include <boost/type_traits/remove_cv.hpp>
0028 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0029 #include <boost/preprocessor/iteration/iterate.hpp>
0030 #include <boost/preprocessor/repetition/enum_params.hpp>
0031 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
0032 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
0033 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
0034 #endif
0035 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0036 #include <boost/log/detail/sfinae_tools.hpp>
0037 #else
0038 #include <boost/type_traits/remove_reference.hpp>
0039 #endif
0040 #if defined(BOOST_NO_CXX11_NULLPTR)
0041 #include <boost/assert.hpp>
0042 #endif
0043 #include <boost/log/detail/header.hpp>
0044
0045 #ifdef BOOST_HAS_PRAGMA_ONCE
0046 #pragma once
0047 #endif
0048
0049 #ifndef BOOST_LOG_LIGHT_FUNCTION_LIMIT
0050 #define BOOST_LOG_LIGHT_FUNCTION_LIMIT 2
0051 #endif
0052
0053 namespace boost {
0054
0055 BOOST_LOG_OPEN_NAMESPACE
0056
0057 namespace aux {
0058
0059 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0060
0061 template< typename T, typename ThisT >
0062 struct is_cv_same { enum _ { value = false }; };
0063 template< typename T >
0064 struct is_cv_same< T, T > { enum _ { value = true }; };
0065 template< typename T >
0066 struct is_cv_same< T, const T > { enum _ { value = true }; };
0067 template< typename T >
0068 struct is_cv_same< T, volatile T > { enum _ { value = true }; };
0069 template< typename T >
0070 struct is_cv_same< T, const volatile T > { enum _ { value = true }; };
0071
0072 template< typename T, typename ThisT >
0073 struct is_rv_or_same { enum _ { value = false }; };
0074 template< typename T >
0075 struct is_rv_or_same< T, T > { enum _ { value = true }; };
0076 template< typename T, typename ThisT >
0077 struct is_rv_or_same< boost::rv< T >, ThisT > { enum _ { value = true }; };
0078
0079 #endif
0080
0081 template< typename SignatureT >
0082 class light_function;
0083
0084 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0085
0086 template< typename ResultT, typename... ArgsT >
0087 class light_function< ResultT (ArgsT...) >
0088 {
0089 typedef light_function this_type;
0090 BOOST_COPYABLE_AND_MOVABLE(this_type)
0091
0092 public:
0093 typedef ResultT result_type;
0094
0095 private:
0096 struct impl_base
0097 {
0098 typedef result_type (*invoke_type)(void*, ArgsT...);
0099 const invoke_type invoke;
0100
0101 typedef impl_base* (*clone_type)(const void*);
0102 const clone_type clone;
0103
0104 typedef void (*destroy_type)(void*);
0105 const destroy_type destroy;
0106
0107 impl_base(invoke_type inv, clone_type cl, destroy_type dstr) : invoke(inv), clone(cl), destroy(dstr)
0108 {
0109 }
0110
0111 BOOST_DELETED_FUNCTION(impl_base(impl_base const&))
0112 BOOST_DELETED_FUNCTION(impl_base& operator= (impl_base const&))
0113 };
0114
0115 #if !defined(BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS)
0116 template< typename FunT >
0117 class impl;
0118 template< typename FunT >
0119 friend class impl;
0120 #endif
0121
0122 template< typename FunT >
0123 class impl :
0124 public impl_base
0125 {
0126 typedef impl< FunT > this_type;
0127
0128 FunT m_Function;
0129
0130 public:
0131 explicit impl(FunT const& fun) :
0132 impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
0133 m_Function(fun)
0134 {
0135 }
0136
0137 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0138 explicit impl(FunT&& fun) :
0139 impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
0140 m_Function(boost::move(fun))
0141 {
0142 }
0143 #endif
0144
0145 static void destroy_impl(void* self)
0146 {
0147 delete static_cast< impl* >(static_cast< impl_base* >(self));
0148 }
0149 static impl_base* clone_impl(const void* self)
0150 {
0151 return new impl(static_cast< const impl* >(static_cast< const impl_base* >(self))->m_Function);
0152 }
0153 static result_type invoke_impl(void* self, ArgsT... args)
0154 {
0155 return static_cast< impl* >(static_cast< impl_base* >(self))->m_Function(args...);
0156 }
0157
0158 BOOST_DELETED_FUNCTION(impl(impl const&))
0159 BOOST_DELETED_FUNCTION(impl& operator= (impl const&))
0160 };
0161
0162 private:
0163 impl_base* m_pImpl;
0164
0165 public:
0166 BOOST_CONSTEXPR light_function() BOOST_NOEXCEPT : m_pImpl(NULL)
0167 {
0168 }
0169 light_function(this_type const& that)
0170 {
0171 if (that.m_pImpl)
0172 m_pImpl = that.m_pImpl->clone(that.m_pImpl);
0173 else
0174 m_pImpl = NULL;
0175 }
0176
0177 light_function(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
0178 {
0179 m_pImpl = that.m_pImpl;
0180 that.m_pImpl = NULL;
0181 }
0182
0183 light_function(BOOST_RV_REF(const this_type) that) BOOST_NOEXCEPT
0184 {
0185 m_pImpl = that.m_pImpl;
0186 ((this_type&)that).m_pImpl = NULL;
0187 }
0188
0189 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0190 template< typename FunT >
0191 light_function(FunT&& fun) :
0192 m_pImpl(new impl< typename remove_cv< typename remove_reference< FunT >::type >::type >(boost::forward< FunT >(fun)))
0193 {
0194 }
0195 #else
0196 template< typename FunT >
0197 light_function(FunT const& fun, typename boost::disable_if_c< is_rv_or_same< FunT, this_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :
0198 m_pImpl(new impl< FunT >(fun))
0199 {
0200 }
0201 template< typename FunT >
0202 light_function(BOOST_RV_REF(FunT) fun, typename boost::disable_if_c< is_cv_same< FunT, this_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :
0203 m_pImpl(new impl< typename remove_cv< FunT >::type >(fun))
0204 {
0205 }
0206 #endif
0207
0208
0209 #if !defined(BOOST_NO_CXX11_NULLPTR)
0210 BOOST_CONSTEXPR light_function(std::nullptr_t) BOOST_NOEXCEPT
0211 #else
0212 BOOST_CONSTEXPR light_function(int p) BOOST_NOEXCEPT
0213 #endif
0214 : m_pImpl(NULL)
0215 {
0216 #if defined(BOOST_NO_CXX11_NULLPTR)
0217 BOOST_ASSERT(p == 0);
0218 #endif
0219 }
0220 ~light_function()
0221 {
0222 clear();
0223 }
0224
0225 light_function& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
0226 {
0227 this->swap(that);
0228 return *this;
0229 }
0230 light_function& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
0231 {
0232 light_function tmp = static_cast< this_type const& >(that);
0233 this->swap(tmp);
0234 return *this;
0235 }
0236
0237 #if !defined(BOOST_NO_CXX11_NULLPTR)
0238 light_function& operator= (std::nullptr_t)
0239 #else
0240 light_function& operator= (int p)
0241 #endif
0242 {
0243 #if defined(BOOST_NO_CXX11_NULLPTR)
0244 BOOST_ASSERT(p == 0);
0245 #endif
0246 clear();
0247 return *this;
0248 }
0249 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0250 template< typename FunT >
0251 light_function& operator= (FunT&& fun)
0252 {
0253 light_function tmp(boost::forward< FunT >(fun));
0254 this->swap(tmp);
0255 return *this;
0256 }
0257 #else
0258 template< typename FunT >
0259 typename boost::disable_if_c< is_rv_or_same< FunT, this_type >::value, this_type& >::type
0260 operator= (FunT const& fun)
0261 {
0262 light_function tmp(fun);
0263 this->swap(tmp);
0264 return *this;
0265 }
0266 #endif
0267
0268 result_type operator() (ArgsT... args) const
0269 {
0270 return m_pImpl->invoke(m_pImpl, args...);
0271 }
0272
0273 BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
0274 bool operator! () const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
0275 bool empty() const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
0276 void clear() BOOST_NOEXCEPT
0277 {
0278 if (m_pImpl)
0279 {
0280 m_pImpl->destroy(m_pImpl);
0281 m_pImpl = NULL;
0282 }
0283 }
0284
0285 void swap(this_type& that) BOOST_NOEXCEPT
0286 {
0287 impl_base* p = m_pImpl;
0288 m_pImpl = that.m_pImpl;
0289 that.m_pImpl = p;
0290 }
0291 };
0292
0293 template< typename... ArgsT >
0294 class light_function< void (ArgsT...) >
0295 {
0296 typedef light_function this_type;
0297 BOOST_COPYABLE_AND_MOVABLE(this_type)
0298
0299 public:
0300 typedef void result_type;
0301
0302 private:
0303 struct impl_base
0304 {
0305 typedef void (*invoke_type)(void*, ArgsT...);
0306 const invoke_type invoke;
0307
0308 typedef impl_base* (*clone_type)(const void*);
0309 const clone_type clone;
0310
0311 typedef void (*destroy_type)(void*);
0312 const destroy_type destroy;
0313
0314 impl_base(invoke_type inv, clone_type cl, destroy_type dstr) : invoke(inv), clone(cl), destroy(dstr)
0315 {
0316 }
0317
0318 BOOST_DELETED_FUNCTION(impl_base(impl_base const&))
0319 BOOST_DELETED_FUNCTION(impl_base& operator= (impl_base const&))
0320 };
0321
0322 #if !defined(BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS)
0323 template< typename FunT >
0324 class impl;
0325 template< typename FunT >
0326 friend class impl;
0327 #endif
0328
0329 template< typename FunT >
0330 class impl :
0331 public impl_base
0332 {
0333 typedef impl< FunT > this_type;
0334
0335 FunT m_Function;
0336
0337 public:
0338 explicit impl(FunT const& fun) :
0339 impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
0340 m_Function(fun)
0341 {
0342 }
0343
0344 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0345 explicit impl(FunT&& fun) :
0346 impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
0347 m_Function(boost::move(fun))
0348 {
0349 }
0350 #endif
0351
0352 static void destroy_impl(void* self)
0353 {
0354 delete static_cast< impl* >(static_cast< impl_base* >(self));
0355 }
0356 static impl_base* clone_impl(const void* self)
0357 {
0358 return new impl(static_cast< const impl* >(static_cast< const impl_base* >(self))->m_Function);
0359 }
0360 static result_type invoke_impl(void* self, ArgsT... args)
0361 {
0362 static_cast< impl* >(static_cast< impl_base* >(self))->m_Function(args...);
0363 }
0364
0365 BOOST_DELETED_FUNCTION(impl(impl const&))
0366 BOOST_DELETED_FUNCTION(impl& operator= (impl const&))
0367 };
0368
0369 private:
0370 impl_base* m_pImpl;
0371
0372 public:
0373 BOOST_CONSTEXPR light_function() BOOST_NOEXCEPT : m_pImpl(NULL)
0374 {
0375 }
0376 light_function(this_type const& that)
0377 {
0378 if (that.m_pImpl)
0379 m_pImpl = that.m_pImpl->clone(that.m_pImpl);
0380 else
0381 m_pImpl = NULL;
0382 }
0383 light_function(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
0384 {
0385 m_pImpl = that.m_pImpl;
0386 that.m_pImpl = NULL;
0387 }
0388
0389 light_function(BOOST_RV_REF(const this_type) that) BOOST_NOEXCEPT
0390 {
0391 m_pImpl = that.m_pImpl;
0392 ((this_type&)that).m_pImpl = NULL;
0393 }
0394
0395 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0396 template< typename FunT >
0397 light_function(FunT&& fun) :
0398 m_pImpl(new impl< typename remove_cv< typename remove_reference< FunT >::type >::type >(boost::forward< FunT >(fun)))
0399 {
0400 }
0401 #else
0402 template< typename FunT >
0403 light_function(FunT const& fun, typename boost::disable_if_c< is_rv_or_same< FunT, this_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :
0404 m_pImpl(new impl< FunT >(fun))
0405 {
0406 }
0407 template< typename FunT >
0408 light_function(BOOST_RV_REF(FunT) fun, typename boost::disable_if_c< is_cv_same< FunT, this_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :
0409 m_pImpl(new impl< typename remove_cv< FunT >::type >(fun))
0410 {
0411 }
0412 #endif
0413
0414
0415 #if !defined(BOOST_NO_CXX11_NULLPTR)
0416 BOOST_CONSTEXPR light_function(std::nullptr_t) BOOST_NOEXCEPT
0417 #else
0418 BOOST_CONSTEXPR light_function(int p) BOOST_NOEXCEPT
0419 #endif
0420 : m_pImpl(NULL)
0421 {
0422 #if defined(BOOST_NO_CXX11_NULLPTR)
0423 BOOST_ASSERT(p == 0);
0424 #endif
0425 }
0426 ~light_function()
0427 {
0428 clear();
0429 }
0430
0431 light_function& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
0432 {
0433 this->swap(that);
0434 return *this;
0435 }
0436 light_function& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
0437 {
0438 light_function tmp = static_cast< this_type const& >(that);
0439 this->swap(tmp);
0440 return *this;
0441 }
0442
0443 #if !defined(BOOST_NO_CXX11_NULLPTR)
0444 light_function& operator= (std::nullptr_t)
0445 #else
0446 light_function& operator= (int p)
0447 #endif
0448 {
0449 #if defined(BOOST_NO_CXX11_NULLPTR)
0450 BOOST_ASSERT(p == 0);
0451 #endif
0452 clear();
0453 return *this;
0454 }
0455 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0456 template< typename FunT >
0457 light_function& operator= (FunT&& fun)
0458 {
0459 light_function tmp(boost::forward< FunT >(fun));
0460 this->swap(tmp);
0461 return *this;
0462 }
0463 #else
0464 template< typename FunT >
0465 typename boost::disable_if_c< is_rv_or_same< FunT, this_type >::value, this_type& >::type
0466 operator= (FunT const& fun)
0467 {
0468 light_function tmp(fun);
0469 this->swap(tmp);
0470 return *this;
0471 }
0472 #endif
0473
0474 result_type operator() (ArgsT... args) const
0475 {
0476 m_pImpl->invoke(m_pImpl, args...);
0477 }
0478
0479 BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
0480 bool operator! () const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
0481 bool empty() const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
0482 void clear() BOOST_NOEXCEPT
0483 {
0484 if (m_pImpl)
0485 {
0486 m_pImpl->destroy(m_pImpl);
0487 m_pImpl = NULL;
0488 }
0489 }
0490
0491 void swap(this_type& that) BOOST_NOEXCEPT
0492 {
0493 impl_base* p = m_pImpl;
0494 m_pImpl = that.m_pImpl;
0495 that.m_pImpl = p;
0496 }
0497 };
0498
0499 #else
0500
0501 #define BOOST_PP_FILENAME_1 <boost/log/detail/light_function_pp.hpp>
0502 #define BOOST_PP_ITERATION_LIMITS (0, BOOST_LOG_LIGHT_FUNCTION_LIMIT)
0503 #include BOOST_PP_ITERATE()
0504
0505 #endif
0506
0507 template< typename SignatureT >
0508 inline void swap(light_function< SignatureT >& left, light_function< SignatureT >& right)
0509 {
0510 left.swap(right);
0511 }
0512
0513 }
0514
0515 BOOST_LOG_CLOSE_NAMESPACE
0516
0517 }
0518
0519 #include <boost/log/detail/footer.hpp>
0520
0521 #endif