NO-JIRA: c++: replace head/next pointer chasing with C++ begin(), end() ranges.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/e547d134 Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/e547d134 Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/e547d134 Branch: refs/heads/go1 Commit: e547d134e53b7ec5510b514727ae59d45ffd76e4 Parents: 4e9afbb Author: Alan Conway <acon...@redhat.com> Authored: Tue Oct 20 10:34:31 2015 -0400 Committer: Alan Conway <acon...@redhat.com> Committed: Tue Oct 20 10:34:31 2015 -0400 ---------------------------------------------------------------------- examples/cpp/broker.cpp | 5 +- .../bindings/cpp/include/proton/connection.hpp | 10 +-- .../bindings/cpp/include/proton/endpoint.hpp | 68 +++++++++++++++++++- proton-c/bindings/cpp/include/proton/link.hpp | 8 +-- .../bindings/cpp/include/proton/session.hpp | 3 + proton-c/bindings/cpp/src/connection.cpp | 9 ++- proton-c/bindings/cpp/src/endpoint.cpp | 17 ++++- proton-c/bindings/cpp/src/link.cpp | 4 +- proton-c/bindings/cpp/src/messaging_adapter.cpp | 3 +- proton-c/bindings/cpp/src/session.cpp | 10 +++ 10 files changed, 115 insertions(+), 22 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/examples/cpp/broker.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/broker.cpp b/examples/cpp/broker.cpp index c37f45c..080bc9c 100644 --- a/examples/cpp/broker.cpp +++ b/examples/cpp/broker.cpp @@ -173,12 +173,11 @@ class broker : public proton::messaging_handler { } void remove_stale_consumers(proton::connection &connection) { - proton::link *l = connection.link_head(proton::endpoint::REMOTE_ACTIVE); - while (l) { + proton::link_range r = connection.find_links(proton::endpoint::REMOTE_ACTIVE); + for (proton::link_iterator l = r.begin(); l != r.end(); ++l) { if (l->sender()) { unsubscribe(*l->sender()); } - l = l->next(proton::endpoint::REMOTE_ACTIVE); } } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/proton-c/bindings/cpp/include/proton/connection.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/connection.hpp b/proton-c/bindings/cpp/include/proton/connection.hpp index 2732802..c7ce447 100644 --- a/proton-c/bindings/cpp/include/proton/connection.hpp +++ b/proton-c/bindings/cpp/include/proton/connection.hpp @@ -66,11 +66,11 @@ class connection : public counted_facade<pn_connection_t, connection, endpoint> /** Create a receiver on default_session() with target=addr and optional handler h */ PN_CPP_EXTERN receiver& open_receiver(const std::string &addr, bool dynamic=false, handler *h=0); - /** Get the first link on this connection matching the state mask. - * Return 0 if none. Don't delete returned pointer. - * @see link::next, endpoint::state - */ - PN_CPP_EXTERN link* link_head(endpoint::state mask); + /** Return links on this connection matching the state mask. */ + PN_CPP_EXTERN link_range find_links(endpoint::state mask); + + /** Return sessions on this connection matching the state mask. */ + PN_CPP_EXTERN session_range find_sessions(endpoint::state mask); /** Get the endpoint state */ PN_CPP_EXTERN endpoint::state state(); http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/proton-c/bindings/cpp/include/proton/endpoint.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/endpoint.hpp b/proton-c/bindings/cpp/include/proton/endpoint.hpp index 51560e0..9fb5368 100644 --- a/proton-c/bindings/cpp/include/proton/endpoint.hpp +++ b/proton-c/bindings/cpp/include/proton/endpoint.hpp @@ -29,6 +29,8 @@ namespace proton { class handler; class connection; class transport; +class session; +class link; /** endpoint is a base class for session, connection and link */ class endpoint @@ -42,7 +44,7 @@ class endpoint * then a match occurs if any of the local or remote flags are set * respectively. * - * @see connection::link_head, connection::session_head, link::next, session::next + * @see connection::links, connection::sessions */ typedef int state; @@ -55,12 +57,72 @@ class endpoint PN_CPP_EXTERN static const int REMOTE_CLOSED; ///< Remote endpoint has been closed PN_CPP_EXTERN static const int LOCAL_MASK; ///< Mask including all LOCAL_ bits (UNINIT, ACTIVE, CLOSED) PN_CPP_EXTERN static const int REMOTE_MASK; ///< Mask including all REMOTE_ bits (UNINIT, ACTIVE, CLOSED) - ///@} + ///@} // TODO: condition, remote_condition, update_condition, get/handler + +}; + +///@cond INTERNAL +template <class T, class D> class iter_base { + public: + typedef T value_type; + + T& operator*() const { return *ptr_; } + T* operator->() const { return ptr_; } + operator bool() const { return ptr_; } + bool operator !() const { return !ptr_; } + iter_base<T, D>& operator++() { static_cast<D*>(this)->advance(); return *this; } + iter_base<T, D>& operator++(int) { iter_base<T, D> x(*this); ++(*this); return x; } + bool operator==(const iter_base<T, D>& x) const { return ptr_ == x.ptr_; } + bool operator!=(const iter_base<T, D>& x) const { return ptr_ != x.ptr_; } + + protected: + explicit iter_base(T* p = 0, endpoint::state s = 0) : ptr_(p), state_(s) {} + T* ptr_; + endpoint::state state_; +}; + +template<class I> class range { + public: + typedef I iterator; + + explicit range(I begin = I(), I end = I()) : begin_(begin), end_(end) {} + I begin() const { return begin_; } + I end() const { return end_; } + private: + I begin_, end_; +}; +///@endcond INTERNAL + +///@ An iterator for a range of sessions. +class session_iterator : public iter_base<session, session_iterator> { + public: + explicit session_iterator(session* p = 0, endpoint::state s = 0) : iter_base(p, s) {} + private: + PN_CPP_EXTERN void advance(); + friend class iter_base<session, session_iterator>; +}; + +///@ A range of sessions. +typedef range<session_iterator> session_range; + +///@ An iterator for a range of links. +class link_iterator : public iter_base<link, link_iterator> { + public: + explicit link_iterator(link* p = 0, endpoint::state s = 0) : + iter_base(p, s), session_(0) {} + explicit link_iterator(const link_iterator& i, session *ssn) : + iter_base(i.ptr_, i.state_), session_(ssn) {} + private: + PN_CPP_EXTERN void advance(); + session* session_; + friend class iter_base<link, link_iterator>; }; +///@ A range of links. +typedef range<link_iterator> link_range; } -#endif /*!PROTON_CPP_ENDPOINT_H*/ +#endif /*!PROTON_CPP_H*/ http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/proton-c/bindings/cpp/include/proton/link.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/link.hpp b/proton-c/bindings/cpp/include/proton/link.hpp index 8146f33..4e502e1 100644 --- a/proton-c/bindings/cpp/include/proton/link.hpp +++ b/proton-c/bindings/cpp/include/proton/link.hpp @@ -77,14 +77,12 @@ class link : public counted_facade<pn_link_t, link, endpoint> /** Link name */ PN_CPP_EXTERN std::string name(); - /** Next link that matches state mask. @see endpoint::state. - * @return 0 if none, do not delete returned pointer - */ - PN_CPP_EXTERN link* next(endpoint::state mask); - /** Connection that owns this link */ PN_CPP_EXTERN class connection &connection(); + /** Session that owns this link */ + PN_CPP_EXTERN class session &session(); + /** Set a custom handler for this link. */ PN_CPP_EXTERN void handler(class handler &); http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/proton-c/bindings/cpp/include/proton/session.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/session.hpp b/proton-c/bindings/cpp/include/proton/session.hpp index 7fe3e8d..b3dc446 100644 --- a/proton-c/bindings/cpp/include/proton/session.hpp +++ b/proton-c/bindings/cpp/include/proton/session.hpp @@ -76,6 +76,9 @@ class session : public counted_facade<pn_session_t, session, endpoint> /** Get the endpoint state */ PN_CPP_EXTERN endpoint::state state(); + + /** Return the links on this session matching the state mask. */ + PN_CPP_EXTERN link_range find_links(endpoint::state mask); }; } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/proton-c/bindings/cpp/src/connection.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/connection.cpp b/proton-c/bindings/cpp/src/connection.cpp index 8f27a01..19657fd 100644 --- a/proton-c/bindings/cpp/src/connection.cpp +++ b/proton-c/bindings/cpp/src/connection.cpp @@ -53,8 +53,13 @@ container& connection::container() { return container_context(pn_object_reactor(pn_cast(this))); } -link* connection::link_head(endpoint::state mask) { - return link::cast(pn_link_head(pn_cast(this), mask)); +link_range connection::find_links(endpoint::state mask) { + return link_range(link_iterator(link::cast(pn_link_head(pn_cast(this), mask)))); +} + +session_range connection::find_sessions(endpoint::state mask) { + return session_range( + session_iterator(session::cast(pn_session_head(pn_cast(this), mask)))); } session& connection::open_session() { return *session::cast(pn_session(pn_cast(this))); } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/proton-c/bindings/cpp/src/endpoint.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/endpoint.cpp b/proton-c/bindings/cpp/src/endpoint.cpp index ed14937..7f65054 100644 --- a/proton-c/bindings/cpp/src/endpoint.cpp +++ b/proton-c/bindings/cpp/src/endpoint.cpp @@ -19,10 +19,15 @@ * */ -#include "proton/endpoint.hpp" #include "proton/connection.hpp" +#include "proton/endpoint.hpp" +#include "proton/session.hpp" +#include "proton/link.hpp" #include "proton/transport.hpp" + #include "proton/connection.h" +#include "proton/session.h" +#include "proton/link.h" namespace proton { @@ -35,4 +40,14 @@ const int endpoint::REMOTE_CLOSED = PN_REMOTE_CLOSED; const int endpoint::LOCAL_MASK = PN_LOCAL_MASK; const int endpoint::REMOTE_MASK = PN_REMOTE_MASK; +void session_iterator::advance() { + ptr_ = session::cast(pn_session_next(pn_cast(ptr_), (pn_state_t) state_)); +} + +void link_iterator::advance() { + do { + ptr_ = link::cast(pn_link_next(pn_cast(ptr_), (pn_state_t) state_)); + } while (session_ && &ptr_->session() != session_); +} + } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/proton-c/bindings/cpp/src/link.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/link.cpp b/proton-c/bindings/cpp/src/link.cpp index 8afad6d..45c23aa 100644 --- a/proton-c/bindings/cpp/src/link.cpp +++ b/proton-c/bindings/cpp/src/link.cpp @@ -67,8 +67,8 @@ class connection &link::connection() { return *connection::cast(pn_session_connection(pn_link_session(pn_cast(this)))); } -link* link::next(endpoint::state mask) { - return link::cast(pn_link_next(pn_cast(this), (pn_state_t) mask)); +class session &link::session() { + return *session::cast(pn_link_session(pn_cast(this))); } void link::handler(class handler &h) { http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/proton-c/bindings/cpp/src/messaging_adapter.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/messaging_adapter.cpp b/proton-c/bindings/cpp/src/messaging_adapter.cpp index 7235244..f155a8d 100644 --- a/proton-c/bindings/cpp/src/messaging_adapter.cpp +++ b/proton-c/bindings/cpp/src/messaging_adapter.cpp @@ -76,7 +76,8 @@ void messaging_adapter::on_delivery(event &e) { messaging_event mevent(messaging_event::MESSAGE, *pe); pn_connection_t *pnc = pn_session_connection(pn_link_session(lnk)); struct connection_context& ctx = connection_context::get(pnc); - // Reusable per-connection message. Avoid expensive heap malloc/free overhead. + // Reusable per-connection message. + // Avoid expensive heap malloc/free overhead. // See PROTON-998 class message &msg(ctx.event_message); mevent.message_ = &msg; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/proton-c/bindings/cpp/src/session.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/session.cpp b/proton-c/bindings/cpp/src/session.cpp index fd5df6f..468e4b8 100644 --- a/proton-c/bindings/cpp/src/session.cpp +++ b/proton-c/bindings/cpp/src/session.cpp @@ -75,4 +75,14 @@ receiver& session::open_receiver(const std::string &addr, bool dynamic, handler } endpoint::state session::state() { return pn_session_state(pn_cast(this)); } + +link_range session::find_links(endpoint::state mask) { + link_range r(connection().find_links(mask)); + link_iterator i(r.begin(), this); + if (i && this != &i->session()) + ++i; + return link_range(i); } + +} // namespace proton + --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org