File indexing completed on 2025-01-30 09:34:30
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_DETAIL_COBALT_MAIN_HPP
0009 #define BOOST_DETAIL_COBALT_MAIN_HPP
0010
0011 #include <boost/cobalt/main.hpp>
0012 #include <boost/cobalt/this_coro.hpp>
0013
0014
0015 #include <boost/config.hpp>
0016
0017
0018 namespace boost::asio
0019 {
0020
0021 template<typename Executor>
0022 class basic_signal_set;
0023
0024 }
0025
0026 namespace boost::cobalt::detail
0027 {
0028
0029 extern "C"
0030 {
0031 int main(int argc, char * argv[]);
0032 }
0033
0034 struct signal_helper
0035 {
0036 asio::cancellation_signal signal;
0037 };
0038
0039 struct main_promise : signal_helper,
0040 promise_cancellation_base<asio::cancellation_slot, asio::enable_total_cancellation>,
0041 promise_throw_if_cancelled_base,
0042 enable_awaitables<main_promise>,
0043 enable_await_allocator<main_promise>,
0044 enable_await_executor<main_promise>
0045 {
0046 main_promise(int, char **) : promise_cancellation_base<asio::cancellation_slot, asio::enable_total_cancellation>(
0047 signal_helper::signal.slot(), asio::enable_total_cancellation())
0048 {
0049 [[maybe_unused]] volatile auto p = &detail::main;
0050 }
0051
0052 #if !defined(BOOST_COBALT_NO_PMR)
0053 inline static pmr::memory_resource * my_resource = pmr::get_default_resource();
0054 void * operator new(const std::size_t size)
0055 {
0056 return my_resource->allocate(size);
0057 }
0058
0059 void operator delete(void * raw, const std::size_t size)
0060 {
0061 return my_resource->deallocate(raw, size);
0062 }
0063 #endif
0064 std::suspend_always initial_suspend() {return {};}
0065
0066 BOOST_COBALT_DECL
0067 auto final_suspend() noexcept -> std::suspend_never;
0068
0069 void unhandled_exception() { throw ; }
0070 void return_value(int res = 0)
0071 {
0072 if (result)
0073 *result = res;
0074 }
0075
0076 friend auto ::co_main (int argc, char * argv[]) -> boost::cobalt::main;
0077 BOOST_COBALT_DECL
0078 static int run_main( ::boost::cobalt::main mn);
0079
0080 friend int main(int argc, char * argv[])
0081 {
0082 #if !defined(BOOST_COBALT_NO_PMR)
0083 pmr::unsynchronized_pool_resource root_resource;
0084 struct reset_res
0085 {
0086 void operator()(pmr::memory_resource * res)
0087 {
0088 this_thread::set_default_resource(res);
0089 }
0090 };
0091 std::unique_ptr<pmr::memory_resource, reset_res> pr{
0092 boost::cobalt::this_thread::set_default_resource(&root_resource)};
0093 char buffer[8096];
0094 pmr::monotonic_buffer_resource main_res{buffer, 8096, &root_resource};
0095 my_resource = &main_res;
0096 #endif
0097 return run_main(co_main(argc, argv));
0098 }
0099
0100 using executor_type = executor;
0101 const executor_type & get_executor() const {return *exec_;}
0102
0103 #if !defined(BOOST_COBALT_NO_PMR)
0104 using allocator_type = pmr::polymorphic_allocator<void>;
0105 using resource_type = pmr::unsynchronized_pool_resource;
0106
0107 mutable resource_type resource{my_resource};
0108 allocator_type get_allocator() const { return allocator_type(&resource); }
0109 #endif
0110
0111 using promise_cancellation_base<asio::cancellation_slot, asio::enable_total_cancellation>::await_transform;
0112 using promise_throw_if_cancelled_base::await_transform;
0113 using enable_awaitables<main_promise>::await_transform;
0114 using enable_await_allocator<main_promise>::await_transform;
0115 using enable_await_executor<main_promise>::await_transform;
0116
0117 private:
0118 int * result;
0119 std::optional<asio::executor_work_guard<executor_type>> exec;
0120 std::optional<executor_type> exec_;
0121 asio::basic_signal_set<executor_type> * signal_set;
0122 ::boost::cobalt::main get_return_object()
0123 {
0124 return ::boost::cobalt::main{this};
0125 }
0126 };
0127
0128 }
0129
0130 namespace std
0131 {
0132
0133 template<typename Char>
0134 struct coroutine_traits<boost::cobalt::main, int, Char>
0135 {
0136 using promise_type = boost::cobalt::detail::main_promise;
0137 };
0138
0139 }
0140
0141 #endif