You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by kp...@apache.org on 2016/03/17 16:34:26 UTC

[3/4] qpid-proton git commit: PROTON-1138: c++: get<>/coerce<> API and documentation.

PROTON-1138: c++: get<>/coerce<> API and documentation.

Consistent get/coerce templates for proton::value, scalar, message_id and annotation_key.

get<T> - get the value, throw conversion_error if type is not exactly T.
coerce<T> - coerce the value to T if it is std::is_convertible, else throw conversion_error

- documentation page on C++/AMQP type conversion
- API doc for all types involved.
- cleanup/hide some internals.


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

Branch: refs/heads/kvdr-PROTON-1159
Commit: d70dab5df243f3a595be21a436f1ef46fa8d8c6d
Parents: f5f68d8
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Mar 14 15:55:46 2016 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Wed Mar 16 16:53:27 2016 -0400

----------------------------------------------------------------------
 examples/cpp/README.dox                         | 198 +++++++++
 examples/cpp/README.hpp                         | 198 ---------
 examples/cpp/direct_recv.cpp                    |   8 +-
 examples/cpp/encode_decode.cpp                  |  13 +-
 examples/cpp/engine/server.cpp                  |   2 +-
 examples/cpp/server.cpp                         |   2 +-
 examples/cpp/server_direct.cpp                  |  12 +-
 proton-c/bindings/cpp/CMakeLists.txt            |   2 +-
 proton-c/bindings/cpp/docs/CMakeLists.txt       |   1 +
 proton-c/bindings/cpp/docs/tutorial.dox         | 428 +++++++++++++++++++
 proton-c/bindings/cpp/docs/tutorial.hpp         | 428 -------------------
 proton-c/bindings/cpp/docs/user.doxygen.in      |  10 +-
 proton-c/bindings/cpp/include/proton/amqp.hpp   |  40 +-
 .../cpp/include/proton/annotation_key.hpp       |  51 ++-
 proton-c/bindings/cpp/include/proton/binary.hpp |  26 +-
 .../bindings/cpp/include/proton/byte_array.hpp  |  52 ++-
 .../bindings/cpp/include/proton/comparable.hpp  |   2 +
 .../cpp/include/proton/connection_engine.hpp    |   2 +-
 proton-c/bindings/cpp/include/proton/data.hpp   |  51 +--
 .../bindings/cpp/include/proton/decimal.hpp     |   5 +-
 .../bindings/cpp/include/proton/decoder.hpp     |  49 ++-
 proton-c/bindings/cpp/include/proton/deque.hpp  |   2 +-
 .../bindings/cpp/include/proton/duration.hpp    |  17 +-
 .../bindings/cpp/include/proton/encoder.hpp     |  65 ++-
 .../bindings/cpp/include/proton/endpoint.hpp    |   5 +-
 proton-c/bindings/cpp/include/proton/error.hpp  |   6 +-
 .../cpp/include/proton/forward_list.hpp         |   2 +-
 proton-c/bindings/cpp/include/proton/io.hpp     |   3 +-
 proton-c/bindings/cpp/include/proton/link.hpp   |   5 +
 proton-c/bindings/cpp/include/proton/list.hpp   |   2 +-
 .../bindings/cpp/include/proton/message.hpp     |   6 +-
 .../bindings/cpp/include/proton/message_id.hpp  |  62 ++-
 proton-c/bindings/cpp/include/proton/scalar.hpp | 217 ++--------
 .../bindings/cpp/include/proton/scalar_base.hpp | 181 ++++++++
 .../bindings/cpp/include/proton/session.hpp     |   4 +-
 proton-c/bindings/cpp/include/proton/symbol.hpp |   4 +
 .../bindings/cpp/include/proton/timestamp.hpp   |  18 +-
 .../bindings/cpp/include/proton/type_id.hpp     |  23 +-
 .../bindings/cpp/include/proton/type_traits.hpp | 108 ++---
 proton-c/bindings/cpp/include/proton/types.hpp  |  88 +++-
 .../bindings/cpp/include/proton/types_fwd.hpp   |  11 +-
 proton-c/bindings/cpp/include/proton/url.hpp    |   2 +-
 proton-c/bindings/cpp/include/proton/value.hpp  | 106 ++---
 proton-c/bindings/cpp/include/proton/vector.hpp |   2 +-
 proton-c/bindings/cpp/src/decoder.cpp           | 127 +++---
 proton-c/bindings/cpp/src/encoder.cpp           |  21 +-
 proton-c/bindings/cpp/src/interop_test.cpp      |  21 -
 proton-c/bindings/cpp/src/message.cpp           |   4 +-
 proton-c/bindings/cpp/src/message_test.cpp      |  16 +-
 proton-c/bindings/cpp/src/scalar.cpp            | 263 ------------
 proton-c/bindings/cpp/src/scalar_base.cpp       | 158 +++++++
 proton-c/bindings/cpp/src/scalar_test.cpp       |  15 +-
 proton-c/bindings/cpp/src/ssl.cpp               |   2 +-
 proton-c/bindings/cpp/src/test_bits.hpp         |   7 +
 proton-c/bindings/cpp/src/types_internal.hpp    |  14 +-
 proton-c/bindings/cpp/src/value.cpp             |  27 +-
 proton-c/bindings/cpp/src/value_test.cpp        |  46 +-
 tests/tools/apps/cpp/reactor_send.cpp           |   2 +-
 58 files changed, 1688 insertions(+), 1554 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/examples/cpp/README.dox
