23ff6e0120
[SVN r83396]
283 lines
6.1 KiB
C++
283 lines
6.1 KiB
C++
// (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
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <boost/thread/synchronized_value.hpp>
|
|
|
|
//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 {
|
|
#if ! defined BOOST_NO_CXX11_AUTO_DECLARATIONS
|
|
auto memberSync = member.synchronize();
|
|
#else
|
|
boost::const_strict_lock_ptr<Member> memberSync = member.synchronize();
|
|
#endif
|
|
Invariant(memberSync);
|
|
return memberSync->name;
|
|
}
|
|
void SetName(const std::string& newName) {
|
|
#if ! defined BOOST_NO_CXX11_AUTO_DECLARATIONS
|
|
auto memberSync = member.synchronize();
|
|
#else
|
|
boost::strict_lock_ptr<Member> memberSync = member.synchronize();
|
|
#endif
|
|
Invariant(memberSync);
|
|
memberSync->name = newName;
|
|
}
|
|
private:
|
|
struct Member {
|
|
Member(unsigned int age) :
|
|
age(age)
|
|
{ }
|
|
std::string name;
|
|
unsigned int age;
|
|
};
|
|
void Invariant(boost::const_strict_lock_ptr<Member> & 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");
|
|
}
|
|
{
|
|
Person3_ts p1(1);
|
|
Person3_ts p2(2);
|
|
Person3_ts p3(3);
|
|
#if ! defined BOOST_NO_CXX11_AUTO_DECLARATIONS
|
|
auto lk1 = p1.unique_synchronize(boost::defer_lock);
|
|
auto lk2 = p2.unique_synchronize(boost::defer_lock);
|
|
auto lk3 = p3.unique_synchronize(boost::defer_lock);
|
|
#else
|
|
boost::unique_lock_ptr<Person3> lk1 = p1.unique_synchronize(boost::defer_lock);
|
|
boost::unique_lock_ptr<Person3> lk2 = p2.unique_synchronize(boost::defer_lock);
|
|
boost::unique_lock_ptr<Person3> lk3 = p3.unique_synchronize(boost::defer_lock);
|
|
#endif
|
|
boost::lock(lk1,lk2,lk3);
|
|
|
|
lk1->SetName("Carmen");
|
|
lk2->SetName("Javier");
|
|
lk3->SetName("Matias");
|
|
}
|
|
#if ! defined BOOST_NO_CXX11_AUTO_DECLARATIONS \
|
|
&& ! defined(BOOST_THREAD_NO_SYNCHRONIZE)
|
|
{
|
|
Person3_ts p1(1);
|
|
Person3_ts p2(2);
|
|
Person3_ts p3(3);
|
|
|
|
auto t = boost::synchronize(p1,p2,p3);
|
|
std::get<0>(t)->SetName("Carmen");
|
|
std::get<1>(t)->SetName("Javier");
|
|
std::get<2>(t)->SetName("Matias");
|
|
}
|
|
{
|
|
const Person3_ts p1(1);
|
|
Person3_ts p2(2);
|
|
const Person3_ts p3(3);
|
|
|
|
auto t = boost::synchronize(p1,p2,p3);
|
|
//std::get<0>(t)->SetName("Carmen");
|
|
std::get<1>(t)->SetName("Javier");
|
|
//std::get<2>(t)->SetName("Matias");
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|