Return-Path: X-Original-To: apmail-qpid-commits-archive@www.apache.org Delivered-To: apmail-qpid-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 6F5A518FAF for ; Mon, 14 Mar 2016 20:01:50 +0000 (UTC) Received: (qmail 1450 invoked by uid 500); 14 Mar 2016 20:01:50 -0000 Delivered-To: apmail-qpid-commits-archive@qpid.apache.org Received: (qmail 1412 invoked by uid 500); 14 Mar 2016 20:01:50 -0000 Mailing-List: contact commits-help@qpid.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@qpid.apache.org Delivered-To: mailing list commits@qpid.apache.org Received: (qmail 1401 invoked by uid 99); 14 Mar 2016 20:01:50 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 14 Mar 2016 20:01:50 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 1EC91DFBA3; Mon, 14 Mar 2016 20:01:50 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: aconway@apache.org To: commits@qpid.apache.org Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: qpid-proton git commit: PROTON-1138: c++: drop extract_cref. Date: Mon, 14 Mar 2016 20:01:50 +0000 (UTC) Repository: qpid-proton Updated Branches: refs/heads/master 6260d5065 -> f5f68d844 PROTON-1138: c++: drop extract_cref. 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 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 Authored: Mon Mar 14 11:35:55 2016 -0400 Committer: Alan Conway 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); + 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 T extract() { T x; *this >> x; return x; } + private: type_id pre_get(); template 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); + 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 struct assignable : public false_type {}; template struct enable_unknown_integer : public enable_if::value, U> {}; -/// Using `exact_cref` 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 struct exact_cref; - -template struct exact_cref { - template exact_cref( - const U& r, - typename enable_if::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 { +class value : public value_base, private comparable { public: /// Create a null value. PN_CPP_EXTERN value(); @@ -69,12 +89,6 @@ class value : private comparable { /// 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 { 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); - - private: - codec::data& data() const; - mutable class codec::data data_; - - friend class message; - friend class codec::encoder; - friend class codec::decoder; }; -template T get(codec::exact_cref v) { T x; v.ref.get(x); return x; } +template T get(const value_base& v) { return codec::decoder(v).extract(); } + } // 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 v) : data(v.ref.data()) { rewind(); } +decoder::decoder(const value_base& v) : data(v.data()) { rewind(); } namespace { template 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 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 v) { - if (v.ref.empty()) +std::ostream& operator<<(std::ostream& o, const value_base& x) { + if (x.empty()) return o << ""; - switch (v.ref.type()) { - case STRING: return o << get(v.ref); - case SYMBOL: return o << get(v.ref); - case DECIMAL32: return o << get(v.ref); - case DECIMAL64: return o << get(v.ref); - case DECIMAL128: return o << get(v.ref); - case UUID: return o << get(v.ref); - case TIMESTAMP: return o << get(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(); + case SYMBOL: return o << d.extract(); + case DECIMAL32: return o << d.extract(); + case DECIMAL64: return o << d.extract(); + case DECIMAL128: return o << d.extract(); + case UUID: return o << d.extract(); + case TIMESTAMP: return o << d.extract(); 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