diff --git a/.gitmodules b/.gitmodules index e69de29b..d2e779d0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "external/function2"] + path = external/function2 + url = https://github.com/Naios/function2 diff --git a/external/function2 b/external/function2 new file mode 160000 index 00000000..2d3a878e --- /dev/null +++ b/external/function2 @@ -0,0 +1 @@ +Subproject commit 2d3a878ef19dd5d2fb188898513610fac0a48621 diff --git a/include/mqtt/callable_overlay.hpp b/include/mqtt/callable_overlay.hpp index 0dbf03c6..fd76ca97 100644 --- a/include/mqtt/callable_overlay.hpp +++ b/include/mqtt/callable_overlay.hpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace MQTT_NS { template @@ -758,7 +759,7 @@ struct callable_overlay final : public Impl * 3.13 PINGREQ – PING request * @return if the handler returns true, then continue receiving, otherwise quit. */ - using pingreq_handler = std::function; + using pingreq_handler = move_only_function; /** * @brief Pingresp handler @@ -766,7 +767,7 @@ struct callable_overlay final : public Impl * 3.13 PINGRESP – PING response * @return if the handler returns true, then continue receiving, otherwise quit. */ - using pingresp_handler = std::function; + using pingresp_handler = move_only_function; // MQTT v3_1_1 handlers @@ -808,7 +809,7 @@ struct callable_overlay final : public Impl * @return if the handler returns true, then continue receiving, otherwise quit. * */ - using connect_handler = std::function< + using connect_handler = move_only_function< bool(buffer client_id, optional user_name, optional password, @@ -828,7 +829,7 @@ struct callable_overlay final : public Impl * 3.2.2.3 Connect Return code * @return if the handler returns true, then continue receiving, otherwise quit. */ - using connack_handler = std::function; + using connack_handler = move_only_function; /** * @brief Publish handler @@ -847,7 +848,7 @@ struct callable_overlay final : public Impl * Published contents * @return if the handler returns true, then continue receiving, otherwise quit. */ - using publish_handler = std::function packet_id, + using publish_handler = move_only_function packet_id, publish_options pubopts, buffer topic_name, buffer contents)>; @@ -860,7 +861,7 @@ struct callable_overlay final : public Impl * 3.4.2 Variable header * @return if the handler returns true, then continue receiving, otherwise quit. */ - using puback_handler = std::function; + using puback_handler = move_only_function; /** * @brief Pubrec handler @@ -870,7 +871,7 @@ struct callable_overlay final : public Impl * 3.5.2 Variable header * @return if the handler returns true, then continue receiving, otherwise quit. */ - using pubrec_handler = std::function; + using pubrec_handler = move_only_function; /** * @brief Pubrel handler @@ -880,7 +881,7 @@ struct callable_overlay final : public Impl * 3.6.2 Variable header * @return if the handler returns true, then continue receiving, otherwise quit. */ - using pubrel_handler = std::function; + using pubrel_handler = move_only_function; /** * @brief Pubcomp handler @@ -890,7 +891,7 @@ struct callable_overlay final : public Impl * 3.7.2 Variable header * @return if the handler returns true, then continue receiving, otherwise quit. */ - using pubcomp_handler = std::function; + using pubcomp_handler = move_only_function; /** * @brief Subscribe handler @@ -902,7 +903,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc385349802
* @return if the handler returns true, then continue receiving, otherwise quit. */ - using subscribe_handler = std::function entries)>; /** @@ -916,7 +917,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc398718071
* @return if the handler returns true, then continue receiving, otherwise quit. */ - using suback_handler = std::function qoss)>; /** @@ -929,7 +930,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc384800448
* @return if the handler returns true, then continue receiving, otherwise quit. */ - using unsubscribe_handler = std::function entries)>; /** @@ -939,14 +940,14 @@ struct callable_overlay final : public Impl * 3.11.2 Variable header * @return if the handler returns true, then continue receiving, otherwise quit. */ - using unsuback_handler = std::function; + using unsuback_handler = move_only_function; /** * @brief Disconnect handler * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc384800463
* 3.14 DISCONNECT – Disconnect notification */ - using disconnect_handler = std::function; + using disconnect_handler = move_only_function; // MQTT v5 handlers @@ -993,7 +994,7 @@ struct callable_overlay final : public Impl * @return if the handler returns true, then continue receiving, otherwise quit. * */ - using v5_connect_handler = std::function< + using v5_connect_handler = move_only_function< bool(buffer client_id, optional user_name, optional password, @@ -1019,7 +1020,7 @@ struct callable_overlay final : public Impl * 3.2.2.3 CONNACK Properties * @return if the handler returns true, then continue receiving, otherwise quit. */ - using v5_connack_handler = std::function< + using v5_connack_handler = move_only_function< bool(bool session_present, v5::connect_reason_code reason_code, v5::properties props) @@ -1050,7 +1051,7 @@ struct callable_overlay final : public Impl * 3.3.2.3 PUBLISH Properties * @return if the handler returns true, then continue receiving, otherwise quit. */ - using v5_publish_handler = std::function< + using v5_publish_handler = move_only_function< bool(optional packet_id, publish_options pubopts, buffer topic_name, @@ -1074,7 +1075,7 @@ struct callable_overlay final : public Impl * 3.4.2.2 PUBACK Properties * @return if the handler returns true, then continue receiving, otherwise quit. */ - using v5_puback_handler = std::function< + using v5_puback_handler = move_only_function< bool(packet_id_t packet_id, v5::puback_reason_code reason_code, v5::properties props) @@ -1096,7 +1097,7 @@ struct callable_overlay final : public Impl * 3.5.2.2 PUBREC Properties * @return if the handler returns true, then continue receiving, otherwise quit. */ - using v5_pubrec_handler = std::function< + using v5_pubrec_handler = move_only_function< bool(packet_id_t packet_id, v5::pubrec_reason_code reason_code, v5::properties props) @@ -1118,7 +1119,7 @@ struct callable_overlay final : public Impl * 3.6.2.2 PUBREL Properties * @return if the handler returns true, then continue receiving, otherwise quit. */ - using v5_pubrel_handler = std::function< + using v5_pubrel_handler = move_only_function< bool(packet_id_t packet_id, v5::pubrel_reason_code reason_code, v5::properties props) @@ -1140,7 +1141,7 @@ struct callable_overlay final : public Impl * 3.7.2.2 PUBCOMP Properties * @return if the handler returns true, then continue receiving, otherwise quit. */ - using v5_pubcomp_handler = std::function< + using v5_pubcomp_handler = move_only_function< bool(packet_id_t packet_id, v5::pubcomp_reason_code reason_code, v5::properties props) @@ -1160,7 +1161,7 @@ struct callable_overlay final : public Impl * 3.8.2.1 SUBSCRIBE Properties * @return if the handler returns true, then continue receiving, otherwise quit. */ - using v5_subscribe_handler = std::function< + using v5_subscribe_handler = move_only_function< bool(packet_id_t packet_id, std::vector entries, v5::properties props) @@ -1181,7 +1182,7 @@ struct callable_overlay final : public Impl * 3.9.2.1 SUBACK Properties * @return if the handler returns true, then continue receiving, otherwise quit. */ - using v5_suback_handler = std::function< + using v5_suback_handler = move_only_function< bool(packet_id_t packet_id, std::vector reasons, v5::properties props) @@ -1202,7 +1203,7 @@ struct callable_overlay final : public Impl * 3.10.2.1 UNSUBSCRIBE Properties * @return if the handler returns true, then continue receiving, otherwise quit. */ - using v5_unsubscribe_handler = std::function< + using v5_unsubscribe_handler = move_only_function< bool(packet_id_t packet_id, std::vector entries, v5::properties props) @@ -1223,7 +1224,7 @@ struct callable_overlay final : public Impl * 3.11.2.1 UNSUBACK Properties * @return if the handler returns true, then continue receiving, otherwise quit. */ - using v5_unsuback_handler = std::function< + using v5_unsuback_handler = move_only_function< bool(packet_id_t, std::vector reasons, v5::properties props) @@ -1242,7 +1243,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901209
* 3.14.2.2 DISCONNECT Properties */ - using v5_disconnect_handler = std::function< + using v5_disconnect_handler = move_only_function< void(v5::disconnect_reason_code reason_code, v5::properties props) >; @@ -1261,7 +1262,7 @@ struct callable_overlay final : public Impl * 3.15.2.2 AUTH Properties * @return if the handler returns true, then continue receiving, otherwise quit. */ - using v5_auth_handler = std::function< + using v5_auth_handler = move_only_function< bool(v5::auth_reason_code reason_code, v5::properties props) >; @@ -1275,7 +1276,7 @@ struct callable_overlay final : public Impl * This handler is called if the client called `disconnect()` and the server closed the socket cleanly. * If the socket is closed by other reasons, error_handler is called. */ - using close_handler = std::function; + using close_handler = move_only_function; /** * @brief Error handler @@ -1284,7 +1285,7 @@ struct callable_overlay final : public Impl * * @param ec error code */ - using error_handler = std::function; + using error_handler = move_only_function; /** * @brief Publish response sent handler @@ -1294,7 +1295,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901026
* 2.2.1 Packet Identifier */ - using pub_res_sent_handler = std::function; + using pub_res_sent_handler = move_only_function; /** * @brief Serialize publish handler @@ -1302,7 +1303,7 @@ struct callable_overlay final : public Impl * To restore the message, use restore_serialized_message(). * @param msg publish message */ - using serialize_publish_message_handler = std::function msg)>; + using serialize_publish_message_handler = move_only_function msg)>; /** * @brief Serialize publish handler @@ -1310,7 +1311,7 @@ struct callable_overlay final : public Impl * To restore the message, use restore_serialized_message(). * @param msg v5::publish message */ - using serialize_v5_publish_message_handler = std::function msg)>; + using serialize_v5_publish_message_handler = move_only_function msg)>; /** * @brief Serialize publish handler @@ -1320,7 +1321,7 @@ struct callable_overlay final : public Impl * @param data pointer to the serializing message * @param size size of the serializing message */ - using serialize_publish_handler = std::function; + using serialize_publish_handler = move_only_function; /** * @brief Serialize pubrel handler @@ -1330,7 +1331,7 @@ struct callable_overlay final : public Impl * To restore the message, use restore_serialized_message(). * @param msg pubrel message */ - using serialize_pubrel_message_handler = std::function msg)>; + using serialize_pubrel_message_handler = move_only_function msg)>; /** * @brief Serialize pubrel handler @@ -1340,7 +1341,7 @@ struct callable_overlay final : public Impl * To restore the message, use restore_serialized_message(). * @param msg pubrel message */ - using serialize_v5_pubrel_message_handler = std::function msg)>; + using serialize_v5_pubrel_message_handler = move_only_function msg)>; /** * @brief Serialize pubrel handler @@ -1352,19 +1353,19 @@ struct callable_overlay final : public Impl * @param data pointer to the serializing message * @param size size of the serializing message */ - using serialize_pubrel_handler = std::function; + using serialize_pubrel_handler = move_only_function; /** * @brief Remove serialized message * @param packet_id packet identifier of the removing message */ - using serialize_remove_handler = std::function; + using serialize_remove_handler = move_only_function; /** * @brief Pre-send handler * This handler is called when any mqtt control packet is decided to send. */ - using pre_send_handler = std::function; + using pre_send_handler = move_only_function; /** * @brief is valid length handler @@ -1374,7 +1375,7 @@ struct callable_overlay final : public Impl * @return true if check is success, otherwise false */ using is_valid_length_handler = - std::function; + move_only_function; /** * @brief next read handler @@ -1382,7 +1383,7 @@ struct callable_overlay final : public Impl * @param func A callback function that is called when async operation will finish. */ using mqtt_message_processed_handler = - std::function; + move_only_function; @@ -1879,7 +1880,7 @@ struct callable_overlay final : public Impl serialize_remove_handler h_remove) { h_serialize_publish_ = [h_publish = force_move(h_publish)] - (basic_publish_message msg) { + (basic_publish_message msg) mutable { if (h_publish) { auto buf = msg.continuous_buffer(); h_publish(msg.packet_id(), buf.data(), buf.size()); @@ -1887,7 +1888,7 @@ struct callable_overlay final : public Impl }; h_serialize_pubrel_ = [h_pubrel = force_move(h_pubrel)] - (basic_pubrel_message msg) { + (basic_pubrel_message msg) mutable { if (h_pubrel) { auto buf = msg.continuous_buffer(); h_pubrel(msg.packet_id(), buf.data(), buf.size()); @@ -1908,7 +1909,7 @@ struct callable_overlay final : public Impl serialize_remove_handler h_remove) { h_serialize_v5_publish_ = [h_publish = force_move(h_publish)] - (v5::basic_publish_message msg) { + (v5::basic_publish_message msg) mutable { if (h_publish) { auto buf = msg.continuous_buffer(); h_publish(msg.packet_id(), buf.data(), buf.size()); @@ -1916,7 +1917,7 @@ struct callable_overlay final : public Impl }; h_serialize_v5_pubrel_ = [h_pubrel = force_move(h_pubrel)] - (v5::basic_pubrel_message msg) { + (v5::basic_pubrel_message msg) mutable { if (h_pubrel) { auto buf = msg.continuous_buffer(); h_pubrel(msg.packet_id(), buf.data(), buf.size()); @@ -2042,7 +2043,7 @@ struct callable_overlay final : public Impl * @brief Get mqtt_message_processed_handler. * @return mqtt_message_processed_handler. */ - mqtt_message_processed_handler get_mqtt_message_processed_handler() const { + mqtt_message_processed_handler const& get_mqtt_message_processed_handler() const { return h_mqtt_message_processed_; } @@ -2051,7 +2052,7 @@ struct callable_overlay final : public Impl * @param h handler */ void set_close_handler(close_handler h = close_handler()) { - h_close_ = force_move(h); + // h_close_ = force_move(h); } /** @@ -2066,7 +2067,7 @@ struct callable_overlay final : public Impl * @brief Get close handler * @return handler */ - close_handler get_close_handler() const { + close_handler const& get_close_handler() const { return h_close_; } @@ -2074,7 +2075,7 @@ struct callable_overlay final : public Impl * @brief Get error handler * @return handler */ - error_handler get_error_handler() const { + error_handler const& get_error_handler() const { return h_error_; } diff --git a/include/mqtt/endpoint.hpp b/include/mqtt/endpoint.hpp index 179cfa2b..5b86acfd 100644 --- a/include/mqtt/endpoint.hpp +++ b/include/mqtt/endpoint.hpp @@ -71,6 +71,7 @@ #include #include #include +#include #if defined(MQTT_USE_WS) #include @@ -173,7 +174,7 @@ class endpoint : public std::enable_shared_from_this; public: - using async_handler_t = std::function; + using async_handler_t = move_only_function; using packet_id_t = typename packet_id_type::type; /** @@ -2229,7 +2230,7 @@ class endpoint : public std::enable_shared_from_thispost( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::success)); } ); @@ -2268,7 +2269,7 @@ class endpoint : public std::enable_shared_from_thispost( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::success)); } ); @@ -2756,7 +2757,7 @@ class endpoint : public std::enable_shared_from_this const& f) { + void for_each_store(move_only_function f) { MQTT_LOG("mqtt_api", info) << MQTT_ADD_VALUE(address, this) << "for_each_store(ptr, size)"; LockGuard lck (store_mtx_); store_.for_each( - [f]( + [f = force_move(f)] + ( basic_store_message_variant const& message, any const& /*life_keeper*/ - ) { + ) mutable { auto cb = continuous_buffer(message); f(cb.data(), cb.size()); return false; // no erase @@ -4343,16 +4345,17 @@ class endpoint : public std::enable_shared_from_this)> const& f) { + void for_each_store(move_only_function)> f) { MQTT_LOG("mqtt_api", info) << MQTT_ADD_VALUE(address, this) << "for_each_store(store_message_variant)"; LockGuard lck (store_mtx_); store_.for_each( - [f]( + [f = force_move(f)] + ( basic_store_message_variant const& message, any const& /*life_keeper*/ - ) { + ) mutable { f(message); return false; // no erase } @@ -4363,17 +4366,18 @@ class endpoint : public std::enable_shared_from_this, any)> const& f) { + void for_each_store_with_life_keeper(move_only_function, any)> f) { MQTT_LOG("mqtt_api", info) << MQTT_ADD_VALUE(address, this) << "for_each_store(store_message_variant, life_keeper)"; LockGuard lck (store_mtx_); store_.for_each( - [f]( + [f = force_move(f)] + ( basic_store_message_variant const& message, any const& life_keeper - ) { + ) mutable { f(message, life_keeper); return false; // no erase } @@ -4782,7 +4786,7 @@ class endpoint : public std::enable_shared_from_this(std::get<0>(msg_lk))) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -4799,7 +4803,7 @@ class endpoint : public std::enable_shared_from_this(msg_lk)), [func = force_move(func), life_keeper = force_move(std::get<1>(msg_lk))] - (error_code ec) { + (error_code ec) mutable { if (func) func(ec); } ); @@ -4810,7 +4814,7 @@ class endpoint : public std::enable_shared_from_this(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -4859,14 +4863,14 @@ class endpoint : public std::enable_shared_from_this&& msg) mutable { + [this, func = force_move(func)] (v5::basic_publish_message&& msg) mutable { if (publish_send_count_.load() == publish_send_max_) { { LockGuard lck (publish_send_queue_mtx_); publish_send_queue_.emplace_back(force_move(msg), true); } socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { // message has already been stored so func should be called with success here if (func) func(boost::system::errc::make_error_code(boost::system::errc::success)); } @@ -5365,7 +5369,7 @@ class endpoint : public std::enable_shared_from_this; using parse_handler = - std::function< + move_only_function< void( this_type_sp&& spep, any&& session_life_keeper, @@ -10492,7 +10496,7 @@ class endpoint : public std::enable_shared_from_this(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -10512,7 +10516,7 @@ class endpoint : public std::enable_shared_from_this(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -10551,7 +10555,7 @@ class endpoint : public std::enable_shared_from_thispost( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -10566,7 +10570,7 @@ class endpoint : public std::enable_shared_from_this(msg_lk)), - [life_keeper = force_move(std::get<1>(msg_lk)), func](error_code ec) { + [life_keeper = force_move(std::get<1>(msg_lk)), func = force_move(func)](error_code ec) mutable { if (func) func(ec); } ); @@ -10596,14 +10600,14 @@ class endpoint : public std::enable_shared_from_this&& msg) mutable { + [this, func = force_move(func)] (v5::basic_publish_message&& msg) mutable { if (publish_send_count_.load() == publish_send_max_) { { LockGuard lck (publish_send_queue_mtx_); publish_send_queue_.emplace_back(force_move(msg), true); } socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { // message has already been stored so func should be called with success here if (func) func(boost::system::errc::make_error_code(boost::system::errc::success)); } @@ -10635,7 +10639,7 @@ class endpoint : public std::enable_shared_from_this(packet_id); if (maximum_packet_size_send_ < size(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -10644,7 +10648,7 @@ class endpoint : public std::enable_shared_from_thisshared_from_this(), packet_id, func = force_move(func)] - (error_code ec) { + (error_code ec) mutable { if (func) func(ec); on_pub_res_sent(packet_id); } @@ -10654,7 +10658,7 @@ class endpoint : public std::enable_shared_from_this(packet_id, reason, force_move(props)); if (maximum_packet_size_send_ < size(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -10663,7 +10667,7 @@ class endpoint : public std::enable_shared_from_thisshared_from_this(), packet_id, func = force_move(func)] - (error_code ec) { + (error_code ec) mutable { erase_publish_received(packet_id); if (func) func(ec); on_pub_res_sent(packet_id); @@ -10687,7 +10691,7 @@ class endpoint : public std::enable_shared_from_this(packet_id); if (maximum_packet_size_send_ < size(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -10702,7 +10706,7 @@ class endpoint : public std::enable_shared_from_this(packet_id, reason, force_move(props)); if (maximum_packet_size_send_ < size(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -10711,7 +10715,7 @@ class endpoint : public std::enable_shared_from_thisshared_from_this(), packet_id, func = force_move(func)] - (error_code ec) { + (error_code ec) mutable { erase_publish_received(packet_id); if (func) func(ec); } @@ -10738,7 +10742,7 @@ class endpoint : public std::enable_shared_from_this(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -10777,7 +10781,8 @@ class endpoint : public std::enable_shared_from_this(packet_id); if (maximum_packet_size_send_ < size(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -10822,7 +10827,7 @@ class endpoint : public std::enable_shared_from_thisshared_from_this(), packet_id, func = force_move(func)] - (error_code ec) { + (error_code ec) mutable { if (func) func(ec); on_pub_res_sent(packet_id); } @@ -10832,7 +10837,7 @@ class endpoint : public std::enable_shared_from_this(packet_id, reason, force_move(props)); if (maximum_packet_size_send_ < size(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -10841,7 +10846,7 @@ class endpoint : public std::enable_shared_from_thisshared_from_this(), packet_id, func = force_move(func)] - (error_code ec) { + (error_code ec) mutable { if (func) func(ec); on_pub_res_sent(packet_id); } @@ -10868,7 +10873,7 @@ class endpoint : public std::enable_shared_from_thispost( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -10891,7 +10896,7 @@ class endpoint : public std::enable_shared_from_thispost( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -10926,7 +10931,7 @@ class endpoint : public std::enable_shared_from_this(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -10945,7 +10950,7 @@ class endpoint : public std::enable_shared_from_this(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -10977,7 +10982,7 @@ class endpoint : public std::enable_shared_from_thispost( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -11000,7 +11005,7 @@ class endpoint : public std::enable_shared_from_thispost( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -11030,7 +11035,7 @@ class endpoint : public std::enable_shared_from_this(packet_id); if (maximum_packet_size_send_ < size(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -11064,7 +11069,7 @@ class endpoint : public std::enable_shared_from_this(force_move(params), packet_id, force_move(props)); if (maximum_packet_size_send_ < size(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -11087,7 +11092,7 @@ class endpoint : public std::enable_shared_from_this(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -11100,7 +11105,7 @@ class endpoint : public std::enable_shared_from_this(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -11121,7 +11126,7 @@ class endpoint : public std::enable_shared_from_this(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -11133,7 +11138,7 @@ class endpoint : public std::enable_shared_from_this(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -11160,7 +11165,7 @@ class endpoint : public std::enable_shared_from_this(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -11184,7 +11189,7 @@ class endpoint : public std::enable_shared_from_this(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -11196,7 +11201,7 @@ class endpoint : public std::enable_shared_from_this(msg)) { socket_->post( - [func = force_move(func)] { + [func = force_move(func)] () mutable { if (func) func(boost::system::errc::make_error_code(boost::system::errc::message_size)); } ); @@ -11210,10 +11215,10 @@ class endpoint : public std::enable_shared_from_this func) { + void async_send_store(move_only_function func) { // packet_id has already been registered auto g = shared_scope_guard( - [func = force_move(func)] { + [func = force_move(func)] () mutable { func(); } ); @@ -11359,7 +11364,7 @@ class endpoint : public std::enable_shared_from_thisqueue_.pop_front(); @@ -11379,7 +11384,7 @@ class endpoint : public std::enable_shared_from_thistotal_bytes_sent_ += bytes_transferred; for (std::size_t i = 0; i != num_of_messages_; ++i) { @@ -11418,7 +11423,7 @@ class endpoint : public std::enable_shared_from_this(iterator_count)); // And further, only up to the specified maximum bytes @@ -11446,11 +11451,11 @@ class endpoint : public std::enable_shared_from_thisshared_from_this(), [handlers = force_move(handlers)] - (error_code ec) { - for (auto const& h : handlers) { + (error_code ec) mutable { + for (auto& h : handlers) { if (h) h(ec); } }, diff --git a/include/mqtt/move_only_function.hpp b/include/mqtt/move_only_function.hpp new file mode 100644 index 00000000..6b4bebc2 --- /dev/null +++ b/include/mqtt/move_only_function.hpp @@ -0,0 +1,21 @@ +// Copyright Takatoshi Kondo 2022 +// +// 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) + +#if !defined(MQTT_MOVE_ONLY_FUNCTION_HPP) +#define MQTT_MOVE_ONLY_FUNCTION_HPP + +#include + +#include + +namespace MQTT_NS { + +template +using move_only_function = fu2::unique_function; + +} // namespace MQTT_NS + +#endif // MQTT_MOVE_ONLY_FUNCTION_HPP diff --git a/include/mqtt/null_strand.hpp b/include/mqtt/null_strand.hpp index a9f56b0c..f14fe124 100644 --- a/include/mqtt/null_strand.hpp +++ b/include/mqtt/null_strand.hpp @@ -17,9 +17,77 @@ namespace MQTT_NS { namespace as = boost::asio; -// Using standard executor style null_strand / simple executor -using null_strand = as::io_context::executor_type; +namespace detail { + +struct null_strand { + using inner_executor_type = as::io_context::executor_type; + template + explicit null_strand(Executor e) noexcept + : exe_{force_move(e)} + {} + + template + void defer(Func&& f, Allocator) const { + as::defer( + exe_, + [f = std::forward(f)] () mutable { + std::move(f)(); + } + ); + } + template + void dispatch(Func&& f, Allocator) const { + as::dispatch( + exe_, + [f = std::forward(f)] () mutable { + std::move(f)(); + } + ); + } + template + void post(Func&& f, Allocator) const { + as::post( + exe_, + [f = std::forward(f)] () mutable { + std::move(f)(); + } + ); + } + as::any_io_executor get_inner_executor() const { + return exe_; + } + void on_work_started() const noexcept {} + void on_work_finished() const noexcept {} + bool running_in_this_thread() const noexcept { return true; } + operator as::any_io_executor() const { + return exe_; + } +private: + as::io_context::executor_type exe_; +}; + +} // namespace detail + +using null_strand = detail::null_strand; + +inline bool operator==(null_strand const& lhs, null_strand const& rhs) { + return std::addressof(lhs) == std::addressof(rhs); +} + +inline bool operator!=(null_strand const& lhs, null_strand const& rhs) { + return !(lhs == rhs); +} } // namespace MQTT_NS +namespace boost { +namespace asio { + +template<> +struct is_executor : std::true_type { +}; + +} // namespace asio +} // namespace boost + #endif // MQTT_NULL_STRAND_HPP diff --git a/include/mqtt/server.hpp b/include/mqtt/server.hpp index 1cdc6b99..1e8c85fd 100644 --- a/include/mqtt/server.hpp +++ b/include/mqtt/server.hpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace MQTT_NS { @@ -53,7 +54,7 @@ class server { * After this handler called, the next accept will automatically start. * @param ep endpoint of the connecting client */ - using accept_handler = std::function ep)>; + using accept_handler = move_only_function ep)>; /** * @brief Error handler during after accepted before connection established @@ -61,7 +62,7 @@ class server { * @param ec error code * @param ioc_con io_context for incoming connection */ - using connection_error_handler = std::function; + using connection_error_handler = move_only_function; /** * @brief Error handler for listen and accpet @@ -69,7 +70,7 @@ class server { * You need to call listen() again if you want to restart accepting. * @param ec error code */ - using error_handler = std::function; + using error_handler = move_only_function; /** * @brief Error handler for listen and accpet @@ -78,7 +79,7 @@ class server { * @param ec error code * @param ioc_con io_context for listen or accept */ - using error_handler_with_ioc = std::function; + using error_handler_with_ioc = move_only_function; template server( @@ -119,7 +120,7 @@ class server { server( AsioEndpoint&& ep, as::io_context& ioc_accept, - std::function ioc_con_getter, + move_only_function ioc_con_getter, AcceptorConfig&& config = [](as::ip::tcp::acceptor&) {}) : ep_(std::forward(ep)), ioc_accept_(ioc_accept), @@ -173,7 +174,7 @@ class server { void set_error_handler(error_handler h) { h_error_ = [h = force_move(h)] - (error_code ec, as::io_context&) { + (error_code ec, as::io_context&) mutable { if (h) h(ec); }; } @@ -230,9 +231,9 @@ class server { as::ip::tcp::endpoint ep_; as::io_context& ioc_accept_; as::io_context* ioc_con_ = nullptr; - std::function ioc_con_getter_; + move_only_function ioc_con_getter_; optional acceptor_; - std::function config_; + move_only_function config_; bool close_request_{false}; accept_handler h_accept_; connection_error_handler h_connection_error_; @@ -258,7 +259,7 @@ class server_tls { * After this handler called, the next accept will automatically start. * @param ep endpoint of the connecting client */ - using accept_handler = std::function ep)>; + using accept_handler = move_only_function ep)>; /** * @brief Error handler during after accepted before connection established @@ -266,7 +267,7 @@ class server_tls { * @param ec error code * @param ioc_con io_context for incoming connection */ - using connection_error_handler = std::function; + using connection_error_handler = move_only_function; /** * @brief Error handler for listen and accpet @@ -274,7 +275,7 @@ class server_tls { * You need to call listen() again if you want to restart accepting. * @param ec error code */ - using error_handler = std::function; + using error_handler = move_only_function; /** * @brief Error handler for listen and accpet @@ -283,7 +284,7 @@ class server_tls { * @param ec error code * @param ioc_con io_context for listen or accept */ - using error_handler_with_ioc = std::function; + using error_handler_with_ioc = move_only_function; template server_tls( @@ -330,7 +331,7 @@ class server_tls { AsioEndpoint&& ep, tls::context&& ctx, as::io_context& ioc_accept, - std::function ioc_con_getter, + move_only_function ioc_con_getter, AcceptorConfig&& config = [](as::ip::tcp::acceptor&) {}) : ep_(std::forward(ep)), ioc_accept_(ioc_accept), @@ -385,7 +386,7 @@ class server_tls { void set_error_handler(error_handler h) { h_error_ = [h = force_move(h)] - (error_code ec, as::io_context&) { + (error_code ec, as::io_context&) mutable { if (h) h(ec); }; } @@ -445,10 +446,10 @@ class server_tls { return ctx_; } - using verify_cb_t = std::function> const&) >; + using verify_cb_t = move_only_function> const&) >; void set_verify_callback(verify_cb_t verify_cb) { - verify_cb_with_username_ = verify_cb; + verify_cb_with_username_ = force_move(verify_cb); } private: @@ -551,9 +552,9 @@ class server_tls { as::ip::tcp::endpoint ep_; as::io_context& ioc_accept_; as::io_context* ioc_con_ = nullptr; - std::function ioc_con_getter_; + move_only_function ioc_con_getter_; optional acceptor_; - std::function config_; + move_only_function config_; bool close_request_{false}; accept_handler h_accept_; connection_error_handler h_connection_error_; @@ -582,7 +583,7 @@ class server_ws { * @brief Accept handler * @param ep endpoint of the connecting client */ - using accept_handler = std::function ep)>; + using accept_handler = move_only_function ep)>; /** * @brief Error handler during after accepted before connection established @@ -590,7 +591,7 @@ class server_ws { * @param ec error code * @param ioc_con io_context for incoming connection */ - using connection_error_handler = std::function; + using connection_error_handler = move_only_function; /** * @brief Error handler for listen and accpet @@ -598,7 +599,7 @@ class server_ws { * You need to call listen() again if you want to restart accepting. * @param ec error code */ - using error_handler = std::function; + using error_handler = move_only_function; /** * @brief Error handler for listen and accpet @@ -607,7 +608,7 @@ class server_ws { * @param ec error code * @param ioc_con io_context for listen or accept */ - using error_handler_with_ioc = std::function; + using error_handler_with_ioc = move_only_function; template server_ws( @@ -648,7 +649,7 @@ class server_ws { server_ws( AsioEndpoint&& ep, as::io_context& ioc_accept, - std::function ioc_con_getter, + move_only_function ioc_con_getter, AcceptorConfig&& config = [](as::ip::tcp::acceptor&) {}) : ep_(std::forward(ep)), ioc_accept_(ioc_accept), @@ -701,7 +702,7 @@ class server_ws { void set_error_handler(error_handler h) { h_error_ = [h = force_move(h)] - (error_code ec, as::io_context&) { + (error_code ec, as::io_context&) mutable { if (h) h(ec); }; } @@ -917,9 +918,9 @@ class server_ws { as::ip::tcp::endpoint ep_; as::io_context& ioc_accept_; as::io_context* ioc_con_ = nullptr; - std::function ioc_con_getter_; + move_only_function ioc_con_getter_; optional acceptor_; - std::function config_; + move_only_function config_; bool close_request_{false}; accept_handler h_accept_; connection_error_handler h_connection_error_; @@ -946,7 +947,7 @@ class server_tls_ws { * @brief Accept handler * @param ep endpoint of the connecting client */ - using accept_handler = std::function ep)>; + using accept_handler = move_only_function ep)>; /** * @brief Error handler during after accepted before connection established @@ -954,7 +955,7 @@ class server_tls_ws { * @param ec error code * @param ioc_con io_context for incoming connection */ - using connection_error_handler = std::function; + using connection_error_handler = move_only_function; /** * @brief Error handler for listen and accpet @@ -962,7 +963,7 @@ class server_tls_ws { * You need to call listen() again if you want to restart accepting. * @param ec error code */ - using error_handler = std::function; + using error_handler = move_only_function; /** * @brief Error handler for listen and accpet @@ -971,7 +972,7 @@ class server_tls_ws { * @param ec error code * @param ioc_con io_context for listen or accept */ - using error_handler_with_ioc = std::function; + using error_handler_with_ioc = move_only_function; template server_tls_ws( @@ -1018,7 +1019,7 @@ class server_tls_ws { AsioEndpoint&& ep, tls::context&& ctx, as::io_context& ioc_accept, - std::function ioc_con_getter, + move_only_function ioc_con_getter, AcceptorConfig&& config = [](as::ip::tcp::acceptor&) {}) : ep_(std::forward(ep)), ioc_accept_(ioc_accept), @@ -1073,7 +1074,7 @@ class server_tls_ws { void set_error_handler(error_handler h) { h_error_ = [h = force_move(h)] - (error_code ec, as::io_context&) { + (error_code ec, as::io_context&) mutable { if (h) h(ec); }; } @@ -1133,10 +1134,10 @@ class server_tls_ws { return ctx_; } - using verify_cb_t = std::function> const&) >; + using verify_cb_t = move_only_function> const&) >; void set_verify_callback(verify_cb_t verify_cb) { - verify_cb_with_username_ = verify_cb; + verify_cb_with_username_ = force_move(verify_cb); } private: @@ -1361,9 +1362,9 @@ class server_tls_ws { as::ip::tcp::endpoint ep_; as::io_context& ioc_accept_; as::io_context* ioc_con_ = nullptr; - std::function ioc_con_getter_; + move_only_function ioc_con_getter_; optional acceptor_; - std::function config_; + move_only_function config_; bool close_request_{false}; accept_handler h_accept_; connection_error_handler h_connection_error_; diff --git a/include/mqtt/store.hpp b/include/mqtt/store.hpp index 717ad4f4..3fa0cdcc 100644 --- a/include/mqtt/store.hpp +++ b/include/mqtt/store.hpp @@ -18,6 +18,7 @@ #include #include #include +#include namespace MQTT_NS { @@ -84,10 +85,10 @@ class store { } void for_each( - std::function< + move_only_function< // if return true, then erase element bool(basic_store_message_variant const&, any const&) - > const& f + > f ) { auto& idx = elems_.template get(); auto it = idx.begin(); diff --git a/include/mqtt/strand.hpp b/include/mqtt/strand.hpp index fa83f45d..0b0e29e7 100644 --- a/include/mqtt/strand.hpp +++ b/include/mqtt/strand.hpp @@ -18,6 +18,6 @@ namespace as = boost::asio; using strand = as::strand; -} +} // namespace MQTT_NS #endif // MQTT_STRAND_HPP diff --git a/include/mqtt/tcp_endpoint.hpp b/include/mqtt/tcp_endpoint.hpp index 295ea310..295294d7 100644 --- a/include/mqtt/tcp_endpoint.hpp +++ b/include/mqtt/tcp_endpoint.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include namespace MQTT_NS { @@ -32,7 +33,7 @@ class tcp_endpoint : public socket { MQTT_ALWAYS_INLINE void async_read( as::mutable_buffer buffers, - std::function handler + move_only_function handler ) override final { as::async_read( tcp_, @@ -46,7 +47,7 @@ class tcp_endpoint : public socket { MQTT_ALWAYS_INLINE void async_write( std::vector buffers, - std::function handler + move_only_function handler ) override final { as::async_write( tcp_, @@ -65,21 +66,21 @@ class tcp_endpoint : public socket { return as::write(tcp_,force_move(buffers), ec); } - MQTT_ALWAYS_INLINE void post(std::function handler) override final { + MQTT_ALWAYS_INLINE void post(move_only_function handler) override final { as::post( strand_, force_move(handler) ); } - MQTT_ALWAYS_INLINE void dispatch(std::function handler) override final { + MQTT_ALWAYS_INLINE void dispatch(move_only_function handler) override final { as::dispatch( strand_, force_move(handler) ); } - MQTT_ALWAYS_INLINE void defer(std::function handler) override final { + MQTT_ALWAYS_INLINE void defer(move_only_function handler) override final { as::defer( strand_, force_move(handler) @@ -102,7 +103,7 @@ class tcp_endpoint : public socket { shutdown_and_close_impl(tcp_, ec); } - MQTT_ALWAYS_INLINE void async_clean_shutdown_and_close(std::function handler) override final { + MQTT_ALWAYS_INLINE void async_clean_shutdown_and_close(move_only_function handler) override final { async_shutdown_and_close_impl(tcp_, force_move(handler)); } @@ -156,7 +157,7 @@ class tcp_endpoint : public socket { << ec.message(); } - void async_shutdown_and_close_impl(as::basic_socket& s, std::function handler) { + void async_shutdown_and_close_impl(as::basic_socket& s, move_only_function handler) { post( [this, &s, handler = force_move(handler)] () mutable { error_code ec; @@ -175,7 +176,7 @@ class tcp_endpoint : public socket { << ec.message(); shutdown_and_close_impl(lowest_layer(), ec); } - void async_shutdown_and_close_impl(tls::stream& s, std::function handler) { + void async_shutdown_and_close_impl(tls::stream& s, move_only_function handler) { s.async_shutdown( as::bind_executor( strand_, diff --git a/include/mqtt/type_erased_socket.hpp b/include/mqtt/type_erased_socket.hpp index dffd2922..4041311d 100644 --- a/include/mqtt/type_erased_socket.hpp +++ b/include/mqtt/type_erased_socket.hpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace MQTT_NS { @@ -22,17 +23,17 @@ namespace as = boost::asio; class socket { public: virtual ~socket() = default; - virtual void async_read(as::mutable_buffer, std::function) = 0; - virtual void async_write(std::vector, std::function) = 0; + virtual void async_read(as::mutable_buffer, move_only_function) = 0; + virtual void async_write(std::vector, move_only_function) = 0; virtual std::size_t write(std::vector, boost::system::error_code&) = 0; - virtual void post(std::function) = 0; - virtual void dispatch(std::function) = 0; - virtual void defer(std::function) = 0; + virtual void post(move_only_function) = 0; + virtual void dispatch(move_only_function) = 0; + virtual void defer(move_only_function) = 0; virtual bool running_in_this_thread() const = 0; virtual as::ip::tcp::socket::lowest_layer_type& lowest_layer() = 0; virtual any native_handle() = 0; virtual void clean_shutdown_and_close(boost::system::error_code&) = 0; - virtual void async_clean_shutdown_and_close(std::function) = 0; + virtual void async_clean_shutdown_and_close(move_only_function) = 0; virtual void force_shutdown_and_close(boost::system::error_code&) = 0; virtual as::any_io_executor get_executor() = 0; }; diff --git a/include/mqtt/ws_endpoint.hpp b/include/mqtt/ws_endpoint.hpp index 7b5025de..9d784ea8 100644 --- a/include/mqtt/ws_endpoint.hpp +++ b/include/mqtt/ws_endpoint.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #include namespace MQTT_NS { @@ -44,12 +45,12 @@ class ws_endpoint : public socket { MQTT_ALWAYS_INLINE void async_read( as::mutable_buffer buffers, - std::function handler + move_only_function handler ) override final { auto req_size = as::buffer_size(buffers); using beast_read_handler_t = - std::function)>; + move_only_function)>; std::shared_ptr beast_read_handler; if (req_size <= buffer_.size()) { @@ -107,7 +108,7 @@ class ws_endpoint : public socket { MQTT_ALWAYS_INLINE void async_write( std::vector buffers, - std::function handler + move_only_function handler ) override final { ws_.async_write( buffers, @@ -126,21 +127,21 @@ class ws_endpoint : public socket { return as::buffer_size(buffers); } - MQTT_ALWAYS_INLINE void post(std::function handler) override final { + MQTT_ALWAYS_INLINE void post(move_only_function handler) override final { as::post( strand_, force_move(handler) ); } - MQTT_ALWAYS_INLINE void dispatch(std::function handler) override final { + MQTT_ALWAYS_INLINE void dispatch(move_only_function handler) override final { as::dispatch( strand_, force_move(handler) ); } - MQTT_ALWAYS_INLINE void defer(std::function handler) override final { + MQTT_ALWAYS_INLINE void defer(move_only_function handler) override final { as::defer( strand_, force_move(handler) @@ -187,7 +188,7 @@ class ws_endpoint : public socket { shutdown_and_close_impl(next_layer(), ec); } - MQTT_ALWAYS_INLINE void async_clean_shutdown_and_close(std::function handler) override final { + MQTT_ALWAYS_INLINE void async_clean_shutdown_and_close(move_only_function handler) override final { if (ws_.is_open()) { // WebSocket closing process MQTT_LOG("mqtt_impl", trace) @@ -272,7 +273,7 @@ class ws_endpoint : public socket { } private: - void async_read_until_closed(std::function handler) { + void async_read_until_closed(move_only_function handler) { auto buffer = std::make_shared(); ws_.async_read( *buffer, @@ -311,7 +312,7 @@ class ws_endpoint : public socket { << ec.message(); } - void async_shutdown_and_close_impl(as::basic_socket& s, std::function handler) { + void async_shutdown_and_close_impl(as::basic_socket& s, move_only_function handler) { post( [this, &s, handler = force_move(handler)] () mutable { error_code ec; @@ -330,7 +331,7 @@ class ws_endpoint : public socket { << ec.message(); shutdown_and_close_impl(lowest_layer(), ec); } - void async_shutdown_and_close_impl(tls::stream& s, std::function handler) { + void async_shutdown_and_close_impl(tls::stream& s, move_only_function handler) { s.async_shutdown( as::bind_executor( strand_, diff --git a/test/system/st_pubsub_no_strand.cpp b/test/system/st_pubsub_no_strand.cpp index d9795f83..500f68f4 100644 --- a/test/system/st_pubsub_no_strand.cpp +++ b/test/system/st_pubsub_no_strand.cpp @@ -78,13 +78,11 @@ BOOST_AUTO_TEST_CASE( pub_qos0_sub_qos0 ) { () { MQTT_CHK("h_close"); finish(); - return true; }); c->set_error_handler( [] (MQTT_NS::error_code) { BOOST_CHECK(false); - return true; }); c->set_puback_handler( [] diff --git a/update_external.sh b/update_external.sh new file mode 100755 index 00000000..0cf05898 --- /dev/null +++ b/update_external.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +git submodule update --init +cp external/function2/include/function2/function2.hpp include/mqtt/external/