$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r81072 - in trunk: boost/thread libs/thread/example
From: vicente.botet_at_[hidden]
Date: 2012-10-28 13:43:41
Author: viboes
Date: 2012-10-28 13:43:40 EDT (Sun, 28 Oct 2012)
New Revision: 81072
URL: http://svn.boost.org/trac/boost/changeset/81072
Log:
Thread: added first version of synchronized_value
Added:
   trunk/boost/thread/synchronized_value.hpp   (contents, props changed)
   trunk/libs/thread/example/synchronized_value.cpp   (contents, props changed)
Added: trunk/boost/thread/synchronized_value.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/thread/synchronized_value.hpp	2012-10-28 13:43:40 EDT (Sun, 28 Oct 2012)
@@ -0,0 +1,221 @@
+// (C) Copyright 2010 Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk
+// (C) Copyright 2012 Vicente J. Botet Escriba
+// 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)
+
+
+#ifndef BOOST_THREAD_SYNCHRONIZED_VALUE_HPP
+#define BOOST_THREAD_SYNCHRONIZED_VALUE_HPP
+
+#include <boost/thread/detail/config.hpp>
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/lock_types.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+  /**
+   *
+   */
+  template <typename T, typename Lockable = mutex>
+  class synchronized_value
+  {
+  public:
+    typedef T value_type;
+    typedef Lockable lockable_type;
+  private:
+    T value_;
+    mutable lockable_type mtx_;
+  public:
+    /**
+     *
+     */
+    struct strict_synchronizer
+    {
+    private:
+      friend class synchronized_value;
+
+      boost::unique_lock<lockable_type> lk_;
+      T& value_;
+
+      explicit strict_synchronizer(synchronized_value& outer) :
+        lk_(outer.mtx_), value_(outer.value_)
+      {
+      }
+    public:
+      BOOST_THREAD_NO_COPYABLE( strict_synchronizer )
+
+      strict_synchronizer(strict_synchronizer&& other)
+      : lk_(boost::move(other.lk_)),value_(other.value_)
+      {
+      }
+
+      ~strict_synchronizer()
+      {
+      }
+
+      T* operator->()
+      {
+        return &value_;
+      }
+
+      const T* operator->() const
+      {
+        return &value_;
+      }
+
+      T& operator*()
+      {
+        return value_;
+      }
+
+      const T& operator*() const
+      {
+        return value_;
+      }
+
+    };
+
+    strict_synchronizer operator->()
+    {
+      return BOOST_THREAD_MAKE_RV_REF(strict_synchronizer(*this));
+    }
+
+    strict_synchronizer synchronize()
+    {
+      return BOOST_THREAD_MAKE_RV_REF(strict_synchronizer(*this));
+    }
+
+    /**
+     *
+     */
+    struct unique_synchronizer : unique_lock<lockable_type>
+    {
+    private:
+      friend class synchronized_value;
+      typedef unique_lock<lockable_type> base_type;
+
+      T& value_;
+
+      explicit unique_synchronizer(synchronized_value& outer)
+      : base_type(outer.mtx_), value_(outer.value_)
+      {
+      }
+    public:
+      BOOST_THREAD_NO_COPYABLE(unique_synchronizer)
+
+      unique_synchronizer(unique_synchronizer&& other):
+      base_type(static_cast<base_type&&>(other)),value_(other.value_)
+      {
+      }
+
+      ~unique_synchronizer()
+      {
+      }
+
+      T* operator->()
+      {
+        if (this->owns_lock())
+        return &value_;
+        else
+        return 0;
+      }
+
+      const T* operator->() const
+      {
+        if (this->owns_lock())
+        return &value_;
+        else
+        return 0;
+      }
+
+      T& operator*()
+      {
+        BOOST_ASSERT (this->owns_lock());
+        return value_;
+      }
+
+      const T& operator*() const
+      {
+        BOOST_ASSERT (this->owns_lock());
+        return value_;
+      }
+
+    };
+
+  private:
+    class deref_value
+    {
+    private:
+      friend class synchronized_value;
+
+      boost::unique_lock<lockable_type> lk_;
+      T& value_;
+
+      explicit deref_value(synchronized_value& outer):
+      lk_(outer.mtx_),value_(outer.value_)
+      {}
+
+    public:
+      BOOST_THREAD_NO_COPYABLE(deref_value)
+      deref_value(deref_value&& other):
+      lk_(boost::move(other.lk_)),value_(other.value_)
+      {}
+      operator T()
+      {
+        return value_;
+      }
+
+      deref_value& operator=(T const& newVal)
+      {
+        value_=newVal;
+        return *this;
+      }
+    };
+    class const_deref_value
+    {
+    private:
+      friend class synchronized_value;
+
+      boost::unique_lock<lockable_type> lk_;
+      const T& value_;
+
+      explicit const_deref_value(synchronized_value const& outer):
+      lk_(outer.mtx_), value_(outer.value_)
+      {}
+
+    public:
+      BOOST_THREAD_NO_COPYABLE(const_deref_value)
+      const_deref_value(const_deref_value&& other):
+      lk_(boost::move(other.lk_)), value_(other.value_)
+      {}
+
+      operator T()
+      {
+        return value_;
+      }
+    };
+
+  public:
+    deref_value operator*()
+    {
+      return BOOST_THREAD_MAKE_RV_REF(deref_value(*this));
+    }
+
+    const_deref_value operator*() const
+    {
+      return BOOST_THREAD_MAKE_RV_REF(const_deref_value(*this));
+    }
+
+  };
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
+#endif // header
Added: trunk/libs/thread/example/synchronized_value.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/example/synchronized_value.cpp	2012-10-28 13:43:40 EDT (Sun, 28 Oct 2012)
@@ -0,0 +1,95 @@
+// (C) Copyright 2010 Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk
+// (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
+
+void addTrailingSlashIfMissing(boost::synchronized_value<std::string> & path)
+{
+  boost::synchronized_value<std::string>::strict_synchronizer u=path.synchronize();
+
+  if(u->empty() || (*u->rbegin()!='/'))
+  {
+    *u+='/';
+  }
+}
+
+void f(const boost::synchronized_value<int> &v) {
+  std::cout<<"v="<<*v<<std::endl;
+}
+
+void g(const boost::synchronized_value<int>::strict_synchronizer &v) {
+  std::cout<<"v="<<*v<<std::endl;
+}
+
+bool checkIfMissingTrailingSlash(boost::synchronized_value<std::string> & path)
+{
+  boost::synchronized_value<std::string>::strict_synchronizer u=path.synchronize();
+
+  return (u->empty() || (*u->rbegin()!='/'));
+}
+
+int main()
+{
+  {
+    boost::synchronized_value<int> v1;
+    *v1=42;
+    std::cout<<"v1="<<*v1<<std::endl;
+    f(v1);
+    int i=*v1;
+    std::cout<<"i="<<i<<std::endl;
+
+    {
+      boost::synchronized_value<int>::strict_synchronizer u=v1.synchronize();
+
+      *u+=43;
+      std::cout<<"v1="<<*u<<std::endl;
+      g(u);
+    }
+  }
+  {
+    boost::synchronized_value<std::string> s;
+    addTrailingSlashIfMissing(s);
+    std::cout<<"s="<<std::string(*s)<<std::endl;
+  }
+  {
+    boost::synchronized_value<std::string> s;
+#if 0
+    s->append("foo/");
+#else
+    s.synchronize()->append("foo");
+#endif
+    addTrailingSlashIfMissing(s);
+    std::cout<<"s="<<std::string(*s)<<std::endl;
+  }
+  {
+    boost::synchronized_value<std::string> s;
+#if 0
+    s->append("foo");
+#else
+    s.synchronize()->append("foo");
+#endif
+    addTrailingSlashIfMissing(s);
+    std::cout<<"s="<<std::string(*s)<<std::endl;
+  }
+  return 0;
+}
+
+#else
+
+int main()
+{
+  return 0;
+}
+#endif