diff --git a/doc/Jamfile b/doc/Jamfile index 67f2e04..f8eb1ef 100644 --- a/doc/Jamfile +++ b/doc/Jamfile @@ -19,6 +19,7 @@ include-prefix = [ path.native $(include-prefix:D)/include ] ; local doxygen_include = error.hpp logger.hpp + property_types.hpp reason_codes.hpp types.hpp mqtt_client.hpp diff --git a/doc/qbk/reference/properties/auth_props.qbk b/doc/qbk/reference/properties/auth_props.qbk index 46de899..f418f82 100644 --- a/doc/qbk/reference/properties/auth_props.qbk +++ b/doc/qbk/reference/properties/auth_props.qbk @@ -9,7 +9,8 @@ The last field in the Variable header of __AUTH__ packet is a set of Properties. A set contains a Property Length followed by the Properties. A Property consists of an Identifier and a value. -This section lists all possible __AUTH__ Properties and describes their usage: +This class extends [reflink2 prop__properties prop::properties], which provides common functionalities for all property classes. +Below is a list of possible __AUTH__ Properties, along with descriptions of their usage: [table:auth_props AUTH properties [[Identifier] [Value type] [Description]] diff --git a/doc/qbk/reference/properties/connack_props.qbk b/doc/qbk/reference/properties/connack_props.qbk index 4211358..6734928 100644 --- a/doc/qbk/reference/properties/connack_props.qbk +++ b/doc/qbk/reference/properties/connack_props.qbk @@ -9,7 +9,8 @@ The last field in the Variable header of __CONNACK__ packet is a set of Properti A set contains a Property Length followed by the Properties. A Property consists of an Identifier and a value. -This section lists all possible __CONNACK__ Properties and describes their usage: +This class extends [reflink2 prop__properties prop::properties], which provides common functionalities for all property classes. +Below is a list of possible __CONNACK__ Properties, along with descriptions of their usage: [table:connack_props CONNACK properties [[Identifier] [Value type] [Description]] diff --git a/doc/qbk/reference/properties/connect_props.qbk b/doc/qbk/reference/properties/connect_props.qbk index aa4cb3c..76df641 100644 --- a/doc/qbk/reference/properties/connect_props.qbk +++ b/doc/qbk/reference/properties/connect_props.qbk @@ -9,7 +9,8 @@ The last field in the Variable header of __CONNECT__ packet is a set of Properti A set contains a Property Length followed by the Properties. A Property consists of an Identifier and a value. -This section lists all possible __CONNECT__ Properties and describes their usage: +This class extends [reflink2 prop__properties prop::properties], which provides common functionalities for all property classes. +Below is a list of possible __CONNECT__ Properties, along with descriptions of their usage: [table:connect_props CONNECT properties [[Identifier] [Value type] [Description]] diff --git a/doc/qbk/reference/properties/disconnect_props.qbk b/doc/qbk/reference/properties/disconnect_props.qbk index 99f5614..9e31fbe 100644 --- a/doc/qbk/reference/properties/disconnect_props.qbk +++ b/doc/qbk/reference/properties/disconnect_props.qbk @@ -9,7 +9,8 @@ The last field in the Variable header of __DISCONNECT__ packet is a set of Prope A set contains a Property Length followed by the Properties. A Property consists of an Identifier and a value. -This section lists all possible __DISCONNECT__ Properties and describes their usage: +This class extends [reflink2 prop__properties prop::properties], which provides common functionalities for all property classes. +Below is a list of possible __DISCONNECT__ Properties, along with descriptions of their usage: [table:disconnect_props DISCONNECT properties [[Identifier] [Value type] [Description]] diff --git a/doc/qbk/reference/properties/puback_props.qbk b/doc/qbk/reference/properties/puback_props.qbk index c4af7a0..d58a6ba 100644 --- a/doc/qbk/reference/properties/puback_props.qbk +++ b/doc/qbk/reference/properties/puback_props.qbk @@ -9,7 +9,8 @@ The last field in the Variable header of __PUBACK__ packet is a set of Propertie A set contains a Property Length followed by the Properties. A Property consists of an Identifier and a value. -This section lists all possible __PUBACK__ Properties and describes their usage: +This class extends [reflink2 prop__properties prop::properties], which provides common functionalities for all property classes. +Below is a list of possible __PUBACK__ Properties, along with descriptions of their usage: [table:puback_props PUBACK properties [[Identifier] [Value type] [Description]] diff --git a/doc/qbk/reference/properties/pubcomp_props.qbk b/doc/qbk/reference/properties/pubcomp_props.qbk index a3d88c0..1ae7f89 100644 --- a/doc/qbk/reference/properties/pubcomp_props.qbk +++ b/doc/qbk/reference/properties/pubcomp_props.qbk @@ -9,7 +9,8 @@ The last field in the Variable header of __PUBCOMP__ packet is a set of Properti A set contains a Property Length followed by the Properties. A Property consists of an Identifier and a value. -This section lists all possible __PUBCOMP__ Properties and describes their usage: +This class extends [reflink2 prop__properties prop::properties], which provides common functionalities for all property classes. +Below is a list of possible __PUBCOMP__ Properties, along with descriptions of their usage: [table:pubcomp_props PUBCOMP properties [[Identifier] [Value type] [Description]] diff --git a/doc/qbk/reference/properties/publish_props.qbk b/doc/qbk/reference/properties/publish_props.qbk index 347f74c..9320703 100644 --- a/doc/qbk/reference/properties/publish_props.qbk +++ b/doc/qbk/reference/properties/publish_props.qbk @@ -9,7 +9,8 @@ The last field in the Variable header of __PUBLISH__ packet is a set of Properti A set contains a Property Length followed by the Properties. A Property consists of an Identifier and a value. -This section lists all possible __PUBLISH__ Properties and describes their usage: +This class extends [reflink2 prop__properties prop::properties], which provides common functionalities for all property classes. +Below is a list of possible __PUBLISH__ Properties, along with descriptions of their usage: [table:publish_props PUBLISH properties [[Identifier] [Value type] [Description]] @@ -31,8 +32,8 @@ The Identifiers listed in the table above are available within the `boost::mqtt5 [note When accessing a property value, the subscript operator will return a `std::optional` of the value type for all properties, except for `boost::mqtt5::prop::user_property` and `boost::mqtt5::prop::subscription_identifier`, where it will return an instance of -`std::vector>` and `boost::mqtt5::prop::subscription_identifiers` respectively. -`boost::mqtt5::prop::subscription_identifiers` has the interface of `boost::container::small_vector`.] +`std::vector>` and [reflink2 prop__subscription_identifiers prop::subscription_identifiers] respectively. +[reflink2 prop__subscription_identifiers prop::subscription_identifiers] has the interface of `boost::container::small_vector`.] [h4 Example] diff --git a/doc/qbk/reference/properties/pubrec_props.qbk b/doc/qbk/reference/properties/pubrec_props.qbk index 417d74b..405026d 100644 --- a/doc/qbk/reference/properties/pubrec_props.qbk +++ b/doc/qbk/reference/properties/pubrec_props.qbk @@ -9,7 +9,8 @@ The last field in the Variable header of __PUBREC__ packet is a set of Propertie A set contains a Property Length followed by the Properties. A Property consists of an Identifier and a value. -This section lists all possible __PUBREC__ Properties and describes their usage: +This class extends [reflink2 prop__properties prop::properties], which provides common functionalities for all property classes. +Below is a list of possible __PUBREC__ Properties, along with descriptions of their usage: [table:pubrec_props PUBREC properties [[Identifier] [Value type] [Description]] diff --git a/doc/qbk/reference/properties/pubrel_props.qbk b/doc/qbk/reference/properties/pubrel_props.qbk index 146024d..367f2c9 100644 --- a/doc/qbk/reference/properties/pubrel_props.qbk +++ b/doc/qbk/reference/properties/pubrel_props.qbk @@ -9,7 +9,8 @@ The last field in the Variable header of __PUBREL__ packet is a set of Propertie A set contains a Property Length followed by the Properties. A Property consists of an Identifier and a value. -This section lists all possible __PUBREL__ Properties and describes their usage: +This class extends [reflink2 prop__properties prop::properties], which provides common functionalities for all property classes. +Below is a list of possible __PUBREL__ Properties, along with descriptions of their usage: [table:pubrel_props PUBREL properties [[Identifier] [Value type] [Description]] diff --git a/doc/qbk/reference/properties/suback_props.qbk b/doc/qbk/reference/properties/suback_props.qbk index b62e042..ba87c86 100644 --- a/doc/qbk/reference/properties/suback_props.qbk +++ b/doc/qbk/reference/properties/suback_props.qbk @@ -9,7 +9,8 @@ The last field in the Variable header of __SUBACK__ packet is a set of Propertie A set contains a Property Length followed by the Properties. A Property consists of an Identifier and a value. -This section lists all possible __SUBACK__ Properties and describes their usage: +This class extends [reflink2 prop__properties prop::properties], which provides common functionalities for all property classes. +Below is a list of possible __SUBACK__ Properties, along with descriptions of their usage: [table:suback_props SUBACK properties [[Identifier] [Value type] [Description]] diff --git a/doc/qbk/reference/properties/subscribe_props.qbk b/doc/qbk/reference/properties/subscribe_props.qbk index f5ae8cf..c0654ef 100644 --- a/doc/qbk/reference/properties/subscribe_props.qbk +++ b/doc/qbk/reference/properties/subscribe_props.qbk @@ -9,7 +9,8 @@ The last field in the Variable header of __SUBSCRIBE__ packet is a set of Proper A set contains a Property Length followed by the Properties. A Property consists of an Identifier and a value. -This section lists all possible __SUBSCRIBE__ Properties and describes their usage: +This class extends [reflink2 prop__properties prop::properties], which provides common functionalities for all property classes. +Below is a list of possible __SUBSCRIBE__ Properties, along with descriptions of their usage: [table:subscribe_props SUBSCRIBE properties [[Identifier] [Value type] [Description]] @@ -26,8 +27,8 @@ The Identifiers listed in the table above are available within the `boost::mqtt5 [note When accessing a property value, the subscript operator will return a `std::optional` of the value type for all properties, except for `boost::mqtt5::prop::user_property` and `boost::mqtt5::prop::subscription_identifier`, where it will return an instance of -`std::vector>` and `boost::mqtt5::prop::subscription_identifiers` respectively. -`boost::mqtt5::prop::subscription_identifiers` has the interface of `std::optional`.] +`std::vector>` and [reflink2 prop__subscription_identifiers prop::subscription_identifiers] respectively. +[reflink2 prop__subscription_identifiers prop::subscription_identifiers] has the interface of `std::optional`.] [h4 Example] diff --git a/doc/qbk/reference/properties/unsuback_props.qbk b/doc/qbk/reference/properties/unsuback_props.qbk index 9397512..028ab34 100644 --- a/doc/qbk/reference/properties/unsuback_props.qbk +++ b/doc/qbk/reference/properties/unsuback_props.qbk @@ -9,7 +9,8 @@ The last field in the Variable header of __UNSUBACK__ packet is a set of Propert A set contains a Property Length followed by the Properties. A Property consists of an Identifier and a value. -This section lists all possible __UNSUBACK__ Properties and describes their usage: +This class extends [reflink2 prop__properties prop::properties], which provides common functionalities for all property classes. +Below is a list of possible __UNSUBACK__ Properties, along with descriptions of their usage: [table:unsuback_props UNSUBACK properties [[Identifier] [Value type] [Description]] diff --git a/doc/qbk/reference/properties/unsubscribe_props.qbk b/doc/qbk/reference/properties/unsubscribe_props.qbk index b224dc0..ad3a316 100644 --- a/doc/qbk/reference/properties/unsubscribe_props.qbk +++ b/doc/qbk/reference/properties/unsubscribe_props.qbk @@ -9,7 +9,8 @@ The last field in the Variable header of __UNSUBSCRIBE__ packet is a set of Prop A set contains a Property Length followed by the Properties. A Property consists of an Identifier and a value. -This section lists all possible __UNSUBSCRIBE__ Properties and describes their usage: +This class extends [reflink2 prop__properties prop::properties], which provides common functionalities for all property classes. +Below is a list of possible __UNSUBSCRIBE__ Properties, along with descriptions of their usage: [table:unsubscribe_props UNSUBSCRIBE properties [[Identifier] [Value type] [Description]] diff --git a/doc/qbk/reference/properties/will_props.qbk b/doc/qbk/reference/properties/will_props.qbk index bc92185..5633b6a 100644 --- a/doc/qbk/reference/properties/will_props.qbk +++ b/doc/qbk/reference/properties/will_props.qbk @@ -10,7 +10,8 @@ and the Application Message properties to be sent with the [reflink2 will Will] The Will Properties consists of a Property Length and the Properties. A Property consists of an Identifier and a value. -This section lists all possible [reflink2 will Will] Properties and describes their usage: +This class extends [reflink2 prop__properties prop::properties], which provides common functionalities for all property classes. +Below is a list of possible [reflink2 will Will] Properties, along with descriptions of their usage: [table:will_props Will properties [[Identifier] [Value type] [Description]] diff --git a/doc/qbk/reference/quickref.xml b/doc/qbk/reference/quickref.xml index 9b0ba58..f33e92e 100644 --- a/doc/qbk/reference/quickref.xml +++ b/doc/qbk/reference/quickref.xml @@ -20,6 +20,8 @@ subscribe_options subscribe_topic will + subscription_identifiers + properties Concepts diff --git a/include/boost/mqtt5/mqtt_client.hpp b/include/boost/mqtt5/mqtt_client.hpp index be51ec9..df3b133 100644 --- a/include/boost/mqtt5/mqtt_client.hpp +++ b/include/boost/mqtt5/mqtt_client.hpp @@ -522,10 +522,10 @@ public: } /** - * \brief Send a \__SUBSCRIBE\__ packet to Broker to create a subscription + * \brief Send a \__SUBSCRIBE\__ packet to Broker to create a Subscription * to one or more Topics of interest. * - * \details After the subscription has been established, the Broker will send + * \details After the Subscription has been established, the Broker will send * PUBLISH packets to the Client to forward Application Messages that were published * to Topics that the Client subscribed to. The Application Messages can be received * with \ref mqtt_client::async_receive function. @@ -543,7 +543,7 @@ public: * void ( * __ERROR_CODE__, // Result of operation. * std::vector<__REASON_CODE__>, // Vector of Reason Codes indicating - * // the subscription result for each Topic + * // the Subscription result for each Topic * // in the SUBSCRIBE packet. * __SUBACK_PROPS__, // Properties received in the SUBACK packet. * ) @@ -595,10 +595,10 @@ public: } /** - * \brief Send a \__SUBSCRIBE\__ packet to Broker to create a subscription + * \brief Send a \__SUBSCRIBE\__ packet to Broker to create a Subscription * to one Topic of interest. * - * \details After the subscription has been established, the Broker will send + * \details After the Subscription has been established, the Broker will send * \__PUBLISH\__ packets to the Client to forward Application Messages that were published * to Topics that the Client subscribed to. The Application Messages can be received * with \ref mqtt_client::async_receive function. @@ -616,7 +616,7 @@ public: * void ( * __ERROR_CODE__, // Result of operation. * std::vector<__REASON_CODE__>, // Vector of Reason Codes containing the - * // single subscription result for the Topic + * // single Subscription result for the Topic * // in the SUBSCRIBE packet. * __SUBACK_PROPS__, // Properties received in the SUBACK packet. * ) @@ -808,7 +808,7 @@ public: * from internal storage. * * \note It is only recommended to call this function if you have established - * a successful subscription to a Topic using the \ref async_subscribe function. + * a successful Subscription to a Topic using the \ref async_subscribe function. * * \param token Completion token that will be used to produce a * completion handler. The handler will be invoked when the operation completes. diff --git a/include/boost/mqtt5/property_types.hpp b/include/boost/mqtt5/property_types.hpp index 404167d..9741823 100644 --- a/include/boost/mqtt5/property_types.hpp +++ b/include/boost/mqtt5/property_types.hpp @@ -21,6 +21,7 @@ namespace boost::mqtt5::prop { +/// \cond internal enum property_type : uint8_t { payload_format_indicator_t = 0x01, message_expiry_interval_t = 0x02, @@ -50,7 +51,16 @@ enum property_type : uint8_t { subscription_identifier_available_t = 0x29, shared_subscription_available_t = 0x2a }; +/// \endcond +/** + * \brief A class holding any number of Subscription Identifiers. + * + * \details Subscription Identifier is an integer that can be set in \__SUBSCRIBE_PROPS\__ when subscribing to a Topic. + * Broker will store the mapping between that Subscription and the Subscription Identifier. + * When an incoming \__PUBLISH\__ message matches one or more Subscriptions, respective Subscription + * Identifiers will be forwarded in the \__PUBLISH_PROPS\__ of the received message. + */ class alignas(8) subscription_identifiers : public boost::container::small_vector { @@ -58,8 +68,11 @@ class alignas(8) subscription_identifiers : public: using base_type::base_type; + + /// Constructs Subscription Identifiers with given parameters. subscription_identifiers(int32_t val) : base_type { val } {} + /// \{ Checks whether there are any Subscription Identifiers. bool has_value() const noexcept { return !empty(); } @@ -67,7 +80,9 @@ public: explicit operator bool() const noexcept { return !empty(); } + /// \} + /// \{ Accesses the (first) Subscription Identifier. int32_t& operator*() noexcept { return front(); } @@ -75,19 +90,24 @@ public: int32_t operator*() const noexcept { return front(); } + /// \} + /// Sets or replaces the (first) Subscription Identifier. void emplace(int32_t val = 0) { *this = val; } + /// Returns the first Subscription Identifier. int32_t value() const { return front(); } + /// Returns the first Subscription Identifier if it exists, otherwise returns \p default_val int32_t value_or(int32_t default_val) const noexcept { return empty() ? default_val : front(); } + /// Clears the Subscription Identifiers. void reset() noexcept { clear(); } @@ -142,6 +162,10 @@ using value_type_t = typename property_traits

::type; template constexpr std::string_view name_v = property_traits

::name; +/** + * \brief Base class for different Property classes that contains common access + and modification functions. + */ template class properties { @@ -155,18 +179,21 @@ class properties { public: + /// \brief Accesses the value of a Property by its compile-time constant ID. template constexpr auto& operator[](std::integral_constant) noexcept { return std::get>(_props).value; } + /// \copydoc operator[] template constexpr const auto& operator[](std::integral_constant) const noexcept { return std::get>(_props).value; } +/// \cond internal template using is_apply_on = std::conjunction< std::is_invocable&>... @@ -176,7 +203,18 @@ public: using is_nothrow_apply_on = std::conjunction< std::is_nothrow_invocable&>... >; +/// \endcond + /** + * \brief Applies a function to a Property identified by its ID. + * + * This function iterates over all Properties and invokes the provided function + * on the value of the Property that matches the given property ID. + * + * \param property_id The ID of the Property to apply the function on. + * \param func The function to invoke on the Property value. + * \return `true` if the function was applied to a Property and `false` otherwise. + */ template < typename Func, std::enable_if_t::value, bool> = true @@ -190,14 +228,15 @@ public: constexpr typename ptype::key prop; if (prop.value == property_id) std::invoke(func, px.value); - return prop.value != property_id; + return prop.value == property_id; }; - return (pc(ptype) && ...); + return (pc(ptype) || ...); }, _props ); } +/// \cond internal template using is_visitor = std::conjunction< std::is_invocable_r&>... @@ -207,7 +246,20 @@ public: using is_nothrow_visitor = std::conjunction< std::is_nothrow_invocable&>... >; +/// \endcond + /** + * \brief Invokes a visitor function on each Property. + * + * This function iterates over Properties and invokes the provided function + * on each Property, passing both the compile-time constant Property ID and its value. + * The visitor function should return a boolean value that determines whether iteration continues. + * + * @param func The visitor function to invoke. It must accept two arguments: + * a Property ID and the corresponding Property value. + * @return `true` if the visitor function returns `true` for all Properties, + * `false` otherwise. + */ template < typename Func, std::enable_if_t::value, bool> = true @@ -221,12 +273,13 @@ public: constexpr typename ptype::key prop; return std::invoke(func, prop, px.value); }; - return (pc(props) &&...); + return (pc(props) && ...); }, _props ); } + /// \copydoc visit template < typename Func, std::enable_if_t::value, bool> = true diff --git a/include/boost/mqtt5/reason_codes.hpp b/include/boost/mqtt5/reason_codes.hpp index e993c75..7fa9668 100644 --- a/include/boost/mqtt5/reason_codes.hpp +++ b/include/boost/mqtt5/reason_codes.hpp @@ -48,7 +48,7 @@ class reason_code { uint8_t _code; reason_codes::category _category { reason_codes::category::none }; public: -/// \cond INTERNAL +/// \cond internal constexpr reason_code() : _code(0xff) {} constexpr reason_code(uint8_t code, reason_codes::category cat) : diff --git a/include/boost/mqtt5/types.hpp b/include/boost/mqtt5/types.hpp index ef77345..f557caf 100644 --- a/include/boost/mqtt5/types.hpp +++ b/include/boost/mqtt5/types.hpp @@ -111,7 +111,7 @@ enum class no_local_e : std::uint8_t { * \brief Representation of the Retain As Published Subscribe Option. * * \details A Subscribe Option indicating whether or not Application Messages forwarded - * using this subscription keep the \__RETAIN\__ flag they were published with. + * using this Subscription keep the \__RETAIN\__ flag they were published with. */ enum class retain_as_published_e : std::uint8_t { /** \brief Application Messages have the \__RETAIN\__ flag set to 0. */ @@ -125,13 +125,13 @@ enum class retain_as_published_e : std::uint8_t { * \brief Representation of the Retain Handling Subscribe Option. * * \details A Subscribe Option specifying whether retained messages are sent - * when the subscription is established. + * when the Subscription is established. */ enum class retain_handling_e : std::uint8_t { /** \brief Send retained messages at the time of subscribe. */ send = 0b00, - /** \brief Send retained message only if the subscription does not currently exist. */ + /** \brief Send retained message only if the Subscription does not currently exist. */ new_subscription_only = 0b01, /** \brief Do not send retained messages at the time of subscribe. */ @@ -153,7 +153,7 @@ struct subscribe_options { retain_as_published_e retain_as_published = retain_as_published_e::retain; /** \brief Option determining if retained messages are sent - when the subscription is established. */ + when the Subscription is established. */ retain_handling_e retain_handling = retain_handling_e::new_subscription_only; }; @@ -165,11 +165,11 @@ struct subscribe_topic { /** \brief An UTF-8 Encoded String indicating the Topics to which the Client wants to subscribe. */ std::string topic_filter; - /** \brief The \ref subscribe_options associated with the subscription. */ + /** \brief The \ref subscribe_options associated with the Subscription. */ subscribe_options sub_opts; }; -/// \cond +/// \cond internal class connect_props : public prop::properties< prop::session_expiry_interval_t,