PROTON-1481/PROTON-1590: [C++ binding] Fix ABI problems with mixed C++03/C++11 
compilations
- Different versions of the proton::work class exist in different
  namespaces.
- When the library is compiled as C++11 both versions of the work APIs are 
compiled
- However when client programs are compiled only one version of the work APIs
  (either 03 or 11, but not both) are available.
- This is hacky but should work as none of these APIs are virtual so don't 
affect ABI layout


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

Branch: refs/heads/master
Commit: 80d76d64893a4fe3d540b5927c32952a3133f348
Parents: b5a5689
Author: Andrew Stitcher <astitc...@apache.org>
Authored: Thu Sep 14 23:16:54 2017 -0400
Committer: Andrew Stitcher <astitc...@apache.org>
Committed: Tue Sep 19 15:57:53 2017 -0400

----------------------------------------------------------------------
 .../bindings/cpp/include/proton/container.hpp   |  8 +++
 proton-c/bindings/cpp/include/proton/fwd.hpp    | 14 +++++-
 .../bindings/cpp/include/proton/work_queue.hpp  | 51 ++++++++++++++++----
 proton-c/bindings/cpp/src/container.cpp         |  5 +-
 proton-c/bindings/cpp/src/work_queue.cpp        | 20 +++++++-
 5 files changed, 84 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/80d76d64/proton-c/bindings/cpp/include/proton/container.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/container.hpp 
