You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2015/11/23 18:58:08 UTC

[40/50] [abbrv] qpid-proton git commit: NO-JIRA: C++: Changed the API to no longer require use of external reference counting pointers. Squashed commit of: commit e488552ac50c2c1cb569c94450e10dbde6d5a5eb commit c7a86c91b7b41f3659d28d1229cd7073eb1f2e2a co

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/reactor.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/reactor.hpp b/proton-c/bindings/cpp/include/proton/reactor.hpp
index 8508e20..a7aa671 100644
--- a/proton-c/bindings/cpp/include/proton/reactor.hpp
+++ b/proton-c/bindings/cpp/include/proton/reactor.hpp
@@ -19,29 +19,30 @@
  * under the License.
  */
 
-#include "proton/facade.hpp"
+#include "proton/object.hpp"
 #include "proton/duration.hpp"
-#include "proton/pn_unique_ptr.hpp"
 
 struct pn_reactor_t;
+struct pn_io_t;
 
 namespace proton {
 
 class connection;
+class container;
 class acceptor;
 class url;
 class handler;
+class task;
 
-class reactor : public facade<pn_reactor_t, reactor> {
- public:
-    /** Create a new reactor. */
-    PN_CPP_EXTERN static pn_unique_ptr<reactor> create();
+class reactor : public object<pn_reactor_t> {
+  public:
+    reactor(pn_reactor_t* r = 0) : object(r) {}
 
-    /** Open a connection @see connection::open  */
-    PN_CPP_EXTERN connection& connect(const proton::url&, handler *h=0);
+    /** Create a new reactor. */
+    PN_CPP_EXTERN static reactor create();
 
     /** Open a connection to url and create a receiver with source=url.path() */
-    PN_CPP_EXTERN acceptor& listen(const proton::url &);
+    PN_CPP_EXTERN acceptor listen(const proton::url &);
 
     /** Run the event loop, return when all connections and acceptors are closed. */
     PN_CPP_EXTERN void run();
@@ -64,10 +65,29 @@ class reactor : public facade<pn_reactor_t, reactor> {
     /// Set timeout, process() will return if there is no activity within the timeout.
     PN_CPP_EXTERN void timeout(duration timeout);
 
+    PN_CPP_EXTERN amqp_timestamp mark();
+    PN_CPP_EXTERN amqp_timestamp now();
+    
+    PN_CPP_EXTERN task schedule(int, pn_handler_t*);
+
+    class connection connection(pn_handler_t*) const;
+
+    pn_handler_t* pn_handler() const;
+
+    void pn_handler(pn_handler_t* );
+
+    pn_handler_t* pn_global_handler() const;
+
+    void pn_global_handler(pn_handler_t* );
+
+    pn_io_t* pn_io() const;
+
     PN_CPP_EXTERN void wakeup();
     PN_CPP_EXTERN bool quiesced();
     PN_CPP_EXTERN void yield();
 
+    void container_context(container&);
+
     void operator delete(void*);
 };
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/receiver.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/receiver.hpp b/proton-c/bindings/cpp/include/proton/receiver.hpp
index 16c9425..d0df703 100644
--- a/proton-c/bindings/cpp/include/proton/receiver.hpp
+++ b/proton-c/bindings/cpp/include/proton/receiver.hpp
@@ -32,13 +32,13 @@ struct pn_connection_t;
 namespace proton {
 
 /// A receiving link
-class receiver : public counted_facade<pn_link_t, receiver, link>
+class receiver : public link
 {
   public:
+    receiver(pn_link_t* r=0) : link(r) {}
+
     /// Add credit to the link
     PN_CPP_EXTERN void flow(int count);
-
-    PN_CPP_EXTERN receiver* cast(pn_type*);
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/sender.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/sender.hpp b/proton-c/bindings/cpp/include/proton/sender.hpp
index 3106a7b..af8b9d5 100644
--- a/proton-c/bindings/cpp/include/proton/sender.hpp
+++ b/proton-c/bindings/cpp/include/proton/sender.hpp
@@ -34,13 +34,13 @@ struct pn_connection_t;
 namespace proton {
 
 /// A sending link
-class sender : public counted_facade<pn_link_t, sender, link>
+class sender : public link
 {
   public:
-    /// Send a message on the link.
-    PN_CPP_EXTERN delivery& send(const message &m);
+    sender(pn_link_t* s=0) : link(s) {}
 
-    PN_CPP_EXTERN sender* cast(pn_type*);
+    /// Send a message on the link.
+    PN_CPP_EXTERN delivery send(const message &m);
 };
 
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/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 0e6aa69..c07e6d3 100644
--- a/proton-c/bindings/cpp/include/proton/session.hpp
+++ b/proton-c/bindings/cpp/include/proton/session.hpp
@@ -30,6 +30,7 @@
 #include <string>
 
 struct pn_connection_t;
+struct pn_session_t;
 
 namespace proton {
 
@@ -38,9 +39,11 @@ class handler;
 class transport;
 
 /** A session is a collection of links */
-class session : public counted_facade<pn_session_t, session, endpoint>
+class session : public object<pn_session_t>, public endpoint
 {
   public:
+    session(pn_session_t* s=0) : object(s) {}
+
     /** Initiate local open, not complete till messaging_handler::on_session_opened()
      * or proton_handler::on_session_remote_open()
      */
@@ -52,35 +55,50 @@ class session : public counted_facade<pn_session_t, session, endpoint>
     PN_CPP_EXTERN void close();
 
     /// Get connection
-    PN_CPP_EXTERN class connection &connection() const;
+    PN_CPP_EXTERN class connection connection() const;
 
     /** An un-opened receiver link, you can set link properties before calling open().
      *
      *@param name if specified must be unique, by default the container generates a name
      * of the form: <hex-digits> + "@" + container.id()
      */
-    PN_CPP_EXTERN receiver& create_receiver(const std::string& name=std::string());
+    PN_CPP_EXTERN receiver create_receiver(const std::string& name=std::string());
 
     /** An un-opened sender link, you can set link properties before calling open().
      *
      *@param name if specified must be unique, by default the container generates a name
      * of the form: <hex-digits> + "@" + container.id()
      */
-    PN_CPP_EXTERN sender& create_sender(const std::string& name=std::string());
+    PN_CPP_EXTERN sender create_sender(const std::string& name=std::string());
 
     /** Create and open a sender with target=addr and optional handler h */
-    PN_CPP_EXTERN sender& open_sender(const std::string &addr, handler *h=0);
+    PN_CPP_EXTERN sender open_sender(const std::string &addr, handler *h=0);
 
     /** Create and open a receiver with target=addr and optional handler h */
-    PN_CPP_EXTERN receiver& open_receiver(const std::string &addr, bool dynamic=false, handler *h=0);
+    PN_CPP_EXTERN receiver open_receiver(const std::string &addr, bool dynamic=false, handler *h=0);
 
     /** Get the endpoint state */
     PN_CPP_EXTERN endpoint::state state() const;
 
+    /** Navigate the sessions in a connection - get next session with endpoint state*/
+    PN_CPP_EXTERN session next(endpoint::state) const;
+
     /** Return the links on this session matching the state mask. */
     PN_CPP_EXTERN link_range find_links(endpoint::state mask) const;
 };
 
+/// An iterator for sessions.
+class session_iterator : public iter_base<session> {
+ public:
+    explicit session_iterator(session p = session(), endpoint::state s = 0) :
+        iter_base<session>(p, s) {}
+    PN_CPP_EXTERN session_iterator operator++();
+    session_iterator operator++(int) { session_iterator x(*this); ++(*this); return x; }
+};
+
+/// A range of sessions.
+typedef range<session_iterator> session_range;
+
 }
 
 #endif  /*!PROTON_CPP_SESSION_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/task.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/task.hpp b/proton-c/bindings/cpp/include/proton/task.hpp
index 6764f45..8409e10 100644
--- a/proton-c/bindings/cpp/include/proton/task.hpp
+++ b/proton-c/bindings/cpp/include/proton/task.hpp
@@ -22,15 +22,17 @@
  *
  */
 #include "proton/export.hpp"
-#include "proton/facade.hpp"
+#include "proton/object.hpp"
 
 #include "proton/reactor.h"
 
 namespace proton {
 
 /** A task for timer events */
-class task : public counted_facade<pn_task_t, task> {
+class task : public object<pn_task_t> {
   public:
+    task(pn_task_t* t) : object(t) {}
+
     /** Cancel the scheduled task. */
     PN_CPP_EXTERN void cancel();
 };

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/terminus.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/terminus.hpp b/proton-c/bindings/cpp/include/proton/terminus.hpp
index 86b56f7..0a1d4b8 100644
--- a/proton-c/bindings/cpp/include/proton/terminus.hpp
+++ b/proton-c/bindings/cpp/include/proton/terminus.hpp
@@ -24,7 +24,7 @@
 #include "proton/export.hpp"
 
 #include "proton/link.h"
-#include "proton/facade.hpp"
+#include "proton/object.hpp"
 #include <string>
 
 namespace proton {
@@ -34,9 +34,10 @@ class link;
 /** A terminus represents one end of a link.
  * The source terminus is where originate, the target terminus is where they go.
  */
-class terminus : public counted_facade<pn_terminus_t, terminus>
+class terminus
 {
   public:
+    terminus(pn_terminus_t* t) : object_(t) {}
     /// Type of terminus
     enum type_t {
         TYPE_UNSPECIFIED = PN_UNSPECIFIED,
@@ -69,6 +70,9 @@ class terminus : public counted_facade<pn_terminus_t, terminus>
     PN_CPP_EXTERN void address(const std::string &);
     PN_CPP_EXTERN bool dynamic() const;
     PN_CPP_EXTERN void dynamic(bool);
+
+private:
+    pn_terminus_t* object_;
 };
 
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/transport.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/transport.hpp b/proton-c/bindings/cpp/include/proton/transport.hpp
index 3d602b7..0f1bf66 100644
--- a/proton-c/bindings/cpp/include/proton/transport.hpp
+++ b/proton-c/bindings/cpp/include/proton/transport.hpp
@@ -22,7 +22,7 @@
  *
  */
 
-#include "proton/facade.hpp"
+#include "proton/object.hpp"
 
 #include "proton/export.hpp"
 
@@ -33,10 +33,12 @@ namespace proton {
 class connection;
 
 /** Represents a connection transport */
-class transport : public counted_facade<pn_transport_t, transport>
+class transport : public object<pn_transport_t>
 {
   public:
-    class connection* connection() const;
+    transport(pn_transport_t* t) : object(t) {}
+
+    class connection connection() const;
 };
 
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/url.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/url.hpp b/proton-c/bindings/cpp/include/proton/url.hpp
index e8c68aa..4f586cb 100644
--- a/proton-c/bindings/cpp/include/proton/url.hpp
+++ b/proton-c/bindings/cpp/include/proton/url.hpp
@@ -19,7 +19,6 @@
  * under the License.
  */
 
-#include "proton/facade.hpp"
 #include "proton/types.hpp"
 #include "proton/error.hpp"
 #include <iosfwd>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/value.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/value.hpp b/proton-c/bindings/cpp/include/proton/value.hpp
index 62b8a9e..661de51 100644
--- a/proton-c/bindings/cpp/include/proton/value.hpp
+++ b/proton-c/bindings/cpp/include/proton/value.hpp
@@ -21,7 +21,6 @@
 
 #include "proton/data.hpp"
 #include "proton/decoder.hpp"
-#include "proton/pn_unique_ptr.hpp"
 #include "proton/types.hpp"
 
 namespace proton {
@@ -45,22 +44,21 @@ class value : public comparable<value> {
   public:
     PN_CPP_EXTERN value();
     PN_CPP_EXTERN value(const value& x);
-    PN_CPP_EXTERN value(const data&);
-
-    template <class T> value(const T& x) : data_(data::create()) { *data_ = x; }
+    // TODO: Should enumerate specifically all the pointer types that can convert to value
+    // to avoid accidental conversions to bool this will require enable_if<> or the like
+    template <class T> value(const T& x) : data_(data::create()) { data_ = x; }
 
     PN_CPP_EXTERN value& operator=(const value& x);
-    PN_CPP_EXTERN value& operator=(const data& x);
-    template <class T> value& operator=(const T& x) { *data_ = x; return *this; }
+    template <class T> value& operator=(const T& x) { data_ = x; return *this; }
 
     PN_CPP_EXTERN void clear();
     PN_CPP_EXTERN bool empty() const;
 
     /** Encoder to encode complex data into this value. Note this clears the value. */
-    PN_CPP_EXTERN class encoder& encoder();
+    PN_CPP_EXTERN class encoder encoder();
 
     /** Decoder to decode complex data from this value. Note this rewinds the decoder. */
-    PN_CPP_EXTERN class decoder& decoder() const;
+    PN_CPP_EXTERN class decoder decoder() const;
 
     /** Type of the current value*/
     PN_CPP_EXTERN type_id type() const;
@@ -74,12 +72,13 @@ class value : public comparable<value> {
     PN_CPP_EXTERN bool operator==(const value& x) const;
     PN_CPP_EXTERN bool operator<(const value& x) const;
 
-  friend PN_CPP_EXTERN class encoder& operator<<(class encoder& e, const value& dv);
-  friend PN_CPP_EXTERN class decoder& operator>>(class decoder& d, value& dv);
+  friend PN_CPP_EXTERN class encoder operator<<(class encoder e, const value& dv);
+  friend PN_CPP_EXTERN class decoder operator>>(class decoder d, value& dv);
   friend PN_CPP_EXTERN std::ostream& operator<<(std::ostream& o, const value& dv);
 
   private:
-    pn_unique_ptr<data> data_;
+    data data_;
+  friend class message;
 };
 
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/acceptor.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/acceptor.cpp b/proton-c/bindings/cpp/src/acceptor.cpp
index 4fc538c..279f776 100644
--- a/proton-c/bindings/cpp/src/acceptor.cpp
+++ b/proton-c/bindings/cpp/src/acceptor.cpp
@@ -25,6 +25,6 @@
 
 namespace proton {
 
-void acceptor::close() { pn_acceptor_close(pn_cast(this)); }
+void acceptor::close() { pn_acceptor_close(pn_object()); }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/blocking_connection.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/blocking_connection.cpp b/proton-c/bindings/cpp/src/blocking_connection.cpp
index d830872..c7f243b 100644
--- a/proton-c/bindings/cpp/src/blocking_connection.cpp
+++ b/proton-c/bindings/cpp/src/blocking_connection.cpp
@@ -34,6 +34,6 @@ void blocking_connection::close() { impl_->close(); }
 
 duration blocking_connection::timeout() const { return impl_->container_->reactor().timeout(); }
 
-connection& blocking_connection::connection() const { return *impl_->connection_; }
+connection blocking_connection::connection() const { return impl_->connection_; }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/blocking_connection_impl.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/blocking_connection_impl.cpp b/proton-c/bindings/cpp/src/blocking_connection_impl.cpp
index 8abd24b..65ae9bb 100644
--- a/proton-c/bindings/cpp/src/blocking_connection_impl.cpp
+++ b/proton-c/bindings/cpp/src/blocking_connection_impl.cpp
@@ -33,15 +33,15 @@ namespace proton {
 
 namespace {
 struct connection_opening : public blocking_connection_impl::condition {
-    connection_opening(pn_connection_t *c) : pn_connection(c) {}
-    bool operator()() const { return (pn_connection_state(pn_connection) & PN_REMOTE_UNINIT); }
-    pn_connection_t *pn_connection;
+    connection_opening(const connection& c) : connection_(c) {}
+    bool operator()() const { return (connection_.state()) & PN_REMOTE_UNINIT; }
+    const connection& connection_;
 };
 
 struct connection_closed : public blocking_connection_impl::condition {
-    connection_closed(pn_connection_t *c) : pn_connection(c) {}
-    bool operator()() const { return !(pn_connection_state(pn_connection) & PN_REMOTE_ACTIVE); }
-    pn_connection_t *pn_connection;
+    connection_closed(const connection& c) : connection_(c) {}
+    bool operator()() const { return !(connection_.state() & PN_REMOTE_ACTIVE); }
+    const connection& connection_;
 };
 }
 
@@ -50,15 +50,15 @@ blocking_connection_impl::blocking_connection_impl(const url& url, duration time
 {
     container_->reactor().start();
     container_->reactor().timeout(timeout);
-    connection_ = container_->connect(url, this).ptr(); // Set this as handler.
-    wait(connection_opening(pn_cast(connection_.get())));
+    connection_ = container_->connect(url, this); // Set this as handler.
+    wait(connection_opening(connection_));
 }
 
 blocking_connection_impl::~blocking_connection_impl() {}
 
 void blocking_connection_impl::close() {
-    connection_->close();
-    wait(connection_closed(pn_cast(connection_.get())));
+    connection_.close();
+    wait(connection_closed(connection_));
 }
 
 namespace {
@@ -72,10 +72,10 @@ struct save_timeout {
 
 void blocking_connection_impl::wait(const condition &condition, const std::string &msg, duration wait_timeout)
 {
-    reactor& reactor = container_->reactor();
+    reactor reactor = container_->reactor();
 
     if (wait_timeout == duration(-1))
-        wait_timeout = container_->reactor().timeout();
+        wait_timeout = reactor.timeout();
 
     if (wait_timeout == duration::FOREVER) {
         while (!condition()) {
@@ -84,11 +84,11 @@ void blocking_connection_impl::wait(const condition &condition, const std::strin
     } else {
         save_timeout st(reactor);
         reactor.timeout(wait_timeout);
-        pn_timestamp_t deadline = pn_reactor_mark(pn_cast(&reactor)) + wait_timeout.milliseconds;
+        pn_timestamp_t deadline = reactor.mark() + wait_timeout.milliseconds;
         while (!condition()) {
             reactor.process();
             if (!condition()) {
-                pn_timestamp_t now = pn_reactor_mark(pn_cast(&reactor));
+                pn_timestamp_t now = reactor.mark();
                 if (now < deadline)
                     reactor.timeout(duration(deadline - now));
                 else

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/blocking_connection_impl.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/blocking_connection_impl.hpp b/proton-c/bindings/cpp/src/blocking_connection_impl.hpp
index 319b544..cd93de8 100644
--- a/proton-c/bindings/cpp/src/blocking_connection_impl.hpp
+++ b/proton-c/bindings/cpp/src/blocking_connection_impl.hpp
@@ -51,7 +51,7 @@ class blocking_connection_impl : public messaging_handler
     void wait(const condition&, const std::string & ="", duration=duration(-1));
 
     pn_unique_ptr<container> container_;
-    counted_ptr<connection> connection_;
+    connection connection_;
 };
 
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/blocking_fetcher.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/blocking_fetcher.cpp b/proton-c/bindings/cpp/src/blocking_fetcher.cpp
index 55877af..0d0b706 100644
--- a/proton-c/bindings/cpp/src/blocking_fetcher.cpp
+++ b/proton-c/bindings/cpp/src/blocking_fetcher.cpp
@@ -19,6 +19,7 @@
  *
  */
 #include "blocking_fetcher.hpp"
+#include "proton/container.hpp"
 #include "msg.hpp"
 
 #include "proton/event.hpp"
@@ -29,14 +30,14 @@ blocking_fetcher::blocking_fetcher(int prefetch) : messaging_handler(prefetch, f
 
 void blocking_fetcher::on_message(event &e) {
     messages_.push_back(e.message());
-    deliveries_.push_back(e.delivery().ptr());
+    deliveries_.push_back(e.delivery());
     // Wake up enclosing connection.wait()
     e.container().reactor().yield();
 }
 
 void blocking_fetcher::on_link_error(event &e) {
-    link& lnk = e.link();
-    if (pn_link_state(pn_cast(&lnk)) & PN_LOCAL_ACTIVE) {
+    link lnk = e.link();
+    if (lnk.state() & PN_LOCAL_ACTIVE) {
         lnk.close();
         throw error(MSG("Link detached: " << lnk.name()));
     }
@@ -47,8 +48,8 @@ bool blocking_fetcher::has_message() { return !messages_.empty(); }
 message blocking_fetcher::pop() {
     if (messages_.empty())
         throw error(MSG("receiver has no messages"));
-    counted_ptr<delivery> dlv(deliveries_.front());
-    if (!dlv->settled())
+    delivery dlv(deliveries_.front());
+    if (!dlv.settled())
         unsettled_.push_back(dlv);
     message m = messages_.front();
     messages_.pop_front();
@@ -57,10 +58,10 @@ message blocking_fetcher::pop() {
 }
 
 void blocking_fetcher::settle(delivery::state state) {
-    counted_ptr<delivery> dlv = unsettled_.front();
+    delivery dlv = unsettled_.front();
     if (state)
-        dlv->update(state);
-    dlv->settle();
+        dlv.update(state);
+    dlv.settle();
 }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/blocking_fetcher.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/blocking_fetcher.hpp b/proton-c/bindings/cpp/src/blocking_fetcher.hpp
index a0db252..d766bfc 100644
--- a/proton-c/bindings/cpp/src/blocking_fetcher.hpp
+++ b/proton-c/bindings/cpp/src/blocking_fetcher.hpp
@@ -39,8 +39,8 @@ class blocking_fetcher : public messaging_handler {
 
   private:
     std::deque<message> messages_;
-    std::deque<counted_ptr<delivery> > deliveries_;
-    std::deque<counted_ptr<delivery> > unsettled_;
+    std::deque<delivery> deliveries_;
+    std::deque<delivery> unsettled_;
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/blocking_link.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/blocking_link.cpp b/proton-c/bindings/cpp/src/blocking_link.cpp
index 3fc2904..262f6d0 100644
--- a/proton-c/bindings/cpp/src/blocking_link.cpp
+++ b/proton-c/bindings/cpp/src/blocking_link.cpp
@@ -33,53 +33,52 @@ namespace proton {
 
 namespace {
 struct link_opened : public blocking_connection_impl::condition {
-    link_opened(pn_link_t *l) : pn_link(l) {}
-    bool operator()() const { return !(pn_link_state(pn_link) & PN_REMOTE_UNINIT); }
-    pn_link_t *pn_link;
+    link_opened(link l) : pn_link(l) {}
+    bool operator()() const { return !(pn_link.state() & PN_REMOTE_UNINIT); }
+    link pn_link;
 };
 
 struct link_closed : public blocking_connection_impl::condition {
-    link_closed(pn_link_t *l) : pn_link(l) {}
-    bool operator()() const { return (pn_link_state(pn_link) & PN_REMOTE_CLOSED); }
-    pn_link_t *pn_link;
+    link_closed(link l) : pn_link(l) {}
+    bool operator()() const { return (pn_link.state() & PN_REMOTE_CLOSED); }
+    link pn_link;
 };
 
 struct link_not_open : public blocking_connection_impl::condition {
-    link_not_open(pn_link_t *l) : pn_link(l) {}
-    bool operator()() const { return !(pn_link_state(pn_link) & PN_REMOTE_ACTIVE); }
-    pn_link_t *pn_link;
+    link_not_open(link l) : pn_link(l) {}
+    bool operator()() const { return !(pn_link.state() & PN_REMOTE_ACTIVE); }
+    link pn_link;
 };
 
 } // namespace
 
 blocking_link::blocking_link(blocking_connection &c) : connection_(c) {}
 
-void blocking_link::open(proton::link& l) {
-    link_ = l.ptr();
-    connection_.impl_->wait(link_opened(pn_cast(link_.get())), "opening link " + link_->name());
+void blocking_link::open(proton::link l) {
+    link_ = l;
+    connection_.impl_->wait(link_opened(link_), "opening link " + link_.name());
     check_closed();
 }
 
 blocking_link::~blocking_link() {}
 
 void blocking_link::wait_for_closed() {
-    link_closed link_closed(pn_cast(link_.get()));
-    connection_.impl_->wait(link_closed, "closing link " + link_->name());
+    link_closed link_closed(link_);
+    connection_.impl_->wait(link_closed, "closing link " + link_.name());
     check_closed();
 }
 
 void blocking_link::check_closed() {
-    pn_link_t * pn_link = pn_cast(link_.get());
-    if (pn_link_state(pn_link) & PN_REMOTE_CLOSED) {
-        link_->close();
-        throw error(MSG("Link detached: " << link_->name()));
+    if (link_.state() & PN_REMOTE_CLOSED) {
+        link_.close();
+        throw error(MSG("Link detached: " << link_.name()));
     }
 }
 
 void blocking_link::close() {
-    link_->close();
-    link_not_open link_not_open(pn_cast(link_.get()));
-    connection_.impl_->wait(link_not_open, "closing link " + link_->name());
+    link_.close();
+    link_not_open link_not_open(link_);
+    connection_.impl_->wait(link_not_open, "closing link " + link_.name());
 }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/blocking_receiver.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/blocking_receiver.cpp b/proton-c/bindings/cpp/src/blocking_receiver.cpp
index 656e770..00d3dce 100644
--- a/proton-c/bindings/cpp/src/blocking_receiver.cpp
+++ b/proton-c/bindings/cpp/src/blocking_receiver.cpp
@@ -46,26 +46,26 @@ blocking_receiver::blocking_receiver(
     class blocking_connection &c, const std::string& addr, int credit, bool dynamic) :
     blocking_link(c), fetcher_(new blocking_fetcher(credit))
 {
-    open(c.impl_->connection_->open_receiver(addr, dynamic, fetcher_.get()));
-    std::string sa = link_->source().address();
-    std::string rsa = link_->remote_source().address();
+    open(c.impl_->connection_.open_receiver(addr, dynamic, fetcher_.get()));
+    std::string sa = link_.source().address();
+    std::string rsa = link_.remote_source().address();
     if (!sa.empty() && sa.compare(rsa) != 0) {
         wait_for_closed();
-        link_->close();
-        std::string txt = "Failed to open receiver " + link_->name() + ", source does not match";
+        link_.close();
+        std::string txt = "Failed to open receiver " + link_.name() + ", source does not match";
         throw error(MSG(txt));
     }
     if (credit)
-        pn_link_flow(pn_cast(link_), credit);
+        link_.flow(credit);
 }
 
-blocking_receiver::~blocking_receiver() { link_->detach_handler(); }
+blocking_receiver::~blocking_receiver() { link_.detach_handler(); }
 
 message blocking_receiver::receive(duration timeout) {
     if (!receiver().credit())
         receiver().flow(1);
     fetcher_has_message cond(*fetcher_);
-    connection_.impl_->wait(cond, "receiving on receiver " + link_->name(), timeout);
+    connection_.impl_->wait(cond, "receiving on receiver " + link_.name(), timeout);
     return fetcher_->pop();
 }
 
@@ -97,6 +97,6 @@ void blocking_receiver::flow(int count) {
     receiver().flow(count);
 }
 
-receiver& blocking_receiver::receiver() { return *link_->receiver(); }
+receiver blocking_receiver::receiver() { return link_.receiver(); }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/blocking_sender.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/blocking_sender.cpp b/proton-c/bindings/cpp/src/blocking_sender.cpp
index 43480d6..b6ad7dc 100644
--- a/proton-c/bindings/cpp/src/blocking_sender.cpp
+++ b/proton-c/bindings/cpp/src/blocking_sender.cpp
@@ -30,39 +30,39 @@ namespace proton {
 
 namespace {
 struct delivery_settled : public blocking_connection_impl::condition {
-    delivery_settled(pn_delivery_t *d) : pn_delivery(d) {}
-    bool operator()() const { return pn_delivery_settled(pn_delivery); }
-    pn_delivery_t *pn_delivery;
+    delivery_settled(const delivery& d) : pn_delivery(d) {}
+    bool operator()() const { return pn_delivery.settled(); }
+    const delivery& pn_delivery;
 };
 } // namespace
 
 blocking_sender::blocking_sender(blocking_connection &c, const std::string &address) :
     blocking_link(c)
 {
-    open(c.impl_->connection_->open_sender(address));
-    std::string ta = link_->target().address();
-    std::string rta = link_->remote_target().address();
+    open(c.impl_->connection_.open_sender(address));
+    std::string ta = link_.target().address();
+    std::string rta = link_.remote_target().address();
     if (ta.empty() || ta.compare(rta) != 0) {
         wait_for_closed();
-        link_->close();
-        std::string txt = "Failed to open sender " + link_->name() + ", target does not match";
+        link_.close();
+        std::string txt = "Failed to open sender " + link_.name() + ", target does not match";
         throw error(MSG(txt));
     }
 }
 
 blocking_sender::~blocking_sender() {}
 
-delivery& blocking_sender::send(const message &msg, duration timeout) {
-    delivery& dlv = sender().send(msg);
-    connection_.impl_->wait(delivery_settled(pn_cast(&dlv)), "sending on sender " + link_->name(), timeout);
+delivery blocking_sender::send(const message &msg, duration timeout) {
+    delivery dlv = sender().send(msg);
+    connection_.impl_->wait(delivery_settled(dlv), "sending on sender " + link_.name(), timeout);
     return dlv;
 }
 
-delivery& blocking_sender::send(const message &msg) {
+delivery blocking_sender::send(const message &msg) {
     // Use default timeout
     return send(msg, connection_.timeout());
 }
 
-sender& blocking_sender::sender() const { return *link_->sender(); }
+sender blocking_sender::sender() const { return link_.sender(); }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/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 2d401bd..11cc29b 100644
--- a/proton-c/bindings/cpp/src/connection.cpp
+++ b/proton-c/bindings/cpp/src/connection.cpp
@@ -37,52 +37,63 @@
 
 namespace proton {
 
-void connection::open() { pn_connection_open(pn_cast(this)); }
+connection_context& connection::context() const { return connection_context::get(pn_object()); }
 
-void connection::close() { pn_connection_close(pn_cast(this)); }
+void connection::open() { pn_connection_open(pn_object()); }
+
+void connection::close() { pn_connection_close(pn_object()); }
+
+void connection::release() { pn_connection_release(pn_object()); }
 
 std::string connection::host() const {
-    return std::string(pn_connection_get_hostname(pn_cast(this)));
+    return std::string(pn_connection_get_hostname(pn_object()));
+}
+
+void connection::host(const std::string& h) {
+    pn_connection_set_hostname(pn_object(), h.c_str());
 }
 
 std::string connection::container_id() const {
-    const char* id = pn_connection_get_container(pn_cast(this));
+    const char* id = pn_connection_get_container(pn_object());
     return id ? std::string(id) : std::string();
 }
 
+void connection::container_id(const std::string& id) {
+    pn_connection_set_container(pn_object(), id.c_str());
+}
+
 container& connection::container() const {
-    return container_context(pn_object_reactor(pn_cast(this)));
+    return container_context(pn_object_reactor(pn_object()));
 }
 
 link_range connection::find_links(endpoint::state mask) const {
-    return link_range(link_iterator(link::cast(pn_link_head(pn_cast(this), mask))));
+    return link_range(link_iterator(pn_link_head(pn_object(), mask)));
 }
 
 session_range connection::find_sessions(endpoint::state mask) const {
-    return session_range(
-        session_iterator(session::cast(pn_session_head(pn_cast(this), mask))));
+    return session_range(session_iterator(pn_session_head(pn_object(), mask)));
 }
 
-session& connection::open_session() { return *session::cast(pn_session(pn_cast(this))); }
+session connection::open_session() { return pn_session(pn_object()); }
 
-session& connection::default_session() {
-    struct connection_context& ctx = connection_context::get(pn_cast(this));
+session connection::default_session() {
+    struct connection_context& ctx = connection_context::get(pn_object());
     if (!ctx.default_session) {
-        ctx.default_session = &open_session();
-        ctx.default_session->open();
+        ctx.default_session = open_session();
+        ctx.default_session.open();
     }
-    return *ctx.default_session;
+    return ctx.default_session;
 }
 
-sender& connection::open_sender(const std::string &addr, handler *h) {
+sender connection::open_sender(const std::string &addr, handler *h) {
     return default_session().open_sender(addr, h);
 }
 
-receiver& connection::open_receiver(const std::string &addr, bool dynamic, handler *h)
+receiver connection::open_receiver(const std::string &addr, bool dynamic, handler *h)
 {
     return default_session().open_receiver(addr, dynamic, h);
 }
 
-endpoint::state connection::state() const { return pn_connection_state(pn_cast(this)); }
+endpoint::state connection::state() const { return pn_connection_state(pn_object()); }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/connector.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connector.cpp b/proton-c/bindings/cpp/src/connector.cpp
index 49660ea..a8614cd 100644
--- a/proton-c/bindings/cpp/src/connector.cpp
+++ b/proton-c/bindings/cpp/src/connector.cpp
@@ -30,7 +30,7 @@
 
 namespace proton {
 
-connector::connector(connection &c) : connection_(&c) {}
+connector::connector(connection &c) : connection_(c) {}
 
 connector::~connector() {}
 
@@ -39,9 +39,8 @@ void connector::address(const url &a) {
 }
 
 void connector::connect() {
-    pn_connection_t *conn = pn_cast(connection_);
-    pn_connection_set_container(conn, connection_->container().id().c_str());
-    pn_connection_set_hostname(conn, address_.host_port().c_str());
+    connection_.container_id(connection_.container().id());
+    connection_.host(address_.host_port());
 }
 
 void connector::on_connection_local_open(event &e) {
@@ -55,7 +54,7 @@ void connector::on_connection_init(event &e) {
 
 void connector::on_transport_closed(event &e) {
     // TODO: prepend with reconnect logic
-    pn_connection_release(pn_cast(connection_));
+    connection_.release();
     connection_  = 0;
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/connector.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connector.hpp b/proton-c/bindings/cpp/src/connector.hpp
index b311cc9..818282a 100644
--- a/proton-c/bindings/cpp/src/connector.hpp
+++ b/proton-c/bindings/cpp/src/connector.hpp
@@ -48,7 +48,7 @@ class connector : public proton_handler
     virtual void on_transport_closed(event &e);
 
   private:
-    connection* connection_;
+    connection connection_;
     url address_;
 };
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/container.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container.cpp b/proton-c/bindings/cpp/src/container.cpp
index 13f12d9..f19b72b 100644
--- a/proton-c/bindings/cpp/src/container.cpp
+++ b/proton-c/bindings/cpp/src/container.cpp
@@ -28,6 +28,7 @@
 #include "proton/url.hpp"
 #include "proton/sender.hpp"
 #include "proton/receiver.hpp"
+#include "proton/task.hpp"
 
 #include "container_impl.hpp"
 #include "connector.hpp"
@@ -47,26 +48,26 @@ container::container(messaging_handler &mhandler, const std::string& id) :
 
 container::~container() {}
 
-connection& container::connect(const url &host, handler *h) { return impl_->connect(host, h); }
+connection container::connect(const url &host, handler *h) { return impl_->connect(host, h); }
 
-reactor &container::reactor() const { return *impl_->reactor_; }
+reactor container::reactor() const { return impl_->reactor_; }
 
 std::string container::id() const { return impl_->id_; }
 
-void container::run() { impl_->reactor_->run(); }
+void container::run() { impl_->reactor_.run(); }
 
-sender& container::open_sender(const proton::url &url) {
+sender container::open_sender(const proton::url &url) {
     return impl_->open_sender(url);
 }
 
-receiver& container::open_receiver(const proton::url &url) {
+receiver container::open_receiver(const proton::url &url) {
     return impl_->open_receiver(url);
 }
 
-acceptor& container::listen(const proton::url &url) {
+acceptor container::listen(const proton::url &url) {
     return impl_->listen(url);
 }
 
-task& container::schedule(int delay, handler *h) { return impl_->schedule(delay, h); }
+task container::schedule(int delay, handler *h) { return impl_->schedule(delay, h); }
 
 } // namespace proton

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/container_impl.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container_impl.cpp b/proton-c/bindings/cpp/src/container_impl.cpp
index 6dfd797..8a0b56e 100644
--- a/proton-c/bindings/cpp/src/container_impl.cpp
+++ b/proton-c/bindings/cpp/src/container_impl.cpp
@@ -120,16 +120,16 @@ container_impl::container_impl(container& c, handler *h, const std::string& id)
     link_id_(0)
 {
     if (id_.empty()) id_ = uuid().str();
-    container_context(pn_cast(reactor_.get()), container_);
+    reactor_.container_context(container_);
 
     // Set our own global handler that "subclasses" the existing one
-    pn_handler_t *global_handler = pn_reactor_get_global_handler(pn_cast(reactor_.get()));
+    pn_handler_t *global_handler = reactor_.pn_global_handler();
     override_handler_.reset(new override_handler(global_handler));
     counted_ptr<pn_handler_t> cpp_global_handler(cpp_handler(override_handler_.get()));
-    pn_reactor_set_global_handler(pn_cast(reactor_.get()), cpp_global_handler.get());
+    reactor_.pn_global_handler(cpp_global_handler.get());
     if (handler_) {
         counted_ptr<pn_handler_t> pn_handler(cpp_handler(handler_));
-        pn_reactor_set_handler(pn_cast(reactor_.get()), pn_handler.get());
+        reactor_.pn_handler(pn_handler.get());
     }
 
 
@@ -141,46 +141,44 @@ container_impl::container_impl(container& c, handler *h, const std::string& id)
 
 container_impl::~container_impl() {}
 
-connection& container_impl::connect(const proton::url &url, handler *h) {
+connection container_impl::connect(const proton::url &url, handler *h) {
     counted_ptr<pn_handler_t> chandler = h ? cpp_handler(h) : counted_ptr<pn_handler_t>();
-    connection& conn(           // Reactor owns the reference.
-        *connection::cast(pn_reactor_connection(pn_cast(reactor_.get()), chandler.get())));
+    connection conn(reactor_.connection(chandler.get()));
     pn_unique_ptr<connector> ctor(new connector(conn));
     ctor->address(url);  // TODO: url vector
-    connection_context& cc(connection_context::get(pn_cast(&conn)));
+    connection_context& cc(conn.context());
     cc.container_impl = this;
     cc.handler.reset(ctor.release());
     conn.open();
     return conn;
 }
 
-sender& container_impl::open_sender(const proton::url &url) {
-    connection& conn = connect(url, 0);
+sender container_impl::open_sender(const proton::url &url) {
+    connection conn = connect(url, 0);
     std::string path = url.path();
-    sender& snd = conn.default_session().open_sender(id_ + '-' + path);
+    sender snd = conn.default_session().open_sender(id_ + '-' + path);
     snd.target().address(path);
     snd.open();
     return snd;
 }
 
-receiver& container_impl::open_receiver(const proton::url &url) {
-    connection& conn = connect(url, 0);
+receiver container_impl::open_receiver(const proton::url &url) {
+    connection conn = connect(url, 0);
     std::string path = url.path();
-    receiver& rcv = conn.default_session().open_receiver(id_ + '-' + path);
-    pn_terminus_set_address(pn_link_source(pn_cast(&rcv)), path.c_str());
+    receiver rcv = conn.default_session().open_receiver(id_ + '-' + path);
+    rcv.source().address(path);
     rcv.open();
     return rcv;
 }
 
-acceptor& container_impl::listen(const proton::url& url) {
-    pn_acceptor_t *acptr = pn_reactor_acceptor(
-        pn_cast(reactor_.get()), url.host().c_str(), url.port().c_str(), NULL);
-    if (acptr)
-        return *acceptor::cast(acptr);
+acceptor container_impl::listen(const proton::url& url) {
+    acceptor acptr = reactor_.listen(url);
+    if (!!acptr)
+        return acptr;
     else
         throw error(MSG("accept fail: " <<
-                        pn_error_text(pn_io_error(pn_reactor_io(pn_cast(reactor_.get()))))
-                        << "(" << url << ")"));
+                        pn_error_text(pn_io_error(reactor_.pn_io())))
+                        << "(" << url << ")");
 }
 
 std::string container_impl::next_link_name() {
@@ -190,12 +188,11 @@ std::string container_impl::next_link_name() {
     return s.str();
 }
 
-task& container_impl::schedule(int delay, handler *h) {
+task container_impl::schedule(int delay, handler *h) {
     counted_ptr<pn_handler_t> task_handler;
     if (h)
         task_handler = cpp_handler(h);
-    task *t = task::cast(pn_reactor_schedule(pn_cast(reactor_.get()), delay, task_handler.get()));
-    return *t;
+    return reactor_.schedule(delay, task_handler.get());
 }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/container_impl.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container_impl.hpp b/proton-c/bindings/cpp/src/container_impl.hpp
index ec356e2..2d97780 100644
--- a/proton-c/bindings/cpp/src/container_impl.hpp
+++ b/proton-c/bindings/cpp/src/container_impl.hpp
@@ -26,6 +26,7 @@
 #include "proton/connection.hpp"
 #include "proton/link.hpp"
 #include "proton/duration.hpp"
+#include "proton/reactor.hpp"
 
 #include "proton/reactor.h"
 
@@ -38,22 +39,24 @@ class connection;
 class connector;
 class acceptor;
 class container;
+class url;
+class task;
 
 class container_impl
 {
   public:
     PN_CPP_EXTERN container_impl(container&, handler *, const std::string& id);
     PN_CPP_EXTERN ~container_impl();
-    PN_CPP_EXTERN connection& connect(const url&, handler *h);
-    PN_CPP_EXTERN sender& open_sender(connection &connection, const std::string &addr, handler *h);
-    PN_CPP_EXTERN sender& open_sender(const url&);
-    PN_CPP_EXTERN receiver& open_receiver(connection &connection, const std::string &addr, bool dynamic, handler *h);
-    PN_CPP_EXTERN receiver& open_receiver(const url&);
-    PN_CPP_EXTERN class acceptor& listen(const url&);
+    PN_CPP_EXTERN connection connect(const url&, handler *h);
+    PN_CPP_EXTERN sender open_sender(connection &connection, const std::string &addr, handler *h);
+    PN_CPP_EXTERN sender open_sender(const url&);
+    PN_CPP_EXTERN receiver open_receiver(connection &connection, const std::string &addr, bool dynamic, handler *h);
+    PN_CPP_EXTERN receiver open_receiver(const url&);
+    PN_CPP_EXTERN class acceptor listen(const url&);
     PN_CPP_EXTERN duration timeout();
     PN_CPP_EXTERN void timeout(duration timeout);
 
-    task& schedule(int delay, handler *h);
+    task schedule(int delay, handler *h);
     counted_ptr<pn_handler_t> cpp_handler(handler *h);
 
     std::string next_link_name();
@@ -61,7 +64,7 @@ class container_impl
   private:
 
     container& container_;
-    pn_unique_ptr<reactor> reactor_;
+    reactor reactor_;
     handler *handler_;
     pn_unique_ptr<messaging_adapter> messaging_adapter_;
     pn_unique_ptr<handler> override_handler_;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/contexts.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/contexts.hpp b/proton-c/bindings/cpp/src/contexts.hpp
index 1df947e..34df0ce 100644
--- a/proton-c/bindings/cpp/src/contexts.hpp
+++ b/proton-c/bindings/cpp/src/contexts.hpp
@@ -45,7 +45,7 @@ struct connection_context : public counted {
     ~connection_context();
 
     pn_unique_ptr<class handler> handler;
-    session* default_session;   // Owned by connection
+    session default_session;   // Owned by connection
     class container_impl* container_impl;
     message event_message;  // re-used by messaging_adapter for performance
 };

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/conversion_test.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/conversion_test.cpp b/proton-c/bindings/cpp/src/conversion_test.cpp
deleted file mode 100644
index 53ce879..0000000
--- a/proton-c/bindings/cpp/src/conversion_test.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-// Pointer conversion test.
-// NOTE needs to be run with valgrind to be effective.
-
-
-#include "test_bits.hpp"
-#include "proton/connection.hpp"
-#include "proton/session.hpp"
-
-using namespace std;
-using namespace proton;
-
-template <class connection_ptr, class session_ptr>
-void test_owning() {
-
-    connection_ptr conn(connection::cast(pn_connection()));
-    session& s = conn->default_session();
-    session_ptr p = s.ptr();
-    session_ptr p2 = s.ptr();
-}
-
-template <class connection_ptr, class session_ptr>
-void test_counted() {
-    connection_ptr conn(connection::cast(pn_connection()), false);
-    session& s = conn->default_session();
-    session_ptr p = s.ptr();
-    session_ptr p2 = s.ptr();
-}
-
-int main(int argc, char** argv) {
-    int failed = 0;
-    failed += run_test(&test_counted<counted_ptr<connection>,
-                       counted_ptr<session> >, "counted");
-
-#if PN_HAS_STD_PTR
-    failed += run_test(&test_owning<
-                       std::shared_ptr<connection>,
-                       std::shared_ptr<session> >,
-                       "std::shared");
-    failed += run_test(&test_owning<
-                       std::unique_ptr<connection>,
-                       std::unique_ptr<session> >,
-                       "std::unique");
-#endif
-#if PN_HAS_BOOST
-    failed += run_test(&test_owning<
-                       boost::shared_ptr<connection>,
-                       boost::shared_ptr<session> >,
-                       "boost::shared");
-    failed += run_test(&test_counted<
-                       boost::intrusive_ptr<connection>,
-                       boost::intrusive_ptr<session> >,
-                       "boost::intrusive");
-#endif
-    return failed;
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/counted_ptr.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/counted_ptr.cpp b/proton-c/bindings/cpp/src/counted_ptr.cpp
new file mode 100644
index 0000000..261d5ec
--- /dev/null
+++ b/proton-c/bindings/cpp/src/counted_ptr.cpp
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <proton/object.h>
+
+namespace proton {
+
+void incref(const void* p) {
+    if (p) ::pn_incref(const_cast<void*>(p));
+}
+
+void decref(const void* p) {
+    if (p) ::pn_decref(const_cast<void*>(p));
+}
+
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/data.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/data.cpp b/proton-c/bindings/cpp/src/data.cpp
index 0c47019..8a45d6b 100644
--- a/proton-c/bindings/cpp/src/data.cpp
+++ b/proton-c/bindings/cpp/src/data.cpp
@@ -26,35 +26,48 @@
 
 namespace proton {
 
-void data::operator delete(void *p) { ::pn_data_free(reinterpret_cast<pn_data_t*>(p)); }
+data& data::operator=(const data& x) { ::pn_data_copy(pn_object(), x.pn_object()); return *this; }
 
-data& data::operator=(const data& x) { ::pn_data_copy(pn_cast(this), pn_cast(&x)); return *this; }
+void data::clear() { ::pn_data_clear(pn_object()); }
 
-void data::clear() { ::pn_data_clear(pn_cast(this)); }
+bool data::empty() const { return ::pn_data_size(pn_object()) == 0; }
+
+uintptr_t data::point() const { return pn_data_point(pn_object()); }
+
+void data::restore(uintptr_t h) { pn_data_restore(pn_object(), h); }
+
+void data::narrow() { pn_data_narrow(pn_object()); }
+
+void data::widen() { pn_data_widen(pn_object()); }
+
+int data::append(data src) { return pn_data_append(pn_object(), src.pn_object());}
+
+int data::appendn(data src, int limit) { return pn_data_appendn(pn_object(), src.pn_object(), limit);}
+
+bool data::next() const { return pn_data_next(pn_object()); }
 
-bool data::empty() const { return ::pn_data_size(pn_cast(this)) == 0; }
 
 namespace {
 struct save_state {
-    pn_data_t* data;
-    pn_handle_t handle;
-    save_state(pn_data_t* d) : data(d), handle(pn_data_point(d)) {}
-    ~save_state() { if (data) pn_data_restore(data, handle); }
+    data data_;
+    uintptr_t handle;
+    save_state(data d) : data_(d), handle(data_.point()) {}
+    ~save_state() { if (!!data_) data_.restore(handle); }
 };
 }
 
 std::ostream& operator<<(std::ostream& o, const data& d) {
-    save_state(pn_cast(&d));
+    save_state s(d.pn_object());
     d.decoder().rewind();
-    return o << inspectable(pn_cast(&d));
+    return o << inspectable(d.pn_object());
 }
 
-pn_unique_ptr<data> data::create() { return pn_unique_ptr<data>(cast(::pn_data(0))); }
+owned_object<pn_data_t> data::create() { return pn_data(0); }
 
-encoder& data::encoder() { return reinterpret_cast<class encoder&>(*this); }
-decoder& data::decoder() { return reinterpret_cast<class decoder&>(*this); }
+encoder data::encoder() { return proton::encoder(pn_object()); }
+decoder data::decoder() { return proton::decoder(pn_object()); }
 
-type_id data::type() const { return reinterpret_cast<const class decoder&>(*this).type(); }
+type_id data::type() const { return decoder().type(); }
 
 namespace {
 
@@ -69,7 +82,7 @@ template <class T> int compare(const T& a, const T& b) {
 }
 
 int compare_container(data& a, data& b) {
-    decoder::scope sa(a.decoder()), sb(b.decoder());
+    scope sa(a.decoder()), sb(b.decoder());
     // Compare described vs. not-described.
     int cmp = compare(sa.is_described, sb.is_described);
     if (cmp) return cmp;
@@ -129,8 +142,8 @@ int compare_next(data& a, data& b) {
 }
 
 int compare(data& a, data& b) {
-    save_state(pn_cast(&a));
-    save_state(pn_cast(&b));
+    save_state s1(a);
+    save_state s2(b);
     a.decoder().rewind();
     b.decoder().rewind();
     while (a.decoder().more() && b.decoder().more()) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/decoder.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/decoder.cpp b/proton-c/bindings/cpp/src/decoder.cpp
index cab7826..f14345d 100644
--- a/proton-c/bindings/cpp/src/decoder.cpp
+++ b/proton-c/bindings/cpp/src/decoder.cpp
@@ -47,9 +47,9 @@ struct save_state {
 };
 
 struct narrow {
-    pn_data_t* data;
-    narrow(pn_data_t* d) : data(d) { pn_data_narrow(d); }
-    ~narrow() { pn_data_widen(data); }
+    data data_;
+    narrow(data d) : data_(d) { data_.narrow(); }
+    ~narrow() { data_.widen(); }
 };
 
 template <class T> T check(T result) {
@@ -61,10 +61,10 @@ template <class T> T check(T result) {
 }
 
 void decoder::decode(const char* i, size_t size) {
-    save_state ss(pn_cast(this));
+    save_state ss(pn_object());
     const char* end = i + size;
     while (i < end) {
-        i += check(pn_data_decode(pn_cast(this), i, end - i));
+        i += check(pn_data_decode(pn_object(), i, end - i));
     }
 }
 
@@ -73,17 +73,17 @@ void decoder::decode(const std::string& buffer) {
 }
 
 bool decoder::more() const {
-    save_state ss(pn_cast(this));
-    return pn_data_next(pn_cast(this));
+    save_state ss(pn_object());
+    return pn_data_next(pn_object());
 }
 
-void decoder::rewind() { pn_data_rewind(pn_cast(this)); }
+void decoder::rewind() { ::pn_data_rewind(pn_object()); }
 
-void decoder::backup() { pn_data_prev(pn_cast(this)); }
+void decoder::backup() { ::pn_data_prev(pn_object()); }
 
-void decoder::skip() { pn_data_next(pn_cast(this)); }
+void decoder::skip() { ::pn_data_next(pn_object()); }
 
-data& decoder::data() { return *data::cast(pn_cast(this)); }
+data decoder::data() { return proton::data(pn_object()); }
 
 namespace {
 
@@ -115,23 +115,24 @@ void decoder::check_type(type_id want) {
 }
 
 type_id decoder::type() const {
-    save_state ss(pn_cast(this));
-    return pre_get(pn_cast(this));
+    save_state ss(pn_object());
+    return pre_get(pn_object());
 }
 
-decoder& operator>>(decoder& d, start& s) {
-    save_state ss(pn_cast(&d));
-    s.type = pre_get(pn_cast(&d));
+decoder operator>>(decoder d0, start& s) {
+    pn_data_t* d = d0.pn_object();
+    save_state ss(d);
+    s.type = pre_get(d);
     switch (s.type) {
       case ARRAY:
-        s.size = pn_data_get_array(pn_cast(&d));
-        s.element = type_id(pn_data_get_array_type(pn_cast(&d))); s.is_described = pn_data_is_array_described(pn_cast(&d));
+        s.size = pn_data_get_array(d);
+        s.element = type_id(pn_data_get_array_type(d)); s.is_described = pn_data_is_array_described(d);
         break;
       case LIST:
-        s.size = pn_data_get_list(pn_cast(&d));
+        s.size = pn_data_get_list(d);
         break;
       case MAP:
-        s.size = pn_data_get_map(pn_cast(&d));
+        s.size = pn_data_get_map(d);
         break;
       case DESCRIBED:
         s.is_described = true;
@@ -140,32 +141,32 @@ decoder& operator>>(decoder& d, start& s) {
       default:
         throw decode_error(MSG("" << s.type << " is not a container type"));
     }
-    pn_data_enter(pn_cast(&d));
+    pn_data_enter(d);
     ss.cancel();
-    return d;
+    return d0;
 }
 
-decoder& operator>>(decoder& d, finish) { pn_data_exit(pn_cast(&d)); return d; }
+decoder operator>>(decoder d, finish) { pn_data_exit(d.pn_object()); return d; }
 
-decoder& operator>>(decoder& d, skip) { pn_data_next(pn_cast(&d)); return d; }
+decoder operator>>(decoder d, skip) { pn_data_next(d.pn_object()); return d; }
 
-decoder& operator>>(decoder& d, assert_type a) { bad_type(a.type, d.type()); return d; }
+decoder operator>>(decoder d, assert_type a) { bad_type(a.type, d.type()); return d; }
 
-decoder& operator>>(decoder& d, rewind) { d.rewind(); return d; }
+decoder operator>>(decoder d, rewind) { d.rewind(); return d; }
 
-decoder& operator>>(decoder& d, value& v) {
-    pn_data_t *ddata = pn_cast(&d);
-    pn_data_t *vdata = pn_cast(&v.encoder());
-    if (ddata == vdata) throw decode_error("extract into self");
+decoder operator>>(decoder d, value& v) {
+    data ddata = d.data();
+    if (object_base(ddata) == v.data_) throw decode_error("extract into self");
+    data vdata = v.encoder().data();
     {
         narrow n(ddata);
-        check(pn_data_appendn(vdata, ddata, 1));
+        check(vdata.appendn(ddata, 1));
     }
-    if (!pn_data_next(ddata)) throw decode_error("no more data");
+    if (!ddata.next()) throw decode_error("no more data");
     return d;
 }
 
-decoder& operator>>(decoder& d, message_id& id) {
+decoder operator>>(decoder d, message_id& id) {
     switch (d.type()) {
       case ULONG:
       case UUID:
@@ -178,174 +179,185 @@ decoder& operator>>(decoder& d, message_id& id) {
     };
 }
 
-decoder& operator>>(decoder& d, amqp_null) {
-    save_state ss(pn_cast(&d));
-    bad_type(NULL_, pre_get(pn_cast(&d)));
+decoder operator>>(decoder d, amqp_null) {
+    save_state ss(d.pn_object());
+    bad_type(NULL_, pre_get(d.pn_object()));
     return d;
 }
 
-decoder& operator>>(decoder& d, amqp_boolean& value) {
-    extract(pn_cast(&d), value, pn_data_get_bool);
+decoder operator>>(decoder d, amqp_boolean& value) {
+    extract(d.pn_object(), value, pn_data_get_bool);
     return d;
 }
 
-decoder& operator>>(decoder& d, amqp_ubyte& value) {
-    save_state ss(pn_cast(&d));
-    switch (pre_get(pn_cast(&d))) {
-      case UBYTE: value = pn_data_get_ubyte(pn_cast(&d)); break;
-      default: bad_type(UBYTE, type_id(type_id(pn_data_type(pn_cast(&d)))));
+decoder operator>>(decoder d0, amqp_ubyte& value) {
+    pn_data_t* d = d0.pn_object();
+    save_state ss(d);
+    switch (pre_get(d)) {
+      case UBYTE: value = pn_data_get_ubyte(d); break;
+      default: bad_type(UBYTE, type_id(type_id(pn_data_type(d))));
     }
     ss.cancel();
-    return d;
+    return d0;
 }
 
-decoder& operator>>(decoder& d, amqp_byte& value) {
-    save_state ss(pn_cast(&d));
-    switch (pre_get(pn_cast(&d))) {
-      case BYTE: value = pn_data_get_byte(pn_cast(&d)); break;
-      default: bad_type(BYTE, type_id(type_id(pn_data_type(pn_cast(&d)))));
+decoder operator>>(decoder d0, amqp_byte& value) {
+    pn_data_t* d = d0.pn_object();
+    save_state ss(d);
+    switch (pre_get(d)) {
+      case BYTE: value = pn_data_get_byte(d); break;
+      default: bad_type(BYTE, type_id(type_id(pn_data_type(d))));
     }
     ss.cancel();
-    return d;
+    return d0;
 }
 
-decoder& operator>>(decoder& d, amqp_ushort& value) {
-    save_state ss(pn_cast(&d));
-    switch (pre_get(pn_cast(&d))) {
-      case UBYTE: value = pn_data_get_ubyte(pn_cast(&d)); break;
-      case USHORT: value = pn_data_get_ushort(pn_cast(&d)); break;
-      default: bad_type(USHORT, type_id(type_id(pn_data_type(pn_cast(&d)))));
+decoder operator>>(decoder d0, amqp_ushort& value) {
+    pn_data_t* d = d0.pn_object();
+    save_state ss(d);
+    switch (pre_get(d)) {
+      case UBYTE: value = pn_data_get_ubyte(d); break;
+      case USHORT: value = pn_data_get_ushort(d); break;
+      default: bad_type(USHORT, type_id(type_id(pn_data_type(d))));
     }
     ss.cancel();
-    return d;
+    return d0;
 }
 
-decoder& operator>>(decoder& d, amqp_short& value) {
-    save_state ss(pn_cast(&d));
-    switch (pre_get(pn_cast(&d))) {
-      case BYTE: value = pn_data_get_byte(pn_cast(&d)); break;
-      case SHORT: value = pn_data_get_short(pn_cast(&d)); break;
-      default: bad_type(SHORT, type_id(pn_data_type(pn_cast(&d))));
+decoder operator>>(decoder d0, amqp_short& value) {
+    pn_data_t* d = d0.pn_object();
+    save_state ss(d);
+    switch (pre_get(d)) {
+      case BYTE: value = pn_data_get_byte(d); break;
+      case SHORT: value = pn_data_get_short(d); break;
+      default: bad_type(SHORT, type_id(pn_data_type(d)));
     }
     ss.cancel();
-    return d;
+    return d0;
 }
 
-decoder& operator>>(decoder& d, amqp_uint& value) {
-    save_state ss(pn_cast(&d));
-    switch (pre_get(pn_cast(&d))) {
-      case UBYTE: value = pn_data_get_ubyte(pn_cast(&d)); break;
-      case USHORT: value = pn_data_get_ushort(pn_cast(&d)); break;
-      case UINT: value = pn_data_get_uint(pn_cast(&d)); break;
-      default: bad_type(UINT, type_id(pn_data_type(pn_cast(&d))));
+decoder operator>>(decoder d0, amqp_uint& value) {
+    pn_data_t* d = d0.pn_object();
+    save_state ss(d);
+    switch (pre_get(d)) {
+      case UBYTE: value = pn_data_get_ubyte(d); break;
+      case USHORT: value = pn_data_get_ushort(d); break;
+      case UINT: value = pn_data_get_uint(d); break;
+      default: bad_type(UINT, type_id(pn_data_type(d)));
     }
     ss.cancel();
-    return d;
+    return d0;
 }
 
-decoder& operator>>(decoder& d, amqp_int& value) {
-    save_state ss(pn_cast(&d));
-    switch (pre_get(pn_cast(&d))) {
-      case BYTE: value = pn_data_get_byte(pn_cast(&d)); break;
-      case SHORT: value = pn_data_get_short(pn_cast(&d)); break;
-      case INT: value = pn_data_get_int(pn_cast(&d)); break;
-      default: bad_type(INT, type_id(pn_data_type(pn_cast(&d))));
+decoder operator>>(decoder d0, amqp_int& value) {
+    pn_data_t* d = d0.pn_object();
+    save_state ss(d);
+    switch (pre_get(d)) {
+      case BYTE: value = pn_data_get_byte(d); break;
+      case SHORT: value = pn_data_get_short(d); break;
+      case INT: value = pn_data_get_int(d); break;
+      default: bad_type(INT, type_id(pn_data_type(d)));
     }
     ss.cancel();
-    return d;
-}
-
-decoder& operator>>(decoder& d, amqp_ulong& value) {
-    save_state ss(pn_cast(&d));
-    switch (pre_get(pn_cast(&d))) {
-      case UBYTE: value = pn_data_get_ubyte(pn_cast(&d)); break;
-      case USHORT: value = pn_data_get_ushort(pn_cast(&d)); break;
-      case UINT: value = pn_data_get_uint(pn_cast(&d)); break;
-      case ULONG: value = pn_data_get_ulong(pn_cast(&d)); break;
-      default: bad_type(ULONG, type_id(pn_data_type(pn_cast(&d))));
+    return d0;
+}
+
+decoder operator>>(decoder d0, amqp_ulong& value) {
+    pn_data_t* d = d0.pn_object();
+    save_state ss(d);
+    switch (pre_get(d)) {
+      case UBYTE: value = pn_data_get_ubyte(d); break;
+      case USHORT: value = pn_data_get_ushort(d); break;
+      case UINT: value = pn_data_get_uint(d); break;
+      case ULONG: value = pn_data_get_ulong(d); break;
+      default: bad_type(ULONG, type_id(pn_data_type(d)));
     }
     ss.cancel();
-    return d;
-}
-
-decoder& operator>>(decoder& d, amqp_long& value) {
-    save_state ss(pn_cast(&d));
-    switch (pre_get(pn_cast(&d))) {
-      case BYTE: value = pn_data_get_byte(pn_cast(&d)); break;
-      case SHORT: value = pn_data_get_short(pn_cast(&d)); break;
-      case INT: value = pn_data_get_int(pn_cast(&d)); break;
-      case LONG: value = pn_data_get_long(pn_cast(&d)); break;
-      default: bad_type(LONG, type_id(pn_data_type(pn_cast(&d))));
+    return d0;
+}
+
+decoder operator>>(decoder d0, amqp_long& value) {
+    pn_data_t* d = d0.pn_object();
+    save_state ss(d);
+    switch (pre_get(d)) {
+      case BYTE: value = pn_data_get_byte(d); break;
+      case SHORT: value = pn_data_get_short(d); break;
+      case INT: value = pn_data_get_int(d); break;
+      case LONG: value = pn_data_get_long(d); break;
+      default: bad_type(LONG, type_id(pn_data_type(d)));
     }
     ss.cancel();
-    return d;
+    return d0;
 }
 
-decoder& operator>>(decoder& d, amqp_char& value) {
-    extract(pn_cast(&d), value, pn_data_get_char);
+decoder operator>>(decoder d, amqp_char& value) {
+    extract(d.pn_object(), value, pn_data_get_char);
     return d;
 }
 
-decoder& operator>>(decoder& d, amqp_timestamp& value) {
-    extract(pn_cast(&d), value, pn_data_get_timestamp);
+decoder operator>>(decoder d, amqp_timestamp& value) {
+    extract(d.pn_object(), value, pn_data_get_timestamp);
     return d;
 }
 
-decoder& operator>>(decoder& d, amqp_float& value) {
-    save_state ss(pn_cast(&d));
-    switch (pre_get(pn_cast(&d))) {
-      case FLOAT: value = pn_data_get_float(pn_cast(&d)); break;
-      case DOUBLE: value = pn_data_get_double(pn_cast(&d)); break;
-      default: bad_type(FLOAT, type_id(pn_data_type(pn_cast(&d))));
+decoder operator>>(decoder d0, amqp_float& value) {
+    pn_data_t* d = d0.pn_object();
+    save_state ss(d);
+    switch (pre_get(d)) {
+      case FLOAT: value = pn_data_get_float(d); break;
+      case DOUBLE: value = pn_data_get_double(d); break;
+      default: bad_type(FLOAT, type_id(pn_data_type(d)));
     }
     ss.cancel();
-    return d;
+    return d0;
 }
 
-decoder& operator>>(decoder& d, amqp_double& value) {
-    save_state ss(pn_cast(&d));
-    switch (pre_get(pn_cast(&d))) {
-      case FLOAT: value = pn_data_get_float(pn_cast(&d)); break;
-      case DOUBLE: value = pn_data_get_double(pn_cast(&d)); break;
-      default: bad_type(DOUBLE, type_id(pn_data_type(pn_cast(&d))));
+decoder operator>>(decoder d0, amqp_double& value) {
+    pn_data_t* d = d0.pn_object();
+    save_state ss(d);
+    switch (pre_get(d)) {
+      case FLOAT: value = pn_data_get_float(d); break;
+      case DOUBLE: value = pn_data_get_double(d); break;
+      default: bad_type(DOUBLE, type_id(pn_data_type(d)));
     }
     ss.cancel();
-    return d;
+    return d0;
 }
 
-decoder& operator>>(decoder& d, amqp_decimal32& value) {
-    extract(pn_cast(&d), value, pn_data_get_decimal32);
+decoder operator>>(decoder d, amqp_decimal32& value) {
+    extract(d.pn_object(), value, pn_data_get_decimal32);
     return d;
 }
 
-decoder& operator>>(decoder& d, amqp_decimal64& value) {
-    extract(pn_cast(&d), value, pn_data_get_decimal64);
+decoder operator>>(decoder d, amqp_decimal64& value) {
+    extract(d.pn_object(), value, pn_data_get_decimal64);
     return d;
 }
 
-decoder& operator>>(decoder& d, amqp_decimal128& value)  {
-    extract(pn_cast(&d), value, pn_data_get_decimal128);
+decoder operator>>(decoder d, amqp_decimal128& value)  {
+    extract(d.pn_object(), value, pn_data_get_decimal128);
     return d;
 }
 
-decoder& operator>>(decoder& d, amqp_uuid& value)  {
-    extract(pn_cast(&d), value, pn_data_get_uuid);
+decoder operator>>(decoder d, amqp_uuid& value)  {
+    extract(d.pn_object(), value, pn_data_get_uuid);
     return d;
 }
 
-decoder& operator>>(decoder& d, std::string& value) {
-    save_state ss(pn_cast(&d));
-    switch (pre_get(pn_cast(&d))) {
-      case STRING: value = str(pn_data_get_string(pn_cast(&d))); break;
-      case BINARY: value = str(pn_data_get_binary(pn_cast(&d))); break;
-      case SYMBOL: value = str(pn_data_get_symbol(pn_cast(&d))); break;
-      default: bad_type(STRING, type_id(pn_data_type(pn_cast(&d))));
+decoder operator>>(decoder d0, std::string& value) {
+    pn_data_t* d = d0.pn_object();
+    save_state ss(d);
+    switch (pre_get(d)) {
+      case STRING: value = str(pn_data_get_string(d)); break;
+      case BINARY: value = str(pn_data_get_binary(d)); break;
+      case SYMBOL: value = str(pn_data_get_symbol(d)); break;
+      default: bad_type(STRING, type_id(pn_data_type(d)));
     }
     ss.cancel();
-    return d;
+    return d0;
 }
 
-void assert_map_scope(const decoder::scope& s) {
+void assert_map_scope(const scope& s) {
     if (s.type != MAP)
         throw decode_error("cannot decode "+type_name(s.type)+" as map");
     if (s.size % 2 != 0)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/delivery.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/delivery.cpp b/proton-c/bindings/cpp/src/delivery.cpp
index d02904f..e6c5a54 100644
--- a/proton-c/bindings/cpp/src/delivery.cpp
+++ b/proton-c/bindings/cpp/src/delivery.cpp
@@ -24,22 +24,23 @@
 
 namespace proton {
 
-bool delivery::settled() const { return pn_delivery_settled(pn_cast(this)); }
+bool delivery::settled() const { return pn_delivery_settled(pn_object()); }
 
-void delivery::settle() { pn_delivery_settle(pn_cast(this)); }
+void delivery::settle() { pn_delivery_settle(pn_object()); }
 
-void delivery::update(delivery::state state) { pn_delivery_update(pn_cast(this), state); }
+void delivery::update(delivery::state state) { pn_delivery_update(pn_object(), state); }
 
 void delivery::settle(delivery::state state) {
     update(state);
     settle();
 }
 
-bool delivery::partial()  const { return pn_delivery_partial(pn_cast(this)); }
-bool delivery::readable() const { return pn_delivery_readable(pn_cast(this)); }
-bool delivery::writable() const { return pn_delivery_writable(pn_cast(this)); }
-bool delivery::updated()  const { return pn_delivery_updated(pn_cast(this)); }
+bool delivery::partial()  const { return pn_delivery_partial(pn_object()); }
+bool delivery::readable() const { return pn_delivery_readable(pn_object()); }
+bool delivery::writable() const { return pn_delivery_writable(pn_object()); }
+bool delivery::updated()  const { return pn_delivery_updated(pn_object()); }
+size_t delivery::pending() const { return pn_delivery_pending(pn_object()); }
 
-void delivery::clear()  { pn_delivery_clear(pn_cast(this)); }
-delivery::state delivery::remote_state() const { return state(pn_delivery_remote_state(pn_cast(this))); }
+void delivery::clear()  { pn_delivery_clear(pn_object()); }
+delivery::state delivery::remote_state() const { return state(pn_delivery_remote_state(pn_object())); }
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/encoder.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/encoder.cpp b/proton-c/bindings/cpp/src/encoder.cpp
index c8e6928..a0b10c0 100644
--- a/proton-c/bindings/cpp/src/encoder.cpp
+++ b/proton-c/bindings/cpp/src/encoder.cpp
@@ -48,19 +48,19 @@ void check(int result, pn_data_t* data) {
 }
 
 bool encoder::encode(char* buffer, size_t& size) {
-    save_state ss(pn_cast(this)); // In case of error
-    ssize_t result = pn_data_encode(pn_cast(this), buffer, size);
+    save_state ss(pn_object()); // In case of error
+    ssize_t result = pn_data_encode(pn_object(), buffer, size);
     if (result == PN_OVERFLOW) {
-        result = pn_data_encoded_size(pn_cast(this));
+        result = pn_data_encoded_size(pn_object());
         if (result >= 0) {
             size = result;
             return false;
         }
     }
-    check(result, pn_cast(this));
+    check(result, pn_object());
     size = result;
     ss.cancel();                // Don't restore state, all is well.
-    pn_data_clear(pn_cast(this));
+    pn_data_clear(pn_object());
     return true;
 }
 
@@ -78,29 +78,29 @@ std::string encoder::encode() {
     return s;
 }
 
-data& encoder::data() { return *data::cast(pn_cast(this)); }
+data encoder::data() { return proton::data(pn_object()); }
 
-encoder& operator<<(encoder& e, const start& s) {
+encoder operator<<(encoder e, const start& s) {
     switch (s.type) {
-      case ARRAY: pn_data_put_array(pn_cast(&e), s.is_described, pn_type_t(s.element)); break;
-      case MAP: pn_data_put_map(pn_cast(&e)); break;
-      case LIST: pn_data_put_list(pn_cast(&e)); break;
-      case DESCRIBED: pn_data_put_described(pn_cast(&e)); break;
+      case ARRAY: pn_data_put_array(e.pn_object(), s.is_described, pn_type_t(s.element)); break;
+      case MAP: pn_data_put_map(e.pn_object()); break;
+      case LIST: pn_data_put_list(e.pn_object()); break;
+      case DESCRIBED: pn_data_put_described(e.pn_object()); break;
       default:
         throw encode_error(MSG("" << s.type << " is not a container type"));
     }
-    pn_data_enter(pn_cast(&e));
+    pn_data_enter(e.pn_object());
     return e;
 }
 
-encoder& operator<<(encoder& e, finish) {
-    pn_data_exit(pn_cast(&e));
+encoder operator<<(encoder e, finish) {
+    pn_data_exit(e.pn_object());
     return e;
 }
 
 namespace {
 template <class T, class U>
-encoder& insert(encoder& e, pn_data_t* data, T& value, int (*put)(pn_data_t*, U)) {
+encoder insert(encoder e, pn_data_t* data, T& value, int (*put)(pn_data_t*, U)) {
     save_state ss(data);         // Save state in case of error.
     check(put(data, value), data);
     ss.cancel();                // Don't restore state, all is good.
@@ -108,36 +108,36 @@ encoder& insert(encoder& e, pn_data_t* data, T& value, int (*put)(pn_data_t*, U)
 }
 }
 
-encoder& operator<<(encoder& e, amqp_null) { pn_data_put_null(pn_cast(&e)); return e; }
-encoder& operator<<(encoder& e, amqp_boolean value) { return insert(e, pn_cast(&e), value, pn_data_put_bool); }
-encoder& operator<<(encoder& e, amqp_ubyte value) { return insert(e, pn_cast(&e), value, pn_data_put_ubyte); }
-encoder& operator<<(encoder& e, amqp_byte value) { return insert(e, pn_cast(&e), value, pn_data_put_byte); }
-encoder& operator<<(encoder& e, amqp_ushort value) { return insert(e, pn_cast(&e), value, pn_data_put_ushort); }
-encoder& operator<<(encoder& e, amqp_short value) { return insert(e, pn_cast(&e), value, pn_data_put_short); }
-encoder& operator<<(encoder& e, amqp_uint value) { return insert(e, pn_cast(&e), value, pn_data_put_uint); }
-encoder& operator<<(encoder& e, amqp_int value) { return insert(e, pn_cast(&e), value, pn_data_put_int); }
-encoder& operator<<(encoder& e, amqp_char value) { return insert(e, pn_cast(&e), value, pn_data_put_char); }
-encoder& operator<<(encoder& e, amqp_ulong value) { return insert(e, pn_cast(&e), value, pn_data_put_ulong); }
-encoder& operator<<(encoder& e, amqp_long value) { return insert(e, pn_cast(&e), value, pn_data_put_long); }
-encoder& operator<<(encoder& e, amqp_timestamp value) { return insert(e, pn_cast(&e), value, pn_data_put_timestamp); }
-encoder& operator<<(encoder& e, amqp_float value) { return insert(e, pn_cast(&e), value, pn_data_put_float); }
-encoder& operator<<(encoder& e, amqp_double value) { return insert(e, pn_cast(&e), value, pn_data_put_double); }
-encoder& operator<<(encoder& e, amqp_decimal32 value) { return insert(e, pn_cast(&e), value, pn_data_put_decimal32); }
-encoder& operator<<(encoder& e, amqp_decimal64 value) { return insert(e, pn_cast(&e), value, pn_data_put_decimal64); }
-encoder& operator<<(encoder& e, amqp_decimal128 value) { return insert(e, pn_cast(&e), value, pn_data_put_decimal128); }
-encoder& operator<<(encoder& e, amqp_uuid value) { return insert(e, pn_cast(&e), value, pn_data_put_uuid); }
-encoder& operator<<(encoder& e, amqp_string value) { return insert(e, pn_cast(&e), value, pn_data_put_string); }
-encoder& operator<<(encoder& e, amqp_symbol value) { return insert(e, pn_cast(&e), value, pn_data_put_symbol); }
-encoder& operator<<(encoder& e, amqp_binary value) { return insert(e, pn_cast(&e), value, pn_data_put_binary); }
-
-encoder& operator<<(encoder& e, const value& v) {
-    pn_data_t *edata = pn_cast(&e);
-    pn_data_t *vdata = pn_cast(&v.decoder());
-    if (edata == vdata) throw encode_error("cannot insert into self");
-    check(pn_data_append(edata, vdata), edata);
+encoder operator<<(encoder e, amqp_null) { pn_data_put_null(e.pn_object()); return e; }
+encoder operator<<(encoder e, amqp_boolean value) { return insert(e, e.pn_object(), value, pn_data_put_bool); }
+encoder operator<<(encoder e, amqp_ubyte value) { return insert(e, e.pn_object(), value, pn_data_put_ubyte); }
+encoder operator<<(encoder e, amqp_byte value) { return insert(e, e.pn_object(), value, pn_data_put_byte); }
+encoder operator<<(encoder e, amqp_ushort value) { return insert(e, e.pn_object(), value, pn_data_put_ushort); }
+encoder operator<<(encoder e, amqp_short value) { return insert(e, e.pn_object(), value, pn_data_put_short); }
+encoder operator<<(encoder e, amqp_uint value) { return insert(e, e.pn_object(), value, pn_data_put_uint); }
+encoder operator<<(encoder e, amqp_int value) { return insert(e, e.pn_object(), value, pn_data_put_int); }
+encoder operator<<(encoder e, amqp_char value) { return insert(e, e.pn_object(), value, pn_data_put_char); }
+encoder operator<<(encoder e, amqp_ulong value) { return insert(e, e.pn_object(), value, pn_data_put_ulong); }
+encoder operator<<(encoder e, amqp_long value) { return insert(e, e.pn_object(), value, pn_data_put_long); }
+encoder operator<<(encoder e, amqp_timestamp value) { return insert(e, e.pn_object(), value, pn_data_put_timestamp); }
+encoder operator<<(encoder e, amqp_float value) { return insert(e, e.pn_object(), value, pn_data_put_float); }
+encoder operator<<(encoder e, amqp_double value) { return insert(e, e.pn_object(), value, pn_data_put_double); }
+encoder operator<<(encoder e, amqp_decimal32 value) { return insert(e, e.pn_object(), value, pn_data_put_decimal32); }
+encoder operator<<(encoder e, amqp_decimal64 value) { return insert(e, e.pn_object(), value, pn_data_put_decimal64); }
+encoder operator<<(encoder e, amqp_decimal128 value) { return insert(e, e.pn_object(), value, pn_data_put_decimal128); }
+encoder operator<<(encoder e, amqp_uuid value) { return insert(e, e.pn_object(), value, pn_data_put_uuid); }
+encoder operator<<(encoder e, amqp_string value) { return insert(e, e.pn_object(), value, pn_data_put_string); }
+encoder operator<<(encoder e, amqp_symbol value) { return insert(e, e.pn_object(), value, pn_data_put_symbol); }
+encoder operator<<(encoder e, amqp_binary value) { return insert(e, e.pn_object(), value, pn_data_put_binary); }
+
+encoder operator<<(encoder e, const value& v) {
+    data edata = e.data();
+    if (object_base(edata) == v.data_) throw encode_error("cannot insert into self");
+    data vdata = v.decoder().data();
+    check(edata.append(vdata), e.pn_object());
     return e;
 }
 
-encoder& operator<<(encoder& e, const message_id& v) { return e << v.value_; }
+encoder operator<<(encoder e, const message_id& v) { return e << v.value_; }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/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 34ea7c7..dcca7bc 100644
--- a/proton-c/bindings/cpp/src/endpoint.cpp
+++ b/proton-c/bindings/cpp/src/endpoint.cpp
@@ -41,15 +41,14 @@ const int endpoint::LOCAL_MASK = PN_LOCAL_MASK;
 const int endpoint::REMOTE_MASK = PN_REMOTE_MASK;
 
 session_iterator session_iterator::operator++() {
-    ptr_ = session::cast(pn_session_next(pn_cast(ptr_), (pn_state_t) state_));
+    ptr_ = ptr_.next(state_);
     return *this;
 }
 
 link_iterator link_iterator::operator++() {
     do {
-        ptr_ = link::cast(pn_link_next(pn_cast(ptr_), (pn_state_t) state_));
-    } while (ptr_ && session_ && &ptr_->session() != session_);
+        ptr_ = ptr_.next(state_);
+    } while (!!ptr_ && session_ && ptr_.session() != *session_);
     return *this;
 }
-
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/engine.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/engine.cpp b/proton-c/bindings/cpp/src/engine.cpp
index 61d4040..ad3d461 100644
--- a/proton-c/bindings/cpp/src/engine.cpp
+++ b/proton-c/bindings/cpp/src/engine.cpp
@@ -123,8 +123,8 @@ bool engine::closed() const {
     return pn_transport_closed(impl_->transport);
 }
 
-class connection& engine::connection() const {
-    return *connection::cast(impl_->connection);
+class connection engine::connection() const {
+    return impl_->connection;
 }
 
 std::string engine::id() const { return connection().container_id(); }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/event.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/event.cpp b/proton-c/bindings/cpp/src/event.cpp
index a732cc4..54cbbc7 100644
--- a/proton-c/bindings/cpp/src/event.cpp
+++ b/proton-c/bindings/cpp/src/event.cpp
@@ -23,6 +23,7 @@
 #include "proton/event.h"
 
 #include "proton/delivery.hpp"
+#include "proton/engine.hpp"
 #include "proton/error.hpp"
 #include "proton/event.hpp"
 #include "proton/handler.hpp"
@@ -38,37 +39,37 @@ event::event() {}
 
 event::~event() {}
 
-event_loop &event::event_loop() const {
+event_loop& event::event_loop() const {
     throw error(MSG("No event_loop context for event"));
 }
 
-container &event::container() const {
+container& event::container() const {
     // Subclasses to override as appropriate
     throw error(MSG("No container context for event"));
 }
 
-engine &event::engine() const {
+engine& event::engine() const {
     // Subclasses to override as appropriate
     throw error(MSG("No engine context for event"));
 }
 
-connection &event::connection() const {
+connection event::connection() const {
     throw error(MSG("No connection context for event"));
 }
 
-sender& event::sender() const {
+sender event::sender() const {
     throw error(MSG("No sender context for event"));
 }
 
-receiver& event::receiver() const {
+receiver event::receiver() const {
     throw error(MSG("No receiver context for event"));
 }
 
-link& event::link() const {
+link event::link() const {
     throw error(MSG("No link context for event"));
 }
 
-delivery& event::delivery() const {
+delivery event::delivery() const {
     throw error(MSG("No link context for event"));
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/facade.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/facade.cpp b/proton-c/bindings/cpp/src/facade.cpp
deleted file mode 100644
index 6609f79..0000000
--- a/proton-c/bindings/cpp/src/facade.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include "proton/facade.hpp"
-#include <proton/object.h>
-
-#if PN_HAS_CPP11
-#include <type_traits>
-#endif
-
-#include <assert.h>
-
-// For empty check.
-#include "proton/acceptor.hpp"
-#include "proton/connection.hpp"
-#include "proton/data.hpp"
-#include "proton/decoder.hpp"
-#include "proton/delivery.hpp"
-#include "proton/encoder.hpp"
-#include "proton/facade.hpp"
-#include "proton/link.hpp"
-#include "proton/message.hpp"
-#include "proton/session.hpp"
-#include "proton/terminus.hpp"
-#include "proton/transport.hpp"
-
-namespace proton {
-
-void incref(const void* p) {
-    if (p) ::pn_incref(const_cast<void*>(p));
-}
-
-void decref(const void* p) {
-    if (p) ::pn_decref(const_cast<void*>(p));
-}
-
-// Make sure facade types are empty.
-#if PN_HAS_CPP11
-#define CHECK_EMPTY(T) static_assert(std::is_empty<T>::value,  "facade " #T " not empty")
-#else
-#define CHECK_EMPTY(T) struct T##_CHECK_EMPTY__ { char T##__facade_not_empty[sizeof(T) == 1 ? 1 : -1]; }
-#endif
-
-CHECK_EMPTY(acceptor);
-CHECK_EMPTY(connection);
-CHECK_EMPTY(data);
-CHECK_EMPTY(decoder);
-CHECK_EMPTY(delivery);
-CHECK_EMPTY(encoder);
-CHECK_EMPTY(link);
-CHECK_EMPTY(session);
-CHECK_EMPTY(terminus);
-CHECK_EMPTY(transport);
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/interop_test.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/interop_test.cpp b/proton-c/bindings/cpp/src/interop_test.cpp
index 9806dac..b7d6c5b 100644
--- a/proton-c/bindings/cpp/src/interop_test.cpp
+++ b/proton-c/bindings/cpp/src/interop_test.cpp
@@ -56,7 +56,7 @@ void test_data_ostream() {
 void test_decoder_primitves_exact() {
     value dv;
     dv.decoder().decode(read("primitives"));
-    decoder& d(dv.decoder());
+    decoder d(dv.decoder());
     ASSERT(d.more());
     try { get< ::int8_t>(d); FAIL("got bool as byte"); } catch(decode_error){}
     ASSERT_EQUAL(true, get<bool>(d));
@@ -81,7 +81,7 @@ void test_decoder_primitves_exact() {
 // Test inserting primitive sand encoding as AMQP.
 void test_encoder_primitives() {
     value dv;
-    encoder& e = dv.encoder();
+    encoder e = dv.encoder();
     e << true << false;
     e << ::uint8_t(42);
     e << ::uint16_t(42) << ::int16_t(-42);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/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 23345b5..587dec9 100644
--- a/proton-c/bindings/cpp/src/link.cpp
+++ b/proton-c/bindings/cpp/src/link.cpp
@@ -32,59 +32,80 @@
 namespace proton {
 
 void link::open() {
-    pn_link_open(pn_cast(this));
+    pn_link_open(pn_object());
 }
 
 void link::close() {
-    pn_link_close(pn_cast(this));
+    pn_link_close(pn_object());
 }
 
-sender* link::sender() {
-    return pn_link_is_sender(pn_cast(this)) ? reinterpret_cast<class sender*>(this) : 0;
+sender link::sender() {
+    return pn_link_is_sender(pn_object()) ? proton::sender(pn_object()) : proton::sender();
 }
 
-receiver* link::receiver() {
-    return pn_link_is_receiver(pn_cast(this)) ? reinterpret_cast<class receiver*>(this) : 0;
+receiver link::receiver() {
+    return pn_link_is_receiver(pn_object()) ? proton::receiver(pn_object()) : proton::receiver();
 }
 
-const sender* link::sender() const {
-    return pn_link_is_sender(pn_cast(this)) ? reinterpret_cast<const class sender*>(this) : 0;
+const sender link::sender() const {
+    return pn_link_is_sender(pn_object()) ? proton::sender(pn_object()) : proton::sender();
 }
 
-const receiver* link::receiver() const {
-    return pn_link_is_receiver(pn_cast(this)) ? reinterpret_cast<const class receiver*>(this) : 0;
+const receiver link::receiver() const {
+    return pn_link_is_receiver(pn_object()) ? proton::receiver(pn_object()) : proton::receiver();
 }
 
 int link::credit() const {
-    return pn_link_credit(pn_cast(this));
+    return pn_link_credit(pn_object());
 }
 
-terminus& link::source() const { return *terminus::cast(pn_link_source(pn_cast(this))); }
-terminus& link::target() const { return *terminus::cast(pn_link_target(pn_cast(this))); }
-terminus& link::remote_source() const { return *terminus::cast(pn_link_remote_source(pn_cast(this))); }
-terminus& link::remote_target() const { return *terminus::cast(pn_link_remote_target(pn_cast(this))); }
+void link::flow(int credit) {
+    pn_link_flow(pn_object(), credit);
+}
+
+terminus link::source() const { return pn_link_source(pn_object()); }
+terminus link::target() const { return pn_link_target(pn_object()); }
+terminus link::remote_source() const { return pn_link_remote_source(pn_object()); }
+terminus link::remote_target() const { return pn_link_remote_target(pn_object()); }
 
-std::string link::name() const { return std::string(pn_link_name(pn_cast(this)));}
+std::string link::name() const { return std::string(pn_link_name(pn_object()));}
 
-class connection &link::connection() const {
-    return *connection::cast(pn_session_connection(pn_link_session(pn_cast(this))));
+class connection link::connection() const {
+    return pn_session_connection(pn_link_session(pn_object()));
 }
 
-class session &link::session() const {
-    return *session::cast(pn_link_session(pn_cast(this)));
+class session link::session() const {
+    return pn_link_session(pn_object());
 }
 
 void link::handler(class handler &h) {
-    pn_record_t *record = pn_link_attachments(pn_cast(this));
-    connection_context& cc(connection_context::get(pn_cast(&connection())));
+    pn_record_t *record = pn_link_attachments(pn_object());
+    connection_context& cc(connection().context());
     counted_ptr<pn_handler_t> chandler = cc.container_impl->cpp_handler(&h);
     pn_record_set_handler(record, chandler.get());
 }
 
 void link::detach_handler() {
-    pn_record_t *record = pn_link_attachments(pn_cast(this));
+    pn_record_t *record = pn_link_attachments(pn_object());
     pn_record_set_handler(record, 0);
 }
 
-endpoint::state link::state() const { return pn_link_state(pn_cast(this)); }
+endpoint::state link::state() const {
+    return pn_link_state(pn_object());
+}
+
+ssize_t link::recv(char* buffer, size_t size) {
+    return pn_link_recv(pn_object(), buffer, size);
+}
+
+bool link::advance() {
+    return pn_link_advance(pn_object());
 }
+
+link link::next(endpoint::state s) const
+{
+    return pn_link_next(pn_object(), s);
+}
+
+}
+


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org