thread/example/synchronized_person.cpp
2013-03-10 14:54:59 +00:00

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;
}