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