qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From acon...@apache.org
Subject [1/2] qpid-proton git commit: PROTON-865: Replace multiple-inheritance with template base-class chaining.
Date Thu, 03 Sep 2015 21:26:42 GMT
Repository: qpid-proton
Updated Branches:
  refs/heads/cjansen-cpp-client 05628c064 -> 76fac4bd4


PROTON-865: Replace multiple-inheritance with template base-class chaining.

Some compilers (e.g. MSVC++) don't do the empty-base-class optimization with
multiple inheritance, so multiple inheritance causes facade classes to be
non-empty, which won't work.


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

Branch: refs/heads/cjansen-cpp-client
Commit: 2fcbc25fd8539911d039925981b0273cccbe7db2
Parents: 05628c0
Author: Alan Conway <aconway@redhat.com>
Authored: Thu Sep 3 16:05:02 2015 -0400
Committer: Alan Conway <aconway@redhat.com>
Committed: Thu Sep 3 16:05:02 2015 -0400

----------------------------------------------------------------------
 .../bindings/cpp/include/proton/connection.hpp  |  2 +-
 .../bindings/cpp/include/proton/counted.hpp     | 15 +++---
 .../bindings/cpp/include/proton/counted_ptr.hpp | 17 ++++--
 proton-c/bindings/cpp/include/proton/data.hpp   |  2 +-
 proton-c/bindings/cpp/include/proton/facade.hpp | 57 +++++++++-----------
 proton-c/bindings/cpp/include/proton/link.hpp   |  2 +-
 .../bindings/cpp/include/proton/receiver.hpp    |  2 +-
 proton-c/bindings/cpp/include/proton/sender.hpp |  2 +-
 .../bindings/cpp/include/proton/session.hpp     |  2 +-
 proton-c/bindings/cpp/src/container_impl.hpp    |  5 --
 proton-c/bindings/cpp/src/facade.cpp            |  8 +--
 11 files changed, 59 insertions(+), 55 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2fcbc25f/proton-c/bindings/cpp/include/proton/connection.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/connection.hpp b/proton-c/bindings/cpp/include/proton/connection.hpp
index bd1d9f5..08b6ad9 100644
--- a/proton-c/bindings/cpp/include/proton/connection.hpp
+++ b/proton-c/bindings/cpp/include/proton/connection.hpp
@@ -35,7 +35,7 @@ class handler;
 class transport;
 
 /** connection to a remote AMQP peer. */