----------------------------------------------------------------------
diff --git a/examples/cpp/README.dox b/examples/cpp/README.dox
new file mode 100644
index 0000000..1e78774
--- /dev/null
+++ b/examples/cpp/README.dox
@@ -0,0 +1,198 @@
+// Examples overview.
+//
+// For a better overview, see the tutorial in the generated documentation.
+//
+// In your build directory do:
+//
+//     make docs-cpp
+//
+// then open proton-c/bindings/cpp/docs/html/tutorial.html in your browser.
+
+// DEVELOPER NOTE: if you are adding or modifying examples you should keep this
+// file and ../proton-c/bindings/cpp/docs/tutorial.hpp up to date.
+
+/** @example helloworld.cpp
+
+Connects to a broker on 127.0.0.1:5672, establishes a subscription
+from the 'examples' node, and creates a sending link to the same
+node. Sends one message and receives it back.
+
+*/
+
+/** @example helloworld_direct.cpp
+
+Variation of helloworld that does not use a broker, but listens for
+incoming connections itself. It establishes a connection to itself
+with a link over which a single message is sent. This demonstrates the
+ease with which a simple daemon an be built using the API.
+
+*/
+
+/** @example simple_send.cpp
+
+An example of sending a fixed number of messages and tracking their
+(asynchronous) acknowledgement. Messages are sent through the 'examples' node on
+an intermediary accessible on 127.0.0.1:5672.
+
+*/
+
+/** @example simple_recv.cpp
+
+Subscribes to the 'examples' node on an intermediary accessible
+on 127.0.0.1:5672. Simply prints out the body of received messages.
+
+*/
+
+/** @example direct_send.cpp
+
+Accepts an incoming connection and then sends like `simple_send`.  You can
+connect directly to `direct_send` *without* a broker using \ref simple_recv.cpp.
+Make sure to stop the broker first or use a different port for `direct_send`.
+
+*/
+
+/** @example direct_recv.cpp
+
+Accepts an incoming connection and then receives like `simple_recv`.  You can
+connect directly to `direct_recv` *without* a broker using \ref simple_send.cpp.
+Make sure to stop the broker first or use a different port for `direct_recv`.
+
+*/
+
+/// @cond INTERNAL
+/** @example encode_decode.cpp
+
+Shows how C++ data types can be converted to and from AMQP types.
+
+*/
+/// @endcond
+
+/** @example client.cpp
+
+The client part of a request-response example. Sends requests and
+prints out responses. Requires an intermediary that supports the AMQP
+1.0 dynamic nodes on which the responses are received. The requests
+are sent through the 'examples' node.
+
+*/
+
+/** @example server.cpp
+
+The server part of a request-response example, that receives requests
+via the examples node, converts the body to uppercase and sends the
+result back to the indicated reply address.
+
+*/
+
+/** @example server_direct.cpp
+
+A variant of the server part of a request-response example that
+accepts incoming connections and does not need an intermediary. Much
+like the original server, it receives incoming requests, converts the
+body to uppercase and sends the result back to the indicated reply
+address. Can be used in conjunction with any of the client
+alternatives.
+
+*/
+
+/** @example recurring_timer.cpp
+
+Shows how to implement recurring time-based events using the scheduler. 
+
+*/
+
+/** @example broker.hpp
+
+Common logic for a simple "mini broker" that creates creates queues
+automatically when a client tries to send or subscribe. This file contains
+the `queue` class that queues messages and the `broker_handler` class
+that manages queues and links and transfers messages to/from clients.
+
+Examples \ref broker.cpp and \ref engine/broker.cpp use this same
+broker logic but show different ways to run it in a server application.
+
+*/
+
+/** @example broker.cpp
+
+A simple, single-threaded broker using the `proton::container`. You can use this
+to run other examples that reqiure an intermediary, or you can use any AMQP 1.0
+broker. This broker creates queues automatically when a client tries to send or
+subscribe.
+
+Uses the broker logic from \ref broker.hpp, the same logic as the
+`proton::connection_engine` broker example \ref engine/broker.cpp.
+
+*/
+
+//////////////// connection_engine examples.
+
+/** \example engine/helloworld.cpp
+
+`proton::connection_engine` example to send a "Hello World" message to
+itself. Compare with the corresponding `proton::container` example \ref
+helloworld.cpp.
+
+*/
+
+/** \example engine/simple_send.cpp
+
+`proton::connection_engine` example of sending a fixed number of messages and
+tracking their (asynchronous) acknowledgement. Messages are sent through the
+'examples' node on an intermediary accessible on 127.0.0.1:5672.
+
+*/
+
+/** \example engine/simple_recv.cpp
+
+`proton::connection_engine` example that subscribes to the 'examples' node and prints
+ the body of received messages.
+
+*/
+
+/** \example engine/direct_send.cpp
+
+`proton::connection_engine` example accepts an incoming connection and then
+sends like `simple_send`.  You can connect directly to `direct_send` *without* a
+broker using \ref simple_recv.cpp.  Make sure to stop the broker first or use a
+different port for `direct_send`.
+
+*/
+
+/** \example engine/direct_recv.cpp
+
+`proton::connection_engine` example accepts an incoming connection and then
+receives like `simple_recv`.  You can connect directly to `direct_recv`
+*without* a broker using \ref simple_send.cpp.  Make sure to stop the broker
+first or use a different port for `direct_recv`.
+
+*/
+
+/** \example engine/client.cpp
+
+`proton::connection_engine` client for request-response example. Sends requests and
+prints out responses. Requires an intermediary that supports the AMQP 1.0
+dynamic nodes on which the responses are received. The requests are sent through
+the 'examples' node.
+
+*/
+
+/** \example engine/server.cpp
+
+`proton::connection_engine` server for request-response example, that receives
+requests via the examples node, converts the body to uppercase and sends the
+result back to the indicated reply address.
+
+*/
+
+/** \example engine/broker.cpp
+
+A simple, single-threaded broker using the `proton::container`. You can use this
+to run other examples that reqiure an intermediary, or you can use any AMQP 1.0
+broker. This broker creates queues automatically when a client tries to send or
+subscribe.
+
+Uses the broker logic from \ref broker.hpp, the same logic as the
+proton::container` broker example \ref broker.cpp.
+
+*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/examples/cpp/README.hpp
----------------------------------------------------------------------
diff --git a/examples/cpp/README.hpp b/examples/cpp/README.hpp
deleted file mode 100644
index 1e78774..0000000
--- a/examples/cpp/README.hpp
+++ /dev/null
@@ -1,198 +0,0 @@
-// Examples overview.
-//
-// For a better overview, see the tutorial in the generated documentation.
-//
-// In your build directory do:
-//
-//     make docs-cpp
-//
-// then open proton-c/bindings/cpp/docs/html/tutorial.html in your browser.
-
-// DEVELOPER NOTE: if you are adding or modifying examples you should keep this
-// file and ../proton-c/bindings/cpp/docs/tutorial.hpp up to date.
-
-/** @example helloworld.cpp
-
-Connects to a broker on 127.0.0.1:5672, establishes a subscription
-from the 'examples' node, and creates a sending link to the same
-node. Sends one message and receives it back.
-
-*/
-
-/** @example helloworld_direct.cpp
-
-Variation of helloworld that does not use a broker, but listens for
-incoming connections itself. It establishes a connection to itself
-with a link over which a single message is sent. This demonstrates the
-ease with which a simple daemon an be built using the API.
-
-*/
-
-/** @example simple_send.cpp
-
-An example of sending a fixed number of messages and tracking their
-(asynchronous) acknowledgement. Messages are sent through the 'examples' node on
-an intermediary accessible on 127.0.0.1:5672.
-
-*/
-
-/** @example simple_recv.cpp
-
-Subscribes to the 'examples' node on an intermediary accessible
-on 127.0.0.1:5672. Simply prints out the body of received messages.
-
-*/
-
-/** @example direct_send.cpp
-
-Accepts an incoming connection and then sends like `simple_send`.  You can
-connect directly to `direct_send` *without* a broker using \ref simple_recv.cpp.
-Make sure to stop the broker first or use a different port for `direct_send`.
-
-*/
-
-/** @example direct_recv.cpp
-
-Accepts an incoming connection and then receives like `simple_recv`.  You can
-connect directly to `direct_recv` *without* a broker using \ref simple_send.cpp.
-Make sure to stop the broker first or use a different port for `direct_recv`.
-
-*/
-
-/// @cond INTERNAL
-/** @example encode_decode.cpp
-
-Shows how C++ data types can be converted to and from AMQP types.
-
-*/
-/// @endcond
-
-/** @example client.cpp
-
-The client part of a request-response example. Sends requests and
-prints out responses. Requires an intermediary that supports the AMQP
-1.0 dynamic nodes on which the responses are received. The requests
-are sent through the 'examples' node.
-
-*/
-
-/** @example server.cpp
-
-The server part of a request-response example, that receives requests
-via the examples node, converts the body to uppercase and sends the
-result back to the indicated reply address.
-
-*/
-
-/** @example server_direct.cpp
-
-A variant of the server part of a request-response example that
-accepts incoming connections and does not need an intermediary. Much
-like the original server, it receives incoming requests, converts the
-body to uppercase and sends the result back to the indicated reply
-address. Can be used in conjunction with any of the client
-alternatives.
-
-*/
-
-/** @example recurring_timer.cpp
-
-Shows how to implement recurring time-based events using the scheduler. 
-
-*/
-
-/** @example broker.hpp
-
-Common logic for a simple "mini broker" that creates creates queues
-automatically when a client tries to send or subscribe. This file contains
-the `queue` class that queues messages and the `broker_handler` class
-that manages queues and links and transfers messages to/from clients.
-
-Examples \ref broker.cpp and \ref engine/broker.cpp use this same
-broker logic but show different ways to run it in a server application.
-
-*/
-
-/** @example broker.cpp
-
-A simple, single-threaded broker using the `proton::container`. You can use this
-to run other examples that reqiure an intermediary, or you can use any AMQP 1.0
-broker. This broker creates queues automatically when a client tries to send or
-subscribe.
-
-Uses the broker logic from \ref broker.hpp, the same logic as the
-`proton::connection_engine` broker example \ref engine/broker.cpp.
-
-*/
-
-//////////////// connection_engine examples.
-
-/** \example engine/helloworld.cpp
-
-`proton::connection_engine` example to send a "Hello World" message to
-itself. Compare with the corresponding `proton::container` example \ref
-helloworld.cpp.
-
-*/
-
-/** \example engine/simple_send.cpp
-
-`proton::connection_engine` example of sending a fixed number of messages and
-tracking their (asynchronous) acknowledgement. Messages are sent through the
-'examples' node on an intermediary accessible on 127.0.0.1:5672.
-
-*/
-
-/** \example engine/simple_recv.cpp
-
-`proton::connection_engine` example that subscribes to the 'examples' node and prints
- the body of received messages.
-
-*/
-
-/** \example engine/direct_send.cpp
-
-`proton::connection_engine` example accepts an incoming connection and then
-sends like `simple_send`.  You can connect directly to `direct_send` *without* a
-broker using \ref simple_recv.cpp.  Make sure to stop the broker first or use a
-different port for `direct_send`.
-
-*/
-
-/** \example engine/direct_recv.cpp
-
-`proton::connection_engine` example accepts an incoming connection and then
-receives like `simple_recv`.  You can connect directly to `direct_recv`
-*without* a broker using \ref simple_send.cpp.  Make sure to stop the broker
-first or use a different port for `direct_recv`.
-
-*/
-
-/** \example engine/client.cpp
-
-`proton::connection_engine` client for request-response example. Sends requests and
-prints out responses. Requires an intermediary that supports the AMQP 1.0
-dynamic nodes on which the responses are received. The requests are sent through
-the 'examples' node.
-
-*/
-
-/** \example engine/server.cpp
-
-`proton::connection_engine` server for request-response example, that receives
-requests via the examples node, converts the body to uppercase and sends the
-result back to the indicated reply address.
-
-*/
-
-/** \example engine/broker.cpp
-
-A simple, single-threaded broker using the `proton::container`. You can use this
-to run other examples that reqiure an intermediary, or you can use any AMQP 1.0
-broker. This broker creates queues automatically when a client tries to send or
-subscribe.
-
-Uses the broker logic from \ref broker.hpp, the same logic as the
-proton::container` broker example \ref broker.cpp.
-
-*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/examples/cpp/direct_recv.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/direct_recv.cpp b/examples/cpp/direct_recv.cpp
index ffb2f03..89bb966 100644
--- a/examples/cpp/direct_recv.cpp
+++ b/examples/cpp/direct_recv.cpp
@@ -49,16 +49,16 @@ class direct_recv : public proton::handler {
 
     void on_message(proton::event &e) {
         proton::message& msg = e.message();
-        
-        if (msg.id().get<uint64_t>() < received) {
+
+        if (proton::coerce<uint64_t>(msg.id()) < received) {
             return; // Ignore duplicate
         }
-        
+
         if (expected == 0 || received < expected) {
             std::cout << msg.body() << std::endl;
             received++;
         }
-        
+
         if (received == expected) {
             e.receiver().close();
             e.connection().close();

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/examples/cpp/encode_decode.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/encode_decode.cpp b/examples/cpp/encode_decode.cpp
index 12fc1ed..b1c39b8 100644
--- a/examples/cpp/encode_decode.cpp
+++ b/examples/cpp/encode_decode.cpp
@@ -71,13 +71,13 @@ void uniform_containers() {
     v = a;
     print(v);
     std::list<int> a1;
-    v.get(a1);                  // Decode as a C++ std::list instead
+    proton::get(v, a1);
     std::cout << a1 << std::endl;
 
     // You can specify that a container should be encoded as an AMQP list instead.
     v = proton::codec::encoder::list(a1);
     print(v);
-    std::cout << v.get<std::vector<int> >() << std::endl;
+    std::cout << proton::get<std::vector<int> >(v) << std::endl;
 
     // C++ map types (types with key_type, mapped_type) convert to an AMQP map by default.
     std::map<std::string, int> m;
@@ -85,7 +85,7 @@ void uniform_containers() {
     m["two"] = 2;
     v = m;
     print(v);
-    std::cout << v.get<std::map<std::string, int> >() << std::endl;
+    std::cout << proton::get<std::map<std::string, int> >(v) << std::endl;
 
     // A sequence of pairs encodes as an AMQP MAP, which lets you control the encoded order.
     std::vector<std::pair<std::string, int> > pairs;
@@ -121,16 +121,15 @@ void mixed_containers() {
     // By default, a sequence of proton::value is treated as an AMQP list.
     v = l;
     print(v);
-    std::vector<proton::value> l2;
-    v.get(l2);
+    std::vector<proton::value> l2 = proton::get<std::vector<proton::value> >(v);
     std::cout << l2 << std::endl;
 
     std::map<proton::value, proton::value> m;
     m[proton::value("five")] = proton::value(5);
     m[proton::value(4)] = proton::value("four"); v = m;
     print(v);
-    std::map<proton::value, proton::value> m2;
-    v.get(m2);
+    typedef std::map<proton::value, proton::value> value_map;
+    value_map m2(proton::get<value_map>(v));
     std::cout << m2 << std::endl;
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/examples/cpp/engine/server.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/engine/server.cpp b/examples/cpp/engine/server.cpp
index 4641c4c..92ee044 100644
--- a/examples/cpp/engine/server.cpp
+++ b/examples/cpp/engine/server.cpp
@@ -61,7 +61,7 @@ class server : public proton::handler {
         std::string reply_to = e.message().reply_to();
         proton::message reply;
         reply.address(reply_to);
-        reply.body(to_upper(e.message().body().get<std::string>()));
+        reply.body(to_upper(proton::get<std::string>(e.message().body())));
         reply.correlation_id(e.message().correlation_id());
         if (!senders[reply_to])
             senders[reply_to] = e.connection().open_sender(reply_to);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/examples/cpp/server.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/server.cpp b/examples/cpp/server.cpp
index 8ac34cc..58fe52d 100644
--- a/examples/cpp/server.cpp
+++ b/examples/cpp/server.cpp
@@ -65,7 +65,7 @@ class server : public proton::handler {
         proton::message reply;
 
         reply.address(reply_to);
-        reply.body(to_upper(e.message().body().get<std::string>()));
+        reply.body(to_upper(proton::get<std::string>(e.message().body())));
         reply.correlation_id(e.message().correlation_id());
 
         if (!senders[reply_to]) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/examples/cpp/server_direct.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/server_direct.cpp b/examples/cpp/server_direct.cpp
index 9d3b79c..c166917 100644
--- a/examples/cpp/server_direct.cpp
+++ b/examples/cpp/server_direct.cpp
@@ -66,7 +66,7 @@ class server : public proton::handler {
 
     void on_link_open(proton::event& e) {
         proton::link link = e.link();
-        
+
         if (!!link.sender() && link.remote_source().dynamic()) {
             link.local_source().address(generate_address());
             senders[link.local_source().address()] = link.sender();
@@ -75,18 +75,18 @@ class server : public proton::handler {
 
     void on_message(proton::event &e) {
         std::cout << "Received " << e.message().body() << std::endl;
-        
+
         std::string reply_to = e.message().reply_to();
         sender_map::iterator it = senders.find(reply_to);
-        
+
         if (it == senders.end()) {
             std::cout << "No link for reply_to: " << reply_to << std::endl;
         } else {
             proton::sender sender = it->second;
             proton::message reply;
-            
+
             reply.address(reply_to);
-            reply.body(to_upper(e.message().body().get<std::string>()));
+            reply.body(to_upper(proton::get<std::string>(e.message().body())));
             reply.correlation_id(e.message().correlation_id());
 
             sender.send(reply);
@@ -102,7 +102,7 @@ int main(int argc, char **argv) {
 
     try {
         opts.parse();
-        
+
         server srv(address);
         proton::container(srv).run();
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/proton-c/bindings/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt
index 11b299d..ebd38c1 100644
--- a/proton-c/bindings/cpp/CMakeLists.txt
+++ b/proton-c/bindings/cpp/CMakeLists.txt
@@ -27,7 +27,7 @@ include_directories(
 set(qpid-proton-cpp-source
   src/acceptor.cpp
   src/binary.cpp
-  src/scalar.cpp
+  src/scalar_base.cpp
   src/condition.cpp
   src/connection.cpp
   src/connection_options.cpp

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/proton-c/bindings/cpp/docs/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/docs/CMakeLists.txt b/proton-c/bindings/cpp/docs/CMakeLists.txt
index cf7876e..c5ae4e5 100644
--- a/proton-c/bindings/cpp/docs/CMakeLists.txt
+++ b/proton-c/bindings/cpp/docs/CMakeLists.txt
@@ -18,6 +18,7 @@
 #
 
 find_package(Doxygen)
+
 if (DOXYGEN_FOUND)
   configure_file (
     ${CMAKE_CURRENT_SOURCE_DIR}/user.doxygen.in

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/proton-c/bindings/cpp/docs/tutorial.dox
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/docs/tutorial.dox b/proton-c/bindings/cpp/docs/tutorial.dox
new file mode 100644
index 0000000..dcfbe05
--- /dev/null
+++ b/proton-c/bindings/cpp/docs/tutorial.dox
@@ -0,0 +1,428 @@
+// -*-markdown-*-
+// NOTE: doxygen can include markdown pages directly but there seems to be a bug
+// 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
+
+This is a brief tutorial that will walk you through the fundamentals of building
+messaging applications in incremental steps. There are further examples, in
+addition the ones mentioned in the tutorial.
+
+Some of the examples require an AMQP *broker* that can receive, store and send
+messages. \ref broker.hpp and \ref broker.cpp define a simple example
+broker. Run without arguments it listens on `0.0.0.0:5672`, the standard AMQP
+port on all network interfaces. To use a different port or network interface:
+
+    broker -a <host>:<port>
+
+Instead of the example broker, you can use any AMQP 1.0 compliant broker. You
+must configure your broker to have a queue (or topic) named "examples".
+
+The `helloworld` examples take an optional URL argument. The other examples take
+an option `-a URL`. A URL looks like:
+
+    HOST:PORT/ADDRESS
+
+It usually defaults to `127.0.0.1:5672/examples`, but you can change this if
+your broker is on a different host or port, or you want to use a different queue
+or topic name (the ADDRESS part of the URL). URL details are at `proton::url`
+
+The first part of the tutorial uses the `proton::container`, later we will
+show some of the same examples implemented using the `proton::connection_engine`.
+Most of the code is the same for either approach.
+
+Hello World!
+------------
+
+\dontinclude helloworld.cpp
+
+Tradition dictates that we start with hello world! This example sends a message
+to a broker and the receives the same message back to demonstrate sending and
+receiving. In a realistic system the sender and receiver would normally be in
+different processes. The complete example is \ref helloworld.cpp
+
+We will include the following classes: `proton::container` runs an event loop
+which dispatches events to a `proton::handler`. This allows a *reactive*
+style of programming which is well suited to messaging applications. `proton::url` is a simple parser for the URL format mentioned above.
+
+\skip   proton/container
+\until  proton/url
+
+We will define a class `hello_world` which is a subclass of
+`proton::handler` and over-rides functions to handle the events
+of interest in sending and receiving a message.
+
+\skip class hello_world
+\until {}
+
+`on_start()` is called when the event loop first starts. We handle that by
+establishing a connection and creating a sender and a receiver.
+
+\skip on_start
+\until }
+
+`on_sendable()` is called when message can be transferred over the associated
+sender link to the remote peer. We create a `proton::message`, set the message
+body to `"Hello World!"` and send the message. Then we close the sender as we only
+want to send one message. Closing the sender will prevent further calls to
+`on_sendable()`.
+
+\skip on_sendable
+\until }
+
+`on_message()` is called when a message is received. We just print the body of
+the message and close the connection, as we only want one message
+
+\skip on_message
+\until }
+
+The message body is a `proton::value`, see the documentation for more on how to
+extract the message body as type-safe C++ values.
+
+Our `main` function creates an instance of the `hello_world` handler and a
+proton::container using that handler. Calling `proton::container::run` sets
+things in motion and returns when we close the connection as there is nothing
+further to do. It may throw an exception, which will be a subclass of
+`proton::error`. That in turn is a subclass of `std::exception`.
+
+\skip main
+\until }
+\until }
+\until }
+
+Hello World, Direct!
+--------------------
+
+\dontinclude helloworld_direct.cpp
+
+Though often used in conjunction with a broker, AMQP does not *require* this. It
+also allows senders and receivers to communicate directly if desired.
+
+We will modify our example to send a message directly to itself. This is a bit
+contrived but illustrates both sides of the direct send/receive scenario. Full
+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.
+
+\skip on_start
+\until }
+
+As we only need then to initiate one link, the sender, we can do that by
+passing in a url rather than an existing connection, and the connection
+will also be automatically established for us.
+
+We send the message in response to the `on_sendable()` callback and
+print the message out in response to the `on_message()` callback exactly
+as before.
+
+\skip on_sendable
+\until }
+\until }
+
+However we also handle two new events. We now close the connection from
+the senders side once the message has been accepted.
+The acceptance of the message is an indication of successful transfer to the
+peer. We are notified of that event through the `on_delivery_accept()`
+callback.
+
+\skip on_delivery_accept
+\until }
+
+Then, once the connection has been closed, of which we are
+notified through the `on_connection_close()` callback, we stop accepting incoming
+connections at which point there is no work to be done and the
+event loop exits, and the run() method will return.
+
+\skip on_connection_close
+\until }
+
+So now we have our example working without a broker involved!
+
+Note that for this example we pick an "unusual" port 8888 since we are talking
+to ourselves rather than a broker.
+
+\skipline url =
+
+Asynchronous Send and Receive
+-----------------------------
+
+Of course, these `HelloWorld!` examples are very artificial, communicating as
+they do over a network connection but with the same process. A more realistic
+example involves communication between separate processes (which could indeed be
+running on completely separate machines).
+
+Let's separate the sender from the receiver, and transfer more than a single
+message between them.
+
+We'll start with a simple sender \ref simple_send.cpp.
+
+\dontinclude simple_send.cpp
+
+As with the previous example, we define the application logic in a class that
+handles events. Because we are transferring more than one message, we need to
+keep track of how many we have sent. We'll use a `sent` member variable for
+that.  The `total` member variable will hold the number of messages we want to
+send.
+
+\skip class simple_send
+\until total
+
+As before, we use the `on_start()` event to establish our sender link over which
+we will transfer messages.
+
+\skip on_start
+\until }
+
+AMQP defines a credit-based flow control mechanism. Flow control allows
+the receiver to control how many messages it is prepared to receive at a
+given time and thus prevents any component being overwhelmed by the
+number of messages it is sent.
+
+In the `on_sendable()` callback, we check that our sender has credit
+before sending messages. We also check that we haven't already sent the
+required number of messages.
+
+\skip on_sendable
+\until }
+\until }
+
+The `proton::sender::send()` call above is asynchronous. When it returns the
+message has not yet actually been transferred across the network to the
+receiver. By handling the `on_accepted()` event, we can get notified when the
+receiver has received and accepted the message. In our example we use this event
+to track the confirmation of the messages we have sent. We only close the
+connection and exit when the receiver has received all the messages we wanted to
+send.
+
+\skip on_delivery_accept
+\until }
+\until }
+
+If we are disconnected after a message is sent and before it has been
+confirmed by the receiver, it is said to be `in doubt`. We don't know
+whether or not it was received. In this example, we will handle that by
+resending any in-doubt messages. This is known as an 'at-least-once'
+guarantee, since each message should eventually be received at least
+once, though a given message may be received more than once (i.e.
+duplicates are possible). In the `on_disconnected()` callback, we reset
+the sent count to reflect only those that have been confirmed. The
+library will automatically try to reconnect for us, and when our sender
+is sendable again, we can restart from the point we know the receiver
+got to.
+
+\skip on_disconnect
+\until }
+
+\dontinclude simple_recv.cpp
+
+Now let's look at the corresponding receiver \ref simple_recv.cpp
+
+This time we'll use an `expected` member variable for for the number of messages we expect and
+a `received` variable to count how many we have received so far.
+
+\skip class simple_recv
+\until received
+
+We handle `on_start()` by creating our receiver, much like we
+did for the sender.
+
+\skip on_start
+\until }
+
+We also handle the `on_message()` event for received messages and print the
+message out as in the `Hello World!` examples.  However we add some logic to
+allow the receiver to wait for a given number of messages, then to close the
+connection and exit. We also add some logic to check for and ignore duplicates,
+using a simple sequential id scheme.
+
+\skip on_message
+\until }
+
+Direct Send and Receive
+-----------------------
+
+Sending between these two examples requires an intermediary broker since neither
+accepts incoming connections. AMQP allows us to send messages directly between
+two processes. In that case one or other of the processes needs to accept
+incoming connections. Let's create a modified version of the receiving example
+that does this with \ref direct_recv.cpp
+
+\dontinclude direct_recv.cpp
+
+There are only two differences here. Instead of initiating a link (and
+implicitly a connection), we listen for incoming connections.
+
+
+\skip on_start
+\until }
+
+When we have received all the expected messages, we then stop listening for
+incoming connections by closing the acceptor object.
+
+\skip on_message
+\until }
+\until }
+\until }
+\until }
+
+You can use the \ref simple_send.cpp example to send to this receiver
+directly. (Note: you will need to stop any broker that is listening on the 5672
+port, or else change the port used by specifying a different address to each
+example via the -a command line switch).
+
+We can also modify the sender to allow the original receiver to connect to it,
+in \ref direct_send.cpp. Again that just requires two modifications:
+
+\dontinclude direct_send.cpp
+
+As with the modified receiver, instead of initiating establishment of a
+link, we listen for incoming connections.
+
+\skip on_start
+\until }
+
+When we have received confirmation of all the messages we sent, we can
+close the acceptor in order to exit.
+
+\skip on_delivery_accept
+\until }
+\until }
+
+To try this modified sender, run the original \ref simple_recv.cpp against it.
+
+The symmetry in the underlying AMQP that enables this is quite unique and
+elegant, and in reflecting this the proton API provides a flexible toolkit for
+implementing all sorts of interesting intermediaries (\ref broker.hpp and \ref
+broker.cpp provide a simple broker for testing purposes is an example of this).
+
+Request/Response
+----------------
+
+A common pattern is to send a request message and expect a response message in
+return. AMQP has special support for this pattern. Let's have a look at a simple
+example. We'll start with \ref server.cpp, the program that will process the
+request and send the response. Note that we are still using a broker in this
+example.
+
+Our server will provide a very simple service: it will respond with the
+body of the request converted to uppercase.
+
+\dontinclude server.cpp
+\skip class server
+\until };
+
+The code here is not too different from the simple receiver example.  When we
+receive a request in `on_message` however, we look at the
+`proton::message::reply_to` address and create a sender with that address for
+the response. We'll cache the senders incase we get further requests with the
+same `reply_to`.
+
+Now let's create a simple \ref client.cpp to test this service out.
+
+\dontinclude client.cpp
+
+Our client takes a list of strings to send as requests
+
+\skipline client(
+
+Since we will be sending and receiving, we create a sender and a receiver in
+`on_start`.  Our receiver has a blank address and sets the `dynamic` flag to
+true, which means we expect the remote end (broker or server) to assign a unique
+address for us.
+
+\skip on_start
+\until }
+
+Now a function to send the next request from our list of requests. We set the
+reply_to address to be the dynamically assigned address of our receiver.
+
+\skip send_request
+\until }
+
+We need to use the address assigned by the broker as the `reply_to` address of
+our requests, so we can't send them until our receiver has been set up. To do
+that, we add an `on_link_open()` method to our handler class, and if the link
+associated with event is the receiver, we use that as the trigger to send our
+first request.
+
+\skip on_link_open
+\until }
+
+When we receive a reply, we send the next request.
+
+\skip on_message
+\until }
+\until }
+\until }
+
+Direct Request/Response
+-----------------------
+
+We can avoid the intermediary process by writing a server that accepts
+connections directly, \ref server_direct.cpp. It involves the following changes
+to our original server:
+
+\dontinclude server_direct.cpp
+
+Our server must generate a unique reply-to addresses for links from the
+client that request a dynamic address (previously this was done by the broker.)
+We use a simple counter.
+
+\skip generate_address
+\until }
+
+Next we need to handle incoming requests for links with dynamic addresses from
+the client.  We give the link a unique address and record it in our `senders`
+map.
+
+\skip on_link_open
+\until }
+
+Note we are interested in *sender* links above because we are implementing the
+server. A *receiver* link created on the client corresponds to a *sender* link
+on the server.
+
+Finally when we receive a message we look up its `reply_to` in our senders map and send the reply.
+
+\skip on_message
+\until }
+\until }
+\until }
+
+Connection Engine
+-----------------
+
+The `proton::connection_engine` is an alternative to the container. For simple
+applications with a single connection, its use is about the same as the the
+`proton::container`, but it allows more flexibility for multi-threaded
+applications or applications with unusual IO requirements.
+
+\dontinclude engine/helloworld.cpp
+
+We'll look at the \ref engine/helloworld.cpp example step-by-step to see how it differs
+from the container \ref helloworld.cpp version.
+
+First we include the `proton::io::socket_engine` class, which is a `proton::connection_engine`
+that uses socket IO.
+
+\skipline proton/io.hpp
+
+Our `hello_world` class differs only in the `on_start()` method. Instead of
+calling `container.connect()`, we simply call `proton::connection::open` to open the
+engine's' connection:
+
+\skip on_start
+\until }
+
+Our `main` function only differs in that it creates and runs a `socket_engine`
+instead of a `container`.
+
+\skip main
+\until }
+\until }
+\until }
+
+*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/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
deleted file mode 100644
index dcfbe05..0000000
--- a/proton-c/bindings/cpp/docs/tutorial.hpp
+++ /dev/null
@@ -1,428 +0,0 @@
-// -*-markdown-*-
-// NOTE: doxygen can include markdown pages directly but there seems to be a bug
-// 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
-
-This is a brief tutorial that will walk you through the fundamentals of building
-messaging applications in incremental steps. There are further examples, in
-addition the ones mentioned in the tutorial.
-
-Some of the examples require an AMQP *broker* that can receive, store and send
-messages. \ref broker.hpp and \ref broker.cpp define a simple example
-broker. Run without arguments it listens on `0.0.0.0:5672`, the standard AMQP
-port on all network interfaces. To use a different port or network interface:
-
-    broker -a <host>:<port>
-
-Instead of the example broker, you can use any AMQP 1.0 compliant broker. You
-must configure your broker to have a queue (or topic) named "examples".
-
-The `helloworld` examples take an optional URL argument. The other examples take
-an option `-a URL`. A URL looks like:
-
-    HOST:PORT/ADDRESS
-
-It usually defaults to `127.0.0.1:5672/examples`, but you can change this if
-your broker is on a different host or port, or you want to use a different queue
-or topic name (the ADDRESS part of the URL). URL details are at `proton::url`
-
-The first part of the tutorial uses the `proton::container`, later we will
-show some of the same examples implemented using the `proton::connection_engine`.
-Most of the code is the same for either approach.
-
-Hello World!
-------------
-
-\dontinclude helloworld.cpp
-
-Tradition dictates that we start with hello world! This example sends a message
-to a broker and the receives the same message back to demonstrate sending and
-receiving. In a realistic system the sender and receiver would normally be in
-different processes. The complete example is \ref helloworld.cpp
-
-We will include the following classes: `proton::container` runs an event loop
-which dispatches events to a `proton::handler`. This allows a *reactive*
-style of programming which is well suited to messaging applications. `proton::url` is a simple parser for the URL format mentioned above.
-
-\skip   proton/container
-\until  proton/url
-
-We will define a class `hello_world` which is a subclass of
-`proton::handler` and over-rides functions to handle the events
-of interest in sending and receiving a message.
-
-\skip class hello_world
-\until {}
-
-`on_start()` is called when the event loop first starts. We handle that by
-establishing a connection and creating a sender and a receiver.
-
-\skip on_start
-\until }
-
-`on_sendable()` is called when message can be transferred over the associated
-sender link to the remote peer. We create a `proton::message`, set the message
-body to `"Hello World!"` and send the message. Then we close the sender as we only
-want to send one message. Closing the sender will prevent further calls to
-`on_sendable()`.
-
-\skip on_sendable
-\until }
-
-`on_message()` is called when a message is received. We just print the body of
-the message and close the connection, as we only want one message
-
-\skip on_message
-\until }
-
-The message body is a `proton::value`, see the documentation for more on how to
-extract the message body as type-safe C++ values.
-
-Our `main` function creates an instance of the `hello_world` handler and a
-proton::container using that handler. Calling `proton::container::run` sets
-things in motion and returns when we close the connection as there is nothing
-further to do. It may throw an exception, which will be a subclass of
-`proton::error`. That in turn is a subclass of `std::exception`.
-
-\skip main
-\until }
-\until }
-\until }
-
-Hello World, Direct!
---------------------
-
-\dontinclude helloworld_direct.cpp
-
-Though often used in conjunction with a broker, AMQP does not *require* this. It
-also allows senders and receivers to communicate directly if desired.
-
-We will modify our example to send a message directly to itself. This is a bit
-contrived but illustrates both sides of the direct send/receive scenario. Full
-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.
-
-\skip on_start
-\until }
-
-As we only need then to initiate one link, the sender, we can do that by
-passing in a url rather than an existing connection, and the connection
-will also be automatically established for us.
-
-We send the message in response to the `on_sendable()` callback and
-print the message out in response to the `on_message()` callback exactly
-as before.
-
-\skip on_sendable
-\until }
-\until }
-
-However we also handle two new events. We now close the connection from
-the senders side once the message has been accepted.
-The acceptance of the message is an indication of successful transfer to the
-peer. We are notified of that event through the `on_delivery_accept()`
-callback.
-
-\skip on_delivery_accept
-\until }
-
-Then, once the connection has been closed, of which we are
-notified through the `on_connection_close()` callback, we stop accepting incoming
-connections at which point there is no work to be done and the
-event loop exits, and the run() method will return.
-
-\skip on_connection_close
-\until }
-
-So now we have our example working without a broker involved!
-
-Note that for this example we pick an "unusual" port 8888 since we are talking
-to ourselves rather than a broker.
-
-\skipline url =
-
-Asynchronous Send and Receive
------------------------------
-
-Of course, these `HelloWorld!` examples are very artificial, communicating as
-they do over a network connection but with the same process. A more realistic
-example involves communication between separate processes (which could indeed be
-running on completely separate machines).
-
-Let's separate the sender from the receiver, and transfer more than a single
-message between them.
-
-We'll start with a simple sender \ref simple_send.cpp.
-
-\dontinclude simple_send.cpp
-
-As with the previous example, we define the application logic in a class that
-handles events. Because we are transferring more than one message, we need to
-keep track of how many we have sent. We'll use a `sent` member variable for
-that.  The `total` member variable will hold the number of messages we want to
-send.
-
-\skip class simple_send
-\until total
-
-As before, we use the `on_start()` event to establish our sender link over which
-we will transfer messages.
-
-\skip on_start
-\until }
-
-AMQP defines a credit-based flow control mechanism. Flow control allows
-the receiver to control how many messages it is prepared to receive at a
-given time and thus prevents any component being overwhelmed by the
-number of messages it is sent.
-
-In the `on_sendable()` callback, we check that our sender has credit
-before sending messages. We also check that we haven't already sent the
-required number of messages.
-
-\skip on_sendable
-\until }
-\until }
-
-The `proton::sender::send()` call above is asynchronous. When it returns the
-message has not yet actually been transferred across the network to the
-receiver. By handling the `on_accepted()` event, we can get notified when the
-receiver has received and accepted the message. In our example we use this event
-to track the confirmation of the messages we have sent. We only close the
-connection and exit when the receiver has received all the messages we wanted to
-send.
-
-\skip on_delivery_accept
-\until }
-\until }
-
-If we are disconnected after a message is sent and before it has been
-confirmed by the receiver, it is said to be `in doubt`. We don't know
-whether or not it was received. In this example, we will handle that by
-resending any in-doubt messages. This is known as an 'at-least-once'
-guarantee, since each message should eventually be received at least
-once, though a given message may be received more than once (i.e.
-duplicates are possible). In the `on_disconnected()` callback, we reset
-the sent count to reflect only those that have been confirmed. The
-library will automatically try to reconnect for us, and when our sender
-is sendable again, we can restart from the point we know the receiver
-got to.
-
-\skip on_disconnect
-\until }
-
-\dontinclude simple_recv.cpp
-
-Now let's look at the corresponding receiver \ref simple_recv.cpp
-
-This time we'll use an `expected` member variable for for the number of messages we expect and
-a `received` variable to count how many we have received so far.
-
-\skip class simple_recv
-\until received
-
-We handle `on_start()` by creating our receiver, much like we
-did for the sender.
-
-\skip on_start
-\until }
-
-We also handle the `on_message()` event for received messages and print the
-message out as in the `Hello World!` examples.  However we add some logic to
-allow the receiver to wait for a given number of messages, then to close the
-connection and exit. We also add some logic to check for and ignore duplicates,
-using a simple sequential id scheme.
-
-\skip on_message
-\until }
-
-Direct Send and Receive
------------------------
-
-Sending between these two examples requires an intermediary broker since neither
-accepts incoming connections. AMQP allows us to send messages directly between
-two processes. In that case one or other of the processes needs to accept
-incoming connections. Let's create a modified version of the receiving example
-that does this with \ref direct_recv.cpp
-
-\dontinclude direct_recv.cpp
-
-There are only two differences here. Instead of initiating a link (and
-implicitly a connection), we listen for incoming connections.
-
-
-\skip on_start
-\until }
-
-When we have received all the expected messages, we then stop listening for
-incoming connections by closing the acceptor object.
-
-\skip on_message
-\until }
-\until }
-\until }
-\until }
-
-You can use the \ref simple_send.cpp example to send to this receiver
-directly. (Note: you will need to stop any broker that is listening on the 5672
-port, or else change the port used by specifying a different address to each
-example via the -a command line switch).
-
-We can also modify the sender to allow the original receiver to connect to it,
-in \ref direct_send.cpp. Again that just requires two modifications:
-
-\dontinclude direct_send.cpp
-
-As with the modified receiver, instead of initiating establishment of a
-link, we listen for incoming connections.
-
-\skip on_start
-\until }
-
-When we have received confirmation of all the messages we sent, we can
-close the acceptor in order to exit.
-
-\skip on_delivery_accept
-\until }
-\until }
-
-To try this modified sender, run the original \ref simple_recv.cpp against it.
-
-The symmetry in the underlying AMQP that enables this is quite unique and
-elegant, and in reflecting this the proton API provides a flexible toolkit for
-implementing all sorts of interesting intermediaries (\ref broker.hpp and \ref
-broker.cpp provide a simple broker for testing purposes is an example of this).
-
-Request/Response
-----------------
-
-A common pattern is to send a request message and expect a response message in
-return. AMQP has special support for this pattern. Let's have a look at a simple
-example. We'll start with \ref server.cpp, the program that will process the
-request and send the response. Note that we are still using a broker in this
-example.
-
-Our server will provide a very simple service: it will respond with the
-body of the request converted to uppercase.
-
-\dontinclude server.cpp
-\skip class server
-\until };
-
-The code here is not too different from the simple receiver example.  When we
-receive a request in `on_message` however, we look at the
-`proton::message::reply_to` address and create a sender with that address for
-the response. We'll cache the senders incase we get further requests with the
-same `reply_to`.
-
-Now let's create a simple \ref client.cpp to test this service out.
-
-\dontinclude client.cpp
-
-Our client takes a list of strings to send as requests
-
-\skipline client(
-
-Since we will be sending and receiving, we create a sender and a receiver in
-`on_start`.  Our receiver has a blank address and sets the `dynamic` flag to
-true, which means we expect the remote end (broker or server) to assign a unique
-address for us.
-
-\skip on_start
-\until }
-
-Now a function to send the next request from our list of requests. We set the
-reply_to address to be the dynamically assigned address of our receiver.
-
-\skip send_request
-\until }
-
-We need to use the address assigned by the broker as the `reply_to` address of
-our requests, so we can't send them until our receiver has been set up. To do
-that, we add an `on_link_open()` method to our handler class, and if the link
-associated with event is the receiver, we use that as the trigger to send our
-first request.
-
-\skip on_link_open
-\until }
-
-When we receive a reply, we send the next request.
-
-\skip on_message
-\until }
-\until }
-\until }
-
-Direct Request/Response
------------------------
-
-We can avoid the intermediary process by writing a server that accepts
-connections directly, \ref server_direct.cpp. It involves the following changes
-to our original server:
-
-\dontinclude server_direct.cpp
-
-Our server must generate a unique reply-to addresses for links from the
-client that request a dynamic address (previously this was done by the broker.)
-We use a simple counter.
-
-\skip generate_address
-\until }
-
-Next we need to handle incoming requests for links with dynamic addresses from
-the client.  We give the link a unique address and record it in our `senders`
-map.
-
-\skip on_link_open
-\until }
-
-Note we are interested in *sender* links above because we are implementing the
-server. A *receiver* link created on the client corresponds to a *sender* link
-on the server.
-
-Finally when we receive a message we look up its `reply_to` in our senders map and send the reply.
-
-\skip on_message
-\until }
-\until }
-\until }
-
-Connection Engine
------------------
-
-The `proton::connection_engine` is an alternative to the container. For simple
-applications with a single connection, its use is about the same as the the
-`proton::container`, but it allows more flexibility for multi-threaded
-applications or applications with unusual IO requirements.
-
-\dontinclude engine/helloworld.cpp
-
-We'll look at the \ref engine/helloworld.cpp example step-by-step to see how it differs
-from the container \ref helloworld.cpp version.
-
-First we include the `proton::io::socket_engine` class, which is a `proton::connection_engine`
-that uses socket IO.
-
-\skipline proton/io.hpp
-
-Our `hello_world` class differs only in the `on_start()` method. Instead of
-calling `container.connect()`, we simply call `proton::connection::open` to open the
-engine's' connection:
-
-\skip on_start
-\until }
-
-Our `main` function only differs in that it creates and runs a `socket_engine`
-instead of a `container`.
-
-\skip main
-\until }
-\until }
-\until }
-
-*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/proton-c/bindings/cpp/docs/user.doxygen.in
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/docs/user.doxygen.in b/proton-c/bindings/cpp/docs/user.doxygen.in
index e76337a..26b1784 100644
--- a/proton-c/bindings/cpp/docs/user.doxygen.in
+++ b/proton-c/bindings/cpp/docs/user.doxygen.in
@@ -25,13 +25,13 @@ OUTPUT_DIRECTORY        = .
 OUTPUT_LANGUAGE         = English
 BRIEF_MEMBER_DESC       = YES
 REPEAT_BRIEF            = YES
+ALWAYS_DETAILED_SEC     = NO
 INLINE_INHERITED_MEMB   = YES
 JAVADOC_AUTOBRIEF       = YES
 MULTILINE_CPP_IS_BRIEF  = NO
 INHERIT_DOCS            = YES
 BUILTIN_STL_SUPPORT     = YES
 INLINE_SIMPLE_STRUCTS   = YES
-EXTRACT_LOCAL_CLASSES   = NO
 HIDE_UNDOC_CLASSES      = YES
 HIDE_COMPOUND_REFERENCE = YES
 HIDE_SCOPE_NAMES        = YES
@@ -44,6 +44,7 @@ ENABLE_PREPROCESSING = YES
 MACRO_EXPANSION = YES
 EXPAND_ONLY_PREDEF = YES
 PREDEFINED = protected=private PN_CPP_EXTERN=
+EXCLUDE_SYMBOLS = internal internal::*
 
 # Configuration options related to warning and progress messages
 
@@ -52,14 +53,17 @@ WARNINGS               = YES
 
 # Configuration options related to the input files
 
-INPUT = @CMAKE_SOURCE_DIR@/proton-c/bindings/cpp/include @CMAKE_SOURCE_DIR@/proton-c/bindings/cpp/docs @CMAKE_SOURCE_DIR@/examples/cpp/README.hpp
-FILE_PATTERNS          = *.hpp *.md
+INPUT = @CMAKE_SOURCE_DIR@/proton-c/bindings/cpp/include @CMAKE_SOURCE_DIR@/proton-c/bindings/cpp/docs @CMAKE_SOURCE_DIR@/examples/cpp/README.dox
+FILE_PATTERNS          = *.hpp *.md *.dox
+FULL_PATH_NAMES        = YES
 RECURSIVE              = YES
+STRIP_FROM_PATH        = @CMAKE_SOURCE_DIR@/proton-c/bindings/cpp/include
 EXAMPLE_PATH           = @CMAKE_SOURCE_DIR@/examples/cpp
 EXAMPLE_RECURSIVE      = YES
 
 # View and list options
 
+GENERATE_TREEVIEW       = YES
 GENERATE_TODOLIST       = NO
 GENERATE_TESTLIST       = NO
 GENERATE_BUGLIST        = NO

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/proton-c/bindings/cpp/include/proton/amqp.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/amqp.hpp b/proton-c/bindings/cpp/include/proton/amqp.hpp
index 2ca122f..990bf06 100644
--- a/proton-c/bindings/cpp/include/proton/amqp.hpp
+++ b/proton-c/bindings/cpp/include/proton/amqp.hpp
@@ -25,7 +25,8 @@
 
 namespace proton {
 
-
+/// AMQP typedefs for C++ types
+///
 /// This namespace contains typedefs to associate AMQP scalar type names with
 /// the corresponding C++ types. These are provided as a convenience for those
 /// familiar with AMQP, you do not need to use them, you can use the C++ types
@@ -38,31 +39,31 @@ namespace amqp {
 
 ///@name Typedefs for AMQP numeric types.
 ///@{
-///@ Boolean true or false.
+
+/// Boolean true or false.
 typedef bool boolean_type;
-///@ 8-bit unsigned byte 
+/// 8-bit unsigned byte 
 typedef uint8_t ubyte_type;
-///@ 8-bit signed byte
+/// 8-bit signed byte
 typedef int8_t byte_type;
-///@ 16-bit unsigned short integer
+/// 16-bit unsigned short integer
 typedef uint16_t ushort_type;
-///@ 16-bit signed short integer
+/// 16-bit signed short integer
 typedef int16_t short_type;
-///@ 32-bit unsigned integer
+/// 32-bit unsigned integer
 typedef uint32_t uint_type;
-///@ 32-bit signed integer
+/// 32-bit signed integer
 typedef int32_t int_type;
-///@ 64-bit unsigned long integer
+/// 64-bit unsigned long integer
 typedef uint64_t ulong_type;
-///@ 64-bit signed long integer
+/// 64-bit signed long integer
 typedef int64_t long_type;
-///@ 32-bit unicode code point
+/// 32-bit unicode code point
 typedef wchar_t char_type;
-///@ 32-bit binary floating point
+/// 32-bit binary floating point
 typedef float float_type;
-///@ 64-bit binary floating point
+/// 64-bit binary floating point
 typedef double double_type;
-///@}
 
 /// An AMQP string is unicode  UTF-8 encoded.
 typedef std::string string_type;
@@ -79,15 +80,14 @@ typedef proton::timestamp timestamp_type;
 /// A 16-byte universally unique identifier.
 typedef proton::uuid uuid_type;
 
-///@name AMQP decimal floating point types.
-///
-/// These are not usable as arithmetic types in C++. You can pass them on over
-/// AMQP or convert the raw bytes using a decimal support library. @see proton::decimal.
-/// @{
+/// 32 bit decimal floating point
 typedef proton::decimal32 decimal32_type;
+
+/// 64 bit decimal floating point
 typedef proton::decimal64 decimal64_type;
+
+/// 128 bit decimal floating point
 typedef proton::decimal128 decimal128_type;
-///@}
 
 }}
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/proton-c/bindings/cpp/include/proton/annotation_key.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/annotation_key.hpp b/proton-c/bindings/cpp/include/proton/annotation_key.hpp
index 61b6434..acea44e 100644
--- a/proton-c/bindings/cpp/include/proton/annotation_key.hpp
+++ b/proton-c/bindings/cpp/include/proton/annotation_key.hpp
@@ -20,7 +20,7 @@
  * under the License.
  */
 
