|
Boost-Commit : |
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
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