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