-#include <proton/scalar.hpp>
+#include <proton/scalar_base.hpp>
 #include <proton/symbol.hpp>
 
 namespace proton {
@@ -28,39 +28,46 @@ namespace proton {
 /// A key for use with AMQP annotation maps.
 ///
 /// An annotation_key can contain either a uint64_t or a proton::symbol.
-class annotation_key : public restricted_scalar {
+class annotation_key : public scalar_base {
   public:
+    using scalar_base::type;
+
     /// An empty annotation key has a uint64_t == 0 value.
-    annotation_key() { scalar_ = uint64_t(0); }
-    annotation_key(const annotation_key& x) { scalar_ = x; }
-    annotation_key& operator=(const annotation_key& x) { scalar_ = x; return *this; }
+    annotation_key() { put_(uint64_t(0)); }
 
-    annotation_key(uint64_t x) { scalar_ = x; }
-    annotation_key(const symbol& x) { scalar_ = x; }
+    /// Construct from any type that can be assigned
+    template <class T> annotation_key(const T& x) { *this = x; }
 
+    ///@name Assign from a uint64_t or symbol.
+    ///@{
+    annotation_key& operator=(uint64_t x) { put_(x); return *this; }
+    annotation_key& operator=(const symbol& x) { put_(x); return *this; }
+    ///@}
     ///@name Extra conversions for strings, treated as amqp::SYMBOL.
     ///@{
-    annotation_key(const std::string& x) { scalar_ = symbol(x); }
-    annotation_key(const char *x) {scalar_ = symbol(x); }
+    annotation_key& operator=(const std::string& x) { put_(symbol(x)); return *this; }
+    annotation_key& operator=(const char *x) { put_(symbol(x)); return *this; }
     ///@}
 
-    annotation_key& operator=(uint64_t x) { scalar_ = x; return *this; }
-    annotation_key& operator=(const symbol& x) { scalar_ = x; return *this; }
-
-    /// @name Get methods
-    ///
-    /// @{
-    void get(uint64_t& x) const { scalar_.get(x); }
-    void get(symbol& x) const { scalar_.get(x); }
-    /// @}
-
-    /// Return the value as type T.
-    template<class T> T get() const { T x; get(x); return x; }
-
+    ///@cond INTERNAL
   friend class message;
   friend class codec::decoder;
+    ///@endcond
 };
 
+///@cond internal
+template <class T> T get(const annotation_key& x);
+///@endcond
+
+/// Get the uint64_t value or throw conversion_error. @related annotation_key
+template<> inline uint64_t get<uint64_t>(const annotation_key& x) { return internal::get<uint64_t>(x); }
+/// Get the @ref symbol value or throw conversion_error. @related annotation_key
+template<> inline symbol get<symbol>(const annotation_key& x) { return internal::get<symbol>(x); }
+/// Get the @ref binary value or throw conversion_error. @related annotation_key
+
+/// @copydoc scalar::coerce
+/// @related annotation_key
+template<class T> T coerce(const annotation_key& x) { return internal::coerce<T>(x); }
 }
 
 #endif // ANNOTATION_KEY_HPP

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/proton-c/bindings/cpp/include/proton/binary.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/binary.hpp b/proton-c/bindings/cpp/include/proton/binary.hpp
index e907f47..a72ac75 100644
--- a/proton-c/bindings/cpp/include/proton/binary.hpp
+++ b/proton-c/bindings/cpp/include/proton/binary.hpp
@@ -28,22 +28,24 @@
 namespace proton {
 
 /// Arbitrary binary data.
-class binary : public std::vector<char> {
+class binary : public std::vector<uint8_t> {
   public:
-    typedef std::vector<char> byte_vector;
-
-    explicit binary() : byte_vector() {}
-    explicit binary(size_t n) : byte_vector(n) {}
-    explicit binary(size_t n, char x) : byte_vector(n, x) {}
-    template <class Iter> binary(Iter first, Iter last) : byte_vector(first, last) {}
-    explicit binary(const std::string& s) : byte_vector(s.begin(), s.end()) {}
-
-    std::string str() const { return std::string(begin(), end()); }
-
-    binary& operator=(const binary& x) { byte_vector::operator=(x); return *this; }
+    ///@name Constructors @{
+    explicit binary() : std::vector<value_type>() {}
+    explicit binary(size_t n) : std::vector<value_type>(n) {}
+    explicit binary(size_t n, value_type x) : std::vector<value_type>(n, x) {}
+    explicit binary(const std::string& s) : std::vector<value_type>(s.begin(), s.end()) {}
+    template <class Iter> binary(Iter first, Iter last) : std::vector<value_type>(first, last) {}
+    ///@}
+
+    /// Convert to std::string
+    operator std::string() const { return std::string(begin(), end()); }
+
+    /// Assignment
     binary& operator=(const std::string& x) { assign(x.begin(), x.end()); return *this; }
 };
 
+/// Print binary value
 PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const binary&);
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/proton-c/bindings/cpp/include/proton/byte_array.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/byte_array.hpp b/proton-c/bindings/cpp/include/proton/byte_array.hpp
index c2757fa..fe3f864 100644
--- a/proton-c/bindings/cpp/include/proton/byte_array.hpp
+++ b/proton-c/bindings/cpp/include/proton/byte_array.hpp
@@ -23,6 +23,7 @@
 #include <proton/comparable.hpp>
 
 #include <algorithm>
+#include <iterator>
 
 namespace proton {
 
@@ -30,32 +31,51 @@ namespace proton {
 /// as an array of bytes.
 template <size_t N> class byte_array : private comparable<byte_array<N> > {
   public:
-    typedef char value_type;
+    ///@name Sequence container typedefs
+    ///@{
+    typedef uint8_t                                   value_type;
+    typedef value_type*			              pointer;
+    typedef const value_type*                         const_pointer;
+    typedef value_type&                   	      reference;
+    typedef const value_type&             	      const_reference;
+    typedef value_type*          		      iterator;
+    typedef const value_type*			      const_iterator;
+    typedef std::size_t                    	      size_type;
+    typedef std::ptrdiff_t                   	      difference_type;
+    typedef std::reverse_iterator<iterator>	      reverse_iterator;
+    typedef std::reverse_iterator<const_iterator>     const_reverse_iterator;
+    ///@}
 
-    /// Initially all 0.
+    /// 0-initialized byte array
     byte_array() { std::fill(bytes_, bytes_+N, '\0'); }
 
-    /// Returns N
+    /// Size of the array
     static size_t size() { return N; }
 
-    uint8_t* begin() { return bytes_; }
-    uint8_t* end() { return bytes_+N; }
-    uint8_t& operator[](size_t i) { return bytes_[i]; }
+    ///@name Array operators
+    ///@{
+    value_type* begin() { return bytes_; }
+    value_type* end() { return bytes_+N; }
+    value_type& operator[](size_t i) { return bytes_[i]; }
 
-    const uint8_t* begin() const { return bytes_; }
-    const uint8_t* end() const { return bytes_+N; }
-    const uint8_t& operator[](size_t i) const { return bytes_[i]; }
+    const value_type* begin() const { return bytes_; }
+    const value_type* end() const { return bytes_+N; }
+    const value_type& operator[](size_t i) const { return bytes_[i]; }
+    ///@}
 
-    friend bool operator==(const byte_array& x, const byte_array& y) {
-        return std::equal(x.begin(), x.end(), y.begin());
-    }
+    ///@name Comparison operators
+    ///@{
+  friend bool operator==(const byte_array& x, const byte_array& y) {
+      return std::equal(x.begin(), x.end(), y.begin());
+  }
 
-    friend bool operator<(const byte_array& x, const byte_array& y) {
-        return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
-    }
+  friend bool operator<(const byte_array& x, const byte_array& y) {
+      return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+  }
+    ///@}
 
   private:
-    uint8_t bytes_[N];
+    value_type bytes_[N];
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/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
index 8bf0e47..cca0e62 100644
--- a/proton-c/bindings/cpp/include/proton/comparable.hpp
+++ b/proton-c/bindings/cpp/include/proton/comparable.hpp
@@ -22,6 +22,8 @@
 
 namespace proton {
 
+///@cond INTERNAL
+
 /// Base class for comparable types with operator< and
 /// operator==. Provides remaining operators.
 template <class T> class comparable {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/proton-c/bindings/cpp/include/proton/connection_engine.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/connection_engine.hpp b/proton-c/bindings/cpp/include/proton/connection_engine.hpp
index e6946c7..0b1a947 100644
--- a/proton-c/bindings/cpp/include/proton/connection_engine.hpp
+++ b/proton-c/bindings/cpp/include/proton/connection_engine.hpp
@@ -125,7 +125,7 @@ PN_CPP_CLASS_EXTERN connection_engine {
 
     /// Thrown by io_read and io_write functions to indicate an error.
     struct PN_CPP_CLASS_EXTERN io_error : public error {
-        PN_CPP_EXTERN explicit io_error(const std::string&);
+        PN_CPP_EXTERN explicit io_error(const std::string&); ///< Construct with message
     };
 
   protected:

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/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 3d39154..2dadd51 100644
--- a/proton-c/bindings/cpp/include/proton/data.hpp
+++ b/proton-c/bindings/cpp/include/proton/data.hpp
@@ -24,55 +24,62 @@
 #include <proton/types_fwd.hpp>
 #include <proton/type_id.hpp>
 
+///@file
+
 struct pn_data_t;
 
 namespace proton {
 
 class value;
+///@defgroup codec Internal details of AMQP encoding.
+///
+/// You can use these classes on an experimental basis to create your own AMQP
+/// encodings for C++ types, but they may change in the future. For examples of use
+/// see the built-in encodings, for example in proton/vector.hpp or proton/map.hpp
 
+/// @ingroup codec
 namespace codec {
 
 /// Wrapper for a proton data object.
 class data : public internal::object<pn_data_t> {
   public:
+    /// Wrap an existing proton-C data object.
     data(pn_data_t* d=0) : internal::object<pn_data_t>(d) {}
 
+    /// Create a new data object.
     PN_CPP_EXTERN static data create();
 
-    // Copy the contents of another data object.
+    /// Copy the contents of another data object.
     PN_CPP_EXTERN void copy(const data&);
 
-    /** Clear the data. */
+    /// Clear the data.
     PN_CPP_EXTERN void clear();
 
-    /** Rewind current position to the start */
+    /// Rewind current position to the start.
     PN_CPP_EXTERN void rewind();
 
-    /** True if there are no values. */
+    /// True if there are no values.
     PN_CPP_EXTERN bool empty() const;
 
-    /** Return the data cursor position */
-    PN_CPP_EXTERN void* point() const;
-
-    /** Restore the cursor position to a previously saved position */
-    PN_CPP_EXTERN void restore(void* h);
-
-    PN_CPP_EXTERN void narrow();
-
-    PN_CPP_EXTERN void widen();
-
+    /// Append the contents of another data object.
     PN_CPP_EXTERN int append(data src);
 
+    /// Append up to limit items from data object.
     PN_CPP_EXTERN int appendn(data src, int limit);
 
+  protected:
+    PN_CPP_EXTERN void* point() const;
+    PN_CPP_EXTERN void restore(void* h);
+    PN_CPP_EXTERN void narrow();
+    PN_CPP_EXTERN void widen();
     PN_CPP_EXTERN bool next();
-
     PN_CPP_EXTERN bool prev();
 
+  friend struct state_guard;
   friend PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const data&);
 };
 
-/// state_guard saves the state and restores it in dtor unless cancel() is called.
+// state_guard saves the state and restores it in dtor unless cancel() is called.
 struct state_guard {
     data& data_;
     void* point_;
@@ -83,13 +90,6 @@ struct state_guard {
     void cancel() { cancel_ = true; }
 };
 
-/// Narrow the data object, widen it in dtor.
-struct narrow_guard {
-    data& data_;
-    narrow_guard(data& d) : data_(d) { data_.narrow(); }
-    ~narrow_guard() { data_.widen(); }
-};
-
 // Start encoding a complex type.
 struct start {
     start(type_id type_=NULL_TYPE, type_id element_=NULL_TYPE,
@@ -107,10 +107,11 @@ struct start {
     PN_CPP_EXTERN static start described() { return start(DESCRIBED, NULL_TYPE, true); }
 };
 
-/// Finish inserting or extracting a complex type.
+// Finish inserting or extracting a complex type.
 struct finish {};
 
 } // codec
+
 } // proton
 
-#endif // PROTON_DATA_HPP
+#endif  /*!PROTON_DATA_HPP*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/proton-c/bindings/cpp/include/proton/decimal.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/decimal.hpp b/proton-c/bindings/cpp/include/proton/decimal.hpp
index ddb8ea8..dada944 100644
--- a/proton-c/bindings/cpp/include/proton/decimal.hpp
+++ b/proton-c/bindings/cpp/include/proton/decimal.hpp
@@ -49,13 +49,16 @@ class decimal64 : public byte_array<8> {};
 
 /// 128-bit decimal floating point.
 class decimal128 : public byte_array<16> {};
+///@}
 
+/// Print decimal values
+///@{
 PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const decimal32&);
 PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const decimal64&);
 PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const decimal128&);
-
 ///@}
 
+
 }
 
 #endif // DECIMAL_HPP

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/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 9a835c0..e6fc78b 100644
--- a/proton-c/bindings/cpp/include/proton/decoder.hpp
+++ b/proton-c/bindings/cpp/include/proton/decoder.hpp
@@ -20,10 +20,12 @@
  */
 
 #include <proton/data.hpp>
+#include <proton/types_fwd.hpp>
 #include <proton/type_traits.hpp>
 
 #include <utility>
 
+// Proton namespace
 namespace proton {
 
 class annotation_key;
@@ -32,19 +34,23 @@ class scalar;
 class value;
 class value_base;
 
+/// @ingroup codec
 namespace codec {
 
 /// Stream-like decoder from AMQP bytes to C++ values.
 ///
-/// Internal use only, see proton::value, proton::scalar and proton::amqp
+/// Internal use only, see proton::value, proton::scalar and \ref types
 /// for the recommended ways to manage AMQP data.
 class decoder : public data {
   public:
-    ///@internal
-    explicit decoder(const data& d) : data(d) {}
+
+    /// Wrap Proton-C data object.
+    /// The exact flag if set means decode only when there is an exact match
+    /// between the AMQP and C++ type. If not set then perform automatic conversions.
+    explicit decoder(const data& d, bool exact=false) : data(d), exact_(exact) {}
 
     /// Attach decoder to a proton::value. The decoder is rewound to the start of the data.
-    PN_CPP_EXTERN explicit decoder(const value_base&);
+    PN_CPP_EXTERN explicit decoder(const value_base&, bool exact=false);
 
     /// Decode AMQP data from a buffer and add it to the end of the decoders stream. */
     PN_CPP_EXTERN void decode(const char* buffer, size_t size);
@@ -59,11 +65,9 @@ class decoder : public data {
     /// @throw conversion_error if no more values. @see decoder::more().
     PN_CPP_EXTERN type_id next_type();
 
-    /** @name Extract simple types
-     * Overloads to extract simple types.
-     * @throw conversion_error if the decoder is empty or has an incompatible type.
-     * @{
-     */
+    /// @name Extract built-in types
+    /// @throw conversion_error if the decoder is empty or has an incompatible type.
+    /// @{
     PN_CPP_EXTERN decoder& operator>>(bool&);
     PN_CPP_EXTERN decoder& operator>>(uint8_t&);
     PN_CPP_EXTERN decoder& operator>>(int8_t&);
@@ -96,10 +100,10 @@ class decoder : public data {
     /// Call finish() to "exit" the container and move on to the next value.
     PN_CPP_EXTERN decoder& operator>>(start&);
 
-    // Finish decoding a container type, and move on to the next value in the stream.
+    /// Finish decoding a container type, and move on to the next value in the stream.
     PN_CPP_EXTERN decoder& operator>>(const finish&);
 
-    // XXX doc
+    ///@cond INTERNAL
     template <class T> struct sequence_ref { T& ref; sequence_ref(T& r) : ref(r) {} };
     template <class T> struct associative_ref { T& ref; associative_ref(T& r) : ref(r) {} };
     template <class T> struct pair_sequence_ref { T& ref;  pair_sequence_ref(T& r) : ref(r) {} };
@@ -107,6 +111,7 @@ class decoder : public data {
     template <class T> static sequence_ref<T> sequence(T& x) { return sequence_ref<T>(x); }
     template <class T> static associative_ref<T> associative(T& x) { return associative_ref<T>(x); }
     template <class T> static pair_sequence_ref<T> pair_sequence(T& x) { return pair_sequence_ref<T>(x); }
+    ///@endcond
 
     /** Extract any AMQP sequence (ARRAY, LIST or MAP) to a C++ sequence
      * container of T if the elements types are convertible to T. A MAP is
@@ -124,6 +129,7 @@ class decoder : public data {
 
     /** Extract an AMQP MAP to a C++ associative container */
     template <class T> decoder& operator>>(associative_ref<T> r)  {
+        using namespace internal;
         start s;
         *this >> s;
         assert_type_equal(MAP, s.type);
@@ -140,6 +146,7 @@ class decoder : public data {
     /// Extract an AMQP MAP to a C++ push_back sequence of pairs
     /// preserving encoded order.
     template <class T> decoder& operator>>(pair_sequence_ref<T> r)  {
+        using namespace internal;
         start s;
         *this >> s;
         assert_type_equal(MAP, s.type);
@@ -154,30 +161,32 @@ class decoder : public data {
         return *this;
     }
 
-    /// Extract and return a value.
-    template <class T> T extract() { T x; *this >> x; return x; }
-
   private:
     type_id pre_get();
     template <class T, class U> decoder& extract(T& x, U (*get)(pn_data_t*));
+    bool exact_;
 
   friend class message;
 };
 
+template<class T> T get(decoder& d) {
+    assert_type_equal(internal::type_id_of<T>::value, d.next_type());
+    T x;
+    d >> x;
+    return x;
+}
+
 // operator >> for integer types that are not covered by the standard overrides.
-template <class T> typename codec::enable_unknown_integer<T, decoder&>::type
+template <class T> typename internal::enable_if<internal::is_unknown_integer<T>::value, decoder&>::type
 operator>>(decoder& d, T& i)  {
+    using namespace internal;
     typename integer_type<sizeof(T), is_signed<T>::value>::type v;
     d >> v;                     // Extract as a known integer type
     i = v;                      // C++ conversion to the target type.
     return d;
 }
 
-///@cond INTERNAL
-
-} // internal
+} // codec
 } // proton
 
-/// @endcond
-
 #endif // PROTON_DECODER_HPP

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/proton-c/bindings/cpp/include/proton/deque.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/deque.hpp b/proton-c/bindings/cpp/include/proton/deque.hpp
index 18d142d..7d0b278 100644
--- a/proton-c/bindings/cpp/include/proton/deque.hpp
+++ b/proton-c/bindings/cpp/include/proton/deque.hpp
@@ -31,7 +31,7 @@ namespace codec {
 /// std::deque<T> for most T is encoded as an amqp::ARRAY (same type elements)
 template <class T, class A>
 encoder& operator<<(encoder& e, const std::deque<T, A>& x) {
-    return e << encoder::array(x, type_id_of<T>::value);
+    return e << encoder::array(x, internal::type_id_of<T>::value);
 }
 
 /// std::deque<value> encodes as amqp::LIST (mixed type elements)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/proton-c/bindings/cpp/include/proton/duration.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/duration.hpp b/proton-c/bindings/cpp/include/proton/duration.hpp
index 51f7a46..9d41d2d 100644
--- a/proton-c/bindings/cpp/include/proton/duration.hpp
+++ b/proton-c/bindings/cpp/include/proton/duration.hpp
@@ -33,11 +33,13 @@ namespace proton {
 /// A span of time in milliseconds.
 class duration : private comparable<duration> {
   public:
-    typedef uint64_t numeric_type;
-    explicit duration(numeric_type ms = 0) : ms_(ms) {}
-    duration& operator=(numeric_type ms) { ms_ = ms; return *this; }
-    numeric_type milliseconds() const { return ms_; }
-    numeric_type ms() const { return ms_; }
+    typedef uint64_t numeric_type; ///< Numeric type used to store milliseconds
+
+    explicit duration(numeric_type ms = 0) : ms_(ms) {} ///< Construct from milliseconds
+    duration& operator=(numeric_type ms) { ms_ = ms; return *this; } ///< Assign
+
+    numeric_type milliseconds() const { return ms_; } ///< Return milliseconds
+    numeric_type ms() const { return ms_; }           ///< Return milliseconds
 
     PN_CPP_EXTERN static const duration FOREVER;   ///< Wait for ever
     PN_CPP_EXTERN static const duration IMMEDIATE; ///< Don't wait at all
@@ -48,8 +50,11 @@ class duration : private comparable<duration> {
     numeric_type ms_;
 };
 
+/// Print duration
 PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, duration);
 
+///@name Comparison and arithmetic operators
+///@{
 inline bool operator<(duration x, duration y) { return x.ms() < y.ms(); }
 inline bool operator==(duration x, duration y) { return x.ms() == y.ms(); }
 
@@ -57,7 +62,7 @@ inline duration operator+(duration x, duration y) { return duration(x.ms() + y.m
 inline duration operator-(duration x, duration y) { return duration(x.ms() - y.ms()); }
 inline duration operator*(duration d, uint64_t n) { return duration(d.ms()*n); }
 inline duration operator*(uint64_t n, duration d) { return d * n; }
-
+///@}
 }
 
 #endif // PROTON_CPP_DURATION_H

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/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 c76c9ce..b9d4461 100644
--- a/proton-c/bindings/cpp/include/proton/encoder.hpp
+++ b/proton-c/bindings/cpp/include/proton/encoder.hpp
@@ -1,5 +1,5 @@
-#ifndef ENCODER_H
-#define ENCODER_H
+#ifndef PROTON_ENCODER_HPP
+#define PROTON_ENCODER_HPP
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -21,23 +21,24 @@
  */
 
 #include <proton/data.hpp>
+#include <proton/types_fwd.hpp>
 #include <proton/type_traits.hpp>
 
 namespace proton {
 
-class scalar;
-class value;
+class scalar_base;
 class value_base;
 
+/// @ingroup codec
 namespace codec {
 
 /// Stream-like encoder from AMQP bytes to C++ values.
 ///
-/// Internal use only, see proton::value, proton::scalar and proton::amqp
+/// Internal use only, see proton::value, proton::scalar and \ref types
 /// for the recommended ways to manage AMQP data.
 class encoder : public data {
   public:
-    ///@internal
+    /// Wrap Proton-C data object.
     explicit encoder(const data& d) : data(d) {}
 
     /// Encoder into v. Clears any current value in v.
@@ -63,6 +64,8 @@ class encoder : public data {
     /** Encode the current values into a std::string. Clears the encoder. */
     PN_CPP_EXTERN std::string encode();
 
+    /// @name Insert built-in types
+    /// @{
     PN_CPP_EXTERN encoder& operator<<(bool);
     PN_CPP_EXTERN encoder& operator<<(uint8_t);
     PN_CPP_EXTERN encoder& operator<<(int8_t);
@@ -83,17 +86,24 @@ class encoder : public data {
     PN_CPP_EXTERN encoder& operator<<(const std::string&);
     PN_CPP_EXTERN encoder& operator<<(const symbol&);
     PN_CPP_EXTERN encoder& operator<<(const binary&);
-    PN_CPP_EXTERN encoder& operator<<(const scalar&);
+    PN_CPP_EXTERN encoder& operator<<(const scalar_base&);
     PN_CPP_EXTERN encoder& operator<<(const null&);
+    ///@}
 
-    /// Inserts proton::value.
+    /// Insert a proton::value.
+    /// @internal NOTE insert value_base, not value to avoid recursive implicit conversions.
     PN_CPP_EXTERN encoder& operator<<(const value_base&);
 
+    /// Start a complex type
     PN_CPP_EXTERN encoder& operator<<(const start&);
     /// Finish a complex type
     PN_CPP_EXTERN encoder& operator<<(const finish&);
 
-    // XXX doc
+    ///@cond INTERNAL
+
+    // Undefined template to  prevent pointers being implicitly converted to bool.
+    template <class T> void* operator<<(const T*);
+
     template <class T> struct list_cref { T& ref; list_cref(T& r) : ref(r) {} };
     template <class T> struct map_cref { T& ref;  map_cref(T& r) : ref(r) {} };
 
@@ -135,26 +145,47 @@ class encoder : public data {
         *this << finish();
         return *this;
     }
+    ///@endcond
 
   private:
     template<class T, class U> encoder& insert(const T& x, int (*put)(pn_data_t*, U));
     void check(long result);
 };
 
-///@internal
-/// Invalid template to  prevent pointers being implicitly converted to bool.
-template <class T> void* operator<<(encoder&, const T*);
 
-// Treat char* as string
+/// Treat char* as string
 inline encoder& operator<<(encoder& e, const char* s) { return e << std::string(s); }
 
-// operator << for integer types that are not covered by the standard overrides.
-template <class T> typename codec::enable_unknown_integer<T, encoder&>::type
+/// operator << for integer types that are not covered by the standard overrides.
+template <class T> typename internal::enable_if<internal::is_unknown_integer<T>::value, encoder&>::type
 operator<<(encoder& e, T i)  {
+    using namespace internal;
     return e << static_cast<typename integer_type<sizeof(T), is_signed<T>::value>::type>(i);
 }
 
-} // internal
+///@cond INTERNAL
+namespace is_encodable_impl {   // Protected the world from wildcard operator<<
+
+using namespace internal;
+
+sfinae::no operator<<(sfinae::wildcard, sfinae::wildcard); // Fallback
+
+template<typename T> struct is_encodable : public sfinae {
+    static yes test(encoder);
+    static no test(...);         // Failed test, no match.
+    static encoder &e;
+    static const T& t;
+    static bool const value = sizeof(test(e << t)) == sizeof(yes);
+};
+// Avoid recursion
+template <> struct is_encodable<value> : public true_type {};
+
+} // namespace is_encodable_impl
+
+using is_encodable_impl::is_encodable;
+///@endcond
+
+} // codec
 } // proton
 
-#endif // ENCODER_H
+#endif  /*!PROTON_ENCODER_HPP*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d70dab5d/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 705ce7d..d59e093 100644
--- a/proton-c/bindings/cpp/include/proton/endpoint.hpp
+++ b/proton-c/bindings/cpp/include/proton/endpoint.hpp
@@ -75,6 +75,7 @@ PN_CPP_CLASS_EXTERN endpoint {
 #endif
 };
 
+///@cond INTERNAL
 namespace internal {
 
 template <class T, class D> class iter_base {
@@ -86,7 +87,7 @@ template <class T, class D> class iter_base {
     D operator++(int) { D x(*this); ++(*this); return x; }
     bool operator==(const iter_base<T, D>& x) const { return obj_ == x.obj_; }
     bool operator!=(const iter_base<T, D>& x) const { return obj_ != x.obj_; }
-
+    ///@}
   protected:
     explicit iter_base(T p = 0) : obj_(p) {}
     T obj_;
@@ -105,6 +106,8 @@ template<class I> class iter_range {
 };
 
 } // namespace internal
+///@endcond
+
 } // namespace proton
 
 #endif // PROTON_CPP_H


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