Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:52:46

0001 // Copyright (C) 2013 Vicente J. Botet Escriba
0002 //
0003 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 //
0006 // 2013,2018 Vicente J. Botet Escriba
0007 //    Adapt to boost from CCIA C++11 implementation
0008 //    Make use of Boost.Move
0009 
0010 #ifndef BOOST_THREAD_DETAIL_NULLARY_FUNCTION_HPP
0011 #define BOOST_THREAD_DETAIL_NULLARY_FUNCTION_HPP
0012 
0013 #include <boost/config.hpp>
0014 #include <boost/thread/detail/memory.hpp>
0015 #include <boost/thread/detail/move.hpp>
0016 #include <boost/thread/csbl/memory/shared_ptr.hpp>
0017 #include <boost/type_traits/decay.hpp>
0018 #include <boost/type_traits/is_same.hpp>
0019 
0020 namespace boost
0021 {
0022   namespace detail
0023   {
0024 
0025     template <typename F>
0026     class nullary_function;
0027     template <>
0028     class nullary_function<void()>
0029     {
0030       struct impl_base
0031       {
0032         virtual void call()=0;
0033         virtual ~impl_base()
0034         {
0035         }
0036       };
0037       csbl::shared_ptr<impl_base> impl;
0038       template <typename F>
0039       struct impl_type: impl_base
0040       {
0041         F f;
0042 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
0043         impl_type(F &f_)
0044           : f(f_)
0045         {}
0046 #endif
0047         impl_type(BOOST_THREAD_RV_REF(F) f_)
0048           : f(boost::move(f_))
0049         {}
0050 
0051         void call()
0052         {
0053           f();
0054         }
0055       };
0056       struct impl_type_ptr: impl_base
0057       {
0058         void (*f)();
0059         impl_type_ptr(void (*f_)())
0060           : f(f_)
0061         {}
0062         void call()
0063         {
0064           f();
0065         }
0066       };
0067     public:
0068       BOOST_THREAD_COPYABLE_AND_MOVABLE(nullary_function)
0069 
0070       explicit nullary_function(void (*f)()):
0071       impl(new impl_type_ptr(f))
0072       {}
0073 
0074 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
0075       template<typename F>
0076       explicit nullary_function(F& f
0077                                 , typename disable_if<is_same<typename decay<F>::type, nullary_function>, int* >::type=0
0078                                 ):
0079       impl(new impl_type<F>(f))
0080       {}
0081 #endif
0082       template<typename F>
0083       nullary_function(BOOST_THREAD_RV_REF(F) f
0084                        , typename disable_if<is_same<typename decay<F>::type, nullary_function>, int* >::type=0
0085                        ):
0086       impl(new impl_type<typename decay<F>::type>(thread_detail::decay_copy(boost::forward<F>(f))))
0087       {}
0088 
0089       nullary_function()
0090         : impl()
0091       {
0092       }
0093       nullary_function(nullary_function const& other) BOOST_NOEXCEPT :
0094       impl(other.impl)
0095       {
0096       }
0097       nullary_function(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT :
0098 #if defined BOOST_NO_CXX11_SMART_PTR
0099       impl(BOOST_THREAD_RV(other).impl)
0100       {
0101         BOOST_THREAD_RV(other).impl.reset();
0102       }
0103 #else
0104       impl(boost::move(other.impl))
0105       {
0106       }
0107 #endif
0108       ~nullary_function()
0109       {
0110       }
0111 
0112       nullary_function& operator=(BOOST_THREAD_COPY_ASSIGN_REF(nullary_function) other) BOOST_NOEXCEPT
0113       {
0114         impl=other.impl;
0115         return *this;
0116       }
0117       nullary_function& operator=(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT
0118       {
0119 #if defined BOOST_NO_CXX11_SMART_PTR
0120         impl=BOOST_THREAD_RV(other).impl;
0121         BOOST_THREAD_RV(other).impl.reset();
0122 #else
0123         impl = boost::move(other.impl);
0124 #endif
0125         return *this;
0126       }
0127 
0128 
0129       void operator()()
0130       { if (impl) impl->call();}
0131 
0132     };
0133 
0134     template <typename R>
0135     class nullary_function<R()>
0136     {
0137       struct impl_base
0138       {
0139         virtual R call()=0;
0140         virtual ~impl_base()
0141         {
0142         }
0143       };
0144       csbl::shared_ptr<impl_base> impl;
0145       template <typename F>
0146       struct impl_type: impl_base
0147       {
0148         F f;
0149 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
0150         impl_type(F &f_)
0151           : f(f_)
0152         {}
0153 #endif
0154         impl_type(BOOST_THREAD_RV_REF(F) f_)
0155           : f(boost::move(f_))
0156         {}
0157 
0158         R call()
0159         {
0160           return f();
0161         }
0162       };
0163       struct impl_type_ptr: impl_base
0164       {
0165         R (*f)();
0166         impl_type_ptr(R (*f_)())
0167           : f(f_)
0168         {}
0169 
0170         R call()
0171         {
0172           return f();
0173         }
0174       };
0175     public:
0176       BOOST_THREAD_COPYABLE_AND_MOVABLE(nullary_function)
0177 
0178       nullary_function(R (*f)()):
0179       impl(new impl_type_ptr(f))
0180       {}
0181 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
0182       template<typename F>
0183       nullary_function(F& f):
0184       impl(new impl_type<F>(f))
0185       {}
0186 #endif
0187       template<typename F>
0188       nullary_function(BOOST_THREAD_RV_REF(F) f):
0189       impl(new impl_type<typename decay<F>::type>(thread_detail::decay_copy(boost::forward<F>(f))))
0190       {}
0191 
0192       nullary_function(nullary_function const& other) BOOST_NOEXCEPT :
0193       impl(other.impl)
0194       {
0195       }
0196       nullary_function(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT :
0197 #if defined BOOST_NO_CXX11_SMART_PTR
0198       impl(BOOST_THREAD_RV(other).impl)
0199       {
0200         BOOST_THREAD_RV(other).impl.reset();
0201       }
0202 #else
0203       impl(boost::move(other.impl))
0204       {
0205       }
0206 #endif
0207       nullary_function()
0208         : impl()
0209       {
0210       }
0211       ~nullary_function()
0212       {
0213       }
0214 
0215       nullary_function& operator=(BOOST_THREAD_COPY_ASSIGN_REF(nullary_function) other) BOOST_NOEXCEPT
0216       {
0217         impl=other.impl;
0218         return *this;
0219       }
0220       nullary_function& operator=(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT
0221       {
0222 #if defined BOOST_NO_CXX11_SMART_PTR
0223         impl=BOOST_THREAD_RV(other).impl;
0224         BOOST_THREAD_RV(other).impl.reset();
0225 #else
0226         impl = boost::move(other.impl);
0227 #endif
0228         return *this;
0229       }
0230 
0231       R operator()()
0232       { if (impl) return impl->call(); else return R();}
0233 
0234     };
0235   }
0236   BOOST_THREAD_DCL_MOVABLE_BEG(F) detail::nullary_function<F> BOOST_THREAD_DCL_MOVABLE_END
0237 }
0238 
0239 #endif // header