b/proton-c/bindings/cpp/include/proton/container.hpp
index 64caa15..6b02282 100644
--- a/proton-c/bindings/cpp/include/proton/container.hpp
+++ b/proton-c/bindings/cpp/include/proton/container.hpp
@@ -290,6 +290,14 @@ class PN_CPP_CLASS_EXTERN container {
     /// `std::function<void()>` type for the `fn` parameter.
     PN_CPP_EXTERN void schedule(duration dur, work fn);
 
+    /// @cond INTERNAL
+    /// This is a hack to ensure that the C++03 version is declared
+    /// only during the compilation of the library
+#if PN_CPP_HAS_STD_FUNCTION && defined(qpid_proton_cpp_EXPORTS)
+    PN_CPP_EXTERN void schedule(duration dur, v03::work fn);
+#endif
+    /// @endcond
+
   private:
     class impl;
     internal::pn_unique_ptr<impl> impl_;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/80d76d64/proton-c/bindings/cpp/include/proton/fwd.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/fwd.hpp 
b/proton-c/bindings/cpp/include/proton/fwd.hpp
index 679b974..c5d2ccf 100644
--- a/proton-c/bindings/cpp/include/proton/fwd.hpp
+++ b/proton-c/bindings/cpp/include/proton/fwd.hpp
@@ -25,6 +25,8 @@
 /// @file
 /// Forward declarations.
 
+#include "./internal/config.hpp"
+
 namespace proton {
 
 class annotation_key;
@@ -57,9 +59,19 @@ class tracker;
 class transport;
 class url;
 class void_function0;
-class work;
 class work_queue;
 
+namespace v03 { class work; }
+#if PN_CPP_HAS_STD_FUNCTION
+namespace v11 { class work; }
+#endif
+
+#if PN_CPP_HAS_STD_FUNCTION
+using v11::work;
+#else
+using v03::work;
+#endif
+
 namespace io {
 
 class connection_driver;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/80d76d64/proton-c/bindings/cpp/include/proton/work_queue.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/work_queue.hpp 
b/proton-c/bindings/cpp/include/proton/work_queue.hpp
index a4244c7..1729080 100644
--- a/proton-c/bindings/cpp/include/proton/work_queue.hpp
+++ b/proton-c/bindings/cpp/include/proton/work_queue.hpp
@@ -44,9 +44,27 @@ namespace proton {
 ///
 /// It can be created from a function that takes no parameters and
 /// returns no value.
+namespace v03 {
 class work {
   public:
+    /// **Experimental**
+    work(void_function0& f): item_(&f) {}
+
+    /// **Experimental**
+    void operator()() { (*item_)(); }
+
+    ~work() {}
+
+
+  private:
+    void_function0* item_;
+};
+}
+
 #if PN_CPP_HAS_STD_FUNCTION
+namespace v11 {
+class work {
+  public:
     /// **Unsettled API**
     work(void_function0& f): item_( [&f]() { f(); }) {}
 
@@ -57,23 +75,20 @@ class work {
 
     /// **Unsettled API**
     void operator()() { item_(); }
-#else
-    /// **Experimetnal**
-    work(void_function0& f): item_(&f) {}
 
-    /// **Experimetnal**
-    void operator()() { (*item_)(); }
-#endif
     ~work() {}
 
-
   private:
-#if PN_CPP_HAS_STD_FUNCTION
     std::function<void()> item_;
+};
+}
+#endif
+
+#if PN_CPP_HAS_STD_FUNCTION
+using v11::work;
 #else
-    void_function0* item_;
+using v03::work;
 #endif
-};
 
 /// **Unsettled API** - A context for thread-safe execution of work.
 ///
@@ -116,6 +131,14 @@ class PN_CPP_CLASS_EXTERN work_queue {
     /// reason.
     PN_CPP_EXTERN bool add(work fn);
 
+    /// @cond INTERNAL
+    /// This is a hack to ensure that the C++03 version is declared
+    /// only during the compilation of the library
+#if PN_CPP_HAS_STD_FUNCTION && defined(qpid_proton_cpp_EXPORTS)
+    PN_CPP_EXTERN bool add(v03::work fn);
+#endif
+    /// @endcond
+
     /// **Unsettled API** - Add work `fn` to the work queue after a
     /// duration.
     ///
@@ -126,6 +149,14 @@ class PN_CPP_CLASS_EXTERN work_queue {
     /// @copydetails add()
     PN_CPP_EXTERN void schedule(duration, work fn);
 
+    /// @cond INTERNAL
+    /// This is a hack to ensure that the C++03 version is declared
+    /// only during the compilation of the library
+#if PN_CPP_HAS_STD_FUNCTION && defined(qpid_proton_cpp_EXPORTS)
+    PN_CPP_EXTERN void schedule(duration, v03::work fn);
+#endif
+    /// @endcond
+
   private:
     PN_CPP_EXTERN static work_queue& get(pn_connection_t*);
     PN_CPP_EXTERN static work_queue& get(pn_session_t*);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/80d76d64/proton-c/bindings/cpp/src/container.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container.cpp 
b/proton-c/bindings/cpp/src/container.cpp
index c82e1a8..11218db 100644
--- a/proton-c/bindings/cpp/src/container.cpp
+++ b/proton-c/bindings/cpp/src/container.cpp
@@ -106,7 +106,10 @@ returned<receiver> container::open_receiver(
 
 std::string container::id() const { return impl_->id(); }
 
-void container::schedule(duration d, work f) { return impl_->schedule(d, f); }
+void container::schedule(duration d, v03::work f) { return impl_->schedule(d, 
f); }
+#if PN_CPP_HAS_STD_FUNCTION
+void container::schedule(duration d, v11::work f) { return impl_->schedule(d, 
f); }
+#endif
 
 void container::client_connection_options(const connection_options& c) { 
impl_->client_connection_options(c); }
 connection_options container::client_connection_options() const { return 
impl_->client_connection_options(); }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/80d76d64/proton-c/bindings/cpp/src/work_queue.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/work_queue.cpp 
b/proton-c/bindings/cpp/src/work_queue.cpp
index f8fc45c..c8da7fb 100644
--- a/proton-c/bindings/cpp/src/work_queue.cpp
+++ b/proton-c/bindings/cpp/src/work_queue.cpp
@@ -37,17 +37,33 @@ work_queue::~work_queue() {}
 
 work_queue& work_queue::operator=(impl* i) { impl_.reset(i); return *this; }
 
-bool work_queue::add(work f) {
+bool work_queue::add(v03::work f) {
     // If we have no actual work queue, then can't defer
     if (!impl_) return false;
     return impl_->add(f);
 }
 
-void work_queue::schedule(duration d, work f) {
+#if PN_CPP_HAS_STD_FUNCTION
+bool work_queue::add(v11::work f) {
+    // If we have no actual work queue, then can't defer
+    if (!impl_) return false;
+    return impl_->add(f);
+}
+#endif
+
+void work_queue::schedule(duration d, v03::work f) {
+    // If we have no actual work queue, then can't defer
+    if (!impl_) return;
+    return impl_->schedule(d, f);
+}
+
+#if PN_CPP_HAS_STD_FUNCTION
+void work_queue::schedule(duration d, v11::work f) {
     // If we have no actual work queue, then can't defer
     if (!impl_) return;
     return impl_->schedule(d, f);
 }
+#endif
 
 work_queue& work_queue::get(pn_connection_t* c) {
     return connection_context::get(c).work_queue_;


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

Reply via email to