$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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;
 }