From 1f4afb9c6cf9d5dbcc04af5d533060034601a5ee Mon Sep 17 00:00:00 2001 From: Aleksandar Fabijanic Date: Sun, 31 Mar 2013 16:28:53 -0500 Subject: [PATCH] improved SOO swap, fixed Darwin-clang build config --- CHANGELOG | 2 +- Foundation/include/Poco/Any.h | 35 ++++++++++++++++++--------- Foundation/include/Poco/Dynamic/Var.h | 14 ++++++++--- build/config/Darwin-clang | 2 +- 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b6d6750e1..c59051200 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -33,7 +33,7 @@ Release 1.5.2 (2013-03-??) - fixed GH #131: no timezone global var on OpenBSD - fixed GH #102: Some subprojects don't have x64 solutions for VS 2010 - added GH #75: Poco::Uri addQueryParameter method -- Poco::Environment::osDisplayName() now recognized Windows 8/Server 2012 +- Poco::Environment::osDisplayName() now recognizes Windows 8/Server 2012 - fixed GH #140: Poco::Runnable threading cleanup issue - simplified default TCP/HTTPServer construction - fixed GH #141: Application::run() documentation/implementation discrepancy diff --git a/Foundation/include/Poco/Any.h b/Foundation/include/Poco/Any.h index fb212a8dc..05acb5f4a 100644 --- a/Foundation/include/Poco/Any.h +++ b/Foundation/include/Poco/Any.h @@ -106,9 +106,9 @@ public: return pHolder; } -// MSVC71 doesn't extend friendship to nested class (Any::Holder) -#if !defined(POCO_MSVC_VERSION) || (defined(POCO_MSVC_VERSION) && (POCO_MSVC_VERSION > 71)) - private: +// MSVC71,80 won't extend friendship to nested class (Any::Holder) +#if !defined(POCO_MSVC_VERSION) || (defined(POCO_MSVC_VERSION) && (POCO_MSVC_VERSION > 80)) +// private: #endif PlaceholderT* pHolder; @@ -165,7 +165,7 @@ public: if(!empty()) { if(_valueHolder.isLocal()) - content()->~ValueHolder(); + destruct(); else delete content(); } @@ -174,9 +174,9 @@ public: Any& swap(Any& other) /// Swaps the content of the two Anys. /// - /// When small object optimizaton is enabled, - /// swap is only exception-safe when both (*this and - /// other) objects are allocated on the heap. + /// When small object optimizaton is enabled, swap only + /// has no-throw guarantee when both (*this and other) + /// objects are allocated on the heap. { if (this == &other) return *this; @@ -187,16 +187,24 @@ public: else { Any tmp(*this); - if (_valueHolder.isLocal()) this->~Any(); - construct(other); - other = tmp; + try + { + if (_valueHolder.isLocal()) destruct(); + construct(other); + other = tmp; + } + catch (...) + { + construct(tmp); + throw; + } } return *this; } template - Any & operator = (const ValueType& rhs) + Any& operator = (const ValueType& rhs) /// Assignment operator for all types != Any. /// /// Example: @@ -309,6 +317,11 @@ private: _valueHolder.erase(); } + void destruct() + { + content()->~ValueHolder(); + } + Placeholder _valueHolder; diff --git a/Foundation/include/Poco/Dynamic/Var.h b/Foundation/include/Poco/Dynamic/Var.h index 1b7da04a1..d4957cbb9 100644 --- a/Foundation/include/Poco/Dynamic/Var.h +++ b/Foundation/include/Poco/Dynamic/Var.h @@ -668,9 +668,17 @@ inline void Var::swap(Var& other) else { Var tmp(*this); - if (_placeholder.isLocal()) destruct(); - construct(other); - other = tmp; + try + { + if (_placeholder.isLocal()) destruct(); + construct(other); + other = tmp; + } + catch (...) + { + construct(tmp); + throw; + } } #endif diff --git a/build/config/Darwin-clang b/build/config/Darwin-clang index 30f491463..6bdd172e6 100644 --- a/build/config/Darwin-clang +++ b/build/config/Darwin-clang @@ -33,7 +33,7 @@ LINK = $(CXX) -bind_at_load LIB = libtool -static -o RANLIB = ranlib SHLIB = $(CXX) -dynamiclib -o $@ -DYLIB = $(CXX) -dynamic -bundle $(RORELOCS) suppress -Wl,-bind_at_load -o $@ +DYLIB = $(CXX) -dynamic -bundle $(RORELOCS) -Wl,-bind_at_load -o $@ SHLIBLN = $(POCO_BASE)/build/script/shlibln STRIP = DEP = $(POCO_BASE)/build/script/makedepend.clang