Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:25

0001 //
0002 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
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 // Official repository: https://github.com/boostorg/beast
0008 //
0009 
0010 #ifndef BOOST_BEAST_CORE_IMPL_ASYNC_BASE_HPP
0011 #define BOOST_BEAST_CORE_IMPL_ASYNC_BASE_HPP
0012 
0013 #include <boost/core/exchange.hpp>
0014 
0015 namespace boost {
0016 namespace beast {
0017 
0018 namespace detail {
0019 
0020 template<class State, class Allocator>
0021 struct allocate_stable_state final
0022     : stable_base
0023     , boost::empty_value<Allocator>
0024 {
0025     State value;
0026 
0027     template<class... Args>
0028     explicit
0029     allocate_stable_state(
0030         Allocator const& alloc,
0031         Args&&... args)
0032         : boost::empty_value<Allocator>(
0033             boost::empty_init_t{}, alloc)
0034         , value{std::forward<Args>(args)...}
0035     {
0036     }
0037 
0038     void destroy() override
0039     {
0040         using A = typename allocator_traits<
0041             Allocator>::template rebind_alloc<
0042                 allocate_stable_state>;
0043 
0044         A a(this->get());
0045         auto* p = this;
0046         p->~allocate_stable_state();
0047         a.deallocate(p, 1);
0048     }
0049 };
0050 
0051 } // detail
0052 
0053 
0054 template<
0055     class Handler,
0056     class Executor1,
0057     class Allocator>
0058 bool
0059 asio_handler_is_continuation(
0060     async_base<Handler, Executor1, Allocator>* p)
0061 {
0062     using boost::asio::asio_handler_is_continuation;
0063     return asio_handler_is_continuation(
0064         p->get_legacy_handler_pointer());
0065 }
0066 
0067 template<
0068     class State,
0069     class Handler,
0070     class Executor1,
0071     class Allocator,
0072     class... Args>
0073 State&
0074 allocate_stable(
0075     stable_async_base<
0076         Handler, Executor1, Allocator>& base,
0077     Args&&... args)
0078 {
0079     using allocator_type = typename stable_async_base<
0080         Handler, Executor1, Allocator>::allocator_type;
0081     using state = detail::allocate_stable_state<
0082         State, allocator_type>;
0083     using A = typename detail::allocator_traits<
0084         allocator_type>::template rebind_alloc<state>;
0085 
0086     struct deleter
0087     {
0088         allocator_type alloc;
0089         state* ptr;
0090 
0091         ~deleter()
0092         {
0093             if(ptr)
0094             {
0095                 A a(alloc);
0096                 a.deallocate(ptr, 1);
0097             }
0098         }
0099     };
0100 
0101     A a(base.get_allocator());
0102     deleter d{base.get_allocator(), a.allocate(1)};
0103     ::new(static_cast<void*>(d.ptr))
0104         state(d.alloc, std::forward<Args>(args)...);
0105     d.ptr->next_ = base.list_;
0106     base.list_ = d.ptr;
0107     return boost::exchange(d.ptr, nullptr)->value;
0108 }
0109 
0110 } // beast
0111 } // boost
0112 
0113 #endif