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 template<
0009     typename ResultT
0010     BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename ArgT)
0011 >
0012 class light_function< ResultT (BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT)) >
0013 {
0014     typedef light_function this_type;
0015     BOOST_COPYABLE_AND_MOVABLE(this_type)
0016 
0017 public:
0018     typedef ResultT result_type;
0019 
0020 private:
0021     struct impl_base
0022     {
0023         typedef result_type (*invoke_type)(void* BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), ArgT));
0024         const invoke_type invoke;
0025 
0026         typedef impl_base* (*clone_type)(const void*);
0027         const clone_type clone;
0028 
0029         typedef void (*destroy_type)(void*);
0030         const destroy_type destroy;
0031 
0032         impl_base(invoke_type inv, clone_type cl, destroy_type dstr) : invoke(inv), clone(cl), destroy(dstr)
0033         {
0034         }
0035 
0036         BOOST_DELETED_FUNCTION(impl_base(impl_base const&))
0037         BOOST_DELETED_FUNCTION(impl_base& operator= (impl_base const&))
0038     };
0039 
0040 #if !defined(BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS)
0041     template< typename FunT >
0042     class impl;
0043     template< typename FunT >
0044     friend class impl;
0045 #endif
0046 
0047     template< typename FunT >
0048     class impl :
0049         public impl_base
0050     {
0051         typedef impl< FunT > this_type;
0052 
0053         FunT m_Function;
0054 
0055     public:
0056         explicit impl(FunT const& fun) :
0057             impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
0058             m_Function(fun)
0059         {
0060         }
0061 
0062 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0063         explicit impl(FunT&& fun) :
0064             impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
0065             m_Function(boost::move(fun))
0066         {
0067         }
0068 #endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0069 
0070         static void destroy_impl(void* self)
0071         {
0072             delete static_cast< impl* >(static_cast< impl_base* >(self));
0073         }
0074         static impl_base* clone_impl(const void* self)
0075         {
0076             return new impl(static_cast< const impl* >(static_cast< const impl_base* >(self))->m_Function);
0077         }
0078         static result_type invoke_impl(void* self BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, arg))
0079         {
0080             return static_cast< impl* >(static_cast< impl_base* >(self))->m_Function(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), arg));
0081         }
0082 
0083         BOOST_DELETED_FUNCTION(impl(impl const&))
0084         BOOST_DELETED_FUNCTION(impl& operator= (impl const&))
0085     };
0086 
0087 private:
0088     impl_base* m_pImpl;
0089 
0090 public:
0091     BOOST_CONSTEXPR light_function() BOOST_NOEXCEPT : m_pImpl(NULL)
0092     {
0093     }
0094     light_function(this_type const& that)
0095     {
0096         if (that.m_pImpl)
0097             m_pImpl = that.m_pImpl->clone(that.m_pImpl);
0098         else
0099             m_pImpl = NULL;
0100     }
0101 
0102     light_function(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
0103     {
0104         m_pImpl = that.m_pImpl;
0105         that.m_pImpl = NULL;
0106     }
0107 
0108     light_function(BOOST_RV_REF(const this_type) that) BOOST_NOEXCEPT
0109     {
0110         m_pImpl = that.m_pImpl;
0111         ((this_type&)that).m_pImpl = NULL;
0112     }
0113 
0114 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0115     template< typename FunT >
0116     light_function(FunT&& fun) :
0117         m_pImpl(new impl< typename remove_cv< typename remove_reference< FunT >::type >::type >(boost::forward< FunT >(fun)))
0118     {
0119     }
0120 #else
0121     template< typename FunT >
0122     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()) :
0123         m_pImpl(new impl< FunT >(fun))
0124     {
0125     }
0126     template< typename FunT >
0127     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()) :
0128         m_pImpl(new impl< typename remove_cv< FunT >::type >(fun))
0129     {
0130     }
0131 #endif
0132 
0133     //! Constructor from NULL
0134 #if !defined(BOOST_NO_CXX11_NULLPTR)
0135     BOOST_CONSTEXPR light_function(std::nullptr_t) BOOST_NOEXCEPT
0136 #else
0137     BOOST_CONSTEXPR light_function(int p) BOOST_NOEXCEPT
0138 #endif
0139         : m_pImpl(NULL)
0140     {
0141 #if defined(BOOST_NO_CXX11_NULLPTR)
0142         BOOST_ASSERT(p == 0);
0143 #endif
0144     }
0145     ~light_function()
0146     {
0147         clear();
0148     }
0149 
0150     light_function& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
0151     {
0152         this->swap(that);
0153         return *this;
0154     }
0155     light_function& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
0156     {
0157         light_function tmp = static_cast< this_type const& >(that);
0158         this->swap(tmp);
0159         return *this;
0160     }
0161     //! Assignment of NULL
0162 #if !defined(BOOST_NO_CXX11_NULLPTR)
0163     light_function& operator= (std::nullptr_t)
0164 #else
0165     light_function& operator= (int p)
0166 #endif
0167     {
0168 #if defined(BOOST_NO_CXX11_NULLPTR)
0169         BOOST_ASSERT(p == 0);
0170 #endif
0171         clear();
0172         return *this;
0173     }
0174 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0175     template< typename FunT >
0176     light_function& operator= (FunT&& fun)
0177     {
0178         light_function tmp(boost::forward< FunT >(fun));
0179         this->swap(tmp);
0180         return *this;
0181     }
0182 #else
0183     template< typename FunT >
0184     typename boost::disable_if_c< is_rv_or_same< FunT, this_type >::value, this_type& >::type
0185     operator= (FunT const& fun)
0186     {
0187         light_function tmp(fun);
0188         this->swap(tmp);
0189         return *this;
0190     }
0191 #endif
0192 
0193     result_type operator() (BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, arg)) const
0194     {
0195         return m_pImpl->invoke(m_pImpl BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), arg));
0196     }
0197 
0198     BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
0199     bool operator! () const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
0200     bool empty() const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
0201     void clear() BOOST_NOEXCEPT
0202     {
0203         if (m_pImpl)
0204         {
0205             m_pImpl->destroy(m_pImpl);
0206             m_pImpl = NULL;
0207         }
0208     }
0209 
0210     void swap(this_type& that) BOOST_NOEXCEPT
0211     {
0212         impl_base* p = m_pImpl;
0213         m_pImpl = that.m_pImpl;
0214         that.m_pImpl = p;
0215     }
0216 };
0217 
0218 template<
0219     BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), typename ArgT)
0220 >
0221 class light_function< void (BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT)) >
0222 {
0223     typedef light_function this_type;
0224     BOOST_COPYABLE_AND_MOVABLE(this_type)
0225 
0226 public:
0227     typedef void result_type;
0228 
0229 private:
0230     struct impl_base
0231     {
0232         typedef void (*invoke_type)(void* BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), ArgT));
0233         const invoke_type invoke;
0234 
0235         typedef impl_base* (*clone_type)(const void*);
0236         const clone_type clone;
0237 
0238         typedef void (*destroy_type)(void*);
0239         const destroy_type destroy;
0240 
0241         impl_base(invoke_type inv, clone_type cl, destroy_type dstr) : invoke(inv), clone(cl), destroy(dstr)
0242         {
0243         }
0244 
0245         BOOST_DELETED_FUNCTION(impl_base(impl_base const&))
0246         BOOST_DELETED_FUNCTION(impl_base& operator= (impl_base const&))
0247     };
0248 
0249 #if !defined(BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS)
0250     template< typename FunT >
0251     class impl;
0252     template< typename FunT >
0253     friend class impl;
0254 #endif
0255 
0256     template< typename FunT >
0257     class impl :
0258         public impl_base
0259     {
0260         typedef impl< FunT > this_type;
0261 
0262         FunT m_Function;
0263 
0264     public:
0265         explicit impl(FunT const& fun) :
0266             impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
0267             m_Function(fun)
0268         {
0269         }
0270 
0271 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0272         explicit impl(FunT&& fun) :
0273             impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
0274             m_Function(boost::move(fun))
0275         {
0276         }
0277 #endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0278 
0279         static void destroy_impl(void* self)
0280         {
0281             delete static_cast< impl* >(static_cast< impl_base* >(self));
0282         }
0283         static impl_base* clone_impl(const void* self)
0284         {
0285             return new impl(static_cast< const impl* >(static_cast< const impl_base* >(self))->m_Function);
0286         }
0287         static result_type invoke_impl(void* self BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, arg))
0288         {
0289             static_cast< impl* >(static_cast< impl_base* >(self))->m_Function(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), arg));
0290         }
0291 
0292         BOOST_DELETED_FUNCTION(impl(impl const&))
0293         BOOST_DELETED_FUNCTION(impl& operator= (impl const&))
0294     };
0295 
0296 private:
0297     impl_base* m_pImpl;
0298 
0299 public:
0300     BOOST_CONSTEXPR light_function() BOOST_NOEXCEPT : m_pImpl(NULL)
0301     {
0302     }
0303     light_function(this_type const& that)
0304     {
0305         if (that.m_pImpl)
0306             m_pImpl = that.m_pImpl->clone(that.m_pImpl);
0307         else
0308             m_pImpl = NULL;
0309     }
0310     light_function(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
0311     {
0312         m_pImpl = that.m_pImpl;
0313         that.m_pImpl = NULL;
0314     }
0315 
0316     light_function(BOOST_RV_REF(const this_type) that) BOOST_NOEXCEPT
0317     {
0318         m_pImpl = that.m_pImpl;
0319         ((this_type&)that).m_pImpl = NULL;
0320     }
0321 
0322 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0323     template< typename FunT >
0324     light_function(FunT&& fun) :
0325         m_pImpl(new impl< typename remove_cv< typename remove_reference< FunT >::type >::type >(boost::forward< FunT >(fun)))
0326     {
0327     }
0328 #else
0329     template< typename FunT >
0330     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()) :
0331         m_pImpl(new impl< FunT >(fun))
0332     {
0333     }
0334     template< typename FunT >
0335     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()) :
0336         m_pImpl(new impl< typename remove_cv< FunT >::type >(fun))
0337     {
0338     }
0339 #endif
0340 
0341     //! Constructor from NULL
0342 #if !defined(BOOST_NO_CXX11_NULLPTR)
0343     BOOST_CONSTEXPR light_function(std::nullptr_t) BOOST_NOEXCEPT
0344 #else
0345     BOOST_CONSTEXPR light_function(int p) BOOST_NOEXCEPT
0346 #endif
0347         : m_pImpl(NULL)
0348     {
0349 #if defined(BOOST_NO_CXX11_NULLPTR)
0350         BOOST_ASSERT(p == 0);
0351 #endif
0352     }
0353     ~light_function()
0354     {
0355         clear();
0356     }
0357 
0358     light_function& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
0359     {
0360         this->swap(that);
0361         return *this;
0362     }
0363     light_function& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
0364     {
0365         light_function tmp = static_cast< this_type const& >(that);
0366         this->swap(tmp);
0367         return *this;
0368     }
0369     //! Assignment of NULL
0370 #if !defined(BOOST_NO_CXX11_NULLPTR)
0371     light_function& operator= (std::nullptr_t)
0372 #else
0373     light_function& operator= (int p)
0374 #endif
0375     {
0376 #if defined(BOOST_NO_CXX11_NULLPTR)
0377         BOOST_ASSERT(p == 0);
0378 #endif
0379         clear();
0380         return *this;
0381     }
0382 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0383     template< typename FunT >
0384     light_function& operator= (FunT&& fun)
0385     {
0386         light_function tmp(boost::forward< FunT >(fun));
0387         this->swap(tmp);
0388         return *this;
0389     }
0390 #else
0391     template< typename FunT >
0392     typename boost::disable_if_c< is_rv_or_same< FunT, this_type >::value, this_type& >::type
0393     operator= (FunT const& fun)
0394     {
0395         light_function tmp(fun);
0396         this->swap(tmp);
0397         return *this;
0398     }
0399 #endif
0400 
0401     result_type operator() (BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, arg)) const
0402     {
0403         m_pImpl->invoke(m_pImpl BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), arg));
0404     }
0405 
0406     BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
0407     bool operator! () const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
0408     bool empty() const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
0409     void clear() BOOST_NOEXCEPT
0410     {
0411         if (m_pImpl)
0412         {
0413             m_pImpl->destroy(m_pImpl);
0414             m_pImpl = NULL;
0415         }
0416     }
0417 
0418     void swap(this_type& that) BOOST_NOEXCEPT
0419     {
0420         impl_base* p = m_pImpl;
0421         m_pImpl = that.m_pImpl;
0422         that.m_pImpl = p;
0423     }
0424 };