Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81644 - in trunk: boost/thread libs/thread/example
From: vicente.botet_at_[hidden]
Date: 2012-12-01 06:02:18


Author: viboes
Date: 2012-12-01 06:02:16 EST (Sat, 01 Dec 2012)
New Revision: 81644
URL: http://svn.boost.org/trac/boost/changeset/81644

Log:
Thread: Added const_strict_synchronizer.
Added:
   trunk/libs/thread/example/synchronized_person.cpp (contents, props changed)
Text files modified:
   trunk/boost/thread/synchronized_value.hpp | 74 ++++++++++++++++++++++++++++++++-------
   trunk/libs/thread/example/synchronized_value.cpp | 2
   2 files changed, 61 insertions(+), 15 deletions(-)

Modified: trunk/boost/thread/synchronized_value.hpp
==============================================================================
--- trunk/boost/thread/synchronized_value.hpp (original)
+++ trunk/boost/thread/synchronized_value.hpp 2012-12-01 06:02:16 EST (Sat, 01 Dec 2012)
@@ -13,6 +13,7 @@
 
 #include <boost/thread/mutex.hpp>
 #include <boost/thread/lock_types.hpp>
+#include <boost/thread/lock_guard.hpp>
 
 #include <boost/config/abi_prefix.hpp>
 
@@ -31,64 +32,109 @@
     T value_;
     mutable lockable_type mtx_;
   public:
+ synchronized_value()
+ : value_()
+ {
+ }
+
+ synchronized_value(T other)
+ : value_(other)
+ {
+ }
+
     /**
      *
      */
- struct strict_synchronizer
+ struct const_strict_synchronizer
     {
- private:
+ protected:
       friend class synchronized_value;
 
       boost::unique_lock<lockable_type> lk_;
- T& value_;
+ T const& value_;
 
- explicit strict_synchronizer(synchronized_value& outer) :
+ explicit const_strict_synchronizer(synchronized_value const& outer) :
         lk_(outer.mtx_), value_(outer.value_)
       {
       }
     public:
- BOOST_THREAD_NO_COPYABLE( strict_synchronizer )
+ BOOST_THREAD_NO_COPYABLE( const_strict_synchronizer )
 
- strict_synchronizer(strict_synchronizer&& other)
+ const_strict_synchronizer(const_strict_synchronizer&& other)
       : lk_(boost::move(other.lk_)),value_(other.value_)
       {
       }
 
- ~strict_synchronizer()
+ ~const_strict_synchronizer()
       {
       }
 
- T* operator->()
+ const T* operator->() const
       {
         return &value_;
       }
 
- const T* operator->() const
+ const T& operator*() const
       {
- return &value_;
+ return value_;
       }
 
- T& operator*()
+ };
+
+ /**
+ *
+ */
+ struct strict_synchronizer : const_strict_synchronizer
+ {
+ protected:
+ friend class synchronized_value;
+
+ explicit strict_synchronizer(synchronized_value& outer) :
+ const_strict_synchronizer(const_cast<synchronized_value&>(outer))
       {
- return value_;
       }
+ public:
+ BOOST_THREAD_NO_COPYABLE( strict_synchronizer )
 
- const T& operator*() const
+ strict_synchronizer(strict_synchronizer&& other)
+ : const_strict_synchronizer(boost::move(other))
+ {
+ }
+
+ ~strict_synchronizer()
       {
- return value_;
+ }
+
+ T* operator->()
+ {
+ return const_cast<T*>(&this->value_);
+ }
+
+ T& operator*()
+ {
+ return const_cast<T&>(this->value_);
       }
 
     };
 
+
     strict_synchronizer operator->()
     {
       return BOOST_THREAD_MAKE_RV_REF(strict_synchronizer(*this));
     }
+ const_strict_synchronizer operator->() const
+ {
+ return BOOST_THREAD_MAKE_RV_REF(const_strict_synchronizer(*this));
+ }
 
     strict_synchronizer synchronize()
     {
       return BOOST_THREAD_MAKE_RV_REF(strict_synchronizer(*this));
     }
