You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by as...@apache.org on 2015/11/20 16:35:42 UTC

[1/3] 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 commit 2034e

Repository: qpid-proton
Updated Branches:
  refs/heads/master aa226be31 -> 645fe09e4


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/message.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/message.cpp b/proton-c/bindings/cpp/src/message.cpp
index 285771b..7c032f0 100644
--- a/proton-c/bindings/cpp/src/message.cpp
+++ b/proton-c/bindings/cpp/src/message.cpp
@@ -66,9 +66,28 @@ void check(int err) {
 }
 } // namespace
 
-void message::id(const message_id& id) { *data::cast(pn_message_id(message_)) = id.value_; }
+void message::id(const message_id& id) { data(pn_message_id(message_)) = id.value_; }
 
-message_id message::id() const { return message_id(*data::cast(pn_message_id(message_))); }
+namespace {
+inline message_id from_pn_atom(const pn_atom_t& v) {
+  switch (v.type) {
+    case PN_ULONG:
+      return message_id(amqp_ulong(v.u.as_ulong));
+    case PN_UUID:
+      return message_id(amqp_uuid(v.u.as_uuid));
+    case PN_BINARY:
+      return message_id(amqp_binary(v.u.as_bytes));
+    case PN_STRING:
+      return message_id(amqp_string(v.u.as_bytes));
+    default:
+      return message_id();
+  }
+}
+}
+
+message_id message::id() const {
+    return from_pn_atom(pn_message_get_id(message_));
+}
 
 void message::user_id(const std::string &id) {
     check(pn_message_set_user_id(message_, pn_bytes(id)));
@@ -106,11 +125,11 @@ std::string message::reply_to() const {
 }
 
 void message::correlation_id(const message_id& id) {
-    *data::cast(pn_message_correlation_id(message_)) = id.value_;
+    data(pn_message_correlation_id(message_)) = id.value_;
 }
 
 message_id message::correlation_id() const {
-    return message_id(*data::cast(pn_message_correlation_id(message_)));
+    return from_pn_atom(pn_message_get_correlation_id(message_));
 }
 
 void message::content_type(const std::string &s) {
@@ -169,24 +188,24 @@ void message::inferred(bool b) { pn_message_set_inferred(message_, b); }
 
 void message::body(const value& v) { body() = v; }
 
-const data& message::body() const {
-    return *data::cast(pn_message_body(message_));
+const data message::body() const {
+    return pn_message_body(message_);
 }
 
-data& message::body() {
-    return *data::cast(pn_message_body(message_));
+data message::body() {
+    return pn_message_body(message_);
 }
 
 void message::properties(const value& v) {
     properties() = v;
 }
 
-const data& message::properties() const {
-    return *data::cast(pn_message_properties(message_));
+const data message::properties() const {
+    return pn_message_properties(message_);
 }
 
-data& message::properties() {
-    return *data::cast(pn_message_properties(message_));
+data message::properties() {
+    return pn_message_properties(message_);
 }
 
 namespace {
@@ -256,14 +275,14 @@ void message::decode(const std::string &s) {
     check(pn_message_decode(message_, s.data(), s.size()));
 }
 
-void message::decode(proton::link &link, proton::delivery &delivery) {
+void message::decode(proton::link link, proton::delivery delivery) {
     std::string buf;
-    buf.resize(pn_delivery_pending(pn_cast(&delivery)));
-    ssize_t n = pn_link_recv(pn_cast(&link), (char *) buf.data(), buf.size());
+    buf.resize(delivery.pending());
+    ssize_t n = link.recv((char *) buf.data(), buf.size());
     if (n != (ssize_t) buf.size()) throw error(MSG("link read failure"));
     clear();
     decode(buf);
-    pn_link_advance(pn_cast(&link));
+    link.advance();
 }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/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 f155a8d..e3bced8 100644
--- a/proton-c/bindings/cpp/src/messaging_adapter.cpp
+++ b/proton-c/bindings/cpp/src/messaging_adapter.cpp
@@ -68,7 +68,7 @@ void messaging_adapter::on_delivery(event &e) {
     if (pe) {
         pn_event_t *cevent = pe->pn_event();
         pn_link_t *lnk = pn_event_link(cevent);
-        delivery &dlv = pe->delivery();
+        delivery dlv = pe->delivery();
 
         if (pn_link_is_receiver(lnk)) {
             if (!dlv.partial() && dlv.readable()) {
@@ -81,7 +81,7 @@ void messaging_adapter::on_delivery(event &e) {
                 // See PROTON-998
                 class message &msg(ctx.event_message);
                 mevent.message_ = &msg;
-                mevent.message_->decode(*link::cast(lnk), dlv);
+                mevent.message_->decode(lnk, dlv);
                 if (pn_link_state(lnk) & PN_LOCAL_CLOSED) {
                     if (auto_accept_)
                         dlv.release();

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/messaging_event.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_event.cpp b/proton-c/bindings/cpp/src/messaging_event.cpp
index 3a0514d..b1fedc3 100644
--- a/proton-c/bindings/cpp/src/messaging_event.cpp
+++ b/proton-c/bindings/cpp/src/messaging_event.cpp
@@ -55,7 +55,7 @@ messaging_event::~messaging_event() {}
 
 messaging_event::event_type messaging_event::type() const { return type_; }
 
-connection &messaging_event::connection() const {
+connection messaging_event::connection() const {
     if (type_ == messaging_event::PROTON)
         return proton_event::connection();
     if (parent_event_)
@@ -63,7 +63,7 @@ connection &messaging_event::connection() const {
     throw error(MSG("No connection context for event"));
 }
 
-sender& messaging_event::sender() const {
+sender messaging_event::sender() const {
     if (type_ == messaging_event::PROTON)
         return proton_event::sender();
     if (parent_event_)
@@ -71,7 +71,7 @@ sender& messaging_event::sender() const {
     throw error(MSG("No sender context for event"));
 }
 
-receiver& messaging_event::receiver() const {
+receiver messaging_event::receiver() const {
     if (type_ == messaging_event::PROTON)
         return proton_event::receiver();
     if (parent_event_)
@@ -79,7 +79,7 @@ receiver& messaging_event::receiver() const {
     throw error(MSG("No receiver context for event"));
 }
 
-link& messaging_event::link() const {
+link messaging_event::link() const {
     if (type_ == messaging_event::PROTON)
         return proton_event::link();
     if (parent_event_)
@@ -87,7 +87,7 @@ link& messaging_event::link() const {
     throw error(MSG("No link context for event"));
 }
 
-delivery& messaging_event::delivery() const {
+delivery messaging_event::delivery() const {
     if (type_ == messaging_event::PROTON)
         return proton_event::delivery();
     if (parent_event_)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/messaging_event.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_event.hpp b/proton-c/bindings/cpp/src/messaging_event.hpp
index f97d1a5..7d85d2b 100644
--- a/proton-c/bindings/cpp/src/messaging_event.hpp
+++ b/proton-c/bindings/cpp/src/messaging_event.hpp
@@ -88,11 +88,11 @@ class messaging_event : public proton_event
     ~messaging_event();
 
     virtual PN_CPP_EXTERN void dispatch(handler &h);
-    virtual PN_CPP_EXTERN class connection &connection() const;
-    virtual PN_CPP_EXTERN class sender& sender() const;
-    virtual PN_CPP_EXTERN class receiver& receiver() const;
-    virtual PN_CPP_EXTERN class link& link() const;
-    virtual PN_CPP_EXTERN class delivery& delivery() const;
+    virtual PN_CPP_EXTERN class connection connection() const;
+    virtual PN_CPP_EXTERN class sender sender() const;
+    virtual PN_CPP_EXTERN class receiver receiver() const;
+    virtual PN_CPP_EXTERN class link link() const;
+    virtual PN_CPP_EXTERN class delivery delivery() const;
     virtual PN_CPP_EXTERN class message& message() const;
 
     PN_CPP_EXTERN event_type type() const;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/object.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/object.cpp b/proton-c/bindings/cpp/src/object.cpp
new file mode 100644
index 0000000..d5fb7ef
--- /dev/null
+++ b/proton-c/bindings/cpp/src/object.cpp
@@ -0,0 +1,33 @@
+/*
+ * 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.hpp"
+#include <proton/object.h>
+
+namespace proton {
+
+void object_base::incref() const {
+    if (object_) ::pn_incref(const_cast<void*>(object_));
+}
+
+void object_base::decref() const {
+    if (object_) ::pn_decref(const_cast<void*>(object_));
+}
+
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/proton_event.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/proton_event.cpp b/proton-c/bindings/cpp/src/proton_event.cpp
index 068d245..c324985 100644
--- a/proton-c/bindings/cpp/src/proton_event.cpp
+++ b/proton-c/bindings/cpp/src/proton_event.cpp
@@ -49,53 +49,53 @@ std::string proton_event::name() const { return pn_event_type_name(pn_event_type
 
 pn_event_t *proton_event::pn_event() const { return pn_event_; }
 
-event_loop &proton_event::event_loop() const {
+event_loop& proton_event::event_loop() const {
     if (!event_loop_)
         throw error(MSG("No event_loop context for this event"));
     return *event_loop_;
 }
 
-container &proton_event::container() const {
+container& proton_event::container() const {
     class container *c = dynamic_cast<class container*>(event_loop_);
     if (!c)
         throw error(MSG("No container context for this event"));
     return *c;
 }
 
-engine &proton_event::engine() const {
+engine& proton_event::engine() const {
     class engine *e = dynamic_cast<class engine*>(event_loop_);
     if (!e)
         throw error(MSG("No engine context for this event"));
     return *e;
 }
 
-connection &proton_event::connection() const {
+connection proton_event::connection() const {
     pn_connection_t *conn = pn_event_connection(pn_event());
     if (!conn)
         throw error(MSG("No connection context for this event"));
-    return *connection::cast(conn);
+    return conn;
 }
 
-link& proton_event::link() const {
-    class link *lnk = link::cast(pn_event_link(pn_event()));
+link proton_event::link() const {
+    class link lnk = pn_event_link(pn_event());
     if (!lnk) throw error(MSG("No link context for this event"));
-    return *lnk;
+    return lnk;
 }
 
-sender& proton_event::sender() const {
+sender proton_event::sender() const {
     if (!link().sender()) throw error(MSG("No sender context for this event"));
-    return *link().sender();
+    return link().sender();
 }
 
-receiver& proton_event::receiver() const {
+receiver proton_event::receiver() const {
     if (!link().receiver()) throw error(MSG("No receiver context for this event"));
-    return *link().receiver();
+    return link().receiver();
 }
 
-delivery& proton_event::delivery() const {
-    class delivery *dlv = delivery::cast(pn_event_delivery(pn_event()));
+delivery proton_event::delivery() const {
+    pn_delivery_t* dlv = pn_event_delivery(pn_event());
     if (!dlv) throw error(MSG("No delivery context for this event"));
-    return *dlv;
+    return dlv;
 }
 
 void proton_event::dispatch(handler &h) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/proton_event.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/proton_event.hpp b/proton-c/bindings/cpp/src/proton_event.hpp
index e382d8c..04a3e54 100644
--- a/proton-c/bindings/cpp/src/proton_event.hpp
+++ b/proton-c/bindings/cpp/src/proton_event.hpp
@@ -273,14 +273,14 @@ class proton_event : public event
     ///@}
 
     virtual void dispatch(handler &h);
-    virtual class event_loop &event_loop() const;
-    virtual class container &container() const;
-    virtual class engine &engine() const;
-    virtual class connection &connection() const;
-    virtual class sender& sender() const;
-    virtual class receiver& receiver() const;
-    virtual class link& link() const;
-    virtual class delivery& delivery() const;
+    virtual class event_loop& event_loop() const;
+    virtual class container& container() const;
+    virtual class engine& engine() const;
+    virtual class connection connection() const;
+    virtual class sender sender() const;
+    virtual class receiver receiver() const;
+    virtual class link link() const;
+    virtual class delivery delivery() const;
 
     /** Get type of event */
     event_type type() const;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/reactor.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/reactor.cpp b/proton-c/bindings/cpp/src/reactor.cpp
index fcef673..31d3275 100644
--- a/proton-c/bindings/cpp/src/reactor.cpp
+++ b/proton-c/bindings/cpp/src/reactor.cpp
@@ -18,25 +18,65 @@
  */
 
 #include "proton/reactor.hpp"
+#include "proton/acceptor.hpp"
+#include "proton/connection.hpp"
+#include "proton/task.hpp"
+#include "proton/url.hpp"
+
+#include "contexts.hpp"
 
 #include <proton/reactor.h>
 
 namespace proton {
 
-pn_unique_ptr<reactor> reactor::create() {
-    return pn_unique_ptr<reactor>(reactor::cast(pn_reactor()));
+reactor reactor::create() {
+    return reactor(pn_reactor());
+}
+
+void reactor::run() { pn_reactor_run(pn_object()); }
+void reactor::start() { pn_reactor_start(pn_object()); }
+bool reactor::process() { return pn_reactor_process(pn_object()); }
+void reactor::stop() { pn_reactor_stop(pn_object()); }
+void reactor::wakeup() { pn_reactor_wakeup(pn_object()); }
+bool reactor::quiesced() { return pn_reactor_quiesced(pn_object()); }
+void reactor::yield() { pn_reactor_yield(pn_object()); }
+amqp_timestamp reactor::mark() { return pn_reactor_mark(pn_object()); }
+amqp_timestamp reactor::now() { return pn_reactor_now(pn_object()); }
+
+acceptor reactor::listen(const url& url){
+    return pn_reactor_acceptor(pn_object(), url.host().c_str(), url.port().c_str(), 0);
+}
+
+task reactor::schedule(int delay, pn_handler_t* handler) {
+    return pn_reactor_schedule(pn_object(), delay, handler);
+}
+
+connection reactor::connection(pn_handler_t* h) const {
+    return pn_reactor_connection(pn_object(), h);
+}
+
+pn_io_t* reactor::pn_io() const {
+    return pn_reactor_io(pn_object());
 }
 
-void reactor::run() { pn_reactor_run(pn_cast(this)); }
-void reactor::start() { pn_reactor_start(pn_cast(this)); }
-bool reactor::process() { return pn_reactor_process(pn_cast(this)); }
-void reactor::stop() { pn_reactor_stop(pn_cast(this)); }
-void reactor::wakeup() { pn_reactor_wakeup(pn_cast(this)); }
-bool reactor::quiesced() { return pn_reactor_quiesced(pn_cast(this)); }
-void reactor::yield() { pn_reactor_yield(pn_cast(this)); }
+void reactor::pn_handler(pn_handler_t* h) {
+    pn_reactor_set_handler(pn_object(), h);
+}
+
+pn_handler_t* reactor::pn_handler() const {
+    return pn_reactor_get_handler(pn_object());
+}
+
+void reactor::pn_global_handler(pn_handler_t* h) {
+    pn_reactor_set_global_handler(pn_object(), h);
+}
+
+pn_handler_t* reactor::pn_global_handler() const {
+    return pn_reactor_get_global_handler(pn_object());
+}
 
 duration reactor::timeout() {
-    pn_millis_t tmo = pn_reactor_get_timeout(pn_cast(this));
+    pn_millis_t tmo = pn_reactor_get_timeout(pn_object());
     if (tmo == PN_MILLIS_MAX)
         return duration::FOREVER;
     return duration(tmo);
@@ -44,11 +84,14 @@ duration reactor::timeout() {
 
 void reactor::timeout(duration timeout) {
     if (timeout == duration::FOREVER || timeout.milliseconds > PN_MILLIS_MAX)
-        pn_reactor_set_timeout(pn_cast(this), PN_MILLIS_MAX);
+        pn_reactor_set_timeout(pn_object(), PN_MILLIS_MAX);
     else
-        pn_reactor_set_timeout(pn_cast(this), timeout.milliseconds);
+        pn_reactor_set_timeout(pn_object(), timeout.milliseconds);
 }
 
+void reactor::container_context(container& c) {
+    proton::container_context(pn_object(), c);
+}
 
 void reactor::operator delete(void* p) {
     pn_reactor_free(reinterpret_cast<pn_reactor_t*>(p));

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/receiver.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/receiver.cpp b/proton-c/bindings/cpp/src/receiver.cpp
index d997c23..dec9fa6 100644
--- a/proton-c/bindings/cpp/src/receiver.cpp
+++ b/proton-c/bindings/cpp/src/receiver.cpp
@@ -30,9 +30,7 @@
 namespace proton {
 
 void receiver::flow(int count) {
-    pn_link_flow(pn_cast(this), count);
+    pn_link_flow(pn_object(), count);
 }
 
-receiver* receiver::cast(pn_type* p) { return link::cast(p)->receiver(); }
-
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/sender.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/sender.cpp b/proton-c/bindings/cpp/src/sender.cpp
index cd1b0ae..177e6f0 100644
--- a/proton-c/bindings/cpp/src/sender.cpp
+++ b/proton-c/bindings/cpp/src/sender.cpp
@@ -41,19 +41,17 @@ namespace {
 amqp_ulong tag_counter = 0;
 }
 
-delivery& sender::send(const message &message) {
+delivery sender::send(const message &message) {
     amqp_ulong id = ++tag_counter;
     pn_delivery_t *dlv =
-        pn_delivery(pn_cast(this), pn_dtag(reinterpret_cast<const char*>(&id), sizeof(id)));
+        pn_delivery(pn_object(), pn_dtag(reinterpret_cast<const char*>(&id), sizeof(id)));
     std::string buf;
     message.encode(buf);
-    pn_link_send(pn_cast(this), buf.data(), buf.size());
-    pn_link_advance(pn_cast(this));
-    if (pn_link_snd_settle_mode(pn_cast(this)) == PN_SND_SETTLED)
+    pn_link_send(pn_object(), buf.data(), buf.size());
+    pn_link_advance(pn_object());
+    if (pn_link_snd_settle_mode(pn_object()) == PN_SND_SETTLED)
         pn_delivery_settle(dlv);
-    return *delivery::cast(dlv);
+    return dlv;
 }
 
-sender* sender::cast(pn_type* p) { return link::cast(p)->sender(); }
-
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/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 6d0d955..e903080 100644
--- a/proton-c/bindings/cpp/src/session.cpp
+++ b/proton-c/bindings/cpp/src/session.cpp
@@ -30,43 +30,40 @@
 namespace proton {
 
 void session::open() {
-    pn_session_open(pn_cast(this));
+    pn_session_open(pn_object());
 }
 
-connection &session::connection() const {
-    return *proton::connection::cast(pn_session_connection(pn_cast(this)));
+connection session::connection() const {
+    return pn_session_connection(pn_object());
 }
 
 namespace {
 std::string set_name(const std::string& name, session* s) {
     if (name.empty())
-        return connection_context::get(
-            pn_cast(&s->connection())).container_impl->next_link_name();
+        return s->connection().context().container_impl->next_link_name();
     return name;
 }
 }
 
-receiver& session::create_receiver(const std::string& name) {
-    return *reinterpret_cast<receiver*>(
-        pn_receiver(pn_cast(this), set_name(name, this).c_str()));
+receiver session::create_receiver(const std::string& name) {
+    return pn_receiver(pn_object(), set_name(name, this).c_str());
 }
 
-sender& session::create_sender(const std::string& name) {
-    return *reinterpret_cast<sender*>(
-        pn_sender(pn_cast(this), set_name(name, this).c_str()));
+sender session::create_sender(const std::string& name) {
+    return pn_sender(pn_object(), set_name(name, this).c_str());
 }
 
-sender& session::open_sender(const std::string &addr, handler *h) {
-    sender& snd = create_sender();
+sender session::open_sender(const std::string &addr, handler *h) {
+    sender snd = create_sender();
     snd.target().address(addr);
     if (h) snd.handler(*h);
     snd.open();
     return snd;
 }
 
-receiver& session::open_receiver(const std::string &addr, bool dynamic, handler *h)
+receiver session::open_receiver(const std::string &addr, bool dynamic, handler *h)
 {
-    receiver& rcv = create_receiver();
+    receiver rcv = create_receiver();
     rcv.source().address(addr);
     if (dynamic) rcv.source().dynamic(true);
     if (h) rcv.handler(*h);
@@ -74,12 +71,17 @@ receiver& session::open_receiver(const std::string &addr, bool dynamic, handler
     return rcv;
 }
 
-endpoint::state session::state() const { return pn_session_state(pn_cast(this)); }
+session session::next(endpoint::state s) const
+{
+    return pn_session_next(pn_object(), s);
+}
+
+endpoint::state session::state() const { return pn_session_state(pn_object()); }
 
 link_range session::find_links(endpoint::state mask)  const {
     link_range r(connection().find_links(mask));
-    link_iterator i(r.begin(), this);
-    if (i && this != &i->session())
+    link_iterator i(r.begin(), *this);
+    if (i && *this != i->session())
         ++i;
     return link_range(i);
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/task.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/task.cpp b/proton-c/bindings/cpp/src/task.cpp
index 6e6b4a6..7c0a683 100644
--- a/proton-c/bindings/cpp/src/task.cpp
+++ b/proton-c/bindings/cpp/src/task.cpp
@@ -24,6 +24,6 @@
 
 namespace proton {
 
-void task::cancel() { pn_task_cancel(pn_cast(this)); }
+void task::cancel() { pn_task_cancel(pn_object()); }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/terminus.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/terminus.cpp b/proton-c/bindings/cpp/src/terminus.cpp
index 8948eb5..def6aa9 100644
--- a/proton-c/bindings/cpp/src/terminus.cpp
+++ b/proton-c/bindings/cpp/src/terminus.cpp
@@ -25,44 +25,44 @@
 namespace proton {
 
 terminus::type_t terminus::type() const {
-    return (type_t) pn_terminus_get_type(pn_cast(this));
+    return (type_t) pn_terminus_get_type(object_);
 }
 
 void terminus::type(type_t type) {
-    pn_terminus_set_type(pn_cast(this), (pn_terminus_type_t) type);
+    pn_terminus_set_type(object_, (pn_terminus_type_t) type);
 }
 
 terminus::expiry_policy_t terminus::expiry_policy() const {
-    return (expiry_policy_t) pn_terminus_get_type(pn_cast(this));
+    return (expiry_policy_t) pn_terminus_get_type(object_);
 }
 
 void terminus::expiry_policy(expiry_policy_t policy) {
-    pn_terminus_set_expiry_policy(pn_cast(this), (pn_expiry_policy_t) policy);
+    pn_terminus_set_expiry_policy(object_, (pn_expiry_policy_t) policy);
 }
 
 terminus::distribution_mode_t terminus::distribution_mode() const {
-    return (distribution_mode_t) pn_terminus_get_type(pn_cast(this));
+    return (distribution_mode_t) pn_terminus_get_type(object_);
 }
 
 void terminus::distribution_mode(distribution_mode_t mode) {
-    pn_terminus_set_distribution_mode(pn_cast(this), (pn_distribution_mode_t) mode);
+    pn_terminus_set_distribution_mode(object_, (pn_distribution_mode_t) mode);
 }
 
 std::string terminus::address() const {
-    const char *addr = pn_terminus_get_address(pn_cast(this));
+    const char *addr = pn_terminus_get_address(object_);
     return addr ? std::string(addr) : std::string();
 }
 
 void terminus::address(const std::string &addr) {
-    pn_terminus_set_address(pn_cast(this), addr.c_str());
+    pn_terminus_set_address(object_, addr.c_str());
 }
 
 bool terminus::dynamic() const {
-    return (type_t) pn_terminus_is_dynamic(pn_cast(this));
+    return (type_t) pn_terminus_is_dynamic(object_);
 }
 
 void terminus::dynamic(bool d) {
-    pn_terminus_set_dynamic(pn_cast(this), d);
+    pn_terminus_set_dynamic(object_, d);
 }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/transport.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/transport.cpp b/proton-c/bindings/cpp/src/transport.cpp
index 58114ae..6e6e612 100644
--- a/proton-c/bindings/cpp/src/transport.cpp
+++ b/proton-c/bindings/cpp/src/transport.cpp
@@ -24,8 +24,8 @@
 
 namespace proton {
 
-connection* transport::connection() const {
-    return connection::cast(pn_transport_connection(pn_cast(this)));
+connection transport::connection() const {
+    return pn_transport_connection(pn_object());
 }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/src/value.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/value.cpp b/proton-c/bindings/cpp/src/value.cpp
index 7059d69..be5ca5e 100644
--- a/proton-c/bindings/cpp/src/value.cpp
+++ b/proton-c/bindings/cpp/src/value.cpp
@@ -28,27 +28,23 @@ namespace proton {
 
 value::value() : data_(data::create()) {}
 
-value::value(const value& x) : data_(data::create()) { *data_ = *x.data_; }
+value::value(const value& x) : data_(data::create()) { data_ = x.data_; }
 
-value::value(const data& x) : data_(data::create()) { *data_ = x; }
+value& value::operator=(const value& x) { data_ = x.data_; return *this; }
 
-value& value::operator=(const value& x) { *data_ = *x.data_; return *this; }
+void value::clear() { data_.clear(); }
 
-value& value::operator=(const data& x) { *data_ = x; return *this; }
+bool value::empty() const { return data_.empty(); }
 
-void value::clear() { data_->clear(); }
+class encoder value::encoder() { clear(); return data_.encoder(); }
 
-bool value::empty() const { return data_->empty(); }
-
-class encoder& value::encoder() { clear(); return data_->encoder(); }
-
-class decoder& value::decoder() const { data_->decoder().rewind(); return data_->decoder(); }
+class decoder value::decoder() const { data_.decoder().rewind(); return data_.decoder(); }
 
 type_id value::type() const { return decoder().type(); }
 
-bool value::operator==(const value& x) const { return *data_ == *x.data_; }
+bool value::operator==(const value& x) const { return data_ == x.data_; }
 
-bool value::operator<(const value& x) const { return *data_ < *x.data_; }
+bool value::operator<(const value& x) const { return data_ < x.data_; }
 
 std::ostream& operator<<(std::ostream& o, const value& v) {
     // pn_inspect prints strings with quotes which is not normal in C++.
@@ -57,7 +53,7 @@ std::ostream& operator<<(std::ostream& o, const value& v) {
       case SYMBOL:
         return o << v.get<std::string>();
       default:
-        return o << *v.data_;
+        return o << v.data_;
     }
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/tests/tools/apps/cpp/reactor_send.cpp
----------------------------------------------------------------------
diff --git a/tests/tools/apps/cpp/reactor_send.cpp b/tests/tools/apps/cpp/reactor_send.cpp
index 6bdab23..86406f6 100644
--- a/tests/tools/apps/cpp/reactor_send.cpp
+++ b/tests/tools/apps/cpp/reactor_send.cpp
@@ -49,7 +49,7 @@ class reactor_send : public proton::messaging_handler {
     proton::amqp_binary received_content_;
     bool replying_;
     proton::message_id id_value_;
-    pn_reactor_t *reactor_;
+    proton::reactor reactor_;
   public:
 
     reactor_send(const std::string &url, int c, int size, bool replying)
@@ -65,16 +65,16 @@ class reactor_send : public proton::messaging_handler {
 
     void on_start(proton::event &e) {
         e.container().open_sender(url_);
-        reactor_ = pn_cast(&e.container().reactor());
+        reactor_ = e.container().reactor();
     }
 
     void on_sendable(proton::event &e) {
-        proton::sender& sender = e.sender();
+        proton::sender sender = e.sender();
 
         while (sender.credit() && sent_ < total_) {
             id_value_ = sent_ + 1;
             message_.correlation_id(id_value_);
-            proton::amqp_timestamp reactor_now(pn_reactor_now(reactor_));
+            proton::amqp_timestamp reactor_now(reactor_.now());
             message_.creation_time(reactor_now);
             sender.send(message_);
             sent_++;


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


[2/3] 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 commit 2034e

Posted by as...@apache.org.
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


[3/3] 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 commit 2034e

Posted by as...@apache.org.
NO-JIRA: C++: Changed the API to no longer require use of external reference counting
pointers.
Squashed commit of:
commit e488552ac50c2c1cb569c94450e10dbde6d5a5eb
commit c7a86c91b7b41f3659d28d1229cd7073eb1f2e2a
commit 2034e83fca2f24c118e83f01ce0cd468c7796c4d
commit 72f0b533fc4e9f7a761d1141d62fadf15a0ce84c
commit 5f4991f7f73e795d4624582f0cc2b4e9381c9d5a
commit 756bcfdcdcda36cddfaead71f4cddb3f1b4dee16
commit 0bc309e5989f07320317a9f1198d5c27d1285119
commit c0bb30077a1fa522535cc92c46d3582c26aa4005
commit 29c9ec4aa3642135140606fcbea72608e9ade611


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/645fe09e
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/645fe09e
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/645fe09e

Branch: refs/heads/master
Commit: 645fe09e47477372f84ae176518148c2bd3de396
Parents: aa226be
Author: Andrew Stitcher <as...@apache.org>
Authored: Fri Nov 20 10:17:20 2015 -0500
Committer: Andrew Stitcher <as...@apache.org>
Committed: Fri Nov 20 10:17:20 2015 -0500

----------------------------------------------------------------------
 examples/cpp/broker.hpp                         |  43 +--
 examples/cpp/client.cpp                         |  14 +-
 examples/cpp/direct_recv.cpp                    |   6 +-
 examples/cpp/direct_send.cpp                    |   8 +-
 examples/cpp/encode_decode.cpp                  |   2 +-
 examples/cpp/example_test.py                    |   4 +-
 examples/cpp/helloworld.cpp                     |   2 +-
 examples/cpp/helloworld_blocking.cpp            |   1 +
 examples/cpp/helloworld_direct.cpp              |   7 +-
 examples/cpp/recurring_timer.cpp                |  10 +-
 examples/cpp/server.cpp                         |  12 +-
 examples/cpp/server_direct.cpp                  |  12 +-
 examples/cpp/simple_recv.cpp                    |   4 +-
 examples/cpp/simple_send.cpp                    |   6 +-
 proton-c/bindings/cpp/CMakeLists.txt            |   4 +-
 .../bindings/cpp/include/proton/acceptor.hpp    |   6 +-
 .../cpp/include/proton/blocking_connection.hpp  |   3 +-
 .../cpp/include/proton/blocking_link.hpp        |   5 +-
 .../cpp/include/proton/blocking_receiver.hpp    |   2 +-
 .../cpp/include/proton/blocking_sender.hpp      |   6 +-
 .../bindings/cpp/include/proton/connection.hpp  |  29 +-
 .../bindings/cpp/include/proton/container.hpp   |  12 +-
 .../bindings/cpp/include/proton/counted_ptr.hpp |   2 +-
 proton-c/bindings/cpp/include/proton/data.hpp   |  37 ++-
 .../bindings/cpp/include/proton/decoder.hpp     | 112 ++++----
 .../bindings/cpp/include/proton/delivery.hpp    |  12 +-
 .../bindings/cpp/include/proton/encoder.hpp     | 105 +++----
 .../bindings/cpp/include/proton/endpoint.hpp    |  37 +--
 proton-c/bindings/cpp/include/proton/engine.hpp |   2 +-
 proton-c/bindings/cpp/include/proton/event.hpp  |  16 +-
 .../bindings/cpp/include/proton/event_loop.hpp  |   5 +-
 proton-c/bindings/cpp/include/proton/facade.hpp | 145 ----------
 .../bindings/cpp/include/proton/handler.hpp     |   1 +
 proton-c/bindings/cpp/include/proton/link.hpp   |  54 +++-
 .../bindings/cpp/include/proton/message.hpp     |  11 +-
 .../bindings/cpp/include/proton/message_id.hpp  |   7 +-
 .../cpp/include/proton/messaging_adapter.hpp    |   1 -
 proton-c/bindings/cpp/include/proton/object.hpp | 113 ++++++++
 .../bindings/cpp/include/proton/reactor.hpp     |  38 ++-
 .../bindings/cpp/include/proton/receiver.hpp    |   6 +-
 proton-c/bindings/cpp/include/proton/sender.hpp |   8 +-
 .../bindings/cpp/include/proton/session.hpp     |  30 +-
 proton-c/bindings/cpp/include/proton/task.hpp   |   6 +-
 .../bindings/cpp/include/proton/terminus.hpp    |   8 +-
 .../bindings/cpp/include/proton/transport.hpp   |   8 +-
 proton-c/bindings/cpp/include/proton/url.hpp    |   1 -
 proton-c/bindings/cpp/include/proton/value.hpp  |  21 +-
 proton-c/bindings/cpp/src/acceptor.cpp          |   2 +-
 .../bindings/cpp/src/blocking_connection.cpp    |   2 +-
 .../cpp/src/blocking_connection_impl.cpp        |  28 +-
 .../cpp/src/blocking_connection_impl.hpp        |   2 +-
 proton-c/bindings/cpp/src/blocking_fetcher.cpp  |  17 +-
 proton-c/bindings/cpp/src/blocking_fetcher.hpp  |   4 +-
 proton-c/bindings/cpp/src/blocking_link.cpp     |  41 ++-
 proton-c/bindings/cpp/src/blocking_receiver.cpp |  18 +-
 proton-c/bindings/cpp/src/blocking_sender.cpp   |  26 +-
 proton-c/bindings/cpp/src/connection.cpp        |  45 +--
 proton-c/bindings/cpp/src/connector.cpp         |   9 +-
 proton-c/bindings/cpp/src/connector.hpp         |   2 +-
 proton-c/bindings/cpp/src/container.cpp         |  15 +-
 proton-c/bindings/cpp/src/container_impl.cpp    |  47 ++-
 proton-c/bindings/cpp/src/container_impl.hpp    |  19 +-
 proton-c/bindings/cpp/src/contexts.hpp          |   2 +-
 proton-c/bindings/cpp/src/conversion_test.cpp   |  74 -----
 proton-c/bindings/cpp/src/counted_ptr.cpp       |  32 +++
 proton-c/bindings/cpp/src/data.cpp              |  47 +--
 proton-c/bindings/cpp/src/decoder.cpp           | 286 ++++++++++---------
 proton-c/bindings/cpp/src/delivery.cpp          |  19 +-
 proton-c/bindings/cpp/src/encoder.cpp           |  86 +++---
 proton-c/bindings/cpp/src/endpoint.cpp          |   7 +-
 proton-c/bindings/cpp/src/engine.cpp            |   4 +-
 proton-c/bindings/cpp/src/event.cpp             |  17 +-
 proton-c/bindings/cpp/src/facade.cpp            |  70 -----
 proton-c/bindings/cpp/src/interop_test.cpp      |   4 +-
 proton-c/bindings/cpp/src/link.cpp              |  69 +++--
 proton-c/bindings/cpp/src/message.cpp           |  51 ++--
 proton-c/bindings/cpp/src/messaging_adapter.cpp |   4 +-
 proton-c/bindings/cpp/src/messaging_event.cpp   |  10 +-
 proton-c/bindings/cpp/src/messaging_event.hpp   |  10 +-
 proton-c/bindings/cpp/src/object.cpp            |  33 +++
 proton-c/bindings/cpp/src/proton_event.cpp      |  30 +-
 proton-c/bindings/cpp/src/proton_event.hpp      |  16 +-
 proton-c/bindings/cpp/src/reactor.cpp           |  67 ++++-
 proton-c/bindings/cpp/src/receiver.cpp          |   4 +-
 proton-c/bindings/cpp/src/sender.cpp            |  14 +-
 proton-c/bindings/cpp/src/session.cpp           |  38 +--
 proton-c/bindings/cpp/src/task.cpp              |   2 +-
 proton-c/bindings/cpp/src/terminus.cpp          |  20 +-
 proton-c/bindings/cpp/src/transport.cpp         |   4 +-
 proton-c/bindings/cpp/src/value.cpp             |  22 +-
 tests/tools/apps/cpp/reactor_send.cpp           |   8 +-
 91 files changed, 1205 insertions(+), 1106 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/broker.hpp
----------------------------------------------------------------------
diff --git a/examples/cpp/broker.hpp b/examples/cpp/broker.hpp
index 51dcaa3..32fd5c7 100644
--- a/examples/cpp/broker.hpp
+++ b/examples/cpp/broker.hpp
@@ -43,17 +43,17 @@ class queue {
 
     std::string name() const { return name_; }
 
-    void subscribe(proton::sender &s) {
-        consumers_.push_back(s.ptr());
+    void subscribe(proton::sender s) {
+        consumers_.push_back(s);
     }
 
     // Return true if queue can be deleted.
-    bool unsubscribe(proton::sender &s) {
-        consumers_.remove(s.ptr());
+    bool unsubscribe(proton::sender s) {
+        consumers_.remove(s);
         return (consumers_.size() == 0 && (dynamic_ || messages_.size() == 0));
     }
 
-    void publish(const proton::message &m, proton::receiver *r) {
+    void publish(const proton::message &m, proton::receiver r) {
         messages_.push_back(m);
         dispatch(0);
     }
@@ -69,7 +69,7 @@ class queue {
         bool result = false;
         sender_list::iterator it = consumers_.begin();
         if (!s && count)
-            s = it->get();
+            s = &*it;
 
         while (messages_.size()) {
             if (s->credit()) {
@@ -88,7 +88,7 @@ class queue {
 
   private:
     typedef std::deque<proton::message> message_queue;
-    typedef std::list<proton::counted_ptr<proton::sender> > sender_list;
+    typedef std::list<proton::sender> sender_list;
 
     std::string name_;
     bool dynamic_;
@@ -136,13 +136,13 @@ class broker_handler : public proton::messaging_handler {
     broker_handler(queues& qs) : queues_(qs) {}
 
     void on_link_opening(proton::event &e) {
-        proton::link& lnk = e.link();
-        if (lnk.sender()) {
-            proton::terminus &remote_source(lnk.remote_source());
+        proton::link lnk = e.link();
+        if (!!lnk.sender()) {
+            proton::terminus remote_source(lnk.remote_source());
             queue &q = remote_source.dynamic() ?
                 queues_.dynamic() : queues_.get(remote_source.address());
             lnk.source().address(q.name());
-            q.subscribe(*lnk.sender());
+            q.subscribe(lnk.sender());
             std::cout << "broker outgoing link from " << q.name() << std::endl;
         }
         else {                  // Receiver
@@ -154,16 +154,16 @@ class broker_handler : public proton::messaging_handler {
         }
     }
 
-    void unsubscribe (proton::sender &lnk) {
+    void unsubscribe (proton::sender lnk) {
         std::string address = lnk.source().address();
         if (queues_.get(address).unsubscribe(lnk))
             queues_.erase(address);
     }
 
     void on_link_closing(proton::event &e) {
-        proton::link &lnk = e.link();
-        if (lnk.sender()) 
-            unsubscribe(*lnk.sender());
+        proton::link lnk = e.link();
+        if (!!lnk.sender()) 
+            unsubscribe(lnk.sender());
     }
 
     void on_connection_closing(proton::event &e) {
@@ -174,18 +174,19 @@ class broker_handler : public proton::messaging_handler {
         remove_stale_consumers(e.connection());
     }
 
-    void remove_stale_consumers(proton::connection &connection) {
-        proton::link_range r = connection.find_links(proton::endpoint::REMOTE_ACTIVE);
+    void remove_stale_consumers(proton::connection connection) {
+      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());
+            if (!!l->sender())
+                unsubscribe(l->sender());
         }
     }
 
     void on_sendable(proton::event &e) {
-        proton::link& lnk = e.link();
+        proton::link lnk = e.link();
         std::string address = lnk.source().address();
-        queues_.get(address).dispatch(lnk.sender());
+        proton::sender s = lnk.sender();
+        queues_.get(address).dispatch(&s);
     }
 
     void on_message(proton::event &e) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/client.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/client.cpp b/examples/cpp/client.cpp
index 05924f6..7e576b1 100644
--- a/examples/cpp/client.cpp
+++ b/examples/cpp/client.cpp
@@ -31,27 +31,27 @@ class client : public proton::messaging_handler {
   private:
     proton::url url;
     std::vector<std::string> requests;
-    proton::counted_ptr<proton::sender> sender;
-    proton::counted_ptr<proton::receiver> receiver;
+    proton::sender sender;
+    proton::receiver receiver;
 
   public:
     client(const proton::url &u, const std::vector<std::string>& r) : url(u), requests(r) {}
 
     void on_start(proton::event &e) {
-        sender = e.container().open_sender(url).ptr();
+        sender = e.container().open_sender(url);
         // Create a receiver with a dynamically chosen unique address.
-        receiver = sender->connection().open_receiver("", true/*dynamic*/).ptr();
+        receiver = sender.connection().open_receiver("", true/*dynamic*/);
     }
 
     void send_request() {
         proton::message req;
         req.body(requests.front());
-        req.reply_to(receiver->remote_source().address());
-        sender->send(req);
+        req.reply_to(receiver.remote_source().address());
+        sender.send(req);
     }
 
     void on_link_opened(proton::event &e) {
-        if (&e.link() == receiver.get())
+        if (e.link() == receiver)
             send_request();
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/direct_recv.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/direct_recv.cpp b/examples/cpp/direct_recv.cpp
index 50ada7c..ad16d26 100644
--- a/examples/cpp/direct_recv.cpp
+++ b/examples/cpp/direct_recv.cpp
@@ -36,13 +36,13 @@ class direct_recv : public proton::messaging_handler {
     proton::url url;
     uint64_t expected;
     uint64_t received;
-    proton::counted_ptr<proton::acceptor> acceptor;
+    proton::acceptor acceptor;
 
   public:
     direct_recv(const std::string &s, int c) : url(s), expected(c), received(0) {}
 
     void on_start(proton::event &e) {
-        acceptor = e.container().listen(url).ptr();
+        acceptor = e.container().listen(url);
         std::cout << "direct_recv listening on " << url << std::endl;
     }
 
@@ -57,7 +57,7 @@ class direct_recv : public proton::messaging_handler {
         if (received == expected) {
             e.receiver().close();
             e.connection().close();
-            if (acceptor) acceptor->close();
+            if (!!acceptor) acceptor.close();
         }
     }
 };

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/direct_send.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/direct_send.cpp b/examples/cpp/direct_send.cpp
index 13ca510..909ef3f 100644
--- a/examples/cpp/direct_send.cpp
+++ b/examples/cpp/direct_send.cpp
@@ -36,18 +36,18 @@ class simple_send : public proton::messaging_handler {
     int sent;
     int confirmed;
     int total;
-    proton::counted_ptr<proton::acceptor> acceptor;
+    proton::acceptor acceptor;
   public:
 
     simple_send(const std::string &s, int c) : url(s), sent(0), confirmed(0), total(c) {}
 
     void on_start(proton::event &e) {
-        acceptor = e.container().listen(url).ptr();
+        acceptor = e.container().listen(url);
         std::cout << "direct_send listening on " << url << std::endl;
     }
 
     void on_sendable(proton::event &e) {
-        proton::sender& sender = e.sender();
+        proton::sender sender = e.sender();
         while (sender.credit() && sent < total) {
             proton::message msg;
             msg.id(sent + 1);
@@ -64,7 +64,7 @@ class simple_send : public proton::messaging_handler {
         if (confirmed == total) {
             std::cout << "all messages confirmed" << std::endl;
             e.connection().close();
-            acceptor->close();
+            acceptor.close();
         }
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/encode_decode.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/encode_decode.cpp b/examples/cpp/encode_decode.cpp
index 1ed8b64..aced54b 100644
--- a/examples/cpp/encode_decode.cpp
+++ b/examples/cpp/encode_decode.cpp
@@ -231,7 +231,7 @@ void print_next(proton::decoder& d) {
 
 // Print a value, for example purposes. Normal code can use operator<<
 void print(proton::value& v) {
-    proton::decoder& d = v.decoder();
+    proton::decoder d = v.decoder();
     d.rewind();
     while (d.more()) {
         print_next(d);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/example_test.py
----------------------------------------------------------------------
diff --git a/examples/cpp/example_test.py b/examples/cpp/example_test.py
index 51b215e..2f8b08c 100644
--- a/examples/cpp/example_test.py
+++ b/examples/cpp/example_test.py
@@ -122,7 +122,7 @@ class ExampleTest(unittest.TestCase):
 
     def test_helloworld_blocking(self):
         b = Broker.get()
-        hw = execute("helloworld_blocking", b.addr, b.addr)
+        hw = execute("helloworld_blocking", b.addr)
         self.assertEqual('"Hello World!"\n', hw)
 
     def test_helloworld_direct(self):
@@ -180,7 +180,7 @@ class ExampleTest(unittest.TestCase):
         finally:
             server.kill()
 
-    def test_request_response(self):
+    def test_request_response_sync(self):
         b = Broker.get()
         server = background("server", "-a", b.addr)
         try:

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/helloworld.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld.cpp b/examples/cpp/helloworld.cpp
index d6caa27..b18c151 100644
--- a/examples/cpp/helloworld.cpp
+++ b/examples/cpp/helloworld.cpp
@@ -34,7 +34,7 @@ class hello_world : public proton::messaging_handler {
     hello_world(const proton::url& u) : url(u) {}
 
     void on_start(proton::event &e) {
-        proton::connection& conn = e.container().connect(url);
+        proton::connection conn = e.container().connect(url);
         conn.open_receiver(url.path());
         conn.open_sender(url.path());
     }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/helloworld_blocking.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld_blocking.cpp b/examples/cpp/helloworld_blocking.cpp
index 81a56b9..a67276e 100644
--- a/examples/cpp/helloworld_blocking.cpp
+++ b/examples/cpp/helloworld_blocking.cpp
@@ -24,6 +24,7 @@
 #include "proton/blocking_sender.hpp"
 #include "proton/blocking_receiver.hpp"
 #include "proton/duration.hpp"
+#include "proton/url.hpp"
 
 #include <iostream>
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/helloworld_direct.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld_direct.cpp b/examples/cpp/helloworld_direct.cpp
index d055fde..826b371 100644
--- a/examples/cpp/helloworld_direct.cpp
+++ b/examples/cpp/helloworld_direct.cpp
@@ -23,19 +23,18 @@
 #include "proton/container.hpp"
 #include "proton/messaging_handler.hpp"
 
-//#include "proton/acceptor.hpp"
 #include <iostream>
 
 class hello_world_direct : public proton::messaging_handler {
   private:
     proton::url url;
-    proton::counted_ptr<proton::acceptor> acceptor;
+    proton::acceptor acceptor;
   public:
 
     hello_world_direct(const proton::url& u) : url(u) {}
 
     void on_start(proton::event &e) {
-        acceptor = e.container().listen(url).ptr();
+        acceptor = e.container().listen(url);
         e.container().open_sender(url);
     }
 
@@ -54,7 +53,7 @@ class hello_world_direct : public proton::messaging_handler {
     }
 
     void on_connection_closed(proton::event &e) {
-        acceptor->close();
+        acceptor.close();
     }
 };
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/recurring_timer.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/recurring_timer.cpp b/examples/cpp/recurring_timer.cpp
index 7d4b508..4beaaf6 100644
--- a/examples/cpp/recurring_timer.cpp
+++ b/examples/cpp/recurring_timer.cpp
@@ -46,12 +46,12 @@ class recurring : public proton::messaging_handler {
     int remaining_msecs, tick_ms;
     ticker tick_handler;
     tocker tock_handler;
-    proton::task *cancel_task;
+    proton::task cancel_task;
   public:
 
     recurring(int msecs, int tickms) : remaining_msecs(msecs), tick_ms(tickms), cancel_task(0) {}
 
-    proton::task& ticktock(proton::event &e) {
+    proton::task ticktock(proton::event &e) {
         // Show timer events in separate handlers.
         e.container().schedule(tick_ms, &tick_handler);
         return e.container().schedule(tick_ms * 3, &tock_handler);
@@ -59,13 +59,13 @@ class recurring : public proton::messaging_handler {
 
     void on_start(proton::event &e) {
         // Demonstrate cancel(), we will cancel the first tock on the first recurring::on_timer_task
-        cancel_task = &ticktock(e);
+        cancel_task = ticktock(e);
         e.container().schedule(0);
     }
 
     void on_timer_task(proton::event &e) {
-        if (cancel_task) {
-            cancel_task->cancel();
+        if (!!cancel_task) {
+            cancel_task.cancel();
             cancel_task = 0;
             e.container().schedule(tick_ms * 4);
         } else {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/server.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/server.cpp b/examples/cpp/server.cpp
index fd00eb1..fc2b462 100644
--- a/examples/cpp/server.cpp
+++ b/examples/cpp/server.cpp
@@ -32,9 +32,9 @@
 
 class server : public proton::messaging_handler {
   private:
-    typedef std::map<std::string, proton::counted_ptr<proton::sender> > sender_map;
+    typedef std::map<std::string, proton::sender> sender_map;
     proton::url url;
-    proton::counted_ptr<proton::connection> connection;
+    proton::connection connection;
     sender_map senders;
 
   public:
@@ -42,8 +42,8 @@ class server : public proton::messaging_handler {
     server(const std::string &u) : url(u) {}
 
     void on_start(proton::event &e) {
-        connection = e.container().connect(url).ptr();
-        connection->open_receiver(url.path());
+        connection = e.container().connect(url);
+        connection.open_receiver(url.path());
         std::cout << "server connected to " << url << std::endl;
     }
 
@@ -62,8 +62,8 @@ class server : public proton::messaging_handler {
         reply.body(to_upper(e.message().body().get<std::string>()));
         reply.correlation_id(e.message().correlation_id());
         if (!senders[reply_to])
-            senders[reply_to] = connection->open_sender(reply_to).ptr();
-        senders[reply_to]->send(reply);
+            senders[reply_to] = connection.open_sender(reply_to);
+        senders[reply_to].send(reply);
     }
 };
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/server_direct.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/server_direct.cpp b/examples/cpp/server_direct.cpp
index 76bb5ad..8bbcefe 100644
--- a/examples/cpp/server_direct.cpp
+++ b/examples/cpp/server_direct.cpp
@@ -34,7 +34,7 @@
 
 class server : public proton::messaging_handler {
   private:
-    typedef std::map<std::string, proton::counted_ptr<proton::sender> > sender_map;
+    typedef std::map<std::string, proton::sender> sender_map;
     proton::url url;
     sender_map senders;
     int address_counter;
@@ -62,10 +62,10 @@ class server : public proton::messaging_handler {
     }
 
     void on_link_opening(proton::event& e) {
-        proton::link& link = e.link();
-        if (link.sender() && link.remote_source().dynamic()) {
+        proton::link link = e.link();
+        if (!!link.sender() && link.remote_source().dynamic()) {
             link.source().address(generate_address());
-            senders[link.source().address()] = link.sender()->ptr();
+            senders[link.source().address()] = link.sender();
         }
     }
 
@@ -76,12 +76,12 @@ class server : public proton::messaging_handler {
         if (it == senders.end()) {
             std::cout << "No link for reply_to: " << reply_to << std::endl;
         } else {
-            proton::counted_ptr<proton::sender> sender = it->second;
+            proton::sender sender = it->second;
             proton::message reply;
             reply.address(reply_to);
             reply.body(to_upper(e.message().body().get<std::string>()));
             reply.correlation_id(e.message().correlation_id());
-            sender->send(reply);
+            sender.send(reply);
         }
     }
 };

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/simple_recv.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/simple_recv.cpp b/examples/cpp/simple_recv.cpp
index bcb28e3..1e0d071 100644
--- a/examples/cpp/simple_recv.cpp
+++ b/examples/cpp/simple_recv.cpp
@@ -35,7 +35,7 @@
 class simple_recv : public proton::messaging_handler {
   private:
     proton::url url;
-    proton::counted_ptr<proton::receiver> receiver;
+    proton::receiver receiver;
     uint64_t expected;
     uint64_t received;
   public:
@@ -43,7 +43,7 @@ class simple_recv : public proton::messaging_handler {
     simple_recv(const std::string &s, int c) : url(s), expected(c), received(0) {}
 
     void on_start(proton::event &e) {
-        receiver = e.container().open_receiver(url).ptr();
+        receiver = e.container().open_receiver(url);
         std::cout << "simple_recv listening on " << url << std::endl;
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/simple_send.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/simple_send.cpp b/examples/cpp/simple_send.cpp
index 31e2c73..4d056fc 100644
--- a/examples/cpp/simple_send.cpp
+++ b/examples/cpp/simple_send.cpp
@@ -32,7 +32,7 @@
 class simple_send : public proton::messaging_handler {
   private:
     proton::url url;
-    proton::counted_ptr<proton::sender> sender;
+    proton::sender sender;
     int sent;
     int confirmed;
     int total;
@@ -41,11 +41,11 @@ class simple_send : public proton::messaging_handler {
     simple_send(const std::string &s, int c) : url(s), sent(0), confirmed(0), total(c) {}
 
     void on_start(proton::event &e) {
-        sender = e.container().open_sender(url).ptr();
+        sender = e.container().open_sender(url);
     }
 
     void on_sendable(proton::event &e) {
-        proton::sender& sender = e.sender();
+        proton::sender sender = e.sender();
         while (sender.credit() && sent < total) {
             proton::message msg;
             msg.id(sent + 1);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt
index 7660961..bf9af46 100644
--- a/proton-c/bindings/cpp/CMakeLists.txt
+++ b/proton-c/bindings/cpp/CMakeLists.txt
@@ -36,6 +36,7 @@ set(qpid-proton-cpp-source
   src/connector.cpp
   src/container.cpp
   src/container_impl.cpp
+  src/counted_ptr.cpp
   src/contexts.cpp
   src/data.cpp
   src/decoder.cpp
@@ -46,13 +47,13 @@ set(qpid-proton-cpp-source
   src/engine.cpp
   src/error.cpp
   src/event.cpp
-  src/facade.cpp
   src/handler.cpp
   src/link.cpp
   src/message.cpp
   src/messaging_adapter.cpp
   src/messaging_event.cpp
   src/messaging_handler.cpp
+  src/object.cpp
   src/proton_bits.cpp
   src/proton_event.cpp
   src/proton_handler.cpp
@@ -163,5 +164,4 @@ endmacro(add_cpp_test)
 
 add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests)
 add_cpp_test(message_test)
-add_cpp_test(conversion_test)
 add_cpp_test(encode_decode_test)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/acceptor.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/acceptor.hpp b/proton-c/bindings/cpp/include/proton/acceptor.hpp
index ed7c852..c4fbdde 100644
--- a/proton-c/bindings/cpp/include/proton/acceptor.hpp
+++ b/proton-c/bindings/cpp/include/proton/acceptor.hpp
@@ -24,16 +24,18 @@
 
 #include "proton/reactor.h"
 #include "proton/export.hpp"
-#include "proton/facade.hpp"
+#include "proton/object.hpp"
 
 struct pn_connection_t;
 
 namespace proton {
 
 /** acceptor accepts connections. @see container::listen */
-class acceptor : public counted_facade<pn_acceptor_t, acceptor>
+class acceptor : public object<pn_acceptor_t>
 {
   public:
+    acceptor(pn_acceptor_t* a=0) : object(a) {}
+
     /** close the acceptor */
     PN_CPP_EXTERN void close();
 };

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/blocking_connection.hpp b/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
index 87e9b2e..bcdf0e7 100644
--- a/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
+++ b/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
@@ -22,7 +22,6 @@
  *
  */
 
-#include "proton/pn_unique_ptr.hpp"
 #include "proton/export.hpp"
 #include "proton/duration.hpp"
 #include "proton/pn_unique_ptr.hpp"
@@ -43,7 +42,7 @@ class blocking_connection
     PN_CPP_EXTERN ~blocking_connection();
     PN_CPP_EXTERN void close();
     PN_CPP_EXTERN duration timeout() const;
-    PN_CPP_EXTERN class connection& connection() const;
+    PN_CPP_EXTERN class connection connection() const;
 
   private:
     blocking_connection(const blocking_connection&);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/blocking_link.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/blocking_link.hpp b/proton-c/bindings/cpp/include/proton/blocking_link.hpp
index 6913654..2b0a089 100644
--- a/proton-c/bindings/cpp/include/proton/blocking_link.hpp
+++ b/proton-c/bindings/cpp/include/proton/blocking_link.hpp
@@ -24,6 +24,7 @@
 #include "proton/export.hpp"
 #include "proton/counted_ptr.hpp"
 #include "proton/duration.hpp"
+#include "proton/link.hpp"
 
 #include <string>
 
@@ -40,12 +41,12 @@ class blocking_link
 
   protected:
     blocking_link(blocking_connection&);
-    void open(link&);
+    void open(link);
     void check_closed();
     void wait_for_closed();
 
     blocking_connection& connection_;
-    counted_ptr<link> link_;
+    link link_;
 
   private:
     blocking_link(const blocking_link&);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/blocking_receiver.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/blocking_receiver.hpp b/proton-c/bindings/cpp/include/proton/blocking_receiver.hpp
index 3bd657d..4d3b9fc 100644
--- a/proton-c/bindings/cpp/include/proton/blocking_receiver.hpp
+++ b/proton-c/bindings/cpp/include/proton/blocking_receiver.hpp
@@ -52,7 +52,7 @@ class blocking_receiver : public blocking_link
     PN_CPP_EXTERN void settle(delivery::state state);
     PN_CPP_EXTERN void flow(int count);
 
-    PN_CPP_EXTERN class receiver& receiver();
+    PN_CPP_EXTERN class receiver receiver();
   private:
     pn_unique_ptr<blocking_fetcher> fetcher_;
 };

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/blocking_sender.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/blocking_sender.hpp b/proton-c/bindings/cpp/include/proton/blocking_sender.hpp
index b7c2697..a544e75 100644
--- a/proton-c/bindings/cpp/include/proton/blocking_sender.hpp
+++ b/proton-c/bindings/cpp/include/proton/blocking_sender.hpp
@@ -39,10 +39,10 @@ class blocking_sender : public blocking_link
     PN_CPP_EXTERN blocking_sender(class blocking_connection &c, const std::string &address);
     PN_CPP_EXTERN ~blocking_sender();
 
-    PN_CPP_EXTERN delivery& send(const message &msg);
-    PN_CPP_EXTERN delivery& send(const message &msg, duration timeout);
+    PN_CPP_EXTERN delivery send(const message &msg);
+    PN_CPP_EXTERN delivery send(const message &msg, duration timeout);
 
-    PN_CPP_EXTERN class sender& sender() const;
+    PN_CPP_EXTERN class sender sender() const;
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/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 68d46a3..e38148b 100644
--- a/proton-c/bindings/cpp/include/proton/connection.hpp
+++ b/proton-c/bindings/cpp/include/proton/connection.hpp
@@ -23,7 +23,9 @@
  */
 #include "proton/export.hpp"
 #include "proton/endpoint.hpp"
-#include "proton/container.hpp"
+#include "proton/link.hpp"
+#include "proton/object.hpp"
+#include "proton/session.hpp"
 #include "proton/types.h"
 #include <string>
 
@@ -31,13 +33,18 @@ struct pn_connection_t;
 
 namespace proton {
 
+class connection_context;
 class handler;
 class engine;
 
 /** connection to a remote AMQP peer. */
-class connection : public counted_facade<pn_connection_t, connection, endpoint>
+class connection : public object<pn_connection_t>, endpoint
 {
   public:
+    connection(pn_connection_t* c=0) : object(c) {}
+
+    /// Get the connection context object from the connection
+    PN_CPP_EXTERN connection_context& context() const;
 
     /// Get the event_loop, can be a container or an engine.
     PN_CPP_EXTERN class event_loop &event_loop() const;
@@ -51,10 +58,16 @@ class connection : public counted_facade<pn_connection_t, connection, endpoint>
     /// Return the AMQP host name for the connection.
     PN_CPP_EXTERN std::string host() const;
 
+    /// Set the AMQP host name for the connection
+    PN_CPP_EXTERN void host(const std::string& h);
+
     /// Return the container-ID for the connection. All connections have a container_id,
     /// even if they don't have a container event_loop.
     PN_CPP_EXTERN std::string container_id() const;
 
+    // Set the container-ID for the connection
+    PN_CPP_EXTERN void container_id(const std::string& id);
+
     /** Initiate local open, not complete till messaging_handler::on_connection_opened()
      * or proton_handler::on_connection_remote_open()
      */
@@ -65,17 +78,21 @@ class connection : public counted_facade<pn_connection_t, connection, endpoint>
      */
     PN_CPP_EXTERN void close();
 
+    /** Release link and session resources of this connection
+     */
+    PN_CPP_EXTERN void release();
+
     /** Create a new session */
-    PN_CPP_EXTERN class session& open_session();
+    PN_CPP_EXTERN session open_session();
 
     /** Default session is created on first call and re-used for the lifetime of the connection */
-    PN_CPP_EXTERN class session& default_session();
+    PN_CPP_EXTERN session default_session();
 
     /** Create a sender on default_session() 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 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);
+    PN_CPP_EXTERN receiver open_receiver(const std::string &addr, bool dynamic=false, handler *h=0);
 
     /** Return links on this connection matching the state mask. */
     PN_CPP_EXTERN link_range find_links(endpoint::state mask) const;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/container.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/container.hpp b/proton-c/bindings/cpp/include/proton/container.hpp
index de91505..984d37a 100644
--- a/proton-c/bindings/cpp/include/proton/container.hpp
+++ b/proton-c/bindings/cpp/include/proton/container.hpp
@@ -59,28 +59,28 @@ class container : public event_loop {
     PN_CPP_EXTERN ~container();
 
     /** Locally open a connection @see connection::open  */
-    PN_CPP_EXTERN connection& connect(const proton::url&, handler *h=0);
+    PN_CPP_EXTERN connection connect(const proton::url&, handler *h=0);
 
     /** 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();
 
     /** Open a connection to url and create a sender with target=url.path() */
-    PN_CPP_EXTERN sender& open_sender(const proton::url &);
+    PN_CPP_EXTERN sender open_sender(const proton::url &);
 
     /** Create a receiver on connection with source=url.path() */
-    PN_CPP_EXTERN receiver& open_receiver(const url &);
+    PN_CPP_EXTERN receiver open_receiver(const url &);
 
     /// Identifier for the container
     PN_CPP_EXTERN std::string id() const;
 
     /// The reactor associated with this container.
-    PN_CPP_EXTERN class reactor& reactor() const;
+    PN_CPP_EXTERN class reactor reactor() const;
 
     // Schedule a timer task event in delay milliseconds.
-    PN_CPP_EXTERN task& schedule(int delay, handler *h = 0);
+    PN_CPP_EXTERN task schedule(int delay, handler *h = 0);
 
   private:
     pn_unique_ptr<container_impl> impl_;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/counted_ptr.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/counted_ptr.hpp b/proton-c/bindings/cpp/include/proton/counted_ptr.hpp
index 7023bd7..0865e4a 100644
--- a/proton-c/bindings/cpp/include/proton/counted_ptr.hpp
+++ b/proton-c/bindings/cpp/include/proton/counted_ptr.hpp
@@ -78,7 +78,7 @@ template <class T> class counted_ptr : public proton::comparable<counted_ptr<T>
     T* get() const { return ptr_; }
     T* operator->() const { return ptr_; }
     T& operator*() const { return *ptr_; }
-    operator bool() const { return ptr_; }
+    operator bool() const { return !!ptr_; }
     bool operator!() const { return !ptr_; }
 
     template <class U> operator counted_ptr<U>() const { return counted_ptr<U>(get()); }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/data.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/data.hpp b/proton-c/bindings/cpp/include/proton/data.hpp
index 752765e..9ac0e82 100644
--- a/proton-c/bindings/cpp/include/proton/data.hpp
+++ b/proton-c/bindings/cpp/include/proton/data.hpp
@@ -22,7 +22,7 @@
 #include "proton/decoder.hpp"
 #include "proton/encoder.hpp"
 #include "proton/export.hpp"
-#include "proton/facade.hpp"
+#include "proton/object.hpp"
 #include "proton/pn_unique_ptr.hpp"
 
 #include <iosfwd>
@@ -37,14 +37,17 @@ class data;
  * Holds a sequence of AMQP values, allows inserting and extracting via encoder() and decoder().
  * Cannot be directly instantiated, use `value`
  */
-class data : public facade<pn_data_t, data, comparable<data> > {
+class data : public object<pn_data_t> {
   public:
-    PN_CPP_EXTERN static pn_unique_ptr<data> create();
+    data(pn_data_t* d) : object(d) {}
+    data(owned_object<pn_data_t> d) : object(d) {}
+
+    PN_CPP_EXTERN static owned_object<pn_data_t> create();
 
     PN_CPP_EXTERN data& operator=(const data&);
 
     template<class T> data& operator=(const T &t) {
-        clear(); encoder() << t; decoder().rewind(); return *this;
+        clear(); encoder() << t; return *this;
     }
 
     /** Clear the data. */
@@ -54,10 +57,26 @@ class data : public facade<pn_data_t, data, comparable<data> > {
     PN_CPP_EXTERN bool empty() const;
 
     /** Encoder to encode into this value */
-    PN_CPP_EXTERN class encoder& encoder();
+    PN_CPP_EXTERN class encoder encoder();
 
     /** Decoder to decode from this value */
-    PN_CPP_EXTERN class decoder& decoder();
+    PN_CPP_EXTERN class decoder decoder();
+
+    /** Return the data cursor position */
+    PN_CPP_EXTERN uintptr_t point() const;
+
+    /** Restore the cursor position to a previously saved position */
+    PN_CPP_EXTERN void restore(uintptr_t h);
+
+    PN_CPP_EXTERN void narrow();
+
+    PN_CPP_EXTERN void widen();
+
+    PN_CPP_EXTERN int append(data src);
+
+    PN_CPP_EXTERN int appendn(data src, int limit);
+
+    PN_CPP_EXTERN bool next() const;
 
     /** Rewind and return the type of the first value*/
     PN_CPP_EXTERN type_id type() const;
@@ -70,13 +89,11 @@ class data : public facade<pn_data_t, data, comparable<data> > {
     PN_CPP_EXTERN bool operator==(const data& x) const;
     PN_CPP_EXTERN bool operator<(const data& x) const;
 
-    PN_CPP_EXTERN void operator delete(void *);
-
     /** Human readable representation of data. */
   friend PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const data&);
-
+  friend class value;
   private:
-    class decoder& decoder() const { return const_cast<data*>(this)->decoder(); }
+    class decoder decoder() const { return const_cast<data*>(this)->decoder(); }
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/decoder.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/decoder.hpp b/proton-c/bindings/cpp/include/proton/decoder.hpp
index 3da078c..8f487bc 100644
--- a/proton-c/bindings/cpp/include/proton/decoder.hpp
+++ b/proton-c/bindings/cpp/include/proton/decoder.hpp
@@ -22,8 +22,7 @@
 #include "proton/error.hpp"
 #include "proton/type_traits.hpp"
 #include "proton/types.hpp"
-#include "proton/facade.hpp"
-
+#include "proton/object.hpp"
 #include <iosfwd>
 
 #ifndef PN_NO_CONTAINER_CONVERT
@@ -45,6 +44,7 @@ struct pn_data_t;
 
 namespace proton {
 
+class data;
 class message_id;
 
 /** Raised by decoder operations on error.*/
@@ -148,8 +148,10 @@ Finally you can extract an AMQP LIST with mixed type elements into a container o
 
 You can also extract container values element-by-element, see decoder::operator>>(decoder&, start&)
 */
-class decoder : public facade<pn_data_t, decoder> {
+class decoder : public object<pn_data_t> {
   public:
+    decoder(pn_data_t* d) : object(d) {}
+
     /** Copy AMQP data from a byte buffer into the decoder. */
     PN_CPP_EXTERN decoder(const char* buffer, size_t size);
 
@@ -179,48 +181,39 @@ class decoder : public facade<pn_data_t, decoder> {
     /** Back up by one value */
     PN_CPP_EXTERN void backup();
 
-    PN_CPP_EXTERN class data& data();
+    PN_CPP_EXTERN class data data();
 
     /** @name Extract simple types
      * Overloads to extract simple types.
      * @throw error if the decoder is empty or the current value has an incompatible type.
      * @{
      */
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_null);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_boolean&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_ubyte&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_byte&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_ushort&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_short&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_uint&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_int&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_char&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_ulong&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_long&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_timestamp&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_float&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_double&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_decimal32&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_decimal64&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_decimal128&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_uuid&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, std::string&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, message_id&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, value&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_null);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_boolean&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_ubyte&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_byte&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_ushort&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_short&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_uint&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_int&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_char&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_ulong&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_long&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_timestamp&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_float&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_double&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_decimal32&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_decimal64&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_decimal128&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_uuid&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, std::string&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, message_id&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, value&);
     ///@}
 
     /** Extract and return a value of type T. */
     template <class T> T extract() { T value; *this >> value; return value; }
 
-    /** Call decoder::start() in constructor, decoder::finish in destructor().
-     *
-     */
-    struct scope : public start {
-        decoder& decoder_;
-        scope(decoder& d) : decoder_(d) { d >> *this; }
-        ~scope() { decoder_ >> finish(); }
-    };
-
     /** start extracting a container value, one of array, list, map, described.
      * The basic pattern is:
      *
@@ -247,19 +240,19 @@ class decoder : public facade<pn_data_t, decoder> {
      *
      *@throw decoder::error if the current value is not a container type.
      */
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, start&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, start&);
 
     /** Finish extracting a container value. */
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, finish);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, finish);
 
     /** Skip a value */
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, struct skip);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, struct skip);
 
     /** Throw an exception if decoder.type() != assert_type.type */
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, assert_type);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, assert_type);
 
     /** Rewind to the beginning */
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, struct rewind);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, struct rewind);
 
   private:
     PN_CPP_EXTERN void check_type(type_id);
@@ -267,11 +260,19 @@ class decoder : public facade<pn_data_t, decoder> {
   friend class encoder;
 };
 
+/** Call decoder::start() in constructor, decoder::finish in destructor().
+ *
+ */
+struct scope : public start {
+    decoder decoder_;
+    scope(decoder d) : decoder_(d) { decoder_ >> *this; }
+    ~scope() { decoder_ >> finish(); }
+};
 
 // operator >> for integer types that are not covered by the standard overrides.
 template <class T>
-typename enable_if<is_unknown_integer<T>::value, decoder&>::type
-operator>>(decoder& d, T& i)  {
+typename enable_if<is_unknown_integer<T>::value, decoder>::type
+operator>>(decoder d, T& i)  {
     typename integer_type<sizeof(T), is_signed<T>::value>::type v;
     d >> v;                     // Extract as a known integer type
     i = v;
@@ -336,8 +337,8 @@ template <class T> pairs_ref<T> to_pairs(T& v) { return pairs_ref<T>(v); }
  * the elements types are convertible to T. A MAP is extracted as [key1, value1,
  * key2, value2...]
  */
-template <class T> decoder& operator>>(decoder& d, sequence_ref<T> ref)  {
-    decoder::scope s(d);
+template <class T> decoder operator>>(decoder d, sequence_ref<T> ref)  {
+    scope s(d);
     if (s.is_described) d >> skip();
     T& v = ref.value;
     v.clear();
@@ -347,11 +348,11 @@ template <class T> decoder& operator>>(decoder& d, sequence_ref<T> ref)  {
     return d;
 }
 
-PN_CPP_EXTERN void assert_map_scope(const decoder::scope& s);
+PN_CPP_EXTERN void assert_map_scope(const scope& s);
 
 /** Extract an AMQP MAP to a C++ map */
-template <class T> decoder& operator>>(decoder& d, map_ref<T> ref)  {
-    decoder::scope s(d);
+template <class T> decoder operator>>(decoder d, map_ref<T> ref)  {
+    scope s(d);
     assert_map_scope(s);
     T& m = ref.value;
     m.clear();
@@ -365,8 +366,8 @@ template <class T> decoder& operator>>(decoder& d, map_ref<T> ref)  {
 }
 
 /** Extract an AMQP MAP to a C++ container of std::pair, preserving order. */
-template <class T> decoder& operator>>(decoder& d, pairs_ref<T> ref)  {
-    decoder::scope s(d);
+template <class T> decoder operator>>(decoder d, pairs_ref<T> ref)  {
+    scope s(d);
     assert_map_scope(s);
     T& m = ref.value;
     m.clear();
@@ -380,25 +381,24 @@ template <class T> decoder& operator>>(decoder& d, pairs_ref<T> ref)  {
 #ifndef PN_NO_CONTAINER_CONVERT
 
 // Decode to sequence.
-template <class T, class A> decoder& operator>>(decoder &d, std::vector<T, A>& v) { return d >> to_sequence(v); }
-template <class T, class A> decoder& operator>>(decoder &d, std::deque<T, A>& v) { return d >> to_sequence(v); }
-template <class T, class A> decoder& operator>>(decoder &d, std::list<T, A>& v) { return d >> to_sequence(v); }
+template <class T, class A> decoder operator>>(decoder d, std::vector<T, A>& v) { return d >> to_sequence(v); }
+template <class T, class A> decoder operator>>(decoder d, std::deque<T, A>& v) { return d >> to_sequence(v); }
+template <class T, class A> decoder operator>>(decoder d, std::list<T, A>& v) { return d >> to_sequence(v); }
 
 // Decode to map.
-template <class K, class T, class C, class A> decoder& operator>>(decoder &d, std::map<K, T, C, A>& v) { return d >> to_map(v); }
+template <class K, class T, class C, class A> decoder operator>>(decoder d, std::map<K, T, C, A>& v) { return d >> to_map(v); }
 
 #if PN_HAS_CPP11
 
 // Decode to sequence.
-template <class T, class A> decoder& operator>>(decoder &d, std::forward_list<T, A>& v) { return d >> to_sequence(v); }
-template <class T, std::size_t N> decoder& operator>>(decoder &d, std::array<T, N>& v) { return d >> to_sequence(v); }
+template <class T, class A> decoder operator>>(decoder d, std::forward_list<T, A>& v) { return d >> to_sequence(v); }
+template <class T, std::size_t N> decoder operator>>(decoder d, std::array<T, N>& v) { return d >> to_sequence(v); }
 
 // Decode to map.
-template <class K, class T, class C, class A> decoder& operator>>(decoder &d, std::unordered_map<K, T, C, A>& v) { return d >> to_map(v); }
+template <class K, class T, class C, class A> decoder operator>>(decoder d, std::unordered_map<K, T, C, A>& v) { return d >> to_map(v); }
 
 #endif // PN_HAS_CPP11
 #endif // PN_NO_CONTAINER_CONVERT
 
 }
-
 #endif // DECODER_H

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/delivery.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/delivery.hpp b/proton-c/bindings/cpp/include/proton/delivery.hpp
index 35c3b59..da62082 100644
--- a/proton-c/bindings/cpp/include/proton/delivery.hpp
+++ b/proton-c/bindings/cpp/include/proton/delivery.hpp
@@ -1,3 +1,4 @@
+
 #ifndef PROTON_CPP_DELIVERY_H
 #define PROTON_CPP_DELIVERY_H
 
@@ -22,7 +23,7 @@
  *
  */
 #include "proton/export.hpp"
-#include "proton/facade.hpp"
+#include "proton/object.hpp"
 
 #include "proton/delivery.h"
 #include "proton/disposition.h"
@@ -30,8 +31,10 @@
 namespace proton {
 
 /** delivery status of a message */
-class delivery : public counted_facade<pn_delivery_t, delivery> {
+class delivery : public object<pn_delivery_t> {
   public:
+    delivery(pn_delivery_t* d=0) : object(d) {}
+
     /** Delivery state of a message */
     enum state {
         NONE = 0, ///< Unknown state
@@ -108,6 +111,11 @@ class delivery : public counted_facade<pn_delivery_t, delivery> {
      * Get the remote disposition state for a delivery.
      */
     PN_CPP_EXTERN state remote_state() const;
+
+    /**
+     * Get the size of the current delivery
+     */
+    PN_CPP_EXTERN size_t pending() const;
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/encoder.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/encoder.hpp b/proton-c/bindings/cpp/include/proton/encoder.hpp
index c10ad10..a28ea26 100644
--- a/proton-c/bindings/cpp/include/proton/encoder.hpp
+++ b/proton-c/bindings/cpp/include/proton/encoder.hpp
@@ -22,7 +22,7 @@
 #include "proton/error.hpp"
 #include "proton/types.hpp"
 #include "proton/type_traits.hpp"
-#include "proton/facade.hpp"
+#include "proton/object.hpp"
 #include <iosfwd>
 
 #ifndef PN_NO_CONTAINER_CONVERT
@@ -44,6 +44,7 @@ struct pn_data_t;
 
 namespace proton {
 
+class data;
 class message_id;
 
 /** Raised by encoder operations on error */
@@ -88,8 +89,10 @@ struct encode_error : public error { PN_CPP_EXTERN explicit encode_error(const s
  *
  * You can also insert containers element-by-element, see operator<<(encoder&, const start&)
  */
-class encoder : public facade<pn_data_t, encoder> {
+class encoder : public object<pn_data_t> {
   public:
+    encoder(pn_data_t* e) : object(e) {}
+
     /**
      * Encode the current values into buffer and update size to reflect the number of bytes encoded.
      *
@@ -109,34 +112,34 @@ class encoder : public facade<pn_data_t, encoder> {
     /** Encode the current values into a std::string. Clears the encoder. */
     PN_CPP_EXTERN std::string encode();
 
-    PN_CPP_EXTERN class data& data();
+    PN_CPP_EXTERN class data data();
 
     /** @name Insert simple types.
      *@{
      */
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_null);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_boolean);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_ubyte);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_byte);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_ushort);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_short);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_uint);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_int);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_char);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_ulong);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_long);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_timestamp);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_float);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_double);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_decimal32);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_decimal64);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_decimal128);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_uuid);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_string);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_symbol);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_binary);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, const message_id&);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, const value&);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_null);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_boolean);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_ubyte);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_byte);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_ushort);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_short);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_uint);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_int);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_char);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_ulong);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_long);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_timestamp);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_float);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_double);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_decimal32);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_decimal64);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_decimal128);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_uuid);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_string);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_symbol);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_binary);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, const message_id&);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, const value&);
     ///@}
 
     /**
@@ -149,38 +152,38 @@ class encoder : public facade<pn_data_t, encoder> {
      *
      *      enc << start::list() << amqp_int(1) << amqp_symbol("two") << 3.0 << finish();
      */
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, const start&);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, const start&);
 
     /** Finish a container type. See operator<<(encoder&, const start&) */
-  friend PN_CPP_EXTERN encoder& operator<<(encoder& e, finish);
+  friend PN_CPP_EXTERN encoder operator<<(encoder e, finish);
 
 
     /**@name Insert values returned by the as<type_id> helper.
      *@{
      */
-  template <class T, type_id A> friend PN_CPP_EXTERN encoder& operator<<(encoder&, cref<T, A>);
-  template <class T> friend encoder& operator<<(encoder&, cref<T, ARRAY>);
-  template <class T> friend encoder& operator<<(encoder&, cref<T, LIST>);
-  template <class T> friend encoder& operator<<(encoder&, cref<T, MAP>);
+  template <class T, type_id A> friend PN_CPP_EXTERN encoder operator<<(encoder, cref<T, A>);
+  template <class T> friend encoder operator<<(encoder, cref<T, ARRAY>);
+  template <class T> friend encoder operator<<(encoder, cref<T, LIST>);
+  template <class T> friend encoder operator<<(encoder, cref<T, MAP>);
     // TODO aconway 2015-06-16: described values.
     ///@}
 };
 
 // Need to disambiguate char* conversion to bool and std::string as amqp_string.
-inline encoder& operator<<(encoder& e, char* s) { return e << amqp_string(s); }
-inline encoder& operator<<(encoder& e, const char* s) { return e << amqp_string(s); }
-inline encoder& operator<<(encoder& e, const std::string& s) { return e << amqp_string(s); }
+inline encoder operator<<(encoder e, char* s) { return e << amqp_string(s); }
+inline encoder operator<<(encoder e, const char* s) { return e << amqp_string(s); }
+inline encoder operator<<(encoder e, const std::string& s) { return e << amqp_string(s); }
 
 // operator << for integer types that are not covered by the standard overrides.
 template <class T>
-typename enable_if<is_unknown_integer<T>::value, encoder&>::type operator<<(encoder& e, T i)  {
+typename enable_if<is_unknown_integer<T>::value, encoder>::type operator<<(encoder e, T i)  {
     typename integer_type<sizeof(T), is_signed<T>::value>::type v = i;
     return e << v;              // Insert as a known integer type
 }
 
 // TODO aconway 2015-06-16: described array insertion.
 
-template <class T> encoder& operator<<(encoder& e, cref<T, ARRAY> a) {
+template <class T> encoder operator<<(encoder e, cref<T, ARRAY> a) {
     e << start::array(type_id_of<typename T::value_type>::value);
     for (typename T::const_iterator i = a.value.begin(); i != a.value.end(); ++i)
         e << *i;
@@ -188,7 +191,7 @@ template <class T> encoder& operator<<(encoder& e, cref<T, ARRAY> a) {
     return e;
 }
 
-template <class T> encoder& operator<<(encoder& e, cref<T, LIST> l) {
+template <class T> encoder operator<<(encoder e, cref<T, LIST> l) {
     e << start::list();
     for (typename T::const_iterator i = l.value.begin(); i != l.value.end(); ++i)
         e << *i;
@@ -196,7 +199,7 @@ template <class T> encoder& operator<<(encoder& e, cref<T, LIST> l) {
     return e;
 }
 
-template <class T> encoder& operator<<(encoder& e, cref<T, MAP> m){
+template <class T> encoder operator<<(encoder e, cref<T, MAP> m){
     e << start::map();
     for (typename T::const_iterator i = m.value.begin(); i != m.value.end(); ++i) {
         e << i->first;
@@ -208,30 +211,30 @@ template <class T> encoder& operator<<(encoder& e, cref<T, MAP> m){
 
 #ifndef PN_NO_CONTAINER_CONVERT
 // Encode as ARRAY
-template <class T, class A> encoder& operator<<(encoder &e, const std::vector<T, A>& v) { return e << as<ARRAY>(v); }
-template <class T, class A> encoder& operator<<(encoder &e, const std::deque<T, A>& v) { return e << as<ARRAY>(v); }
-template <class T, class A> encoder& operator<<(encoder &e, const std::list<T, A>& v) { return e << as<ARRAY>(v); }
+template <class T, class A> encoder operator<<(encoder e, const std::vector<T, A>& v) { return e << as<ARRAY>(v); }
+template <class T, class A> encoder operator<<(encoder e, const std::deque<T, A>& v) { return e << as<ARRAY>(v); }
+template <class T, class A> encoder operator<<(encoder e, const std::list<T, A>& v) { return e << as<ARRAY>(v); }
 
 // Encode as LIST
-template <class A> encoder& operator<<(encoder &e, const std::vector<value, A>& v) { return e << as<LIST>(v); }
-template <class A> encoder& operator<<(encoder &e, const std::deque<value, A>& v) { return e << as<LIST>(v); }
-template <class A> encoder& operator<<(encoder &e, const std::list<value, A>& v) { return e << as<LIST>(v); }
+template <class A> encoder operator<<(encoder e, const std::vector<value, A>& v) { return e << as<LIST>(v); }
+template <class A> encoder operator<<(encoder e, const std::deque<value, A>& v) { return e << as<LIST>(v); }
+template <class A> encoder operator<<(encoder e, const std::list<value, A>& v) { return e << as<LIST>(v); }
 
 // Encode as MAP
-template <class K, class T, class C, class A> encoder& operator<<(encoder &e, const std::map<K, T, C, A>& v) { return e << as<MAP>(v); }
+template <class K, class T, class C, class A> encoder operator<<(encoder e, const std::map<K, T, C, A>& v) { return e << as<MAP>(v); }
 
 #if PN_HAS_CPP11
 
 // Encode as ARRAY.
-template <class T, class A> encoder& operator<<(encoder &e, const std::forward_list<T, A>& v) { return e << as<ARRAY>(v); }
-template <class T, std::size_t N> encoder& operator<<(encoder &e, const std::array<T, N>& v) { return e << as<ARRAY>(v); }
+template <class T, class A> encoder operator<<(encoder e, const std::forward_list<T, A>& v) { return e << as<ARRAY>(v); }
+template <class T, std::size_t N> encoder operator<<(encoder e, const std::array<T, N>& v) { return e << as<ARRAY>(v); }
 
 // Encode as LIST.
-template <class A> encoder& operator<<(encoder &e, const std::forward_list<value, A>& v) { return e << as<LIST>(v); }
-template <std::size_t N> encoder& operator<<(encoder &e, const std::array<value, N>& v) { return e << as<LIST>(v); }
+template <class A> encoder operator<<(encoder e, const std::forward_list<value, A>& v) { return e << as<LIST>(v); }
+template <std::size_t N> encoder operator<<(encoder e, const std::array<value, N>& v) { return e << as<LIST>(v); }
 
 // Encode as map.
-template <class K, class T, class C, class A> encoder& operator<<(encoder &e, const std::unordered_map<K, T, C, A>& v) { return e << as<MAP>(v); }
+template <class K, class T, class C, class A> encoder operator<<(encoder e, const std::unordered_map<K, T, C, A>& v) { return e << as<MAP>(v); }
 
 #endif // PN_HAS_CPP11
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/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 d1cccb5..9e6fa8d 100644
--- a/proton-c/bindings/cpp/include/proton/endpoint.hpp
+++ b/proton-c/bindings/cpp/include/proton/endpoint.hpp
@@ -69,15 +69,15 @@ template <class T> class iter_base {
     typedef T value_type;
 
     T& operator*() const { return *ptr_; }
-    T* operator->() const { return ptr_; }
-    operator bool() const { return ptr_; }
+    const T* operator->() const { return &ptr_; }
+    operator bool() const { return !!ptr_; }
     bool operator !() const { return !ptr_; }
     bool operator==(const iter_base<T>& x) const { return ptr_ == x.ptr_; }
     bool operator!=(const iter_base<T>& x) const { return ptr_ != x.ptr_; }
 
   protected:
-    explicit iter_base(T* p = 0, endpoint::state s = 0) : ptr_(p), state_(s) {}
-    T* ptr_;
+    explicit iter_base(T p = 0, endpoint::state s = 0) : ptr_(p), state_(s) {}
+    T ptr_;
     endpoint::state state_;
 };
 ///@endcond INTERNAL
@@ -94,35 +94,6 @@ template<class I> class range {
     I begin_, end_;
 };
 
-/// An iterator for sessions.
-class session_iterator : public iter_base<session> {
- public:
-    explicit session_iterator(session* p = 0, 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;
-
-/// An iterator for links.
-class link_iterator : public iter_base<link> {
-  public:
-    explicit link_iterator(link* p = 0, endpoint::state s = 0) :
-        iter_base<link>(p, s), session_(0) {}
-    explicit link_iterator(const link_iterator& i, const session *ssn) :
-        iter_base<link>(i.ptr_, i.state_), session_(ssn) {}
-    PN_CPP_EXTERN link_iterator operator++();
-    link_iterator operator++(int) { link_iterator x(*this); ++(*this); return x; }
-
-  private:
-    const session* session_;
-};
-
-/// A range of links.
-typedef range<link_iterator> link_range;
-
 }
 
 #endif  /*!PROTON_CPP_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/engine.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/engine.hpp b/proton-c/bindings/cpp/include/proton/engine.hpp
index f27033d..340d21b 100644
--- a/proton-c/bindings/cpp/include/proton/engine.hpp
+++ b/proton-c/bindings/cpp/include/proton/engine.hpp
@@ -139,7 +139,7 @@ class engine : public event_loop {
     PN_CPP_EXTERN bool closed() const;
 
     /** The AMQP connection associated with this engine. */
-    PN_CPP_EXTERN class connection&  connection() const;
+    PN_CPP_EXTERN class connection  connection() const;
 
     /** The AMQP container-id associated with this engine. */
     PN_CPP_EXTERN  std::string id() const;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/event.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/event.hpp b/proton-c/bindings/cpp/include/proton/event.hpp
index ed310f1..f0ba897 100644
--- a/proton-c/bindings/cpp/include/proton/event.hpp
+++ b/proton-c/bindings/cpp/include/proton/event.hpp
@@ -46,24 +46,24 @@ class event {
     virtual PN_CPP_EXTERN std::string name() const = 0;
 
     /// Get the event_loop object, can be a container or an engine.
-    virtual PN_CPP_EXTERN class event_loop &event_loop() const;
+    virtual PN_CPP_EXTERN class event_loop& event_loop() const;
 
     /// Get the container, throw an exception if event_loop is not a container.
-    virtual PN_CPP_EXTERN class container &container() const;
+    virtual PN_CPP_EXTERN class container& container() const;
 
     /// Get the engine, , throw an exception if event_loop is not an engine.
-    virtual PN_CPP_EXTERN class engine &engine() const;
+    virtual PN_CPP_EXTERN class engine& engine() const;
 
     /// Get connection.
-    virtual PN_CPP_EXTERN class connection &connection() const;
+    virtual PN_CPP_EXTERN class connection connection() const;
     /// Get sender @throws error if no sender.
-    virtual PN_CPP_EXTERN class sender& sender() const;
+    virtual PN_CPP_EXTERN class sender sender() const;
     /// Get receiver @throws error if no receiver.
-    virtual PN_CPP_EXTERN class receiver& receiver() const;
+    virtual PN_CPP_EXTERN class receiver receiver() const;
     /// Get link @throws error if no link.
-    virtual PN_CPP_EXTERN class link& link() const;
+    virtual PN_CPP_EXTERN class link link() const;
     /// Get delivery @throws error if no delivery.
-    virtual PN_CPP_EXTERN class delivery& delivery() const;
+    virtual PN_CPP_EXTERN class delivery delivery() const;
     /** Get message @throws error if no message. */
     virtual PN_CPP_EXTERN class message &message() const;
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/event_loop.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/event_loop.hpp b/proton-c/bindings/cpp/include/proton/event_loop.hpp
index e5dff37..fcc83d8 100644
--- a/proton-c/bindings/cpp/include/proton/event_loop.hpp
+++ b/proton-c/bindings/cpp/include/proton/event_loop.hpp
@@ -23,10 +23,12 @@
 
 #include <string>
 
+namespace proton {
+
 /**
  * An event_loop dispatches events to event handlers.  event_loop is an abstract
  * class, concrete subclasses are proton::container and prton::engine.
-*/
+ */
 class event_loop {
   public:
     PN_CPP_EXTERN virtual ~event_loop() {}
@@ -38,4 +40,5 @@ class event_loop {
     // TODO aconway 2015-11-02: injecting application events.
 };
 
+}
 #endif // EVENT_LOOP_HPP

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/facade.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/facade.hpp b/proton-c/bindings/cpp/include/proton/facade.hpp
deleted file mode 100644
index 7900ada..0000000
--- a/proton-c/bindings/cpp/include/proton/facade.hpp
+++ /dev/null
@@ -1,145 +0,0 @@
-#ifndef PROTON_CPP_FACADE_H
-#define PROTON_CPP_FACADE_H
-
-/*
- *
- * 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.
- *
- */
-
-/*! \page c-and-cpp C and memory management.
- *\brief
- *
- * The C++ API is a very thin wrapper over the C API.  The C API consists of a
- * set of `struct` types and associated C functions.  For each there is a a C++
- * `facade` that provides C++ member functions to call the corresponding C
- * functions on the underlying C struct. Facade classes derive from the
- * `proton::facade` template.
- *
- * The facade class occupies no additional memory. The C+ facade pointer points
- * directly to the underlying C++ struct, calling C++ member functions corresponds
- * directly to calling the C function.
- *
- * If you want to mix C and C++ code (which should be done carefully!) you can
- * cast between a facade pointer and a C struct pointer with `proton::pn_cast`
- * and `foo::cast()` where `foo` is some C++ facade class.
- *
- * Deleting a facade object calls the appropriate `pn_foo_free` function or
- * `pn_decref` as appropriate.
- *
- * Some proton structs are reference counted, the facade classes for these
- * derive from the `proton::counted_facade` template. Most proton functions that
- * return facade objects return a reference to an object that is owned by the
- * called object. Such references are only valid in a limited scope (for example
- * in an event handler function.) To keep a reference outside that scope, call
- * the `ptr()` member function. This returns a `proton::counted_ptr`, which you
- * can convert safely to `std::shared_ptr`, `std::unique_ptr`,
- * `boost::shared_ptr`, or `boost::intrusive_ptr`.
- */
-
-/**@file
- * Classes and templates used by object facades.
- */
-
-#include "proton/export.hpp"
-#include "counted_ptr.hpp"
-
-namespace proton {
-
-///@cond INTERNAL
-struct empty_base {};
-///@endcond
-
-/**
- * Base class for C++ facades of proton C struct types.
- *
- * @see \ref c-and-cpp
- */
-template <class P, class T, class Base=empty_base> class facade : public Base {
-  public:
-    /// The underlying C struct type.
-    typedef P pn_type;
-
-    /// Cast the C struct pointer to a C++ facade pointer.
-    static T* cast(P* p) { return reinterpret_cast<T*>(p); }
-
-  private:
-    facade();
-    facade(const facade&);
-    facade& operator=(const facade&);
-    void operator delete(void* p);
-};
-
-/** Cast a facade type to the C struct type.
- * Allow casting away const, the underlying pn structs have not constness.
- */
-template <class T> typename T::pn_type* pn_cast(const T* p) {
-    return reinterpret_cast<typename T::pn_type*>(const_cast<T*>(p));
-}
-
-/** Cast a counted pointer to a facade type to the C struct type.
- * Allow casting away const, the underlying pn structs have not constness.
- */
-template <class T> typename T::pn_type* pn_cast(const counted_ptr<T>& p) {
-    return reinterpret_cast<typename T::pn_type*>(const_cast<T*>(p.get()));
-}
-
-/**
- * Some proton C structs are reference counted. The C++ facade for such structs can be
- * converted to any of the following smart pointers: std::shared_ptr, std::unique_ptr,
- * boost::shared_ptr, boost::intrusive_ptr.
- *
- * unique_ptr takes ownership of a single *reference* not the underlying struct,
- * so it is safe to have multiple unique_ptr to the same facade object or to mix
- * unique_ptr with shared_ptr etc.
- *
- * Deleting a counted_facade subclass actually calls `pn_decref` to remove a reference.
- */
-template <class P, class T, class Base=empty_base>
-class counted_facade : public facade<P, T, Base>
-{
-  public:
-
-    /// Deleting a counted_facade actually calls `pn_decref` to remove a reference.
-    void operator delete(void* p) { decref(p); }
-
-    /** Get a reference-counted pointer to the underlying object.  It can be
-     * converted safely to `std::shared_ptr`, `std::unique_ptr`,
-     * `boost::shared_ptr`, or `boost::intrusive_ptr`.
-     */
-    counted_ptr<T> ptr() {
-        return counted_ptr<T>(static_cast<T*>(this));
-    }
-
-    /** Get a reference-counted pointer to the underlying object.  It can be
-     * converted safely to `std::shared_ptr`, `std::unique_ptr`,
-     * `boost::shared_ptr`, or `boost::intrusive_ptr`.
-     */
-    counted_ptr<const T> ptr() const {
-        return counted_ptr<const T>(static_cast<const T*>(this));
-    }
-
-  private:
-    counted_facade(const counted_facade&);
-    counted_facade& operator=(const counted_facade&);
-
-  template <class U> friend class counted_ptr;
-};
-
-}
-#endif  /*!PROTON_CPP_FACADE_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/handler.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/handler.hpp b/proton-c/bindings/cpp/include/proton/handler.hpp
index 65ff437..70da48b 100644
--- a/proton-c/bindings/cpp/include/proton/handler.hpp
+++ b/proton-c/bindings/cpp/include/proton/handler.hpp
@@ -22,6 +22,7 @@
  *
  */
 #include "proton/export.hpp"
+#include "proton/counted_ptr.hpp"
 #include "proton/event.hpp"
 #include "proton/event.h"
 #include "proton/reactor.h"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/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 b4b40e0..d73156e 100644
--- a/proton-c/bindings/cpp/include/proton/link.hpp
+++ b/proton-c/bindings/cpp/include/proton/link.hpp
@@ -26,7 +26,7 @@
 #include "proton/message.hpp"
 #include "proton/terminus.hpp"
 #include "proton/types.h"
-#include "proton/facade.hpp"
+#include "proton/object.hpp"
 
 #include <string>
 
@@ -36,9 +36,11 @@ class sender;
 class receiver;
 
 /** Messages are transferred across a link. Base class for sender, receiver. */
-class link : public counted_facade<pn_link_t, link, endpoint>
+class link : public object<pn_link_t> , public endpoint
 {
   public:
+    link(pn_link_t* l=0) : object(l) {}
+
     /** Locally open the link, not complete till messaging_handler::on_link_opened or
      * proton_handler::link_remote_open
      */
@@ -50,33 +52,36 @@ class link : public counted_facade<pn_link_t, link, endpoint>
     PN_CPP_EXTERN void close();
 
     /** Return sender if this link is a sender, 0 if not. */
-    PN_CPP_EXTERN class sender* sender();
-    PN_CPP_EXTERN const class sender* sender() const;
+    PN_CPP_EXTERN class sender sender();
+    PN_CPP_EXTERN const class sender sender() const;
 
     /** Return receiver if this link is a receiver, 0 if not. */
-    PN_CPP_EXTERN class receiver* receiver();
-    PN_CPP_EXTERN const class receiver* receiver() const;
+    PN_CPP_EXTERN class receiver receiver();
+    PN_CPP_EXTERN const class receiver receiver() const;
 
     /** Credit available on the link */
     PN_CPP_EXTERN int credit() const;
 
+    /** Grant credit to the link */
+    PN_CPP_EXTERN void flow(int credit);
+
     /** Local source of the link. */
-    PN_CPP_EXTERN terminus& source() const;
+    PN_CPP_EXTERN terminus source() const;
     /** Local target of the link. */
-    PN_CPP_EXTERN terminus& target() const;
+    PN_CPP_EXTERN terminus target() const;
     /** Remote source of the link. */
-    PN_CPP_EXTERN terminus& remote_source() const;
+    PN_CPP_EXTERN terminus remote_source() const;
     /** Remote target of the link. */
-    PN_CPP_EXTERN terminus& remote_target() const;
+    PN_CPP_EXTERN terminus remote_target() const;
 
     /** Link name */
     PN_CPP_EXTERN std::string name() const;
 
     /** Connection that owns this link */
-    PN_CPP_EXTERN class connection &connection() const;
+    PN_CPP_EXTERN class connection connection() const;
 
     /** Session that owns this link */
-    PN_CPP_EXTERN class session &session() const;
+    PN_CPP_EXTERN class session session() const;
 
     /** Set a custom handler for this link. */
     PN_CPP_EXTERN void handler(class handler &);
@@ -86,8 +91,33 @@ class link : public counted_facade<pn_link_t, link, endpoint>
 
     /** Get the endpoint state */
     PN_CPP_EXTERN endpoint::state state() const;
+
+    /** Get message data from current delivery on link */
+    PN_CPP_EXTERN ssize_t recv(char* buffer, size_t size);
+
+    /** Advance the link one delivery */
+    PN_CPP_EXTERN bool advance();
+
+    /** Navigate the links in a connection - get next link with state */
+    PN_CPP_EXTERN link next(endpoint::state) const;
+};
+
+/// An iterator for links.
+class link_iterator : public iter_base<link> {
+  public:
+    explicit link_iterator(link p = 0, endpoint::state s = 0) :
+        iter_base<link>(p, s), session_(0) {}
+    explicit link_iterator(const link_iterator& i, const session& ssn) :
+        iter_base<link>(i.ptr_, i.state_), session_(&ssn) {}
+    PN_CPP_EXTERN link_iterator operator++();
+    link_iterator operator++(int) { link_iterator x(*this); ++(*this); return x; }
+
+  private:
+    const session* session_;
 };
 
+/// A range of links.
+typedef range<link_iterator> link_range;
 }
 
 #include "proton/sender.hpp"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/message.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/message.hpp b/proton-c/bindings/cpp/include/proton/message.hpp
index f68873b..0954b49 100644
--- a/proton-c/bindings/cpp/include/proton/message.hpp
+++ b/proton-c/bindings/cpp/include/proton/message.hpp
@@ -24,7 +24,6 @@
 
 #include "proton/data.hpp"
 #include "proton/export.hpp"
-#include "proton/facade.hpp"
 #include "proton/message_id.hpp"
 #include "proton/pn_unique_ptr.hpp"
 #include "proton/value.hpp"
@@ -104,10 +103,10 @@ class message
     PN_CPP_EXTERN void body(const value&);
 
     /** Get the body. Note data can be copied to a proton::value */
-    PN_CPP_EXTERN const data& body() const;
+    PN_CPP_EXTERN const data body() const;
 
     /** Get a reference to the body data, can be modified in-place. */
-    PN_CPP_EXTERN data& body();
+    PN_CPP_EXTERN data body();
 
     /** Set the application properties. Must be a map with string keys or an
      * empty value. You can assign to a proton::value from a standard C++ map
@@ -119,10 +118,10 @@ class message
      * an empty value. You can assign proton::value containing a map to a
      * standard C++ map of std::string to proton::value.
      */
-    PN_CPP_EXTERN const data& properties() const;
+    PN_CPP_EXTERN const data properties() const;
 
     /** Get a reference to the application properties, can be modified in-place.*/
-    PN_CPP_EXTERN data& properties();
+    PN_CPP_EXTERN data properties();
 
     /** Set an individual application property. */
     PN_CPP_EXTERN void property(const std::string &name, const value &);
@@ -143,7 +142,7 @@ class message
     PN_CPP_EXTERN void decode(const std::string &bytes);
 
     /// Decode the message from link corresponding to delivery.
-    PN_CPP_EXTERN void decode(proton::link&, proton::delivery&);
+    PN_CPP_EXTERN void decode(proton::link, proton::delivery);
 
     /**
      * Get the inferred flag for a message.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/message_id.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/message_id.hpp b/proton-c/bindings/cpp/include/proton/message_id.hpp
index d6ce186..8e0adf1 100644
--- a/proton-c/bindings/cpp/include/proton/message_id.hpp
+++ b/proton-c/bindings/cpp/include/proton/message_id.hpp
@@ -68,13 +68,14 @@ class message_id : public comparable<message_id> {
     bool operator<(const message_id& x) const { return value_ < x.value_; }
 
   friend std::ostream& operator<<(std::ostream&, const message_id&);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, const message_id&);
-  friend PN_CPP_EXTERN decoder& operator>>(decoder&, message_id&);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, const message_id&);
+  friend PN_CPP_EXTERN decoder operator>>(decoder, message_id&);
 
   private:
-    message_id(const data& d) : value_(d) {}
+    //message_id(const data d) : value_(d) {}
     value value_;
   friend class message;
+  friend class data;
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp b/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp
index 29a26c6..6e4342d 100644
--- a/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp
+++ b/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp
@@ -22,7 +22,6 @@
  *
  */
 
-#include "proton/facade.hpp"
 #include "proton/messaging_handler.hpp"
 
 #include "proton/event.h"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/object.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/object.hpp b/proton-c/bindings/cpp/include/proton/object.hpp
new file mode 100644
index 0000000..118f40d
--- /dev/null
+++ b/proton-c/bindings/cpp/include/proton/object.hpp
@@ -0,0 +1,113 @@
+#ifndef OBJECT_HPP
+#define OBJECT_HPP
+/*
+ * 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/config.hpp"
+#include "proton/export.hpp"
+
+#include <memory>
+
+namespace proton {
+
+/**
+ * Base class for proton object types
+ *
+ * Automatically perform memory management for pn_object based types.
+ *
+ * Note that for the memory management to work correctly no class
+ * inheriting from this should define any data members of its own.
+ * 
+ * This is ok because the entire purpose of this class is to provide
+ * and manage the underlying pointer to the proton-c object.
+ * 
+ * So any class using this one needs to be merely a thin wrapping of
+ * the proton-c object with no data members of it's own. Anything that internally
+ * needs extra data members and a proton-c object must use an inheritor of
+ * object<> as a data member - it must not inherit and add data members.
+ * 
+ */
+class object_base {
+  public:
+    object_base() : object_(0) {}
+    object_base(void* o) : object_(o) {}
+    object_base(const object_base& o) : object_(o.object_) { incref(); }
+
+    #ifdef PN_HAS_CPP11
+    object_base(object_base&& o) : object_base() { *this = o; }
+    #endif
+
+    ~object_base() { decref(); };
+
+    object_base& operator=(object_base o)
+    { std::swap(object_, o.object_); return *this; }
+
+    bool operator!() const { return !object_; }
+
+  private:
+    PN_CPP_EXTERN void incref() const;
+    PN_CPP_EXTERN void decref() const;
+
+    void* object_;
+
+  template <class T>
+  friend class object;
+  template <class T>
+  friend class owned_object;
+  friend bool operator==(const object_base&, const object_base&);
+};
+
+template <class T>
+class owned_object : public object_base {
+  public:
+    owned_object(T* o) : object_base(o) {};
+
+  protected:
+    T* pn_object() const { return static_cast<T*>(object_); }
+
+  template <class U>
+  friend class object;
+};
+
+template <class T>
+class object : public object_base {
+  public:
+    object(T* o, bool take_own=false) : object_base(o) { if (!take_own) incref(); };
+    object(owned_object<T> o) : object_base(o.object_) { o.object_=0; };
+
+    object& operator=(owned_object<T> o)
+    { object_ = o.object_; o = 0; return *this; }
+
+  protected:
+    static const bool take_ownership = true;
+    T* pn_object() const { return static_cast<T*>(object_); }
+};
+
+inline
+bool operator==(const object_base& o1, const object_base& o2) {
+    return o1.object_==o2.object_;
+}
+
+inline
+bool operator!=(const object_base& o1, const object_base& o2) {
+    return !(o1==o2);
+}
+
+}
+#endif // OBJECT_HPP


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