File indexing completed on 2025-01-18 09:52:46
0001
0002
0003
0004
0005
0006
0007
0008
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