+ const_strict_synchronizer synchronize() const
+ {
+ return BOOST_THREAD_MAKE_RV_REF(const_strict_synchronizer(*this));
+ }
 
     /**
      *

Added: trunk/libs/thread/example/synchronized_person.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/example/synchronized_person.cpp 2012-12-01 06:02:16 EST (Sat, 01 Dec 2012)
@@ -0,0 +1,246 @@
+// (C) Copyright 2012 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//#define BOOST_THREAD_VERSION 4
+
+// There is yet a limitation when BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET is defined
+#define BOOST_THREAD_DONT_PROVIDE_FUTURE_INVALID_AFTER_GET
+
+#include <iostream>
+#include <string>
+#include <boost/thread/synchronized_value.hpp>
+
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES && ! defined BOOST_NO_CXX11_AUTO
+
+
+//class SafePerson {
+//public:
+// std::string GetName() const {
+// const_unique_access<std::string> name(nameGuard);
+// return *name;
+// }
+// void SetName(const std::string& newName) {
+// unique_access<std::string> name(nameGuard);
+// *name = newName;
+// }
+//private:
+// unique_access_guard<std::string> nameGuard;
+//};
+
+class SafePerson {
+public:
+ std::string GetName() const {
+ return *name;
+ }
+ void SetName(const std::string& newName) {
+ *name = newName;
+ }
+
+private:
+ boost::synchronized_value<std::string> name;
+};
+
+class Person {
+public:
+ std::string GetName() const {
+ return name;
+ }
+ void SetName(const std::string& newName) {
+ name = newName;
+ }
+private:
+ std::string name;
+};
+typedef boost::synchronized_value<Person> Person_ts;
+
+
+//class SafeMemberPerson {
+//public:
+// SafeMemberPerson(unsigned int age) :
+// memberGuard(age)
+// { }
+// std::string GetName() const {
+// const_unique_access<Member> member(memberGuard);
+// return member->name;
+// }
+// void SetName(const std::string& newName) {
+// unique_access<Member> member(memberGuard);
+// member->name = newName;
+// }
+//private:
+// struct Member
+// {
+// Member(unsigned int age) :
+// age(age)
+// { }
+// std::string name;
+// unsigned int age;
+// };
+// unique_access_guard<Member> memberGuard;
+//};
+
+class SafeMemberPerson {
+public:
+ SafeMemberPerson(unsigned int age) :
+ member(Member(age))
+ { }
+ std::string GetName() const {
+ return member->name;
+ }
+ void SetName(const std::string& newName) {
+ member->name = newName;
+ }
+private:
+ struct Member {
+ Member(unsigned int age) :
+ age(age)
+ { }
+ std::string name;
+ unsigned int age;
+ };
+ boost::synchronized_value<Member> member;
+};
+
+
+class Person2 {
+public:
+ Person2(unsigned int age) : age_(age)
+ {}
+ std::string GetName() const {
+ return name_;
+ }
+ void SetName(const std::string& newName) {
+ name_ = newName;
+ }
+ unsigned int GetAge() const {
+ return age_;
+ }
+
+private:
+ std::string name_;
+ unsigned int age_;
+};
+typedef boost::synchronized_value<Person2> Person2_ts;
+
+//===================
+
+//class HelperPerson {
+//public:
+// HelperPerson(unsigned int age) :
+// memberGuard(age)
+// { }
+// std::string GetName() const {
+// const_unique_access<Member> member(memberGuard);
+// Invariant(member);
+// return member->name;
+// }
+// void SetName(const std::string& newName) {
+// unique_access<Member> member(memberGuard);
+// Invariant(member);
+// member->name = newName;
+// }
+//private:
+// void Invariant(const_unique_access<Member>& member) const {
+// if (member->age < 0) throw std::runtime_error("Age cannot be negative");
+// }
+// struct Member {
+// Member(unsigned int age) :
+// age(age)
+// { }
+// std::string name;
+// unsigned int age;
+// };
+// unique_access_guard<Member> memberGuard;
+//};
+
+class HelperPerson {
+public:
+ HelperPerson(unsigned int age) :
+ member(age)
+ { }
+ std::string GetName() const {
+ auto&& memberSync = member.synchronize();
+ Invariant(memberSync);
+ return memberSync->name;
+ }
+ void SetName(const std::string& newName) {
+ auto&& memberSync = member.synchronize();
+ Invariant(memberSync);
+ memberSync->name = newName;
+ }
+private:
+ struct Member {
+ Member(unsigned int age) :
+ age(age)
+ { }
+ std::string name;
+ unsigned int age;
+ };
+ void Invariant(boost::synchronized_value<Member>::const_strict_synchronizer & mbr) const
+ {
+ if (mbr->age < 1) throw std::runtime_error("Age cannot be negative");
+ }
+ boost::synchronized_value<Member> member;
+};
+
+class Person3 {
+public:
+ Person3(unsigned int age) :
+ age_(age)
+ { }
+ std::string GetName() const {
+ Invariant();
+ return name_;
+ }
+ void SetName(const std::string& newName) {
+ Invariant();
+ name_ = newName;
+ }
+private:
+ std::string name_;
+ unsigned int age_;
+ void Invariant() const {
+ if (age_ < 1) throw std::runtime_error("Age cannot be negative");
+ }
+};
+
+typedef boost::synchronized_value<Person3> Person3_ts;
+
+int main()
+{
+ {
+ SafePerson p;
+ p.SetName("Vicente");
+ }
+ {
+ Person_ts p;
+ p->SetName("Vicente");
+ }
+ {
+ SafeMemberPerson p(1);
+ p.SetName("Vicente");
+ }
+ {
+ Person2_ts p(1);
+ p->SetName("Vicente");
+ }
+ {
+ HelperPerson p(1);
+ p.SetName("Vicente");
+ }
+ {
+ Person3_ts p(1);
+ p->SetName("Vicente");
+ }
+ return 0;
+}
+
+#else
+
+int main()
+{
+ return 0;
+}
+#endif

Modified: trunk/libs/thread/example/synchronized_value.cpp
==============================================================================
--- trunk/libs/thread/example/synchronized_value.cpp (original)
+++ trunk/libs/thread/example/synchronized_value.cpp 2012-12-01 06:02:16 EST (Sat, 01 Dec 2012)
@@ -29,7 +29,7 @@
   std::cout<<"v="<<*v<<std::endl;
 }
 
-void g(const boost::synchronized_value<int>::strict_synchronizer &v) {
+void g(const boost::synchronized_value<int>::const_strict_synchronizer &v) {
   std::cout<<"v="<<*v<<std::endl;
 }
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk