// (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 #include #include //class SafePerson { //public: // std::string GetName() const { // const_unique_access name(nameGuard); // return *name; // } // void SetName(const std::string& newName) { // unique_access name(nameGuard); // *name = newName; // } //private: // unique_access_guard nameGuard; //}; class SafePerson { public: std::string GetName() const { return *name; } void SetName(const std::string& newName) { *name = newName; } private: boost::synchronized_value 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_ts; //class SafeMemberPerson { //public: // SafeMemberPerson(unsigned int age) : // memberGuard(age) // { } // std::string GetName() const { // const_unique_access member(memberGuard); // return member->name; // } // void SetName(const std::string& newName) { // unique_access member(memberGuard); // member->name = newName; // } //private: // struct Member // { // Member(unsigned int age) : // age(age) // { } // std::string name; // unsigned int age; // }; // unique_access_guard 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; }; 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_ts; //=================== //class HelperPerson { //public: // HelperPerson(unsigned int age) : // memberGuard(age) // { } // std::string GetName() const { // const_unique_access member(memberGuard); // Invariant(member); // return member->name; // } // void SetName(const std::string& newName) { // unique_access member(memberGuard); // Invariant(member); // member->name = newName; // } //private: // void Invariant(const_unique_access& 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 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 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 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 & mbr) const { if (mbr->age < 1) throw std::runtime_error("Age cannot be negative"); } boost::synchronized_value 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_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 lk1 = p1.unique_synchronize(boost::defer_lock); boost::unique_lock_ptr lk2 = p2.unique_synchronize(boost::defer_lock); boost::unique_lock_ptr 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; }