qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From acon...@apache.org
Subject qpid-proton git commit: PROTON-1138: c++: drop extract_cref<T>.
Date Mon, 14 Mar 2016 20:01:50 GMT
Repository: qpid-proton
Updated Branches:
  refs/heads/master 6260d5065 -> f5f68d844


PROTON-1138: c++: drop extract_cref<T>.

Split proton::value into proton::value_base (holding data and managing interaction with
encoder/decoder) and derived proton::value with user conversion operators.

Removes the need for extract_cref<T> to avoid implicit conversion when passing
proton:value to encoder/decoder, use value_base instead which has no conversions.


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

Branch: refs/heads/master
Commit: f5f68d844fb53d80f8db61c4b814e8e4501e9d75
Parents: 6260d50
Author: Alan Conway <aconway@redhat.com>
Authored: Mon Mar 14 11:35:55 2016 -0400
Committer: Alan Conway <aconway@redhat.com>
Committed: Mon Mar 14 16:00:07 2016 -0400

----------------------------------------------------------------------
 .../bindings/cpp/include/proton/decoder.hpp     |  8 +++-
 .../bindings/cpp/include/proton/encoder.hpp     |  5 ++-
 .../bindings/cpp/include/proton/type_traits.hpp | 13 -------
 proton-c/bindings/cpp/include/proton/value.hpp  | 40 +++++++++++---------
 proton-c/bindings/cpp/src/decoder.cpp           | 11 +++---
 proton-c/bindings/cpp/src/encoder.cpp           | 11 +++---
 proton-c/bindings/cpp/src/value.cpp             | 36 +++++++++---------
 7 files changed, 62 insertions(+), 62 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f5f68d84/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 1df0bba..9a835c0 100644
--- a/proton-c/bindings/cpp/include/proton/decoder.hpp
+++ b/proton-c/bindings/cpp/include/proton/decoder.hpp
@@ -30,6 +30,7 @@ class annotation_key;
 class message_id;
 class scalar;
 class value;
