This is an automated email from the ASF dual-hosted git repository. asf-gitbox-commits pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/qpid-proton.git
commit 490d64a25d6b526c6df2de9d8b35f42ef66a5fc6 Author: Andrew Stitcher <[email protected]> AuthorDate: Fri May 1 18:45:46 2026 -0400 PROTON-2932: [C++] Allow proton::transfer to be hashed --- cpp/include/proton/delivery.hpp | 7 +++++++ cpp/include/proton/tracker.hpp | 7 +++++++ cpp/include/proton/transfer.hpp | 15 +++++++++++++-- cpp/src/delivery.cpp | 2 +- cpp/src/tracker.cpp | 2 +- cpp/src/transfer.cpp | 2 ++ 6 files changed, 31 insertions(+), 4 deletions(-) diff --git a/cpp/include/proton/delivery.hpp b/cpp/include/proton/delivery.hpp index f60ea5438..8278c6a48 100644 --- a/cpp/include/proton/delivery.hpp +++ b/cpp/include/proton/delivery.hpp @@ -98,4 +98,11 @@ typedef internal::iter_range<delivery_iterator> delivery_range; } // proton +/// Specialize std::hash so we can use proton::delivery as a key for unordered datastructures +template <> struct std::hash<proton::delivery> { + std::size_t operator()(const proton::delivery& k) const { + return std::hash<proton::binary>{}(k.tag()); + } +}; + #endif // PROTON_DELIVERY_HPP diff --git a/cpp/include/proton/tracker.hpp b/cpp/include/proton/tracker.hpp index 0c5efef27..c8c2748c4 100644 --- a/cpp/include/proton/tracker.hpp +++ b/cpp/include/proton/tracker.hpp @@ -83,4 +83,11 @@ typedef internal::iter_range<tracker_iterator> tracker_range; } // proton +/// Specialize std::hash so we can use proton::tracker as a key for unordered datastructures +template <> struct std::hash<proton::tracker> { + std::size_t operator()(const proton::tracker& k) const { + return std::hash<proton::binary>{}(k.tag()); + } +}; + #endif // PROTON_TRACKER_HPP diff --git a/cpp/include/proton/transfer.hpp b/cpp/include/proton/transfer.hpp index cf0474a75..afbf6c5ed 100644 --- a/cpp/include/proton/transfer.hpp +++ b/cpp/include/proton/transfer.hpp @@ -22,6 +22,7 @@ * */ +#include "./binary.hpp" #include "./fwd.hpp" #include "./internal/export.hpp" #include "./internal/object.hpp" @@ -77,6 +78,9 @@ class transfer : public internal::object<pn_delivery_t> { /// Return true if the transfer has been settled. PN_CPP_EXTERN bool settled() const; + /// Return the tag for this transfer. + PN_CPP_EXTERN binary tag() const; + /// Set user data on this transfer. PN_CPP_EXTERN void user_data(void* user_data) const; @@ -88,11 +92,18 @@ class transfer : public internal::object<pn_delivery_t> { /// @endcond }; -/// Human-readalbe name of the transfer::state +/// Human-readable name of the transfer::state PN_CPP_EXTERN std::string to_string(enum transfer::state); -/// Human-readalbe name of the transfer::state +/// Human-readable name of the transfer::state PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const enum transfer::state); } // proton +/// Specialize std::hash so we can use proton::transfer as a key for unordered datastructures +template <> struct std::hash<proton::transfer> { + std::size_t operator()(const proton::transfer& k) const { + return std::hash<proton::binary>{}(k.tag()); + } +}; + #endif // PROTON_TRANSFER_HPP diff --git a/cpp/src/delivery.cpp b/cpp/src/delivery.cpp index 102eca671..72066f38f 100644 --- a/cpp/src/delivery.cpp +++ b/cpp/src/delivery.cpp @@ -57,7 +57,7 @@ namespace proton { delivery::delivery(pn_delivery_t* d): transfer(make_wrapper(d)) {} receiver delivery::receiver() const { return make_wrapper<class receiver>(pn_delivery_link(pn_object())); } -binary delivery::tag() const { return bin(pn_delivery_tag(pn_object())); } +binary delivery::tag() const { return transfer::tag(); } delivery::~delivery() = default; void delivery::accept() { settle_delivery(pn_object(), ACCEPTED); } void delivery::reject() { settle_delivery(pn_object(), REJECTED); } diff --git a/cpp/src/tracker.cpp b/cpp/src/tracker.cpp index 3f4db11aa..30f06a242 100644 --- a/cpp/src/tracker.cpp +++ b/cpp/src/tracker.cpp @@ -34,7 +34,7 @@ namespace proton { tracker::tracker(pn_delivery_t *d): transfer(make_wrapper(d)) {} sender tracker::sender() const { return make_wrapper<class sender>(pn_delivery_link(pn_object())); } -binary tracker::tag() const { return bin(pn_delivery_tag(pn_object())); } +binary tracker::tag() const { return transfer::tag(); } tracker_iterator tracker_iterator::operator++() { if (!!obj_) { diff --git a/cpp/src/transfer.cpp b/cpp/src/transfer.cpp index 5fdf34ecd..c3a0ff829 100644 --- a/cpp/src/transfer.cpp +++ b/cpp/src/transfer.cpp @@ -29,6 +29,7 @@ #include <proton/session.h> #include "proton_bits.hpp" +#include "types_internal.hpp" #include <ostream> @@ -45,6 +46,7 @@ bool transfer::settled() const { return pn_delivery_settled(pn_object()); } void transfer::settle() { pn_delivery_settle(pn_object()); } enum transfer::state transfer::state() const { return static_cast<enum state>(pn_delivery_remote_state(pn_object())); } +binary transfer::tag() const { return bin(pn_delivery_tag(pn_object())); } std::string to_string(enum transfer::state s) { return pn_disposition_type_name(s); } std::ostream& operator<<(std::ostream& o, const enum transfer::state s) { return o << to_string(s); } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
