property_variant.hpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. // Copyright Takatoshi Kondo 2018
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #if !defined(MQTT_PROPERTY_VARIANT_HPP)
  7. #define MQTT_PROPERTY_VARIANT_HPP
  8. #include <vector>
  9. #include <mqtt/namespace.hpp>
  10. #include <mqtt/property.hpp>
  11. #include <mqtt/variant.hpp>
  12. #include <mqtt/visitor_util.hpp>
  13. namespace MQTT_NS {
  14. namespace v5 {
  15. // property_variant
  16. using property_variant = variant<
  17. property::payload_format_indicator,
  18. property::message_expiry_interval,
  19. property::content_type,
  20. property::response_topic,
  21. property::correlation_data,
  22. property::subscription_identifier,
  23. property::session_expiry_interval,
  24. property::assigned_client_identifier,
  25. property::server_keep_alive,
  26. property::authentication_method,
  27. property::authentication_data,
  28. property::request_problem_information,
  29. property::will_delay_interval,
  30. property::request_response_information,
  31. property::response_information,
  32. property::server_reference,
  33. property::reason_string,
  34. property::receive_maximum,
  35. property::topic_alias_maximum,
  36. property::topic_alias,
  37. property::maximum_qos,
  38. property::retain_available,
  39. property::user_property,
  40. property::maximum_packet_size,
  41. property::wildcard_subscription_available,
  42. property::subscription_identifier_available,
  43. property::shared_subscription_available
  44. >;
  45. using properties = std::vector<property_variant>;
  46. namespace property {
  47. namespace detail {
  48. struct add_const_buffer_sequence_visitor {
  49. add_const_buffer_sequence_visitor(std::vector<as::const_buffer>& v):v(v) {}
  50. template <typename T>
  51. void operator()(T&& t) const {
  52. t.add_const_buffer_sequence(v);
  53. }
  54. std::vector<as::const_buffer>& v;
  55. };
  56. struct id_visitor {
  57. template <typename T>
  58. id operator()(T const& t) const {
  59. return t.id();
  60. }
  61. };
  62. struct size_visitor {
  63. template <typename T>
  64. std::size_t operator()(T&& t) const {
  65. return t.size();
  66. }
  67. };
  68. struct num_of_const_buffer_sequence_visitor {
  69. template <typename T>
  70. std::size_t operator()(T&& t) const {
  71. return t.num_of_const_buffer_sequence();
  72. }
  73. };
  74. template <typename Iterator>
  75. struct fill_visitor {
  76. fill_visitor(Iterator b, Iterator e):b(b), e(e) {}
  77. template <typename T>
  78. void operator()(T&& t) const {
  79. t.fill(b, e);
  80. }
  81. Iterator b;
  82. Iterator e;
  83. };
  84. template <typename Iterator>
  85. inline fill_visitor<Iterator> make_fill_visitor(Iterator b, Iterator e) {
  86. return fill_visitor<Iterator>(b, e);
  87. }
  88. } // namespace detail
  89. } // namespace property
  90. inline void add_const_buffer_sequence(std::vector<as::const_buffer>& v, property_variant const& pv) {
  91. MQTT_NS::visit(property::detail::add_const_buffer_sequence_visitor(v), pv);
  92. }
  93. inline property::id id(property_variant const& pv) {
  94. return MQTT_NS::visit(property::detail::id_visitor(), pv);
  95. }
  96. inline std::size_t size(property_variant const& pv) {
  97. return MQTT_NS::visit(property::detail::size_visitor(), pv);
  98. }
  99. inline std::size_t num_of_const_buffer_sequence(property_variant const& pv) {
  100. return MQTT_NS::visit(property::detail::num_of_const_buffer_sequence_visitor(), pv);
  101. }
  102. template <typename Iterator>
  103. inline void fill(property_variant const& pv, Iterator b, Iterator e) {
  104. auto vis = property::detail::make_fill_visitor(b, e);
  105. MQTT_NS::visit(vis, pv);
  106. }
  107. struct less_than_visitor {
  108. template <typename T>
  109. bool operator()(T const& lhs, T const& rhs) const {
  110. return lhs < rhs;
  111. }
  112. template <typename T, typename U>
  113. bool operator()(T const& lhs, U const& rhs) const {
  114. return lhs.id() < rhs.id();
  115. }
  116. };
  117. template <typename PropertyVariant>
  118. inline
  119. std::enable_if_t<
  120. std::is_same<PropertyVariant, property_variant>::value,
  121. bool
  122. >
  123. operator<(PropertyVariant const& lhs, PropertyVariant const& rhs) {
  124. return MQTT_NS::visit(
  125. less_than_visitor(),
  126. lhs,
  127. rhs
  128. );
  129. }
  130. struct equal_visitor {
  131. template <typename T>
  132. bool operator()(T const& lhs, T const& rhs) const {
  133. return lhs == rhs;
  134. }
  135. template <typename T, typename U>
  136. bool operator()(T const&, U const&) const {
  137. return false;
  138. }
  139. };
  140. template <typename PropertyVariant>
  141. inline
  142. std::enable_if_t<
  143. std::is_same<PropertyVariant, property_variant>::value,
  144. bool
  145. >
  146. operator==(PropertyVariant const& lhs, PropertyVariant const& rhs) {
  147. return MQTT_NS::visit(
  148. equal_visitor(),
  149. lhs,
  150. rhs
  151. );
  152. }
  153. template <typename PropertyVariant>
  154. inline
  155. std::enable_if_t<
  156. std::is_same<PropertyVariant, property_variant>::value,
  157. bool
  158. >
  159. operator!=(PropertyVariant const& lhs, PropertyVariant const& rhs) {
  160. return !MQTT_NS::visit(
  161. equal_visitor(),
  162. lhs,
  163. rhs
  164. );
  165. }
  166. template <typename... Visitors>
  167. inline
  168. void
  169. visit_prop(property_variant const& prop, Visitors&&... visitors) {
  170. MQTT_NS::visit(
  171. make_lambda_visitor(std::forward<Visitors>(visitors)...), prop
  172. );
  173. }
  174. template <typename... Visitors>
  175. inline
  176. void
  177. visit_props(properties const& props, Visitors&&... visitors) {
  178. for (auto const& prop : props) {
  179. visit_prop(
  180. prop,
  181. std::forward<Visitors>(visitors)...
  182. );
  183. }
  184. }
  185. template <typename... Visitors>
  186. inline
  187. void
  188. visit_prop(property_variant&& prop, Visitors&&... visitors) {
  189. MQTT_NS::visit(
  190. make_lambda_visitor(std::forward<Visitors>(visitors)...), force_move(prop)
  191. );
  192. }
  193. template <typename... Visitors>
  194. inline
  195. void
  196. visit_props(properties&& props, Visitors&&... visitors) {
  197. for (auto&& prop : force_move(props)) {
  198. visit_prop(
  199. force_move(prop),
  200. std::forward<Visitors>(visitors)...
  201. );
  202. }
  203. }
  204. } // namespace v5
  205. } // namespace MQTT_NS
  206. #endif // MQTT_PROPERTY_VARIANT_HPP