File indexing completed on 2025-01-18 09:28:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_DETAIL_EXECUTOR_FUNCTION_HPP
0012 #define BOOST_ASIO_DETAIL_EXECUTOR_FUNCTION_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019 #include <boost/asio/detail/handler_alloc_helpers.hpp>
0020 #include <boost/asio/detail/memory.hpp>
0021
0022 #include <boost/asio/detail/push_options.hpp>
0023
0024 namespace boost {
0025 namespace asio {
0026 namespace detail {
0027
0028
0029 class executor_function
0030 {
0031 public:
0032 template <typename F, typename Alloc>
0033 explicit executor_function(F f, const Alloc& a)
0034 {
0035
0036 typedef impl<F, Alloc> impl_type;
0037 typename impl_type::ptr p = {
0038 detail::addressof(a), impl_type::ptr::allocate(a), 0 };
0039 impl_ = new (p.v) impl_type(static_cast<F&&>(f), a);
0040 p.v = 0;
0041 }
0042
0043 executor_function(executor_function&& other) noexcept
0044 : impl_(other.impl_)
0045 {
0046 other.impl_ = 0;
0047 }
0048
0049 ~executor_function()
0050 {
0051 if (impl_)
0052 impl_->complete_(impl_, false);
0053 }
0054
0055 void operator()()
0056 {
0057 if (impl_)
0058 {
0059 impl_base* i = impl_;
0060 impl_ = 0;
0061 i->complete_(i, true);
0062 }
0063 }
0064
0065 private:
0066
0067 struct impl_base
0068 {
0069 void (*complete_)(impl_base*, bool);
0070 };
0071
0072
0073 template <typename Function, typename Alloc>
0074 struct impl : impl_base
0075 {
0076 BOOST_ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR(
0077 thread_info_base::executor_function_tag, impl);
0078
0079 template <typename F>
0080 impl(F&& f, const Alloc& a)
0081 : function_(static_cast<F&&>(f)),
0082 allocator_(a)
0083 {
0084 complete_ = &executor_function::complete<Function, Alloc>;
0085 }
0086
0087 Function function_;
0088 Alloc allocator_;
0089 };
0090
0091
0092 template <typename Function, typename Alloc>
0093 static void complete(impl_base* base, bool call)
0094 {
0095
0096 impl<Function, Alloc>* i(static_cast<impl<Function, Alloc>*>(base));
0097 Alloc allocator(i->allocator_);
0098 typename impl<Function, Alloc>::ptr p = {
0099 detail::addressof(allocator), i, i };
0100
0101
0102
0103
0104
0105
0106
0107 Function function(static_cast<Function&&>(i->function_));
0108 p.reset();
0109
0110
0111 if (call)
0112 {
0113 static_cast<Function&&>(function)();
0114 }
0115 }
0116
0117 impl_base* impl_;
0118 };
0119
0120
0121 class executor_function_view
0122 {
0123 public:
0124 template <typename F>
0125 explicit executor_function_view(F& f) noexcept
0126 : complete_(&executor_function_view::complete<F>),
0127 function_(&f)
0128 {
0129 }
0130
0131 void operator()()
0132 {
0133 complete_(function_);
0134 }
0135
0136 private:
0137
0138 template <typename F>
0139 static void complete(void* f)
0140 {
0141 (*static_cast<F*>(f))();
0142 }
0143
0144 void (*complete_)(void*);
0145 void* function_;
0146 };
0147
0148 }
0149 }
0150 }
0151
0152 #include <boost/asio/detail/pop_options.hpp>
0153
0154 #endif