From ca37d07184e4ec5fe1bbd125837af2fbc2979b08 Mon Sep 17 00:00:00 2001 From: "Vicente J. Botet Escriba" Date: Fri, 22 Feb 2013 17:42:44 +0000 Subject: [PATCH] Thread: Added value semantics to synchronized value [SVN r83086] --- example/synchronized_value.cpp | 78 +++++++++- include/boost/thread/synchronized_value.hpp | 155 +++++++++++++++++++- 2 files changed, 224 insertions(+), 9 deletions(-) diff --git a/example/synchronized_value.cpp b/example/synchronized_value.cpp index 04c7b735..2b0e6368 100644 --- a/example/synchronized_value.cpp +++ b/example/synchronized_value.cpp @@ -10,15 +10,15 @@ #include #include -void addTrailingSlashIfMissing(boost::synchronized_value & path) -{ - boost::strict_lock_ptr u=path.synchronize(); - - if(u->empty() || (*u->rbegin()!='/')) + void addTrailingSlashIfMissing(boost::synchronized_value & path) { - *u+='/'; + boost::strict_lock_ptr u=path.synchronize(); + + if(u->empty() || (*u->rbegin()!='/')) + { + *u+='/'; + } } -} void f(const boost::synchronized_value &v) { std::cout<<"v="<<*v< s2; + s2=s1; + std::cout<<"s1="<< s1 << std::endl; + std::cout<<"s2="<< s2 << std::endl; + } + { + boost::synchronized_value s1("a"); + boost::synchronized_value s2("b"); + std::cout<<"s1="<< s1 << std::endl; + std::cout<<"s2="<< s2 << std::endl; + swap(s1,s2); + std::cout<<"s1="<< s1 << std::endl; + std::cout<<"s2="<< s2 << std::endl; + } +#if ! defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) + { + boost::synchronized_value sts("a"); + std::string s(sts); + std::cout<<"ssts="<< s << std::endl; + } +#endif + { + boost::synchronized_value s1(1); + boost::synchronized_value s2(1); + BOOST_ASSERT(s1==s2); + BOOST_ASSERT(s1<=s2); + BOOST_ASSERT(s1>=s2); + BOOST_ASSERT(s1==1); + BOOST_ASSERT(s1<=1); + BOOST_ASSERT(s1>=1); + } + { + boost::synchronized_value s1(1); + boost::synchronized_value s2(2); + BOOST_ASSERT(s1!=s2); + BOOST_ASSERT(s1!=2); + BOOST_ASSERT(2!=s1); + } + { + boost::synchronized_value s1(1); + boost::synchronized_value s2(2); + BOOST_ASSERT(s1s1); + BOOST_ASSERT(s2>=s1); + BOOST_ASSERT(s1<2); + BOOST_ASSERT(s1<=2); + BOOST_ASSERT(s2>1); + BOOST_ASSERT(s2>=1); + } + return 1; } diff --git a/include/boost/thread/synchronized_value.hpp b/include/boost/thread/synchronized_value.hpp index 6c4cb6ba..563ef7f2 100644 --- a/include/boost/thread/synchronized_value.hpp +++ b/include/boost/thread/synchronized_value.hpp @@ -225,6 +225,7 @@ namespace boost T value_; mutable lockable_type mtx_; public: + // construction/destruction /** * Default constructor. * @@ -277,6 +278,7 @@ namespace boost value_= boost::move(other.value); } + // mutation /** * Assignment operator. * @@ -314,6 +316,7 @@ namespace boost return *this; } + //observers /** * Explicit conversion to value type. * @@ -339,7 +342,6 @@ namespace boost return get(); } #endif - /** * Swap * @@ -497,8 +499,99 @@ namespace boost return BOOST_THREAD_MAKE_RV_REF(const_deref_value(*this)); } + template + void save(OStream& os) const + { + strict_lock lk(mtx_); + os << value_; + } + template + void load(IStream& is) const + { + strict_lock lk(mtx_); + is >> value_; + } + + bool operator==(synchronized_value const& rhs) const + { + unique_lock lk1(mtx_, defer_lock); + unique_lock lk2(rhs.mtx_, defer_lock); + lock(lk1,lk2); + + return value_ == rhs.value_; + } + bool operator<(synchronized_value const& rhs) const + { + unique_lock lk1(mtx_, defer_lock); + unique_lock lk2(rhs.mtx_, defer_lock); + lock(lk1,lk2); + + return value_ < rhs.value_; + } + bool operator>(synchronized_value const& rhs) const + { + unique_lock lk1(mtx_, defer_lock); + unique_lock lk2(rhs.mtx_, defer_lock); + lock(lk1,lk2); + + return value_ > rhs.value_; + } + bool operator<=(synchronized_value const& rhs) const + { + unique_lock lk1(mtx_, defer_lock); + unique_lock lk2(rhs.mtx_, defer_lock); + lock(lk1,lk2); + + return value_ <= rhs.value_; + } + bool operator>=(synchronized_value const& rhs) const + { + unique_lock lk1(mtx_, defer_lock); + unique_lock lk2(rhs.mtx_, defer_lock); + lock(lk1,lk2); + + return value_ >= rhs.value_; + } + bool operator==(value_type const& rhs) const + { + unique_lock lk1(mtx_); + + return value_ == rhs; + } + bool operator!=(value_type const& rhs) const + { + unique_lock lk1(mtx_); + + return value_ != rhs; + } + bool operator<(value_type const& rhs) const + { + unique_lock lk1(mtx_); + + return value_ < rhs; + } + bool operator<=(value_type const& rhs) const + { + unique_lock lk1(mtx_); + + return value_ <= rhs; + } + bool operator>(value_type const& rhs) const + { + unique_lock lk1(mtx_); + + return value_ > rhs; + } + bool operator>=(value_type const& rhs) const + { + unique_lock lk1(mtx_); + + return value_ >= rhs; + } + }; + // Specialized algorithms /** * */ @@ -508,6 +601,66 @@ namespace boost lhs.swap(rhs); } + //Hash support + + template struct hash; + template + struct hash >; + + // Comparison with T + template + bool operator!=(synchronized_value const&lhs, synchronized_value const& rhs) + { + return ! (lhs==rhs); + } + + template + bool operator==(T const& lhs, synchronized_value const&rhs) + { + return rhs==lhs; + } + template + bool operator!=(T const& lhs, synchronized_value const&rhs) + { + return rhs!=lhs; + } + template + bool operator<(T const& lhs, synchronized_value const&rhs) + { + return rhs>=lhs; + } + template + bool operator<=(T const& lhs, synchronized_value const&rhs) + { + return rhs>lhs; + } + template + bool operator>(T const& lhs, synchronized_value const&rhs) + { + return rhs<=lhs; + } + template + bool operator>=(T const& lhs, synchronized_value const&rhs) + { + return rhs + inline OStream& operator<<(OStream& os, synchronized_value const& rhs) + { + rhs.save(os); + return os; + } + template + inline IStream& operator>>(IStream& is, synchronized_value const& rhs) + { + rhs.load(is); + return is; + } + } #include