2 // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 #ifndef BEAST_WEBSOCKET_DETAIL_INVOKABLE_HPP
9 #define BEAST_WEBSOCKET_DETAIL_INVOKABLE_HPP
11 #include <beast/core/handler_ptr.hpp>
12 #include <boost/assert.hpp>
22 // "Parks" a composed operation, to invoke later
29 base(base &&) = default;
30 virtual ~base() = default;
31 virtual void move(void* p) = 0;
32 virtual void operator()() = 0;
40 holder(holder&&) = default;
45 : f(std::forward<U>(u))
50 move(void* p) override
52 ::new(p) holder(std::move(*this));
60 // invocation of f_() can
61 // assign a new invokable.
75 using handler_type = H;
83 using buf_type = char[sizeof(holder<exemplar>)];
85 base* base_ = nullptr;
86 alignas(holder<exemplar>) buf_type buf_;
95 invokable() = default;
97 invokable(invokable&& other)
102 base_ = reinterpret_cast<base*>(&buf_[0]);
103 other.base_->move(buf_);
104 other.base_ = nullptr;
109 operator=(invokable&& other)
111 // Engaged invokables must be invoked before
112 // assignment otherwise the io_service
113 // completion invariants are broken.
114 BOOST_ASSERT(! base_);
119 base_ = reinterpret_cast<base*>(&buf_[0]);
120 other.base_->move(buf_);
121 other.base_ = nullptr;
135 auto const basep = base_;
146 invokable::emplace(F&& f)
148 static_assert(sizeof(buf_type) >= sizeof(holder<F>),
150 BOOST_ASSERT(! base_);
151 ::new(buf_) holder<F>(std::forward<F>(f));
153 base_ = reinterpret_cast<base*>(&buf_[0]);