+class value_base;
 
 namespace codec {
 
@@ -43,7 +44,7 @@ class decoder : public data {
     explicit decoder(const data& d) : data(d) {}
 
     /// Attach decoder to a proton::value. The decoder is rewound to the start of the data.
-    PN_CPP_EXTERN explicit decoder(codec::exact_cref<value>);
+    PN_CPP_EXTERN explicit decoder(const value_base&);
 
     /// 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);
@@ -86,7 +87,7 @@ class decoder : public data {
     PN_CPP_EXTERN decoder& operator>>(message_id&);
     PN_CPP_EXTERN decoder& operator>>(annotation_key&);
     PN_CPP_EXTERN decoder& operator>>(scalar&);
-    PN_CPP_EXTERN decoder& operator>>(value&);
+    PN_CPP_EXTERN decoder& operator>>(value_base&);
     PN_CPP_EXTERN decoder& operator>>(null&);
     ///@}
 
@@ -153,6 +154,9 @@ 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*));

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f5f68d84/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 6ca2ce7..c76c9ce 100644
--- a/proton-c/bindings/cpp/include/proton/encoder.hpp
+++ b/proton-c/bindings/cpp/include/proton/encoder.hpp
@@ -27,6 +27,7 @@ namespace proton {
 
 class scalar;
 class value;
+class value_base;
 
 namespace codec {
 
@@ -40,7 +41,7 @@ class encoder : public data {
     explicit encoder(const data& d) : data(d) {}
 
     /// Encoder into v. Clears any current value in v.
-    PN_CPP_EXTERN explicit encoder(value& v);
+    PN_CPP_EXTERN explicit encoder(value_base& v);
 
     /**
      * Encode the current values into buffer and update size to reflect the
@@ -86,7 +87,7 @@ class encoder : public data {
     PN_CPP_EXTERN encoder& operator<<(const null&);
 
     /// Inserts proton::value.
-    PN_CPP_EXTERN encoder& operator<<(exact_cref<value>);
+    PN_CPP_EXTERN encoder& operator<<(const value_base&);
 
     PN_CPP_EXTERN encoder& operator<<(const start&);
     /// Finish a complex type

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f5f68d84/proton-c/bindings/cpp/include/proton/type_traits.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/type_traits.hpp b/proton-c/bindings/cpp/include/proton/type_traits.hpp
index 9f67715..1000a63 100644
--- a/proton-c/bindings/cpp/include/proton/type_traits.hpp
+++ b/proton-c/bindings/cpp/include/proton/type_traits.hpp
@@ -163,19 +163,6 @@ template<class U> struct assignable<value, U> : public false_type
{};
 template <class T, class U=void> struct enable_unknown_integer :
         public enable_if<is_unknown_integer<T>::value, U> {};
 
-/// Using `exact_cref<const T>` as an argument type instead of `const &T`
-/// ensures that the function will only accept references to an existing T, and
-/// not to a temporary T created by implicit conversion.
-template <class T> struct exact_cref;
-
-template <class T> struct exact_cref {
-    template <class U> exact_cref(
-        const U& r,
-        typename enable_if<is_same<T,U>::value>::type* = 0) : ref(r) {}
-    operator const T&() const { return ref; }
-    const T& ref;
-};
-
 } // internal
 } // proton
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f5f68d84/proton-c/bindings/cpp/include/proton/value.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/value.hpp b/proton-c/bindings/cpp/include/proton/value.hpp
index 359aaeb..e0b7317 100644
--- a/proton-c/bindings/cpp/include/proton/value.hpp
+++ b/proton-c/bindings/cpp/include/proton/value.hpp
@@ -29,11 +29,31 @@
 
 namespace proton {
 
+///@internal - separate value data from implicit conversion constructors to avoid recursions.
+class value_base {
+  public:
+
+    /// Get the type ID for the current value.
+    PN_CPP_EXTERN type_id type() const;
+
+    /// True if the value is null
+    PN_CPP_EXTERN bool empty() const;
+
+  protected:
+    codec::data& data() const;
+    mutable class codec::data data_;
+
+  friend class message;
+  friend class codec::encoder;
+  friend class codec::decoder;
+  friend PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const value_base&);
+};
+
 /// A holder for any single AMQP value, simple or complex (can be list, array, map etc.)
 ///
 /// @see proton::amqp for conversions rules between C++ and AMQP types.
 ///
-class value : private comparable<value> {
+class value : public value_base, private comparable<value> {
   public:
     /// Create a null value.
     PN_CPP_EXTERN value();
@@ -69,12 +89,6 @@ class value : private comparable<value> {
     /// Reset the value to null
     PN_CPP_EXTERN void clear();
 
-    /// True if the value is null
-    PN_CPP_EXTERN bool empty() const;
-
-    /// Get the type ID for the current value.
-    PN_CPP_EXTERN type_id type() const;
-
     /// @name Get methods
     ///
     /// Extract the value to type T.
@@ -105,18 +119,10 @@ class value : private comparable<value> {
   friend PN_CPP_EXTERN void swap(value&, value&);
   friend PN_CPP_EXTERN bool operator==(const value& x, const value& y);
   friend PN_CPP_EXTERN bool operator<(const value& x, const value& y);
-  friend PN_CPP_EXTERN std::ostream& operator<<(std::ostream& o, codec::exact_cref<value>);
-
-  private:
-    codec::data& data() const;
-    mutable class codec::data data_;
-
-  friend class message;
-  friend class codec::encoder;
-  friend class codec::decoder;
 };
 
-template<class T> T get(codec::exact_cref<value> v) { T x; v.ref.get(x); return
x; }
+template<class T> T get(const value_base& v) { return codec::decoder(v).extract<T>();
}
+
 
 } // proton
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f5f68d84/proton-c/bindings/cpp/src/decoder.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/decoder.cpp b/proton-c/bindings/cpp/src/decoder.cpp
index cf0c029..890fac5 100644
--- a/proton-c/bindings/cpp/src/decoder.cpp
+++ b/proton-c/bindings/cpp/src/decoder.cpp
@@ -42,7 +42,7 @@ namespace codec {
  * to be returned by the decoder.
  */
 
-decoder::decoder(exact_cref<value> v) : data(v.ref.data()) { rewind(); }
+decoder::decoder(const value_base& v) : data(v.data()) { rewind(); }
 
 namespace {
 template <class T> T check(T result) {
@@ -139,13 +139,14 @@ decoder& decoder::operator>>(null&) {
     return *this;
 }
 
-decoder& decoder::operator>>(value& v) {
-    if (*this == v.data_)
+decoder& decoder::operator>>(value_base& x) {
+    if (*this == x.data_)
         throw conversion_error("extract into self");
-    v.clear();
+    data d = x.data();
+    d.clear();
     {
         narrow_guard n(*this);
-        check(v.data().appendn(pn_object(), 1));
+        check(d.appendn(*this, 1));
     }
     next();
     return *this;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f5f68d84/proton-c/bindings/cpp/src/encoder.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/encoder.cpp b/proton-c/bindings/cpp/src/encoder.cpp
index a8322c8..538decc 100644
--- a/proton-c/bindings/cpp/src/encoder.cpp
+++ b/proton-c/bindings/cpp/src/encoder.cpp
@@ -44,7 +44,7 @@ void encoder::check(long result) {
 }
 
 
-encoder::encoder(value& v) : data(v.data()) {
+encoder::encoder(value_base& v) : data(v.data()) {
     clear();
 }
 
@@ -142,12 +142,13 @@ encoder& encoder::operator<<(const binary& x) { return
insert(x, pn_data_put_amq
 
 encoder& encoder::operator<<(const scalar& x) { return insert(x.atom_, pn_data_put_atom);
}
 
-encoder& encoder::operator<<(exact_cref<value> x) {
-    if (*this == x.ref.data_)
+encoder& encoder::operator<<(const value_base& x) {
+    if (*this == x.data_)
         throw conversion_error("cannot insert into self");
-    if (x.ref.empty())
+    if (x.empty())
         pn_data_put_null(pn_object());
-    decoder d(x.ref);                 // Rewind
+    data d = x.data();
+    d.rewind();
     check(append(d));
     return *this;
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f5f68d84/proton-c/bindings/cpp/src/value.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/value.cpp b/proton-c/bindings/cpp/src/value.cpp
index 34db621..bece42c 100644
--- a/proton-c/bindings/cpp/src/value.cpp
+++ b/proton-c/bindings/cpp/src/value.cpp
@@ -55,16 +55,14 @@ void swap(value& x, value& y) { std::swap(x.data_, y.data_); }
 
 void value::clear() { if (!!data_) data_.clear(); }
 
-bool value::empty() const { return !data_ || data_.empty(); }
-
-type_id value::type() const {
-    if (empty()) return NULL_TYPE;
-    decoder d(*this);
-    return d.next_type();
+type_id value_base::type() const {
+    return (!data_ || data_.empty()) ? NULL_TYPE : codec::decoder(*this).next_type();
 }
 
+bool value_base::empty() const { return type() == NULL_TYPE; }
+
 // On demand
-codec::data& value::data() const {
+codec::data& value_base::data() const {
     if (!data_)
         data_ = codec::data::create();
     return data_;
@@ -172,20 +170,22 @@ bool operator<(const value& x, const value& y) {
     return compare(x, y) < 0;
 }
 
-std::ostream& operator<<(std::ostream& o, exact_cref<value> v) {
-    if (v.ref.empty())
+std::ostream& operator<<(std::ostream& o, const value_base& x) {
+    if (x.empty())
         return o << "<null>";
-    switch (v.ref.type()) {
-      case STRING: return o << get<std::string>(v.ref);
-      case SYMBOL: return o << get<symbol>(v.ref);
-      case DECIMAL32: return o << get<decimal32>(v.ref);
-      case DECIMAL64: return o << get<decimal64>(v.ref);
-      case DECIMAL128: return o << get<decimal128>(v.ref);
-      case UUID: return o << get<uuid>(v.ref);
-      case TIMESTAMP: return o << get<timestamp>(v.ref);
+    decoder d(x);
+    // Print std::string and proton::foo types using their own operator << consistent
with C++.
+    switch (d.next_type()) {
+      case STRING: return o << d.extract<std::string>();
+      case SYMBOL: return o << d.extract<symbol>();
+      case DECIMAL32: return o << d.extract<decimal32>();
+      case DECIMAL64: return o << d.extract<decimal64>();
+      case DECIMAL128: return o << d.extract<decimal128>();
+      case UUID: return o << d.extract<uuid>();
+      case TIMESTAMP: return o << d.extract<timestamp>();
       default:
         // Use pn_inspect for other types.
-        return o << decoder(v.ref);
+        return o << d;
     }
 }
 


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


Mime
View raw message