Chris@102: // Copyright (C) 2013 Vicente J. Botet Escriba Chris@102: // Chris@102: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@102: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@102: // Chris@102: // 2013/09 Vicente J. Botet Escriba Chris@102: // Adapt to boost from CCIA C++11 implementation Chris@102: // Make use of Boost.Move Chris@102: Chris@102: #ifndef BOOST_THREAD_DETAIL_NULLARY_FUNCTION_HPP Chris@102: #define BOOST_THREAD_DETAIL_NULLARY_FUNCTION_HPP Chris@102: Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: Chris@102: namespace boost Chris@102: { Chris@102: namespace detail Chris@102: { Chris@102: Chris@102: template Chris@102: class nullary_function; Chris@102: template <> Chris@102: class nullary_function Chris@102: { Chris@102: struct impl_base Chris@102: { Chris@102: virtual void call()=0; Chris@102: virtual ~impl_base() Chris@102: { Chris@102: } Chris@102: }; Chris@102: csbl::shared_ptr impl; Chris@102: template Chris@102: struct impl_type: impl_base Chris@102: { Chris@102: F f; Chris@102: #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@102: impl_type(F &f_) Chris@102: : f(f_) Chris@102: {} Chris@102: #endif Chris@102: impl_type(BOOST_THREAD_RV_REF(F) f_) Chris@102: : f(boost::move(f_)) Chris@102: {} Chris@102: Chris@102: void call() Chris@102: { Chris@102: f(); Chris@102: } Chris@102: }; Chris@102: struct impl_type_ptr: impl_base Chris@102: { Chris@102: void (*f)(); Chris@102: impl_type_ptr(void (*f_)()) Chris@102: : f(f_) Chris@102: {} Chris@102: void call() Chris@102: { Chris@102: f(); Chris@102: } Chris@102: }; Chris@102: public: Chris@102: BOOST_THREAD_COPYABLE_AND_MOVABLE(nullary_function) Chris@102: Chris@102: explicit nullary_function(void (*f)()): Chris@102: impl(new impl_type_ptr(f)) Chris@102: {} Chris@102: Chris@102: #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@102: template Chris@102: explicit nullary_function(F& f): Chris@102: impl(new impl_type(f)) Chris@102: {} Chris@102: #endif Chris@102: template Chris@102: nullary_function(BOOST_THREAD_RV_REF(F) f): Chris@102: impl(new impl_type::type>(thread_detail::decay_copy(boost::forward(f)))) Chris@102: {} Chris@102: Chris@102: nullary_function() Chris@102: : impl() Chris@102: { Chris@102: } Chris@102: nullary_function(nullary_function const& other) BOOST_NOEXCEPT : Chris@102: impl(other.impl) Chris@102: { Chris@102: } Chris@102: nullary_function(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT : Chris@102: #if defined BOOST_NO_CXX11_SMART_PTR Chris@102: impl(BOOST_THREAD_RV(other).impl) Chris@102: { Chris@102: BOOST_THREAD_RV(other).impl.reset(); Chris@102: } Chris@102: #else Chris@102: impl(boost::move(other.impl)) Chris@102: { Chris@102: } Chris@102: #endif Chris@102: ~nullary_function() Chris@102: { Chris@102: } Chris@102: Chris@102: nullary_function& operator=(BOOST_THREAD_COPY_ASSIGN_REF(nullary_function) other) BOOST_NOEXCEPT Chris@102: { Chris@102: impl=other.impl; Chris@102: return *this; Chris@102: } Chris@102: nullary_function& operator=(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT Chris@102: { Chris@102: #if defined BOOST_NO_CXX11_SMART_PTR Chris@102: impl=BOOST_THREAD_RV(other).impl; Chris@102: BOOST_THREAD_RV(other).impl.reset(); Chris@102: #else Chris@102: impl = boost::move(other.impl); Chris@102: #endif Chris@102: return *this; Chris@102: } Chris@102: Chris@102: Chris@102: void operator()() Chris@102: { if (impl) impl->call();} Chris@102: Chris@102: }; Chris@102: Chris@102: template Chris@102: class nullary_function Chris@102: { Chris@102: struct impl_base Chris@102: { Chris@102: virtual R call()=0; Chris@102: virtual ~impl_base() Chris@102: { Chris@102: } Chris@102: }; Chris@102: csbl::shared_ptr impl; Chris@102: template Chris@102: struct impl_type: impl_base Chris@102: { Chris@102: F f; Chris@102: #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@102: impl_type(F &f_) Chris@102: : f(f_) Chris@102: {} Chris@102: #endif Chris@102: impl_type(BOOST_THREAD_RV_REF(F) f_) Chris@102: : f(boost::move(f_)) Chris@102: {} Chris@102: Chris@102: R call() Chris@102: { Chris@102: return f(); Chris@102: } Chris@102: }; Chris@102: struct impl_type_ptr: impl_base Chris@102: { Chris@102: R (*f)(); Chris@102: impl_type_ptr(R (*f_)()) Chris@102: : f(f_) Chris@102: {} Chris@102: Chris@102: R call() Chris@102: { Chris@102: return f(); Chris@102: } Chris@102: }; Chris@102: public: Chris@102: BOOST_THREAD_COPYABLE_AND_MOVABLE(nullary_function) Chris@102: Chris@102: nullary_function(R (*f)()): Chris@102: impl(new impl_type_ptr(f)) Chris@102: {} Chris@102: #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@102: template Chris@102: nullary_function(F& f): Chris@102: impl(new impl_type(f)) Chris@102: {} Chris@102: #endif Chris@102: template Chris@102: nullary_function(BOOST_THREAD_RV_REF(F) f): Chris@102: impl(new impl_type::type>(thread_detail::decay_copy(boost::forward(f)))) Chris@102: {} Chris@102: Chris@102: nullary_function(nullary_function const& other) BOOST_NOEXCEPT : Chris@102: impl(other.impl) Chris@102: { Chris@102: } Chris@102: nullary_function(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT : Chris@102: #if defined BOOST_NO_CXX11_SMART_PTR Chris@102: impl(BOOST_THREAD_RV(other).impl) Chris@102: { Chris@102: BOOST_THREAD_RV(other).impl.reset(); Chris@102: } Chris@102: #else Chris@102: impl(boost::move(other.impl)) Chris@102: { Chris@102: } Chris@102: #endif Chris@102: nullary_function() Chris@102: : impl() Chris@102: { Chris@102: } Chris@102: ~nullary_function() Chris@102: { Chris@102: } Chris@102: Chris@102: nullary_function& operator=(BOOST_THREAD_COPY_ASSIGN_REF(nullary_function) other) BOOST_NOEXCEPT Chris@102: { Chris@102: impl=other.impl; Chris@102: return *this; Chris@102: } Chris@102: nullary_function& operator=(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT Chris@102: { Chris@102: #if defined BOOST_NO_CXX11_SMART_PTR Chris@102: impl=BOOST_THREAD_RV(other).impl; Chris@102: BOOST_THREAD_RV(other).impl.reset(); Chris@102: #else Chris@102: impl = boost::move(other.impl); Chris@102: #endif Chris@102: return *this; Chris@102: } Chris@102: Chris@102: R operator()() Chris@102: { if (impl) return impl->call(); else return R();} Chris@102: Chris@102: }; Chris@102: } Chris@102: //BOOST_THREAD_DCL_MOVABLE_BEG(F) detail::nullary_function BOOST_THREAD_DCL_MOVABLE_END Chris@102: } Chris@102: Chris@102: #endif // header