Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:34:30

0001 //
0002 // Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 //BOOST_DETAIL_COBALT_MAIN_HPP