-class connection : public counted_facade<pn_connection_t, connection>, public endpoint
+class connection : public counted_facade<pn_connection_t, connection, endpoint>
 {
   public:
     ///@name getters @{

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2fcbc25f/proton-c/bindings/cpp/include/proton/counted.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/counted.hpp b/proton-c/bindings/cpp/include/proton/counted.hpp
index ea5707b..2195d93 100644
--- a/proton-c/bindings/cpp/include/proton/counted.hpp
+++ b/proton-c/bindings/cpp/include/proton/counted.hpp
@@ -30,16 +30,19 @@ class counted {
   private:
     counted(const counted&);
     counted& operator=(const counted&);
-    int refcount_;
+    mutable int refcount_;
 
-    friend void incref(const counted* p);
-    friend void decref(const counted* p);
+    // TODO aconway 2015-08-27: atomic operations.
+    void incref() const { ++refcount_; }
+    void decref() const { if (--refcount_ == 0) delete this; }
+
+  friend void incref(const counted*);
+  friend void decref(const counted*);
   template <class T> friend class counted_ptr;
 };
 
-// TODO aconway 2015-08-27: atomic operations.
-inline void incref(const counted* p) { if (p) const_cast<counted*>(p)->refcount_
+= 1; }
-inline void decref(const counted* p) { if (p && --const_cast<counted*>(p)->refcount_
== 0) delete p; }
+inline void incref(const counted* p) { if (p) p->incref(); }
+inline void decref(const counted* p) { if (p) p->decref(); }
 
 }
 #endif // COUNTED_HPP

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2fcbc25f/proton-c/bindings/cpp/include/proton/counted_ptr.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/counted_ptr.hpp b/proton-c/bindings/cpp/include/proton/counted_ptr.hpp
index 1332c79..becb0b7 100644
--- a/proton-c/bindings/cpp/include/proton/counted_ptr.hpp
+++ b/proton-c/bindings/cpp/include/proton/counted_ptr.hpp
@@ -31,6 +31,15 @@
 
 namespace proton {
 
+///@cond INTERNAL
+
+// Default refcounting uses pn_incref, pn_decref. Other types must define
+// their own incref/decref overloads.
+void incref(const void*);
+void decref(const void*);
+
+///@endcond
+
 /**
  * Smart pointer for reference counted objects derived from `proton::counted`
  * or `proton::pn_counted`
@@ -39,7 +48,9 @@ template <class T> class counted_ptr : public proton::comparable<counted_ptr<T>
   public:
     typedef T element_type;
 
-    explicit counted_ptr(T *p = 0, bool add_ref = true) : ptr_(p) { if (p && add_ref)
incref(ptr_); }
+    explicit counted_ptr(T *p = 0, bool add_ref = true) : ptr_(p) {
+        if (add_ref) incref(ptr_);
+    }
 
     counted_ptr(const counted_ptr<T>& p) : ptr_(p.ptr_) { incref(ptr_); }
 
@@ -79,8 +90,8 @@ template <class T> class counted_ptr : public proton::comparable<counted_ptr<T>
 };
 
 #if PN_USE_BOOST
-template <class T> inline void intrusive_ptr_add_ref(const T* p) { incref(p); }
-template <class T> inline void intrusive_ptr_release(const T* p) { decref(p); }
+template <class T> inline void intrusive_ptr_add_ref(const T* p) { if (p) p->incref();
}
+template <class T> inline void intrusive_ptr_release(const T* p) { if (p) p->decref();
}
 #endif
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2fcbc25f/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 0448f89..019d3bb 100644
--- a/proton-c/bindings/cpp/include/proton/data.hpp
+++ b/proton-c/bindings/cpp/include/proton/data.hpp
@@ -36,7 +36,7 @@ class data;
  * Holds a sequence of AMQP values, allows inserting and extracting via encoder() and decoder().
  * Cannot be directly instantiated, use `data_value`
  */
-class data : public facade<pn_data_t, data>, public comparable<data> {
+class data : public facade<pn_data_t, data, comparable<data> > {
   public:
     PN_CPP_EXTERN static PN_UNIQUE_PTR<data> create();
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2fcbc25f/proton-c/bindings/cpp/include/proton/facade.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/facade.hpp b/proton-c/bindings/cpp/include/proton/facade.hpp
index d9696f6..c020e6a 100644
--- a/proton-c/bindings/cpp/include/proton/facade.hpp
+++ b/proton-c/bindings/cpp/include/proton/facade.hpp
@@ -62,12 +62,16 @@
 
 namespace proton {
 
+///@cond INTERNAL
+struct empty_base {};
+///@endcond
+
 /**
  * Base class for C++ facades of proton C struct types.
  *
  * @see \ref c-and-cpp
  */
-template <class P, class T> class facade {
+template <class P, class T, class Base=empty_base> class facade : public Base {
   public:
     /// The underlying C struct type.
     typedef P pn_type;
@@ -103,16 +107,25 @@ template <class T> typename T::pn_type* pn_cast(const counted_ptr<T>&
p) {
     return reinterpret_cast<typename T::pn_type*>(const_cast<T*>(p.get()));
 }
 
+/**
+ * Some proton C structs are reference counted. The C++ facade for such structs can be
+ * converted to any of the following smart pointers: std::shared_ptr, std::unique_ptr,
+ * boost::shared_ptr, boost::intrusive_ptr.
+ *
+ * unique_ptr takes ownership of a single *reference* not the underlying struct,
+ * so it is safe to have multiple unique_ptr to the same facade object or to mix
+ * unique_ptr with shared_ptr etc.
+ *
+ * Deleting a counted_facade subclass actually calls `pn_decref` to remove a reference.
+ */
+template <class P, class T, class Base=empty_base>
+class counted_facade : public facade<P, T, Base>
+{
+  public:
 
-///@cond INTERNAL
-class pn_counted {};
-void incref(const pn_counted*);
-void decref(const pn_counted*);
-///@endcond
+    /// Deleting a counted_facade actually calls `pn_decref` to remove a reference.
+    void operator delete(void* p) { decref(p); }
 
-/// Reference counted proton types are convertible to smart pointer types.
-template <class T> class ptr_convertible {
- public:
     operator counted_ptr<T>() { return counted_ptr<T>(static_cast<T*>(this));
}
     operator counted_ptr<const T>() const { return counted_ptr<const T>(static_cast<const
T*>(this)); }
 #if PN_USE_CPP11
@@ -134,32 +147,14 @@ template <class T> class ptr_convertible {
      * You must delete the returned pointer to release the reference.
      * It is safer to convert to one of the supported smart pointer types.
      */
-    T* new_ptr() { proton::incref(static_cast<T*>(this)); return static_cast<T*>(this);
}
-    const T* new_ptr() const { proton::incref(static_cast<T*>(this)); return static_cast<const
T*>(this); }
-};
-
-/**
- * Some proton C structs are reference counted. The C++ facade for such structs can be
- * converted to any of the following smart pointers: std::shared_ptr, std::unique_ptr,
- * boost::shared_ptr, boost::intrusive_ptr.
- *
- * unique_ptr takes ownership of a single *reference* not the underlying struct,
- * so it is safe to have multiple unique_ptr to the same facade object or to mix
- * unique_ptr with shared_ptr etc.
- *
- * Deleting a counted_facade subclass actually calls `pn_decref` to remove a reference.
- */
-template <class P, class T> class counted_facade :
-        public facade<P, T>, public pn_counted, public ptr_convertible<T>
-{
-  public:
-
-    /// Deleting a counted_facade actually calls `pn_decref` to remove a reference.
-    void operator delete(void* p) { decref(reinterpret_cast<pn_counted*>(p)); }
+    T* new_ptr() { incref(this); return static_cast<T*>(this); }
+    const T* new_ptr() const { incref(this); return static_cast<const T*>(this); }
 
   private:
     counted_facade(const counted_facade&);
     counted_facade& operator=(const counted_facade&);
+
+  template <class U> friend class counted_ptr;
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2fcbc25f/proton-c/bindings/cpp/include/proton/link.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/link.hpp b/proton-c/bindings/cpp/include/proton/link.hpp
index 3ef84c7..88b5368 100644
--- a/proton-c/bindings/cpp/include/proton/link.hpp
+++ b/proton-c/bindings/cpp/include/proton/link.hpp
@@ -36,7 +36,7 @@ class sender;
 class receiver;
 
 /** Messages are transferred across a link. Base class for sender, receiver. */
-class link : public counted_facade<pn_link_t, link>, public endpoint
+class link : public counted_facade<pn_link_t, link, endpoint>
 {
   public:
     /** Locally open the link, not complete till messaging_handler::on_link_opened or

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2fcbc25f/proton-c/bindings/cpp/include/proton/receiver.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/receiver.hpp b/proton-c/bindings/cpp/include/proton/receiver.hpp
index 4d1d9ab..16c9425 100644
--- a/proton-c/bindings/cpp/include/proton/receiver.hpp
+++ b/proton-c/bindings/cpp/include/proton/receiver.hpp
@@ -32,7 +32,7 @@ struct pn_connection_t;
 namespace proton {
 
 /// A receiving link
-class receiver : public link, public ptr_convertible<receiver>
+class receiver : public counted_facade<pn_link_t, receiver, link>
 {
   public:
     /// Add credit to the link

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2fcbc25f/proton-c/bindings/cpp/include/proton/sender.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/sender.hpp b/proton-c/bindings/cpp/include/proton/sender.hpp
index 03a52c9..3106a7b 100644
--- a/proton-c/bindings/cpp/include/proton/sender.hpp
+++ b/proton-c/bindings/cpp/include/proton/sender.hpp
@@ -34,7 +34,7 @@ struct pn_connection_t;
 namespace proton {
 
 /// A sending link
-class sender : public link, public ptr_convertible<sender>
+class sender : public counted_facade<pn_link_t, sender, link>
 {
   public:
     /// Send a message on the link.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2fcbc25f/proton-c/bindings/cpp/include/proton/session.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/session.hpp b/proton-c/bindings/cpp/include/proton/session.hpp
index bf4c96d..886de46 100644
--- a/proton-c/bindings/cpp/include/proton/session.hpp
+++ b/proton-c/bindings/cpp/include/proton/session.hpp
@@ -38,7 +38,7 @@ class handler;
 class transport;
 
 /** A session is a collection of links */
-class session : public counted_facade<pn_session_t, session>, public endpoint
+class session : public counted_facade<pn_session_t, session, endpoint>
 {
   public:
     /** Initiate local open, not complete till messaging_handler::on_session_opened()

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2fcbc25f/proton-c/bindings/cpp/src/container_impl.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container_impl.hpp b/proton-c/bindings/cpp/src/container_impl.hpp
index 6caf439..f02e36e 100644
--- a/proton-c/bindings/cpp/src/container_impl.hpp
+++ b/proton-c/bindings/cpp/src/container_impl.hpp
@@ -74,9 +74,4 @@ class container_impl
 
 }
 
-// Allow counted_ptr to a pn_handler_t
-inline void incref(const pn_handler_t* h) { pn_incref(const_cast<pn_handler_t*>(h));
}
-inline void decref(const pn_handler_t* h) { pn_decref(const_cast<pn_handler_t*>(h));
}
-
-
 #endif  /*!PROTON_CPP_CONTAINERIMPL_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2fcbc25f/proton-c/bindings/cpp/src/facade.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/facade.cpp b/proton-c/bindings/cpp/src/facade.cpp
index e92af22..c269ce8 100644
--- a/proton-c/bindings/cpp/src/facade.cpp
+++ b/proton-c/bindings/cpp/src/facade.cpp
@@ -37,12 +37,12 @@
 
 namespace proton {
 
-void incref(const pn_counted* p) {
-    if (p) pn_incref(const_cast<pn_counted*>(p)); 
+void incref(const void* p) {
+    if (p) ::pn_incref(const_cast<void*>(p)); 
 }
 
-void decref(const pn_counted* p) {
-    if (p) pn_decref(const_cast<pn_counted*>(p));
+void decref(const void* p) {
+    if (p) ::pn_decref(const_cast<void*>(p));
 }
 
 #if PN_USE_CPP11


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


Mime
View raw message