| // 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 <boost/config.hpp> |
| #include <boost/thread/detail/memory.hpp> |
| #include <boost/thread/detail/move.hpp> |
| #include <boost/thread/csbl/memory/shared_ptr.hpp> |
| #include <boost/type_traits/decay.hpp> |
| #include <boost/type_traits/is_same.hpp> |
| |
| namespace boost |
| { |
| namespace detail |
| { |
| |
| template <typename F> |
| class nullary_function; |
| template <> |
| class nullary_function<void()> |
| { |
| struct impl_base |
| { |
| virtual void call()=0; |
| virtual ~impl_base() |
| { |
| } |
| }; |
| csbl::shared_ptr<impl_base> impl; |
| template <typename F> |
| 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(boost::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<typename F> |
| explicit nullary_function(F& f |
| , typename disable_if<is_same<typename decay<F>::type, nullary_function>, int* >::type=0 |
| ): |
| impl(new impl_type<F>(f)) |
| {} |
| #endif |
| template<typename F> |
| nullary_function(BOOST_THREAD_RV_REF(F) f |
| , typename disable_if<is_same<typename decay<F>::type, nullary_function>, int* >::type=0 |
| ): |
| impl(new impl_type<typename decay<F>::type>(thread_detail::decay_copy(boost::forward<F>(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(boost::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 = boost::move(other.impl); |
| #endif |
| return *this; |
| } |
| |
| |
| void operator()() |
| { if (impl) impl->call();} |
| |
| }; |
| |
| template <typename R> |
| class nullary_function<R()> |
| { |
| struct impl_base |
| { |
| virtual R call()=0; |
| virtual ~impl_base() |
| { |
| } |
| }; |
| csbl::shared_ptr<impl_base> impl; |
| template <typename F> |
| 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(boost::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<typename F> |
| nullary_function(F& f): |
| impl(new impl_type<F>(f)) |
| {} |
| #endif |
| template<typename F> |
| nullary_function(BOOST_THREAD_RV_REF(F) f): |
| impl(new impl_type<typename decay<F>::type>(thread_detail::decay_copy(boost::forward<F>(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(boost::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 = boost::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<F> BOOST_THREAD_DCL_MOVABLE_END |
| } |
| |
| #endif // header |