qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From acon...@apache.org
Subject [3/3] qpid-proton git commit: PROTON-865: 0-overhead facades, reference counting and smart ptr support.
Date Mon, 31 Aug 2015 17:32:59 GMT
PROTON-865: 0-overhead facades, reference counting and smart ptr support.

See proton/facade.hpp doc comments for details. The highlights:

- 0 overhead facade classes, facade pointers point directly at C structs.
- proton::counted_ptr for automated refcounting of proton objects in any C++ version.
- std:: and boost:: smart pointers supported as alternative to proton::counted_ptr.
- APIs take/return foo& for facade foo, facade can convert to smart pointer.

Tested with g++ and clang++ in c++03 and c++11 mode. Not tested on windows.

This is simpler and more obvious than the proposal floated on the proton list
but has essentially the same properties.


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

Branch: refs/heads/cjansen-cpp-client
Commit: 9bb9c442c3b83df249c2da7411ec74128f27e6b4
Parents: c696258
Author: Alan Conway <aconway@redhat.com>
Authored: Thu Aug 27 10:37:11 2015 -0400
Committer: Alan Conway <aconway@redhat.com>
Committed: Mon Aug 31 13:32:45 2015 -0400

----------------------------------------------------------------------
 CMakeLists.txt                                  |   1 -
 docs/markdown/memory_management.md              | 113 ++++++++
 examples/cpp/CMakeLists.txt                     |   4 +-
 examples/cpp/broker.cpp                         |  40 ++-
 examples/cpp/client.cpp                         |  16 +-
 examples/cpp/direct_recv.cpp                    |   8 +-
 examples/cpp/direct_send.cpp                    |  10 +-
 examples/cpp/encode_decode.cpp                  | 146 +++++-----
 examples/cpp/example_test.py                    |  26 +-
 examples/cpp/helloworld.cpp                     |   6 +-
 examples/cpp/helloworld_blocking.cpp            |  11 +-
 examples/cpp/helloworld_direct.cpp              |   6 +-
 examples/cpp/server.cpp                         |  12 +-
 examples/cpp/server_direct.cpp                  |  15 +-
 examples/cpp/simple_recv.cpp                    |   7 +-
 examples/cpp/simple_send.cpp                    |   9 +-
 examples/cpp/sync_client.cpp                    |   6 +-
 proton-c/bindings/cpp/CMakeLists.txt            |  38 +--
 proton-c/bindings/cpp/docs/mainpage.md          |   2 +-
 proton-c/bindings/cpp/docs/tutorial.hpp         |   6 +-
 .../bindings/cpp/include/proton/acceptor.hpp    |   6 +-
 proton-c/bindings/cpp/include/proton/acking.hpp |  52 ----
 .../cpp/include/proton/blocking_connection.hpp  |   8 +-
 .../cpp/include/proton/blocking_link.hpp        |   1 -
 .../cpp/include/proton/blocking_sender.hpp      |   3 +-
 .../bindings/cpp/include/proton/comparable.hpp  |  44 ++++
 proton-c/bindings/cpp/include/proton/config.hpp |  27 +-
 .../bindings/cpp/include/proton/connection.hpp  |  35 +--
 .../bindings/cpp/include/proton/container.hpp   |  42 ++-
 .../bindings/cpp/include/proton/cstdint.hpp     |   4 +-
 proton-c/bindings/cpp/include/proton/data.hpp   | 103 ++++++--
 .../bindings/cpp/include/proton/decoder.hpp     |  24 +-
 .../bindings/cpp/include/proton/delivery.hpp    |  23 +-
 .../bindings/cpp/include/proton/encoder.hpp     |  24 +-
 .../bindings/cpp/include/proton/endpoint.hpp    |   4 -
 proton-c/bindings/cpp/include/proton/event.hpp  |  12 +-
 proton-c/bindings/cpp/include/proton/export.hpp |   3 +-
 proton-c/bindings/cpp/include/proton/facade.hpp | 263 +++++++++++++++++++
 proton-c/bindings/cpp/include/proton/handle.hpp |  66 -----
 .../bindings/cpp/include/proton/handler.hpp     |  10 +-
 proton-c/bindings/cpp/include/proton/link.hpp   |  54 ++--
 .../bindings/cpp/include/proton/message.hpp     | 167 ++++++++----
 .../cpp/include/proton/messaging_adapter.hpp    |   2 +-
 .../cpp/include/proton/messaging_event.hpp      |  12 +-
 .../cpp/include/proton/messaging_handler.hpp    |   3 +-
 .../cpp/include/proton/proton_event.hpp         |   8 +-
 .../bindings/cpp/include/proton/receiver.hpp    |   5 +-
 proton-c/bindings/cpp/include/proton/sender.hpp |   7 +-
 .../bindings/cpp/include/proton/session.hpp     |  12 +-
 .../include/proton/sync_request_response.hpp    |   3 +-
 .../bindings/cpp/include/proton/terminus.hpp    |   8 +-
 .../bindings/cpp/include/proton/transport.hpp   |  22 +-
 .../bindings/cpp/include/proton/type_traits.hpp |   5 +-
 proton-c/bindings/cpp/include/proton/types.hpp  |  19 +-
 proton-c/bindings/cpp/include/proton/url.hpp    |  10 +-
 proton-c/bindings/cpp/include/proton/value.hpp  |  94 -------
 proton-c/bindings/cpp/include/proton/values.hpp |  53 ----
 .../bindings/cpp/include/proton/wrapper.hpp     |  67 -----
 proton-c/bindings/cpp/src/acceptor.cpp          |   4 +-
 proton-c/bindings/cpp/src/acking.cpp            |  48 ----
 .../bindings/cpp/src/blocking_connection.cpp    |   8 +-
 .../cpp/src/blocking_connection_impl.hpp        |   2 +-
 proton-c/bindings/cpp/src/blocking_link.cpp     |   8 +-
 proton-c/bindings/cpp/src/blocking_receiver.cpp |   8 +-
 proton-c/bindings/cpp/src/blocking_sender.cpp   |  10 +-
 proton-c/bindings/cpp/src/connection.cpp        |  62 +++--
 proton-c/bindings/cpp/src/connection_impl.cpp   | 140 ----------
 proton-c/bindings/cpp/src/connection_impl.hpp   |  74 ------
 proton-c/bindings/cpp/src/connector.cpp         |  17 +-
 proton-c/bindings/cpp/src/connector.hpp         |   3 +-
 proton-c/bindings/cpp/src/container.cpp         |  31 +--
 proton-c/bindings/cpp/src/container_impl.cpp    | 112 +++-----
 proton-c/bindings/cpp/src/container_impl.hpp    |  21 +-
 proton-c/bindings/cpp/src/contexts.cpp          |  80 ++++--
 proton-c/bindings/cpp/src/contexts.hpp          |  28 +-
 proton-c/bindings/cpp/src/conversion_test.cpp   |  83 ++++++
 proton-c/bindings/cpp/src/data.cpp              | 126 +++++++--
 proton-c/bindings/cpp/src/decoder.cpp           | 200 +++++++-------
 proton-c/bindings/cpp/src/delivery.cpp          |  11 +-
 proton-c/bindings/cpp/src/encoder.cpp           |  85 +++---
 proton-c/bindings/cpp/src/endpoint.cpp          |   4 -
 proton-c/bindings/cpp/src/event.cpp             |  17 +-
 proton-c/bindings/cpp/src/facade.cpp            |  77 ++++++
 proton-c/bindings/cpp/src/fetcher.cpp           |  16 +-
 proton-c/bindings/cpp/src/fetcher.hpp           |   4 +-
 proton-c/bindings/cpp/src/interop_test.cpp      |  46 +---
 proton-c/bindings/cpp/src/link.cpp              |  55 ++--
 proton-c/bindings/cpp/src/message.cpp           | 124 ++++-----
 proton-c/bindings/cpp/src/messaging_adapter.cpp |   2 +-
 proton-c/bindings/cpp/src/messaging_event.cpp   |   8 +-
 proton-c/bindings/cpp/src/msg.hpp               |   2 +-
 proton-c/bindings/cpp/src/proton_event.cpp      |  49 ++--
 proton-c/bindings/cpp/src/receiver.cpp          |  14 +-
 proton-c/bindings/cpp/src/sender.cpp            |  26 +-
 proton-c/bindings/cpp/src/session.cpp           |  18 +-
 .../bindings/cpp/src/sync_request_response.cpp  |   4 +-
 proton-c/bindings/cpp/src/terminus.cpp          |  22 +-
 proton-c/bindings/cpp/src/test_bits.hpp         |  48 ++++
 proton-c/bindings/cpp/src/transport.cpp         |  11 +-
 proton-c/bindings/cpp/src/types.cpp             |   4 +-
 proton-c/bindings/cpp/src/value.cpp             | 136 ----------
 proton-c/bindings/cpp/src/values.cpp            |  38 ---
 102 files changed, 1799 insertions(+), 1874 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 209f18d..0b30ad0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -151,7 +151,6 @@ if (ENABLE_VALGRIND)
 endif (ENABLE_VALGRIND)
 
 mark_as_advanced (VALGRIND_EXE)
-message("FIXME VG ${VALGRIND_ENV}")
 
 add_subdirectory(proton-c)
 add_subdirectory(examples)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/docs/markdown/memory_management.md
