// // Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef BEAST_WEBSOCKET_OPTIONS_SET_HPP #define BEAST_WEBSOCKET_OPTIONS_SET_HPP #include #include #include #include #include #include namespace beast { namespace websocket { /** A container of type-erased option setters. */ template class options_set { // workaround for std::function bug in msvc struct callable { virtual ~callable() = default; virtual void operator()( beast::websocket::stream&) = 0; }; template class callable_impl : public callable { T t_; public: template callable_impl(U&& u) : t_(std::forward(u)) { } void operator()(beast::websocket::stream& ws) { t_(ws); } }; template class lambda { Opt opt_; public: lambda(lambda&&) = default; lambda(lambda const&) = default; lambda(Opt const& opt) : opt_(opt) { } void operator()(beast::websocket::stream& ws) const { ws.set_option(opt_); } }; std::unordered_map> list_; public: template void set_option(Opt const& opt) { std::unique_ptr p; p.reset(new callable_impl>{opt}); list_[std::type_index{ typeid(Opt)}] = std::move(p); } void set_options(beast::websocket::stream& ws) { for(auto const& op : list_) (*op.second)(ws); } }; } // websocket } // beast #endif