Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:21

0001 /*
0002  *          Copyright Andrey Semashev 2007 - 2015.
0003  * Distributed under the Boost Software License, Version 1.0.
0004  *    (See accompanying file LICENSE_1_0.txt or copy at
0005  *          http://www.boost.org/LICENSE_1_0.txt)
0006  */
0007 /*!
0008  * \file   light_function.hpp
0009  * \author Andrey Semashev
0010  * \date   20.06.2010
0011  *
0012  * \brief  This header is the Boost.Log library impl, see the library documentation
0013  *         at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
0014  *
0015  * The file contains a lightweight alternative of Boost.Function. It does not provide all
0016  * features of Boost.Function but doesn't introduce dependency on Boost.Bind.
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 // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
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     //! Constructor from NULL
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     //! Assignment of NULL
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 // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
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     //! Constructor from NULL
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     //! Assignment of NULL
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 // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
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 // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
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 } // namespace aux
0514 
0515 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0516 
0517 } // namespace boost
0518 
0519 #include <boost/log/detail/footer.hpp>
0520 
0521 #endif // BOOST_LOG_DETAIL_LIGHT_FUNCTION_HPP_INCLUDED_