----------------------------------------------------------------------
diff --git a/docs/markdown/memory_management.md b/docs/markdown/memory_management.md
new file mode 100644
index 0000000..5a70911
--- /dev/null
+++ b/docs/markdown/memory_management.md
@@ -0,0 +1,113 @@
+Proton memory mangement
+=======================
+
+Proton is a collection of libraries in different programming langauges. Some of
+the libraries (e.g. C and Java) are written directly in those langauges. Some
+(e.g. python and ruby) are "bindings", native libraries that that internally use
+the C library. All the libraries provide a "native" memory management
+experience, you don't need to know anything about C or the proton C library to
+use them.
+
+If you only program in java, python, ruby or a similar garbage-collected
+language then you may be wondering "what is *memory management*?"  Don't worry,
+the proton library takes care of it. However, as usual, you are responsible for
+some non-memory *resource* management. For example if you fail to `close()` a
+proton connection there won't be memory leaks but the remote end will get a rude
+"connection failed" error instead of an orderly connection close.
+
+If you are a C programmer, you are probably rolling your eyes and wondering why
+the kids these days expect their memory to be managed for them. Don't worry, the
+C API offers the standard C experience: you must call `pn_X_free` on a `pn_X_t*`
+when the time is right and you must know when a `pn_X_t*` can become invalid as
+a side effect of some other call. Read the doc, learn the rules and get it
+right. You are a C programmer!
+
+If you are a modern C++11 programmer and always use `shared_ptr` and
+`unique_ptr` to write leak-safe code, then the C++ binding is leak-safe. If you
+are stuck on C++03, the binding supports `boost::shared_ptr` and
+`boost::intrusive_ptr`. If you cannot even use boost, the binding provides a
+simple (type safe, intrusive) smart pointer of its own which can help you.
+
+If you are a Go programmer, you know that Go takes care of *Go-allocated* memory
+but you are responsible other resource cleanup, e.g. closing connections.  Go
+does not have object-scoped cleanup (or indeed objects) but as a crafty Go
+programmer you know that function-scoped cleanup is all you really need, and
+`defer` is your friend. The Go binding internally starts goroutines and
+allocates memory that is not tracked by Go, so proper cleanup is important (but
+you knew that.)
+
+Proton reference counting in C
+------------------------------
+
+Internally, the proton C library uses reference counting, and you can
+*optionally* use it in your code. You should choose *either* reference counting
+*or* `pn_X_free` in your code, *not both*. It might work, but it is the sort of
+Bad Idea that might break your code in the future and will hurt your head in the
+present. `pn_X_free` is all you really need to write an AMQP application in C.
+
+However, proton is designed to be embedded and integrated. If you are
+integrating proton with a new programming language, or some other kind of
+framwork, reference counts may be useful. If your integration target has some
+form of automatic clean-up *and* some way for you to hook into it (finalizers,
+destructors or the like) then reference counts may help (e.g. python, ruby and
+C++). As a counter-example the Go langauge *is* garbage collected but does *not*
+have finalizers, and the Go binding does *not* use reference counts, it is
+written like a "normal" C application with `pn_X_free`.
+
+If you are mixing your own C code with code using a reference-counted proton
+binding (e.g. C++ or python) then you may need to at least be aware of reference
+counting.
+
+You can even use reference counts in plain C code if you find that helpful (I
+don't see how it would be but you never know.)
+
+The proton C API has standard reference counting rules (but see [1] below)
+
+- A pointer *returned* by a `pn_` function is either *borrowed* by the caller,
+  or the caller *owns* a reference (the API doc says which.)
+- The owner of a reference must call `pn_decref()` exactly once to
+  release it.
+- To keep a borrowed pointer, call `pn_incref()`. This adds a new
+  reference, which you now own.
+- A pointer *passed* to a `pn_` function has no change of ownership. If you
+  owned a reference you still do, if you didn't you still don't.
+- An object is never freed while there are still references to it.
+- An object is freed when all references to it are released.
+
+A *borrowed* pointer is valid within some scope (typically the scope of an event
+handling function) but beyond that scope you cannot assume it is valid unless
+you make a new reference with `pn_incref`. The API documentation for the
+function that returned the pointer should tell you what the scope is.
+
+There are "container" relationships in proton: e.g. a connection contains
+sessions, a session contains links. Containers hold a reference to their
+contents. Freeing a container *releases* that reference. For example freeing a
+connection releases its sessions.
+
+If you don't use reference counts, then freeing a container *frees* the contents
+in traditional C style. However if you add a reference to a contained object it
+will *not* be freed till you release your reference, even if all references to
+container are released [1]. This is useful for bindings to langauges with
+"finalizers" or "destructors". You can use reference counts to "pin" proton C
+objects in memory for as long as any binding object needs them.
+
+For example: if you call `pn_message()` then you *own* a reference to the
+newly-created `pn_message_t` and you must call `pn_decref` when you are
+done [2]. If you call `pn_event_link()` in an event handler then you get a
+*borrowed* reference to the link. You can use it in the scope of the event
+handler, but if you want to save it for later you must call `pn_incref`
+to add a reference and of course call `pn_decref` when you are done with
+that reference.
+
+[1] *Internally* the proton library plays tricks with reference counts to
+implement 'weak' pointers and manage circular containment relationships. You do
+*not* need to understand this to use proton, even if you are writing bindings or
+doing funky mixed-language development. However if you are working on the
+implementation of the proton C library itself you may need to learn more, ask on
+proton@qpid.apache.org.
+
+[2] Actually if you call `pn_message()` then you must *either* call
+`pn_decref()` *or* `pn_message_free()`, definitely not both. It is
+possible to mix reference couting and 'free' style memory management in the same
+codebase (`free` is sort-of an alias for `decref`) but it is probably not a good
+idea.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/examples/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt
index 77ab816..40925f9 100644
--- a/examples/cpp/CMakeLists.txt
+++ b/examples/cpp/CMakeLists.txt
@@ -24,13 +24,13 @@ include_directories(
 foreach(example
     broker
     helloworld
-    helloworld_blocking
+    # helloworld_blocking
     helloworld_direct
     simple_recv
     simple_send
     direct_recv
     direct_send
-    sync_client
+    # sync_client
     client
     server
     server_direct

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/examples/cpp/broker.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/broker.cpp b/examples/cpp/broker.cpp
index a57fff9..7752645 100644
--- a/examples/cpp/broker.cpp
+++ b/examples/cpp/broker.cpp
@@ -35,8 +35,8 @@
 class queue {
   public:
     bool dynamic;
-    typedef std::deque<proton::message> message_queue;
-    typedef std::list<proton::sender> sender_list;
+    typedef std::deque<proton::message_value> message_queue;
+    typedef std::list<proton::counted_ptr<proton::sender> > sender_list;
     message_queue messages;
     sender_list consumers;
 
@@ -51,14 +51,13 @@ class queue {
         return (consumers.size() == 0 && (dynamic || messages.size() == 0));
     }
 
-    void publish(proton::message &m) {
+    void publish(const proton::message_value &m) {
         messages.push_back(m);
         dispatch(0);
     }
 
     void dispatch(proton::sender *s) {
-        while (deliver_to(s)) {
-        }
+        while (deliver_to(s)) {}
     }
 
     bool deliver_to(proton::sender *consumer) {
@@ -67,7 +66,8 @@ class queue {
         if (!count) return false;
         bool result = false;
         sender_list::iterator it = consumers.begin();
-        if (!consumer && count) consumer = &*it;
+        if (!consumer && count)
+            consumer = it->get();
 
         while (messages.size()) {
             if (consumer->credit()) {
@@ -118,10 +118,10 @@ class broker : public proton::messaging_handler {
     }
 
     void on_link_opening(proton::event &e) {
-        proton::link lnk = e.link();
+        proton::link& lnk = e.link();
         if (lnk.is_sender()) {
-            proton::sender sender(lnk);
-            proton::terminus remote_source(lnk.remote_source());
+            proton::sender &sender(lnk.sender());
+            proton::terminus &remote_source(lnk.remote_source());
             if (remote_source.is_dynamic()) {
                 std::string address = queue_name();
                 lnk.source().address(address);
@@ -157,10 +157,9 @@ class broker : public proton::messaging_handler {
     }
 
     void on_link_closing(proton::event &e) {
-        proton::link lnk = e.link();
+        proton::link &lnk = e.link();
         if (lnk.is_sender()) {
-            proton::sender s(lnk);
-            unsubscribe(s);
+            unsubscribe(lnk.sender());
         }
     }
 
@@ -173,26 +172,25 @@ class broker : public proton::messaging_handler {
     }
 
     void remove_stale_consumers(proton::connection &connection) {
-        proton::link l = connection.link_head(proton::endpoint::REMOTE_ACTIVE);
+        proton::link *l = connection.link_head(proton::endpoint::REMOTE_ACTIVE);
         while (l) {
-            if (l.is_sender()) {
-                proton::sender s(l);
-                unsubscribe(s);
+            if (l->is_sender()) {
+                unsubscribe(l->sender());
             }
-            l = l.next(proton::endpoint::REMOTE_ACTIVE);
+            l = l->next(proton::endpoint::REMOTE_ACTIVE);
         }
     }
 
     void on_sendable(proton::event &e) {
-        proton::link lnk = e.link();
-        proton::sender sender(lnk);
+        proton::link& lnk = e.link();
         std::string addr = lnk.source().address();
-        get_queue(addr).dispatch(&sender);
+        proton::sender &s(lnk.sender());
+        get_queue(addr).dispatch(&s);
     }
 
     void on_message(proton::event &e) {
         std::string addr = e.link().target().address();
-        proton::message msg = e.message();
+        proton::message_value msg = e.message();
         get_queue(addr).publish(msg);
     }
 };

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/examples/cpp/client.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/client.cpp b/examples/cpp/client.cpp
index 4c34ce7..e58311a 100644
--- a/examples/cpp/client.cpp
+++ b/examples/cpp/client.cpp
@@ -33,8 +33,8 @@ class client : public proton::messaging_handler {
   private:
     proton::url url;
     std::vector<std::string> requests;
-    proton::sender sender;
-    proton::receiver receiver;
+    proton::counted_ptr<proton::sender> sender;
+    proton::counted_ptr<proton::receiver> receiver;
 
   public:
     client(const proton::url &u, const std::vector<std::string>& r) : url(u), requests(r) {}
@@ -42,24 +42,24 @@ class client : public proton::messaging_handler {
     void on_start(proton::event &e) {
         sender = e.container().create_sender(url);
         // Create a receiver with a dynamically chosen unique address.
-        receiver = e.container().create_receiver(sender.connection(), "", true/*dynamic*/);
+        receiver = e.container().create_receiver(sender->connection(), "", true/*dynamic*/);
     }
 
     void send_request() {
-        proton::message req;
+        proton::message_value 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) 
+        if (&e.link() == receiver.get()) 
             send_request();
     }
 
     void on_message(proton::event &e) {
         if (requests.empty()) return; // Spurious extra message!
-        proton::message response = e.message();
+        proton::message& response = e.message();
         std::cout << '"' << requests.front() << '"' << " => " << response.body() << std::endl;
         requests.erase(requests.begin());
         if (!requests.empty()) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/examples/cpp/direct_recv.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/direct_recv.cpp b/examples/cpp/direct_recv.cpp
index 9eead92..94cc943 100644
--- a/examples/cpp/direct_recv.cpp
+++ b/examples/cpp/direct_recv.cpp
@@ -37,7 +37,7 @@ class direct_recv : public proton::messaging_handler {
     proton::url url;
     int expected;
     int received;
-    proton::acceptor acceptor;
+    proton::counted_ptr<proton::acceptor> acceptor;
 
   public:
     direct_recv(const std::string &s, int c) : url(s), expected(c), received(0) {}
@@ -48,8 +48,8 @@ class direct_recv : public proton::messaging_handler {
     }
 
     void on_message(proton::event &e) {
-        proton::message msg = e.message();
-        proton::value id = msg.id();
+        proton::message& msg = e.message();
+        proton::data_value id = msg.id();
         if (id.type() == proton::ULONG) {
             if (id.get<int>() < received)
                 return; // ignore duplicate
@@ -61,7 +61,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/9bb9c442/examples/cpp/direct_send.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/direct_send.cpp b/examples/cpp/direct_send.cpp
index a4e572c..1302ac7 100644
--- a/examples/cpp/direct_send.cpp
+++ b/examples/cpp/direct_send.cpp
@@ -39,7 +39,7 @@ class simple_send : public proton::messaging_handler {
     int sent;
     int confirmed;
     int total;
-    proton::acceptor acceptor;
+    proton::counted_ptr<proton::acceptor> acceptor;
   public:
 
     simple_send(const std::string &s, int c) : url(s), sent(0), confirmed(0), total(c) {}
@@ -50,10 +50,10 @@ class simple_send : public proton::messaging_handler {
     }
 
     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(proton::value(sent + 1));
+            proton::message_value msg;
+            msg.id(proton::data_value(sent + 1));
             std::map<std::string, int> m;
             m["sequence"] = sent+1;
             msg.body(proton::as<proton::MAP>(m));
@@ -67,7 +67,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/9bb9c442/examples/cpp/encode_decode.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/encode_decode.cpp b/examples/cpp/encode_decode.cpp
index ea0f471..5657e73 100644
--- a/examples/cpp/encode_decode.cpp
+++ b/examples/cpp/encode_decode.cpp
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-#include <proton/value.hpp>
+#include <proton/data.hpp>
 #include <algorithm>
 #include <iostream>
 #include <iterator>
@@ -32,55 +32,55 @@ using namespace std;
 
 // Print is defined at the end as an example of how to query and extract complex
 // values in terms of their simple components.
-void print(proton::values& values);
+void print(proton::data&);
 
 // Inserting and extracting simple C++ values.
 void simple_insert_extract() {
-    proton::values vv;
     cout << endl << "== Simple values: int, string, bool" << endl;
-    vv << 42 << "foo" << true;
-    print(vv);
+    proton::data_value dv;
+    dv.encoder() << 42 << "foo" << true;
+    print(dv);
     int i;
     string s;
     bool b;
-    vv.rewind();
-    vv >> i >> s >> b;
+    dv.decoder().rewind();
+    dv.decoder() >> i >> s >> b;
     cout << "Extracted: " << i << ", " << s << ", " << b << endl;
     // Encode and decode as AMQP
-    string amqp_data = vv.encode();
+    string amqp_data = dv.encoder().encode();
     cout << "Encoded as AMQP in " << amqp_data.size() << " bytes" << endl;
-    proton::values vv2;
-    vv2.decode(amqp_data);
-    vv2 >> i >> s >> b;
+    proton::data_value  dt2;
+    dt2.decoder().decode(amqp_data);
+    dt2.decoder() >> i >> s >> b;
     cout << "Decoded: " << i << ", " << s << ", " << b << endl;
 }
 
 // Inserting values as a specific AMQP type
 void simple_insert_extract_exact_type() {
-    proton::values vv;
+    proton::data_value dv;
     cout << endl << "== Specific AMQP types: byte, long, symbol" << endl;
-    vv << proton::amqp_byte('x') << proton::amqp_long(123456789123456789) << proton::amqp_symbol("bar");
-    print(vv);
-    vv.rewind();
+    dv.encoder() << proton::amqp_byte('x') << proton::amqp_long(123456789123456789) << proton::amqp_symbol("bar");
+    print(dv);
+    dv.decoder().rewind();
     // Check that we encoded the correct types, but note that decoding will
     // still convert to standard C++ types, in particular any AMQP integer type
     // can be converted to a long-enough C++ integer type..
     int64_t i1, i2;
     string s;
-    vv >> i1 >> i2 >> s;
+    dv.decoder() >> i1 >> i2 >> s;
     cout << "Extracted (with conversion) " << i1 << ", " << i2 << ", " << s << endl;
 
     // Now use the as() function to fail unless we extract the exact AMQP type expected.
-    vv.rewind();            // amqp_byte(1) << amqp_long(2) << amqp_symbol("bar");
+    dv.decoder().rewind(); // amqp_byte(1) << amqp_long(2) << amqp_symbol("bar");
     proton::amqp_long l;
     // Fails, extracting amqp_byte as amqp_long
-    try { vv >> proton::as<proton::LONG>(l); throw logic_error("expected error"); } catch (proton::decode_error) {}
+    try { dv.decoder() >> proton::as<proton::LONG>(l); throw logic_error("expected error"); } catch (proton::decode_error) {}
     proton::amqp_byte b;
-    vv >> proton::as<proton::BYTE>(b) >> proton::as<proton::LONG>(l); // OK, extract amqp_byte as amqp_byte, amqp_long as amqp_long.
+    dv.decoder() >> proton::as<proton::BYTE>(b) >> proton::as<proton::LONG>(l); // OK, extract amqp_byte as amqp_byte, amqp_long as amqp_long.
     string str;
     // Fails, extracting amqp_symbol as amqp_string.
-    try { vv >> proton::as<proton::STRING>(str); throw logic_error("expected error"); } catch (proton::decode_error) {}
-    vv >> proton::as<proton::SYMBOL>(str);       // OK, extract amqp_symbol as amqp_symbol
+    try { dv.decoder() >> proton::as<proton::STRING>(str); throw logic_error("expected error"); } catch (proton::decode_error) {}
+    dv.decoder() >> proton::as<proton::SYMBOL>(str);       // OK, extract amqp_symbol as amqp_symbol
     cout << "Extracted (exact) " << b << ", " << l << ", " << str << endl;
 }
 
@@ -118,54 +118,54 @@ void insert_extract_containers() {
     m["one"] = 1;
     m["two"] = 2;
 
-    proton::values vv;
-    vv << proton::as<proton::ARRAY>(a) << proton::as<proton::LIST>(l) << proton::as<proton::MAP>(m);
-    print(vv);
+    proton::data_value dv;
+    dv.encoder() << proton::as<proton::ARRAY>(a) << proton::as<proton::LIST>(l) << proton::as<proton::MAP>(m);
+    print(dv);
 
     vector<int> a1, l1;
     map<string, int> m1;
-    vv.rewind();
-    vv >> proton::as<proton::ARRAY>(a1) >> proton::as<proton::LIST>(l1) >> proton::as<proton::MAP>(m1);
+    dv.decoder().rewind();
+    dv.decoder() >> proton::as<proton::ARRAY>(a1) >> proton::as<proton::LIST>(l1) >> proton::as<proton::MAP>(m1);
     cout << "Extracted: " << a1 << ", " << l1 << ", " << m1 << endl;
 }
 
 // Containers with mixed types, use value to represent arbitrary AMQP types.
 void mixed_containers() {
     cout << endl << "== List and map of mixed type values." << endl;
-    vector<proton::value> l;
-    l.push_back(proton::value(42));
-    l.push_back(proton::value(proton::amqp_string("foo")));
-    map<proton::value, proton::value> m;
-    m[proton::value("five")] = proton::value(5);
-    m[proton::value(4)] = proton::value("four");
-    proton::values vv;
-    vv << proton::as<proton::LIST>(l) << proton::as<proton::MAP>(m);
-    print(vv);
+    vector<proton::data_value> l;
+    l.push_back(proton::data_value(42));
+    l.push_back(proton::data_value(proton::amqp_string("foo")));
+    map<proton::data_value, proton::data_value> m;
+    m[proton::data_value("five")] = proton::data_value(5);
+    m[proton::data_value(4)] = proton::data_value("four");
+    proton::data_value dv;
+    dv.encoder() << proton::as<proton::LIST>(l) << proton::as<proton::MAP>(m);
+    print(dv);
 
-    vector<proton::value> l1;
-    map<proton::value, proton::value> m1;
-    vv.rewind();
-    vv >> proton::as<proton::LIST>(l1) >> proton::as<proton::MAP>(m1);
+    vector<proton::data_value> l1;
+    map<proton::data_value, proton::data_value> m1;
+    dv.decoder().rewind();
+    dv.decoder() >> proton::as<proton::LIST>(l1) >> proton::as<proton::MAP>(m1);
     cout << "Extracted: " << l1 << ", " << m1 << endl;
 }
 
 // Insert using stream operators (see print_next for example of extracting with stream ops.)
 void insert_extract_stream_operators() {
     cout << endl << "== Insert with stream operators." << endl;
-    proton::values vv;
+    proton::data_value dv;
     // Note: array elements must be encoded with the exact type, they are not
     // automaticlly converted. Mismatched types for array elements will not
-    // be detected until vv.encode() is called.
-    vv << proton::start::array(proton::INT) << proton::amqp_int(1) << proton::amqp_int(2) << proton::amqp_int(3) << proton::finish();
-    print(vv);
+    // be detected until dv.encode() is called.
+    dv.encoder() << proton::start::array(proton::INT) << proton::amqp_int(1) << proton::amqp_int(2) << proton::amqp_int(3) << proton::finish();
+    print(dv);
 
-    vv.clear();
-    vv << proton::start::list() << proton::amqp_int(42) << false << proton::amqp_symbol("x") << proton::finish();
-    print(vv);
+    dv.clear();
+    dv.encoder() << proton::start::list() << proton::amqp_int(42) << false << proton::amqp_symbol("x") << proton::finish();
+    print(dv);
 
-    vv.clear();
-    vv << proton::start::map() << "k1" << proton::amqp_int(42) << proton::amqp_symbol("k2") << false << proton::finish();
-    print(vv);
+    dv.clear();
+    dv.encoder() << proton::start::map() << "k1" << proton::amqp_int(42) << proton::amqp_symbol("k2") << false << proton::finish();
+    print(dv);
 }
 
 int main(int, char**) {
@@ -187,75 +187,75 @@ int main(int, char**) {
 // NOTE this is for example puroses only: There is a built in ostream operator<< for values.
 //
 //
-void print_next(proton::values& vv) {
-    proton::type_id type = vv.type();
+void print_next(proton::data& dv) {
+    proton::type_id type = dv.type();
     proton::start s;
     switch (type) {
       case proton::ARRAY: {
-          vv >> s;
+          dv.decoder() >> s;
           cout << "array<" << s.element;
           if (s.is_described) {
               cout  << ", descriptor=";
-              print_next(vv);
+              print_next(dv);
           }
           cout << ">[";
           for (size_t i = 0; i < s.size; ++i) {
               if (i) cout << ", ";
-              print_next(vv);
+              print_next(dv);
           }
           cout << "]";
-          vv >> proton::finish();
+          dv.decoder() >> proton::finish();
           break;
       }
       case proton::LIST: {
-          vv >> s;
+          dv.decoder() >> s;
           cout << "list[";
           for (size_t i = 0; i < s.size; ++i) {
               if (i) cout << ", ";
-              print_next(vv);
+              print_next(dv);
           }
           cout << "]";
-          vv >> proton::finish();
+          dv.decoder() >> proton::finish();
           break;
       }
       case proton::MAP: {
-          vv >> s;
+          dv.decoder() >> s;
           cout << "map{";
           for (size_t i = 0; i < s.size/2; ++i) {
               if (i) cout << ", ";
-              print_next(vv);
+              print_next(dv);
               cout << ":";        // key:value
-              print_next(vv);
+              print_next(dv);
           }
           cout << "}";
-          vv >> proton::finish();
+          dv.decoder() >> proton::finish();
           break;
       }
       case proton::DESCRIBED: {
-          vv >> s;
+          dv.decoder() >> s;
           cout << "described(";
-          print_next(vv);      // Descriptor
-          print_next(vv);      // value
-          vv >> proton::finish();
+          print_next(dv);      // Descriptor
+          print_next(dv);      // value
+          dv.decoder() >> proton::finish();
           break;
       }
       default:
         // A simple type. We could continue the switch for all AMQP types but
         // instead we us the `value` type which can hold and print any AMQP
         // value.
-        proton::value v;
-        vv >> v;
+        proton::data_value v;
+        dv.decoder() >> v;
         cout << type << "(" << v << ")";
     }
 }
 
 // Print all the values with print_next
-void print(proton::values& vv) {
-    vv.rewind();
+void print(proton::data& dv) {
+    dv.decoder().rewind();
     cout << "Values: ";
-    while (vv.more()) {
-        print_next(vv);
-        if (vv.more()) cout << ", ";
+    while (dv.decoder().more()) {
+        print_next(dv);
+        if (dv.decoder().more()) cout << ", ";
     }
     cout << endl;
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/examples/cpp/example_test.py
----------------------------------------------------------------------
diff --git a/examples/cpp/example_test.py b/examples/cpp/example_test.py
index f244516..5059678 100644
--- a/examples/cpp/example_test.py
+++ b/examples/cpp/example_test.py
@@ -78,7 +78,7 @@ def wait_addr(addr, timeout=10):
 
 def pick_addr():
     """Pick a new host:port address."""
-    # FIXME aconway 2015-07-14: need a safer way to pick ports.
+    # TODO aconway 2015-07-14: need a safer way to pick ports.
     p =  randrange(10000, 20000)
     return "127.0.0.1:%s" % p
 
@@ -119,10 +119,11 @@ class ExampleTest(unittest.TestCase):
         hw = execute("helloworld", b.addr)
         self.assertEqual('"Hello World!"\n', hw)
 
-    def test_helloworld_blocking(self):
-        b = Broker.get()
-        hw = execute("helloworld_blocking", b.addr, b.addr)
-        self.assertEqual('"Hello World!"\n', hw)
+        # FIXME aconway 2015-08-28: Restore blocking code and examples
+    # def test_helloworld_blocking(self):
+    #     b = Broker.get()
+    #     hw = execute("helloworld_blocking", b.addr, b.addr)
+    #     self.assertEqual('"Hello World!"\n', hw)
 
     def test_helloworld_direct(self):
         addr = pick_addr()
@@ -179,13 +180,14 @@ class ExampleTest(unittest.TestCase):
         finally:
             server.kill()
 
-    def test_sync_request_response(self):
-        b = Broker.get()
-        server = background("server", "-a", b.addr)
-        try:
-            self.assertEqual(execute("sync_client", "-a", b.addr), self.CLIENT_EXPECT)
-        finally:
-            server.kill()
+        # FIXME aconway 2015-08-28: Restore blocking code and examples
+    # def test_sync_request_response(self):
+    #     b = Broker.get()
+    #     server = background("server", "-a", b.addr)
+    #     try:
+    #         self.assertEqual(execute("sync_client", "-a", b.addr), self.CLIENT_EXPECT)
+    #     finally:
+    #         server.kill()
 
     def test_request_response_direct(self):
         addr = pick_addr()

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/examples/cpp/helloworld.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld.cpp b/examples/cpp/helloworld.cpp
index 34e5076..4f73432 100644
--- a/examples/cpp/helloworld.cpp
+++ b/examples/cpp/helloworld.cpp
@@ -34,20 +34,20 @@ 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);
         e.container().create_receiver(conn, url.path());
         e.container().create_sender(conn, url.path());
     }
 
     void on_sendable(proton::event &e) {
-        proton::message m;
+        proton::message_value m;
         m.body("Hello World!");
         e.sender().send(m);
         e.sender().close();
     }
 
     void on_message(proton::event &e) {
-        proton::value body(e.message().body());
+        proton::data& body(e.message().body());
         std::cout << body << std::endl;
         e.connection().close();
     }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/examples/cpp/helloworld_blocking.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld_blocking.cpp b/examples/cpp/helloworld_blocking.cpp
index 9f56fa2..39cc10d 100644
--- a/examples/cpp/helloworld_blocking.cpp
+++ b/examples/cpp/helloworld_blocking.cpp
@@ -19,7 +19,6 @@
  *
  */
 
-#include "proton/container.hpp"
 #include "proton/messaging_handler.hpp"
 #include "proton/blocking_sender.hpp"
 #include "proton/blocking_receiver.hpp"
@@ -34,13 +33,13 @@ int main(int argc, char **argv) {
         proton::blocking_receiver receiver = conn.create_receiver(url.path());
         proton::blocking_sender sender = conn.create_sender(url.path());
 
-        proton::message m;
-        m.body("Hello World!");
-        sender.send(m);
+        proton::message_value m;
+        m->body("Hello World!");
+        sender.send(*m);
 
         proton::duration timeout(30000);
-        proton::message m2 = receiver.receive(timeout);
-        std::cout << m2.body() << std::endl;
+        proton::message_value m2 = receiver.receive(timeout);
+        std::cout << m2->body() << std::endl;
         receiver.accept();
 
         conn.close();

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/examples/cpp/helloworld_direct.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld_direct.cpp b/examples/cpp/helloworld_direct.cpp
index 2c7792e..3240586 100644
--- a/examples/cpp/helloworld_direct.cpp
+++ b/examples/cpp/helloworld_direct.cpp
@@ -28,7 +28,7 @@
 class hello_world_direct : public proton::messaging_handler {
   private:
     proton::url url;
-    proton::acceptor acceptor;
+    proton::counted_ptr<proton::acceptor> acceptor;
   public:
 
     hello_world_direct(const proton::url& u) : url(u) {}
@@ -39,7 +39,7 @@ class hello_world_direct : public proton::messaging_handler {
     }
 
     void on_sendable(proton::event &e) {
-        proton::message m;
+        proton::message_value m;
         m.body("Hello World!");
         e.sender().send(m);
         e.sender().close();
@@ -54,7 +54,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/9bb9c442/examples/cpp/server.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/server.cpp b/examples/cpp/server.cpp
index bad49d3..08c4376 100644
--- a/examples/cpp/server.cpp
+++ b/examples/cpp/server.cpp
@@ -31,9 +31,9 @@
 
 class server : public proton::messaging_handler {
   private:
-    typedef std::map<std::string, proton::sender> sender_map;
+    typedef std::map<std::string, proton::counted_ptr<proton::sender> > sender_map;
     proton::url url;
-    proton::connection connection;
+    proton::counted_ptr<proton::connection> connection;
     sender_map senders;
 
   public:
@@ -42,7 +42,7 @@ class server : public proton::messaging_handler {
 
     void on_start(proton::event &e) {
         connection = e.container().connect(url);
-        e.container().create_receiver(connection, url.path());
+        e.container().create_receiver(*connection, url.path());
         std::cout << "server connected to " << url << std::endl;
     }
 
@@ -56,13 +56,13 @@ class server : public proton::messaging_handler {
     void on_message(proton::event &e) {
         std::cout << "Received " << e.message().body() << std::endl;
         std::string reply_to = e.message().reply_to();
-        proton::message reply;
+        proton::message_value reply;
         reply.address(reply_to);
         reply.body(to_upper(e.message().body().get<std::string>()));
         reply.correlation_id(e.message().correlation_id());
         if (!senders[reply_to])
-            senders[reply_to] = e.container().create_sender(connection, reply_to);
-        senders[reply_to].send(reply);
+            senders[reply_to] = e.container().create_sender(*connection, reply_to);
+        senders[reply_to]->send(reply);
     }
 };
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/examples/cpp/server_direct.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/server_direct.cpp b/examples/cpp/server_direct.cpp
index a2571ca..c89edca 100644
--- a/examples/cpp/server_direct.cpp
+++ b/examples/cpp/server_direct.cpp
@@ -32,9 +32,8 @@
 
 class server : public proton::messaging_handler {
   private:
-    typedef std::map<std::string, proton::sender> sender_map;
+    typedef std::map<std::string, proton::counted_ptr<proton::sender> > sender_map;
     proton::url url;
-    proton::connection connection;
     sender_map senders;
     int address_counter;
 
@@ -61,10 +60,10 @@ class server : public proton::messaging_handler {
     }
 
     void on_link_opening(proton::event& e) {
-        proton::link link = e.link();
-        if (link.is_sender() && link.remote_source() && link.remote_source().is_dynamic()) {
+        proton::link& link = e.link();
+        if (link.is_sender() && link.has_remote_source() && link.remote_source().is_dynamic()) {
             link.source().address(generate_address());
-            senders[link.source().address()] = link;
+            senders[link.source().address()] = link.sender();
         }
     }
 
@@ -75,12 +74,12 @@ class server : public proton::messaging_handler {
         if (it == senders.end()) {
             std::cout << "No link for reply_to: " << reply_to << std::endl;
         } else {
-            proton::sender sender = it->second;
-            proton::message reply;
+            proton::counted_ptr<proton::sender> sender = it->second;
+            proton::message_value 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/9bb9c442/examples/cpp/simple_recv.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/simple_recv.cpp b/examples/cpp/simple_recv.cpp
index 94cd398..88eb48c 100644
--- a/examples/cpp/simple_recv.cpp
+++ b/examples/cpp/simple_recv.cpp
@@ -36,6 +36,7 @@
 class simple_recv : public proton::messaging_handler {
   private:
     proton::url url;
+    proton::counted_ptr<proton::receiver> receiver;
     int expected;
     int received;
   public:
@@ -43,13 +44,13 @@ 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) {
-        e.container().create_receiver(url);
+        receiver = e.container().create_receiver(url);
         std::cout << "simple_recv listening on " << url << std::endl;
     }
 
     void on_message(proton::event &e) {
-        proton::message msg = e.message();
-        proton::value id = msg.id();
+        proton::message& msg = e.message();
+        proton::data_value id = msg.id();
         if (id.type() == proton::ULONG) {
             if (id.get<int>() < received)
                 return; // ignore duplicate

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/examples/cpp/simple_send.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/simple_send.cpp b/examples/cpp/simple_send.cpp
index 0bac49b..1db94af 100644
--- a/examples/cpp/simple_send.cpp
+++ b/examples/cpp/simple_send.cpp
@@ -36,6 +36,7 @@
 class simple_send : public proton::messaging_handler {
   private:
     proton::url url;
+    proton::counted_ptr<proton::sender> sender;
     int sent;
     int confirmed;
     int total;
@@ -44,14 +45,14 @@ 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) {
-        e.container().create_sender(url);
+        sender = e.container().create_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(proton::value(sent + 1));
+            proton::message_value msg;
+            msg.id(proton::data_value(sent + 1));
             std::map<std::string, int> m;
             m["sequence"] = sent+1;
             msg.body(proton::as<proton::MAP>(m));

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/examples/cpp/sync_client.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/sync_client.cpp b/examples/cpp/sync_client.cpp
index d0ad6fc..2bcb5c5 100644
--- a/examples/cpp/sync_client.cpp
+++ b/examples/cpp/sync_client.cpp
@@ -52,9 +52,9 @@ int main(int argc, char **argv) {
         proton::blocking_connection conn(url, proton::duration(timeout));
         proton::sync_request_response client(conn, url.path());
         for (std::vector<std::string>::const_iterator i=requests.begin(); i != requests.end(); i++) {
-            proton::message request;
-            request.body(*i);
-            proton::message response = client.call(request);
+            proton::message_value request;
+            request->body(*i);
+            proton::message_value response(client.call(*request));
             std::cout << request.body() << " => " << response.body() << std::endl;
         }
         return 0;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/proton-c/bindings/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt
index 519eb4e..5e116da 100644
--- a/proton-c/bindings/cpp/CMakeLists.txt
+++ b/proton-c/bindings/cpp/CMakeLists.txt
@@ -26,6 +26,12 @@ if (HAVE_LONG_LONG)
   add_definitions(-DPN_HAVE_LONG_LONG=1)
 endif()
 
+# Check for boost
+find_path(BOOST_INCLUDE_DIR boost/shared_ptr.hpp PATH_SUFFIXES include)
+if (BOOST_INCLUDE_DIR)
+  set(CXX_BOOST_FLAGS "-DPN_USE_BOOST")
+endif()
+
 include_directories(
   "${CMAKE_SOURCE_DIR}/proton-c/include"
   "${CMAKE_CURRENT_SOURCE_DIR}/include"
@@ -33,12 +39,17 @@ include_directories(
 
 set(qpid-proton-cpp-source
   src/acceptor.cpp
-  src/acking.cpp
+  # FIXME aconway 2015-08-28: Restore blocking code and examples
+  # src/blocking_connection.cpp
+  # src/blocking_connection_impl.cpp
+  # src/blocking_link.cpp
+  # src/blocking_receiver.cpp
+  # src/blocking_sender.cpp
   src/connection.cpp
-  src/connection_impl.cpp
   src/connector.cpp
   src/container.cpp
   src/container_impl.cpp
+  src/contexts.cpp
   src/data.cpp
   src/decoder.cpp
   src/delivery.cpp
@@ -47,38 +58,34 @@ set(qpid-proton-cpp-source
   src/endpoint.cpp
   src/error.cpp
   src/event.cpp
+  # FIXME aconway 2015-08-28: Restore blocking code and examples
+  # src/fetcher.cpp
   src/handler.cpp
   src/link.cpp
   src/message.cpp
   src/messaging_adapter.cpp
   src/messaging_event.cpp
   src/messaging_handler.cpp
+  src/proton_bits.cpp
   src/proton_event.cpp
   src/proton_handler.cpp
   src/receiver.cpp
   src/sender.cpp
   src/session.cpp
+  # FIXME aconway 2015-08-28: Restore blocking code and examples
+  # src/sync_request_response.cpp
   src/terminus.cpp
   src/transport.cpp
-  src/url.cpp
-  src/value.cpp
-  src/values.cpp
-  src/proton_bits.cpp
-  src/fetcher.cpp
-  src/blocking_connection.cpp
-  src/blocking_connection_impl.cpp
-  src/blocking_link.cpp
-  src/blocking_sender.cpp
-  src/blocking_receiver.cpp
-  src/sync_request_response.cpp
-  src/contexts.cpp
   src/types.cpp
+  src/url.cpp
+  src/facade.cpp
   )
 
+
 set_source_files_properties (
   ${qpid-proton-cpp-source}
   PROPERTIES
-  COMPILE_FLAGS "${CXX_WARNING_FLAGS}"
+  COMPILE_FLAGS "${CXX_WARNING_FLAGS} ${CXX_BOOST_FLAGS}"
   )
 
 add_library(qpid-proton-cpp SHARED ${qpid-proton-cpp-source})
@@ -113,6 +120,7 @@ macro(add_cpp_test test)
 endmacro(add_cpp_test)
 
 add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests)
+add_cpp_test(conversion_test ${CMAKE_SOURCE_DIR}/tests)
 
 ## Install
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/proton-c/bindings/cpp/docs/mainpage.md
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/docs/mainpage.md b/proton-c/bindings/cpp/docs/mainpage.md
index 70db98b..b370b13 100644
--- a/proton-c/bindings/cpp/docs/mainpage.md
+++ b/proton-c/bindings/cpp/docs/mainpage.md
@@ -67,7 +67,7 @@ Commonly used classes
 
 A brief summary of some of the key classes follows.
 
-The `proton::container` class is a convenient entry point into the API, allowing
+The `proton::container` class is the main entry point into the API, allowing
 connections and links to be established. Applications are structured as one or
 more event handlers.
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/proton-c/bindings/cpp/docs/tutorial.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/docs/tutorial.hpp b/proton-c/bindings/cpp/docs/tutorial.hpp
index 6df7593..56f3e9f 100644
--- a/proton-c/bindings/cpp/docs/tutorial.hpp
+++ b/proton-c/bindings/cpp/docs/tutorial.hpp
@@ -3,9 +3,7 @@
 // that shows messed-up line numbers in \skip \until code extracts so this file
 // is markdown wrapped in a C++ comment - which works.
 
-/** \page tutorial Tutorial
-Tutorial 
-========
+/*! \page tutorial Tutorial
 
 This is a brief tutorial that will walk you through the fundamentals of building
 messaging applications in incremental steps. There are further examples, in
@@ -103,7 +101,7 @@ code at \ref helloworld_direct.cpp
 
 The first difference, is that rather than creating a receiver on the same
 connection as our sender, we listen for incoming connections by invoking the
-`proton::container::listen()` method on the container.
+`proton::container::Xblisten()` method on the container.
 
 \skip on_start
 \until }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/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 6339a08..ed7c852 100644
--- a/proton-c/bindings/cpp/include/proton/acceptor.hpp
+++ b/proton-c/bindings/cpp/include/proton/acceptor.hpp
@@ -24,18 +24,16 @@
 
 #include "proton/reactor.h"
 #include "proton/export.hpp"
-#include "proton/wrapper.hpp"
+#include "proton/facade.hpp"
 
 struct pn_connection_t;
 
 namespace proton {
 
 /** acceptor accepts connections. @see container::listen */
-class acceptor : public wrapper<pn_acceptor_t>
+class acceptor : public counted_facade<pn_acceptor_t, acceptor>
 {
   public:
-    PN_CPP_EXTERN acceptor(pn_acceptor_t * = 0);
-
     /** close the acceptor */
     PN_CPP_EXTERN void close();
 };

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/proton-c/bindings/cpp/include/proton/acking.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/acking.hpp b/proton-c/bindings/cpp/include/proton/acking.hpp
deleted file mode 100644
index 0001a4d..0000000
--- a/proton-c/bindings/cpp/include/proton/acking.hpp
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef PROTON_CPP_ACKING_H
-#define PROTON_CPP_ACKING_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.
- *
- */
-
-#include "proton/export.hpp"
-#include "proton/delivery.hpp"
-
-namespace proton {
-
-
-/** acking provides simple functions to acknowledge, or settle, a delivery */
-class acking
-{
-  public:
-    /** accept a delivery */
-    PN_CPP_EXTERN virtual void accept(delivery &d);
-    /** reject a delivery */
-    PN_CPP_EXTERN virtual void reject(delivery &d);
-    /** release a delivery. Mark it delivery::MODIFIED if it has already been delivered,
-     * delivery::RELEASED otherwise.
-     */
-    PN_CPP_EXTERN virtual void release(delivery &d, bool delivered=true);
-    /** settle a delivery with the given delivery::state */
-    PN_CPP_EXTERN virtual void settle(delivery &d, delivery::state s = delivery::REJECTED);
-};
-
-
-}
-
-#endif  /*!PROTON_CPP_ACKING_H*/
-
-

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/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 e82a2ee..c9a5133 100644
--- a/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
+++ b/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
@@ -22,20 +22,14 @@
  *
  */
 #include "proton/export.hpp"
-#include "proton/handle.hpp"
-#include "proton/endpoint.hpp"
-#include "proton/container.hpp"
+#include "proton/facade.hpp"
 #include "proton/duration.hpp"
-#include "proton/messaging_handler.hpp"
-#include "proton/types.h"
 #include <string>
 
 struct pn_connection_t;
 
 namespace proton {
 class url;
-class container;
-class blocking_connection_impl;
 class ssl_domain;
 class blocking_sender;
 class blocking_receiver;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/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 0fe5e9a..3ec945a 100644
--- a/proton-c/bindings/cpp/include/proton/blocking_link.hpp
+++ b/proton-c/bindings/cpp/include/proton/blocking_link.hpp
@@ -22,7 +22,6 @@
  *
  */
 #include "proton/export.hpp"
-#include "proton/handle.hpp"
 #include "proton/endpoint.hpp"
 #include "proton/container.hpp"
 #include "proton/duration.hpp"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/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 9b3c1a1..55e340e 100644
--- a/proton-c/bindings/cpp/include/proton/blocking_sender.hpp
+++ b/proton-c/bindings/cpp/include/proton/blocking_sender.hpp
@@ -22,7 +22,6 @@
  *
  */
 #include "proton/export.hpp"
-#include "proton/handle.hpp"
 #include "proton/endpoint.hpp"
 #include "proton/container.hpp"
 #include "proton/duration.hpp"
@@ -44,7 +43,7 @@ class blocking_sender : public blocking_link
     PN_CPP_EXTERN delivery send(message &msg);
     PN_CPP_EXTERN delivery send(message &msg, duration timeout);
   private:
-    PN_CPP_EXTERN blocking_sender(blocking_connection &c, sender l);
+    PN_CPP_EXTERN blocking_sender(blocking_connection &c, sender &l);
     friend class blocking_connection;
 };
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/proton-c/bindings/cpp/include/proton/comparable.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/comparable.hpp b/proton-c/bindings/cpp/include/proton/comparable.hpp
new file mode 100644
index 0000000..b409859
--- /dev/null
+++ b/proton-c/bindings/cpp/include/proton/comparable.hpp
@@ -0,0 +1,44 @@
+#ifndef COMPARABLE_HPP
+#define COMPARABLE_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.
+ */
+
+namespace proton {
+
+///@cond INTERNAL
+
+/// Internal base class to provide comparison operators.
+template <class T> struct comparable {
+};
+
+template<class T> bool operator<(const comparable<T>& a, const comparable<T>& b) {
+    return static_cast<const T&>(a) < static_cast<const T&>(b); // operator < provided by type T
+}
+
+template<class T> bool operator>(const comparable<T>& a, const comparable<T>& b) { return b < a; }
+template<class T> bool operator<=(const comparable<T>& a, const comparable<T>& b) { return !(a > b); }
+template<class T> bool operator>=(const comparable<T>& a, const comparable<T>& b) { return !(a < b); }
+template<class T> bool operator==(const comparable<T>& a, const comparable<T>& b) { return a <= b && b <= a; }
+template<class T> bool operator!=(const comparable<T>& a, const comparable<T>& b) { return !(a == b); }
+
+///@endcond
+
+}
+
+#endif // COMPARABLE_HPP

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/proton-c/bindings/cpp/include/proton/config.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/config.hpp b/proton-c/bindings/cpp/include/proton/config.hpp
index 70260b7..322ca1a 100644
--- a/proton-c/bindings/cpp/include/proton/config.hpp
+++ b/proton-c/bindings/cpp/include/proton/config.hpp
@@ -20,11 +20,32 @@
  */
 
 /**@file
- * @internal
+ *
+ * Configuration macros. If set before this file is included (e.g. via -D
+ * options to the compiler) they will not be altered, otherwise we will enable
+ * everything possible.
+ *
+ * The macros are:
+ * - PN_USE_CPP11 - assume a C++11 or greater compiler. Defaulted from compiler settings.
+ * - PN_USE_BOOST - include support for boost smart pointers, default 0.
  */
 
-#if (defined(__cplusplus) && __cplusplus >= 201100) || (defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 150030729)
-#define USE_CPP11
+
+#ifndef PN_USE_CPP11
+#if ((defined(__cplusplus) && __cplusplus >= 201100) || (defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 150030729))
+#define PN_USE_CPP11 1
+#else
+#define PN_USE_CPP11 0
+#endif
 #endif
 
+#if PN_USE_CPP11
+// Simple ownership pointer, use std::unique_ptr in C++11 std::auto_ptr otherwise.
+#define PN_UNIQUE_OR_AUTO_PTR std::unique_ptr
+#else
+// Simple ownership pointer, use std::unique_ptr in C++11 std::auto_ptr otherwise.
+#define PN_UNIQUE_OR_AUTO_PTR std::auto_ptr
+#endif
+
+
 #endif // CONFIG_HPP

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/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 af3c585..d9369b6 100644
--- a/proton-c/bindings/cpp/include/proton/connection.hpp
+++ b/proton-c/bindings/cpp/include/proton/connection.hpp
@@ -22,7 +22,6 @@
  *
  */
 #include "proton/export.hpp"
-#include "proton/handle.hpp"
 #include "proton/endpoint.hpp"
 #include "proton/container.hpp"
 #include "proton/types.h"
@@ -34,31 +33,17 @@ namespace proton {
 
 class handler;
 class transport;
-class connection_impl;
 
-/** connection is the local end of a connectoin to a remote AMQP peer. */
-class connection : public endpoint, public handle<connection_impl>
+/** connection to a remote AMQP peer. */
+class connection : public counted_facade<pn_connection_t, connection>, public endpoint
 {
   public:
-    PN_CPP_EXTERN connection();
-    PN_CPP_EXTERN connection(connection_impl *);
-    PN_CPP_EXTERN connection(const connection& c);
-    PN_CPP_EXTERN connection(class container &c, handler *h = 0);
-    PN_CPP_EXTERN ~connection();
-
-    PN_CPP_EXTERN connection& operator=(const connection& c);
-
     ///@name getters @{
     PN_CPP_EXTERN class transport& transport();
-    PN_CPP_EXTERN handler *override();
-    PN_CPP_EXTERN pn_connection_t *pn_connection();
-    PN_CPP_EXTERN class container &container();
+    PN_CPP_EXTERN class container& container();
     PN_CPP_EXTERN std::string hostname();
     ///@}
 
-    /** override the handler for this connection */
-    PN_CPP_EXTERN void override(handler *h);
-
     /** Initiate local open, not complete till messaging_handler::on_connection_opened()
      * or proton_handler::on_connection_remote_open()
      */
@@ -69,15 +54,17 @@ class connection : public endpoint, public handle<connection_impl>
      */
     PN_CPP_EXTERN void close();
 
+    /** Create a new session */
+    PN_CPP_EXTERN class session& create_session();
+
+    /** Default session is created on first call and re-used for the lifeime of the connection */
+    PN_CPP_EXTERN class session& default_session();
+
     /** Get the first link on this connection matching the state mask.
+     * Return 0 if none. Don't delete returned pointer.
      * @see link::next, endpoint::state
      */
-    PN_CPP_EXTERN link link_head(endpoint::state mask);
-
-  private:
-   friend class private_impl_ref<connection>;
-   friend class connector;
-   friend class connection_impl;
+    PN_CPP_EXTERN link* link_head(endpoint::state mask);
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/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 a0ca59a..014d2c0 100644
--- a/proton-c/bindings/cpp/include/proton/container.hpp
+++ b/proton-c/bindings/cpp/include/proton/container.hpp
@@ -21,11 +21,12 @@
  * under the License.
  *
  */
-#include "proton/export.hpp"
-#include "proton/handle.hpp"
 #include "proton/acceptor.hpp"
 #include "proton/duration.hpp"
+#include "proton/export.hpp"
+#include "proton/facade.hpp"
 #include "proton/url.hpp"
+
 #include <proton/reactor.h>
 #include <string>
 
@@ -41,26 +42,20 @@ class sender;
 class receiver;
 class link;
 class handler;
+class container_impl;
 
-/** Top level container for connections and other objects, runs the event loop */ 
-class container : public handle<container_impl>
+/**
+ * Top level container for connections and other objects, runs the event loop.
+ */
+class container
 {
   public:
-    ///@name internal @internal @{
-    PN_CPP_EXTERN container(container_impl *);
-    PN_CPP_EXTERN container(const container& c);
-    PN_CPP_EXTERN container& operator=(const container& c);
-    PN_CPP_EXTERN ~container();
-    ///@}
-
-    /** Create a container */
     PN_CPP_EXTERN container();
-
-    /** Create a container and set the top-level messaging_handler */
-    PN_CPP_EXTERN container(messaging_handler &mhandler);
+    PN_CPP_EXTERN container(messaging_handler& mhandler);
+    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);
 
     /** Run the event loop, return when all connections and acceptors are closed. */
     PN_CPP_EXTERN void run();
@@ -75,19 +70,19 @@ class container : public handle<container_impl>
     PN_CPP_EXTERN void stop();
 
     /** Create a sender on connection with target=addr and optional handler h */
-    PN_CPP_EXTERN sender create_sender(connection &connection, const std::string &addr, handler *h=0);
+    PN_CPP_EXTERN sender& create_sender(connection &connection, const std::string &addr, handler *h=0);
 
     /** Open a connection to url and create a sender with target=url.path() */
-    PN_CPP_EXTERN sender create_sender(const proton::url &);
+    PN_CPP_EXTERN sender& create_sender(const proton::url &);
 
     /** Create a receiver on connection with target=addr and optional handler h */
-    PN_CPP_EXTERN receiver create_receiver(connection &connection, const std::string &addr, bool dynamic=false, handler *h=0);
+    PN_CPP_EXTERN receiver& create_receiver(connection &connection, const std::string &addr, bool dynamic=false, handler *h=0);
 
     /** Create a receiver on connection with source=url.path() */
-    PN_CPP_EXTERN receiver create_receiver(const url &);
+    PN_CPP_EXTERN receiver& create_receiver(const url &);
 
     /** 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 &);
 
     /// Identifier for the container
     PN_CPP_EXTERN std::string container_id();
@@ -104,8 +99,9 @@ class container : public handle<container_impl>
     PN_CPP_EXTERN void wakeup();
     PN_CPP_EXTERN bool is_quiesced();
     PN_CPP_EXTERN void yield();
-private:
-   friend class private_impl_ref<container>;
+
+  private:
+    PN_UNIQUE_OR_AUTO_PTR<container_impl> impl_;
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/proton-c/bindings/cpp/include/proton/cstdint.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/cstdint.hpp b/proton-c/bindings/cpp/include/proton/cstdint.hpp
index e6404d1..9fb6d37 100644
--- a/proton-c/bindings/cpp/include/proton/cstdint.hpp
+++ b/proton-c/bindings/cpp/include/proton/cstdint.hpp
@@ -19,7 +19,7 @@
  * under the License.
  */
 
-///@cond INTERNAL_DETAIL
+///@cond INTERNAL
 
 /**@file
  *
@@ -27,7 +27,7 @@
  * Not the full cstdint, just the type needed by proton.
  */
 
-#ifdef USE_CPP11
+#if PN_USE_CPP11
 #include <cstdint>
 #else
 #include <proton/type_compat.h>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/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 83b3bff..f91270c 100644
--- a/proton-c/bindings/cpp/include/proton/data.hpp
+++ b/proton-c/bindings/cpp/include/proton/data.hpp
@@ -20,49 +20,108 @@
  */
 
 #include "proton/export.hpp"
+#include "proton/facade.hpp"
+#include "proton/decoder.hpp"
+#include "proton/encoder.hpp"
 #include <iosfwd>
 
 struct pn_data_t;
 
 namespace proton {
 
-/** Base for classes that hold AMQP data, not for direct use. @see value, values, encoder, decoder. */
-class data {
+class data;
+
+/**
+ * Holds a sequence of AMQP values, allows inserting and extracting via encoder() and decoder().
+ * Cannot be directly instantiated, use `data_value`
+ */
+class data : public facade<pn_data_t, data>, public comparable<data> {
   public:
-    PN_CPP_EXTERN explicit data();
-    PN_CPP_EXTERN data(const data&);
-    PN_CPP_EXTERN virtual ~data();
+    PN_CPP_EXTERN static PN_UNIQUE_OR_AUTO_PTR<data> create();
+
     PN_CPP_EXTERN data& operator=(const data&);
+    template<class T> data& operator=(const T &t) {
+        clear(); encoder() << t; decoder().rewind(); return *this;
+    }
 
     /** Clear the data. */
     PN_CPP_EXTERN void clear();
 
-    /** Rewind to the start of the data. */
-    PN_CPP_EXTERN void rewind();
-
     /** True if there are no values. */
     PN_CPP_EXTERN bool empty() const;
 
-    /** The underlying pn_data_t */
-    PN_CPP_EXTERN pn_data_t* pn_data() { return data_; }
+    /** Encoder to encode into this value */
+    PN_CPP_EXTERN class encoder& encoder();
 
-    /** True if this data object owns it's own pn_data_t, false if it is acting as a "view" */
-    PN_CPP_EXTERN bool own() const { return own_; }
+    /** Decoder to decode from this value */
+    PN_CPP_EXTERN class decoder& decoder();
 
-    PN_CPP_EXTERN void swap(data&);
+    /** Type of the current value*/
+    PN_CPP_EXTERN type_id type() { return decoder().type(); }
 
-    /** Human readable representation of data. */
-    friend PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const data&);
+    /** Get the current value, don't move the decoder pointer. */
+    template<class T> void get(T &t) { decoder() >> t; decoder().backup(); }
 
-  protected:
-    /** Does not take ownership, just a view on the data */
-    PN_CPP_EXTERN explicit data(pn_data_t*);
+    /** Get the current value */
+    template<class T> T get() { T t; get(t); return t; }
 
-    /** Does not take ownership, just a view on the data */
-    PN_CPP_EXTERN  void view(pn_data_t*);
+    bool operator==(const data& x) const;
+    bool operator<(const data& x) const;
 
-    mutable pn_data_t* data_;
-    bool own_;
+    void operator delete(void *);
+
+    /** Human readable representation of data. */
+  friend PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const data&);
+};
+
+/** data with normal value semantics: copy, assign etc. */
+class data_value : public comparable<data_value> {
+  public:
+    data_value() : data_(data::create()) {}
+    data_value(const data_value& x) : data_(data::create()) { *data_ = *x.data_; }
+    data_value(const data& x) : data_(data::create()) { *data_ = x; }
+    template <class T> data_value(const T& x) : data_(data::create()) { *data_ = x; }
+
+    operator data&() { return *data_; }
+    operator const data&() const { return *data_; }
+
+    data_value& operator=(const data_value& x) { *data_ = *x.data_; return *this; }
+    data_value& operator=(const data& x) { *data_ = x; return *this; }
+    template <class T> data_value& operator=(const T& x) { *data_ = x; return *this; }
+
+    void clear() { data_->clear(); }
+    bool empty() const { return data_->empty(); }
+
+    /** Encoder to encode into this value */
+    class encoder& encoder() { return data_->encoder(); }
+
+    /** Decoder to decode from this value */
+    class decoder& decoder() { return data_->decoder(); }
+
+    /** Type of the current value*/
+    type_id type() { return decoder().type(); }
+
+    /** Get the current value, don't move the decoder pointer. */
+    template<class T> void get(T &t) { decoder() >> t; decoder().backup(); }
+
+    /** Get the current value */
+    template<class T> T get() { T t; get(t); return t; }
+    template<class T> operator T() { return get<T>(); }
+
+    bool operator==(const data_value& x) const { return *data_ == *x.data_; }
+    bool operator<(const data_value& x) const { return *data_ < *x.data_; }
+
+  friend inline class encoder& operator<<(class encoder& e, const data_value& dv) {
+      return e << *dv.data_;
+  }
+  friend inline class decoder& operator>>(class decoder& d, data_value& dv) {
+      return d >> *dv.data_;
+  }
+  friend inline std::ostream& operator<<(std::ostream& o, const data_value& dv) {
+      return o << *dv.data_;
+  }
+  private:
+    PN_UNIQUE_OR_AUTO_PTR<data> data_;
 };
 
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/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 6761653..ebca61b 100644
--- a/proton-c/bindings/cpp/include/proton/decoder.hpp
+++ b/proton-c/bindings/cpp/include/proton/decoder.hpp
@@ -19,15 +19,17 @@
  * under the License.
  */
 
-#include "proton/data.hpp"
 #include "proton/error.hpp"
 #include "proton/type_traits.hpp"
 #include "proton/types.hpp"
+#include "proton/facade.hpp"
 #include <iosfwd>
 
+struct pn_data_t;
+
 namespace proton {
 
-class value;
+class data;
 
 /** Raised by decoder operations on error.*/
 struct decode_error : public error { PN_CPP_EXTERN explicit decode_error(const std::string&) throw(); };
@@ -66,12 +68,8 @@ struct rewind{};
  * You can also extract container values element-by-element, see decoder::operator>>(decoder&, start&)
  *
 */
-class decoder : public virtual data {
+class decoder : public facade<pn_data_t, decoder> {
   public:
-
-    PN_CPP_EXTERN decoder();
-    PN_CPP_EXTERN ~decoder();
-
     /** Copy AMQP data from a byte buffer into the decoder. */
     PN_CPP_EXTERN decoder(const char* buffer, size_t size);
 
@@ -92,6 +90,14 @@ class decoder : public virtual data {
      */
     PN_CPP_EXTERN type_id type() const;
 
+    /** Rewind to the start of the data. */
+    PN_CPP_EXTERN void rewind();
+
+    /** Back up by one value */
+    PN_CPP_EXTERN void backup(); 
+
+    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.
@@ -116,7 +122,7 @@ class decoder : public virtual data {
     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&, value&);
+    PN_CPP_EXTERN friend decoder& operator>>(decoder&, class data&);
     ///@}
 
     /** Extract and return a value of type T. */
@@ -178,10 +184,8 @@ class decoder : public virtual data {
     PN_CPP_EXTERN friend decoder& operator>>(decoder&, struct rewind);
 
   private:
-    template <class T> decoder& extract(T& value);
     PN_CPP_EXTERN void check_type(type_id);
 
-  friend class value;
   friend class encoder;
 };
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/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 cc74498..5528677 100644
--- a/proton-c/bindings/cpp/include/proton/delivery.hpp
+++ b/proton-c/bindings/cpp/include/proton/delivery.hpp
@@ -22,7 +22,7 @@
  *
  */
 #include "proton/export.hpp"
-#include "proton/wrapper.hpp"
+#include "proton/facade.hpp"
 
 #include "proton/delivery.h"
 #include "proton/disposition.h"
@@ -30,9 +30,7 @@
 namespace proton {
 
 /** delivery status of a message */
-class delivery : public wrapper<pn_delivery_t>
-{
-  public:
+class delivery : public counted_facade<pn_delivery_t, delivery> {
 
     /** Delivery state of a message */
     enum state {
@@ -44,8 +42,6 @@ class delivery : public wrapper<pn_delivery_t>
         MODIFIED = PN_MODIFIED  ///< Settled as modified
     };  // AMQP spec 3.4 delivery State
 
-    PN_CPP_EXTERN delivery(pn_delivery_t * = 0);
-
     /** Return true if the delivery has been settled. */
     PN_CPP_EXTERN bool settled();
 
@@ -54,6 +50,21 @@ class delivery : public wrapper<pn_delivery_t>
 
     /** Set the local state of the delivery. */
     PN_CPP_EXTERN void update(delivery::state state);
+
+    /** update and settle a delivery with the given delivery::state */
+    PN_CPP_EXTERN void settle(delivery::state s);
+
+    /** settle with ACCEPTED state */
+    PN_CPP_EXTERN void accept() { settle(ACCEPTED); }
+
+    /** settle with REJECTED state */
+    PN_CPP_EXTERN void reject() { settle(REJECTED); }
+
+    /** settle with REJECTED state */
+    PN_CPP_EXTERN void release() { settle(RELEASED); }
+
+    /** settle with MODIFIED state */
+    PN_CPP_EXTERN void modifiy() { settle(MODIFIED); }
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/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 b3e2ab4..52309bf 100644
--- a/proton-c/bindings/cpp/include/proton/encoder.hpp
+++ b/proton-c/bindings/cpp/include/proton/encoder.hpp
@@ -19,18 +19,17 @@
  * under the License.
  */
 
-#include "proton/data.hpp"
 #include "proton/error.hpp"
 #include "proton/types.hpp"
 #include "proton/type_traits.hpp"
+#include "proton/facade.hpp"
 #include <iosfwd>
 
 struct pn_data_t;
 
 namespace proton {
 
-class value;
-class values;
+class data;
 
 /** Raised by encoder operations on error */
 struct encode_error : public error { PN_CPP_EXTERN explicit encode_error(const std::string&) throw(); };
@@ -59,11 +58,8 @@ struct encode_error : public error { PN_CPP_EXTERN explicit encode_error(const s
  *
  *@throw decoder::error if the curent value is not a container type.
  */
-class encoder : public virtual data {
+class encoder : public facade<pn_data_t, encoder> {
   public:
-    PN_CPP_EXTERN encoder();
-    PN_CPP_EXTERN ~encoder();
-
     /**
      * Encode the current values into buffer and update size to reflect the number of bytes encoded.
      *
@@ -83,6 +79,8 @@ class encoder : public virtual data {
     /** Encode the current values into a std::string. Clears the encoder. */
     PN_CPP_EXTERN std::string encode();
 
+    PN_CPP_EXTERN class data& data();
+
     /** @name Insert simple types.
      *@{
      */
@@ -107,8 +105,7 @@ class encoder : public virtual data {
   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 value&);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, const values&);
+  friend PN_CPP_EXTERN encoder& operator<<(encoder&, const class data&);
     ///@}
 
     /**
@@ -139,11 +136,6 @@ class encoder : public virtual data {
 
     /** Copy data from a raw pn_data_t */
   friend PN_CPP_EXTERN encoder& operator<<(encoder&, pn_data_t*);
-
-  private:
-    PN_CPP_EXTERN encoder(pn_data_t* pd);
-
-  friend class value;
 };
 
 // Need to disambiguate char* conversion to bool and std::string as amqp_string.
@@ -185,11 +177,11 @@ template <class T> encoder& operator<<(encoder& e, cref<T, MAP> m){
     e << finish();
     return e;
 }
-//@internal Convert a ref to a cref.
+///@cond INTERNAL Convert a ref to a cref.
 template <class T, type_id A> encoder& operator<<(encoder& e, ref<T, A> ref) {
     return e << cref<T,A>(ref);
 }
-
+///@endcond
 
 }
 #endif // ENCODER_H

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/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 11970c7..665ab0c 100644
--- a/proton-c/bindings/cpp/include/proton/endpoint.hpp
+++ b/proton-c/bindings/cpp/include/proton/endpoint.hpp
@@ -58,10 +58,6 @@ class endpoint
      ///@}
 
     // TODO: condition, remote_condition, update_condition, get/handler
-
-  protected:
-    PN_CPP_EXTERN endpoint();
-    PN_CPP_EXTERN ~endpoint();
 };
 
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/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 a9cbedd..5c7b5b1 100644
--- a/proton-c/bindings/cpp/include/proton/event.hpp
+++ b/proton-c/bindings/cpp/include/proton/event.hpp
@@ -46,16 +46,14 @@ class event {
     /// Get connection.
     virtual PN_CPP_EXTERN class connection &connection();
     /// Get sender @throws error if no sender.
-    virtual PN_CPP_EXTERN class sender sender();
+    virtual PN_CPP_EXTERN class sender& sender();
     /// Get receiver @throws error if no receiver.
-    virtual PN_CPP_EXTERN class receiver receiver();
+    virtual PN_CPP_EXTERN class receiver& receiver();
     /// Get link @throws error if no link.
-    virtual PN_CPP_EXTERN class link link();
+    virtual PN_CPP_EXTERN class link& link();
     /// Get delivey @throws error if no delivery.
-    virtual PN_CPP_EXTERN class delivery delivery();
-    /** Get message @throws error if no message.
-     * Refernece is valid only till end of event dispatch. Copy or swap the message to keep it.
-     */
+    virtual PN_CPP_EXTERN class delivery& delivery();
+    /** Get message @throws error if no message. */
     virtual PN_CPP_EXTERN class message &message();
 
   protected:

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9bb9c442/proton-c/bindings/cpp/include/proton/export.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/export.hpp b/proton-c/bindings/cpp/include/proton/export.hpp
index bb211ae..27071ed 100644
--- a/proton-c/bindings/cpp/include/proton/export.hpp
+++ b/proton-c/bindings/cpp/include/proton/export.hpp
@@ -22,7 +22,8 @@
  *
  */
 
-/// Internal: import/export macros @cond INTERNAL
+/// @cond INTERNAL
+/// import/export macros 
 #if defined(WIN32) && !defined(PN_CPP_DECLARE_STATIC)
   //
   // Import and Export definitions for Windows:


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


Mime
View raw message