File indexing completed on 2025-12-15 10:09:31
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_THREAD_SYNCHRONIZED_VALUE_HPP
0009 #define BOOST_THREAD_SYNCHRONIZED_VALUE_HPP
0010
0011 #include <boost/thread/detail/config.hpp>
0012
0013 #include <boost/thread/detail/move.hpp>
0014 #include <boost/thread/mutex.hpp>
0015 #include <boost/thread/lock_types.hpp>
0016 #include <boost/thread/lock_guard.hpp>
0017 #include <boost/thread/lock_algorithms.hpp>
0018 #include <boost/thread/lock_factories.hpp>
0019 #include <boost/thread/strict_lock.hpp>
0020 #include <boost/core/invoke_swap.hpp>
0021 #include <boost/type_traits/declval.hpp>
0022
0023
0024
0025
0026
0027
0028 #if ! defined(BOOST_THREAD_NO_SYNCHRONIZE)
0029 #include <tuple> // todo change to <boost/tuple.hpp> once Boost.Tuple or Boost.Fusion provides Move semantics on C++98 compilers.
0030 #include <functional>
0031 #endif
0032
0033 #include <boost/utility/result_of.hpp>
0034
0035 #include <boost/config/abi_prefix.hpp>
0036
0037 namespace boost
0038 {
0039
0040
0041
0042
0043
0044
0045
0046 template <typename T, typename Lockable = mutex>
0047 class const_strict_lock_ptr
0048 {
0049 public:
0050 typedef T value_type;
0051 typedef Lockable mutex_type;
0052 protected:
0053
0054
0055 boost::unique_lock<mutex_type> lk_;
0056 T const& value_;
0057
0058 public:
0059 BOOST_THREAD_MOVABLE_ONLY( const_strict_lock_ptr )
0060
0061
0062
0063
0064
0065
0066 const_strict_lock_ptr(T const& val, Lockable & mtx) :
0067 lk_(mtx), value_(val)
0068 {
0069 }
0070 const_strict_lock_ptr(T const& val, Lockable & mtx, adopt_lock_t tag) BOOST_NOEXCEPT :
0071 lk_(mtx, tag), value_(val)
0072 {
0073 }
0074
0075
0076
0077
0078 const_strict_lock_ptr(BOOST_THREAD_RV_REF(const_strict_lock_ptr) other) BOOST_NOEXCEPT
0079 : lk_(boost::move(BOOST_THREAD_RV(other).lk_)),value_(BOOST_THREAD_RV(other).value_)
0080 {
0081 }
0082
0083 ~const_strict_lock_ptr()
0084 {
0085 }
0086
0087
0088
0089
0090 const T* operator->() const
0091 {
0092 return &value_;
0093 }
0094
0095
0096
0097
0098 const T& operator*() const
0099 {
0100 return value_;
0101 }
0102
0103 };
0104
0105
0106
0107
0108
0109
0110
0111 template <typename T, typename Lockable = mutex>
0112 class strict_lock_ptr : public const_strict_lock_ptr<T,Lockable>
0113 {
0114 typedef const_strict_lock_ptr<T,Lockable> base_type;
0115 public:
0116 BOOST_THREAD_MOVABLE_ONLY( strict_lock_ptr )
0117
0118
0119
0120
0121
0122
0123 strict_lock_ptr(T & val, Lockable & mtx) :
0124 base_type(val, mtx)
0125 {
0126 }
0127 strict_lock_ptr(T & val, Lockable & mtx, adopt_lock_t tag) :
0128 base_type(val, mtx, tag)
0129 {
0130 }
0131
0132
0133
0134
0135
0136 strict_lock_ptr(BOOST_THREAD_RV_REF(strict_lock_ptr) other)
0137 : base_type(boost::move(static_cast<base_type&>(other)))
0138 {
0139 }
0140
0141 ~strict_lock_ptr()
0142 {
0143 }
0144
0145
0146
0147
0148 T* operator->()
0149 {
0150 return const_cast<T*>(&this->value_);
0151 }
0152
0153
0154
0155
0156 T& operator*()
0157 {
0158 return const_cast<T&>(this->value_);
0159 }
0160
0161 };
0162
0163 template <typename SV>
0164 struct synchronized_value_strict_lock_ptr
0165 {
0166 typedef strict_lock_ptr<typename SV::value_type, typename SV::mutex_type> type;
0167 };
0168
0169 template <typename SV>
0170 struct synchronized_value_strict_lock_ptr<const SV>
0171 {
0172 typedef const_strict_lock_ptr<typename SV::value_type, typename SV::mutex_type> type;
0173 };
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193 template <typename T, typename Lockable = mutex>
0194 class const_unique_lock_ptr : public unique_lock<Lockable>
0195 {
0196 typedef unique_lock<Lockable> base_type;
0197 public:
0198 typedef T value_type;
0199 typedef Lockable mutex_type;
0200 protected:
0201 T const& value_;
0202
0203 public:
0204 BOOST_THREAD_MOVABLE_ONLY(const_unique_lock_ptr)
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214 const_unique_lock_ptr(T const& val, Lockable & mtx)
0215 : base_type(mtx), value_(val)
0216 {
0217 }
0218
0219
0220
0221
0222
0223
0224
0225 const_unique_lock_ptr(T const& val, Lockable & mtx, adopt_lock_t) BOOST_NOEXCEPT
0226 : base_type(mtx, adopt_lock), value_(val)
0227 {
0228 }
0229
0230
0231
0232
0233
0234
0235 const_unique_lock_ptr(T const& val, Lockable & mtx, defer_lock_t) BOOST_NOEXCEPT
0236 : base_type(mtx, defer_lock), value_(val)
0237 {
0238 }
0239
0240
0241
0242
0243
0244
0245
0246 const_unique_lock_ptr(T const& val, Lockable & mtx, try_to_lock_t) BOOST_NOEXCEPT
0247 : base_type(mtx, try_to_lock), value_(val)
0248 {
0249 }
0250
0251
0252
0253
0254 const_unique_lock_ptr(BOOST_THREAD_RV_REF(const_unique_lock_ptr) other) BOOST_NOEXCEPT
0255 : base_type(boost::move(static_cast<base_type&>(other))), value_(BOOST_THREAD_RV(other).value_)
0256 {
0257 }
0258
0259
0260
0261
0262 ~const_unique_lock_ptr()
0263 {
0264 }
0265
0266
0267
0268
0269 const T* operator->() const
0270 {
0271 BOOST_ASSERT (this->owns_lock());
0272 return &value_;
0273 }
0274
0275
0276
0277
0278 const T& operator*() const
0279 {
0280 BOOST_ASSERT (this->owns_lock());
0281 return value_;
0282 }
0283
0284 };
0285
0286
0287
0288
0289
0290
0291
0292 template <typename T, typename Lockable = mutex>
0293 class unique_lock_ptr : public const_unique_lock_ptr<T, Lockable>
0294 {
0295 typedef const_unique_lock_ptr<T, Lockable> base_type;
0296 public:
0297 typedef T value_type;
0298 typedef Lockable mutex_type;
0299
0300 BOOST_THREAD_MOVABLE_ONLY(unique_lock_ptr)
0301
0302
0303
0304
0305
0306
0307 unique_lock_ptr(T & val, Lockable & mtx)
0308 : base_type(val, mtx)
0309 {
0310 }
0311
0312
0313
0314
0315
0316
0317 unique_lock_ptr(T & value, Lockable & mtx, adopt_lock_t) BOOST_NOEXCEPT
0318 : base_type(value, mtx, adopt_lock)
0319 {
0320 }
0321
0322
0323
0324
0325
0326
0327 unique_lock_ptr(T & value, Lockable & mtx, defer_lock_t) BOOST_NOEXCEPT
0328 : base_type(value, mtx, defer_lock)
0329 {
0330 }
0331
0332
0333
0334
0335
0336
0337 unique_lock_ptr(T & value, Lockable & mtx, try_to_lock_t) BOOST_NOEXCEPT
0338 : base_type(value, mtx, try_to_lock)
0339 {
0340 }
0341
0342
0343
0344
0345 unique_lock_ptr(BOOST_THREAD_RV_REF(unique_lock_ptr) other) BOOST_NOEXCEPT
0346 : base_type(boost::move(static_cast<base_type&>(other)))
0347 {
0348 }
0349
0350 ~unique_lock_ptr()
0351 {
0352 }
0353
0354
0355
0356
0357 T* operator->()
0358 {
0359 BOOST_ASSERT (this->owns_lock());
0360 return const_cast<T*>(&this->value_);
0361 }
0362
0363
0364
0365
0366 T& operator*()
0367 {
0368 BOOST_ASSERT (this->owns_lock());
0369 return const_cast<T&>(this->value_);
0370 }
0371
0372
0373 };
0374
0375 template <typename SV>
0376 struct synchronized_value_unique_lock_ptr
0377 {
0378 typedef unique_lock_ptr<typename SV::value_type, typename SV::mutex_type> type;
0379 };
0380
0381 template <typename SV>
0382 struct synchronized_value_unique_lock_ptr<const SV>
0383 {
0384 typedef const_unique_lock_ptr<typename SV::value_type, typename SV::mutex_type> type;
0385 };
0386
0387
0388
0389
0390
0391 template <typename T, typename Lockable = mutex>
0392 class synchronized_value
0393 {
0394
0395 #if ! defined(BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS)
0396 #if ! defined BOOST_NO_CXX11_VARIADIC_TEMPLATES
0397 template <typename ...SV>
0398 friend std::tuple<typename synchronized_value_strict_lock_ptr<SV>::type ...> synchronize(SV& ...sv);
0399 #else
0400 template <typename SV1, typename SV2>
0401 friend std::tuple<
0402 typename synchronized_value_strict_lock_ptr<SV1>::type,
0403 typename synchronized_value_strict_lock_ptr<SV2>::type
0404 >
0405 synchronize(SV1& sv1, SV2& sv2);
0406 template <typename SV1, typename SV2, typename SV3>
0407 friend std::tuple<
0408 typename synchronized_value_strict_lock_ptr<SV1>::type,
0409 typename synchronized_value_strict_lock_ptr<SV2>::type,
0410 typename synchronized_value_strict_lock_ptr<SV3>::type
0411 >
0412 synchronize(SV1& sv1, SV2& sv2, SV3& sv3);
0413 #endif
0414 #endif
0415
0416 public:
0417 typedef T value_type;
0418 typedef Lockable mutex_type;
0419 private:
0420 T value_;
0421 mutable mutex_type mtx_;
0422 public:
0423
0424
0425
0426
0427
0428
0429 synchronized_value()
0430
0431 : value_()
0432 {
0433 }
0434
0435
0436
0437
0438
0439
0440 synchronized_value(T const& other)
0441
0442 : value_(other)
0443 {
0444 }
0445
0446
0447
0448
0449
0450
0451 synchronized_value(BOOST_THREAD_RV_REF(T) other)
0452
0453 : value_(boost::move(other))
0454 {
0455 }
0456
0457
0458
0459
0460
0461
0462
0463 synchronized_value(synchronized_value const& rhs)
0464 {
0465 strict_lock<mutex_type> lk(rhs.mtx_);
0466 value_ = rhs.value_;
0467 }
0468
0469
0470
0471
0472
0473 synchronized_value(BOOST_THREAD_RV_REF(synchronized_value) other)
0474 {
0475 strict_lock<mutex_type> lk(BOOST_THREAD_RV(other).mtx_);
0476 value_= boost::move(BOOST_THREAD_RV(other).value_);
0477 }
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490 synchronized_value& operator=(synchronized_value const& rhs)
0491 {
0492 if(&rhs != this)
0493 {
0494
0495 unique_lock<mutex_type> lk1(mtx_, defer_lock);
0496 unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
0497 lock(lk1,lk2);
0498
0499 value_ = rhs.value_;
0500 }
0501 return *this;
0502 }
0503
0504
0505
0506
0507
0508 synchronized_value& operator=(value_type const& val)
0509 {
0510 {
0511 strict_lock<mutex_type> lk(mtx_);
0512 value_ = val;
0513 }
0514 return *this;
0515 }
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525 T get() const
0526 {
0527 strict_lock<mutex_type> lk(mtx_);
0528 return value_;
0529 }
0530
0531
0532
0533
0534
0535
0536
0537 #if ! defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
0538 explicit operator T() const
0539 {
0540 return get();
0541 }
0542 #endif
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552 T const& value() const
0553 {
0554 return value_;
0555 }
0556
0557
0558
0559
0560
0561
0562
0563
0564 mutex_type const& mutex() const
0565 {
0566 return mtx_;
0567 }
0568
0569
0570
0571
0572
0573
0574
0575
0576 void swap(synchronized_value & rhs)
0577 {
0578 if (this == &rhs) {
0579 return;
0580 }
0581
0582 unique_lock<mutex_type> lk1(mtx_, defer_lock);
0583 unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
0584 lock(lk1,lk2);
0585 boost::core::invoke_swap(value_, rhs.value_);
0586 }
0587
0588
0589
0590
0591
0592 void swap(value_type & rhs)
0593 {
0594 strict_lock<mutex_type> lk(mtx_);
0595 boost::core::invoke_swap(value_, rhs);
0596 }
0597
0598
0599
0600
0601
0602 strict_lock_ptr<T,Lockable> operator->()
0603 {
0604 return BOOST_THREAD_MAKE_RV_REF((strict_lock_ptr<T,Lockable>(value_, mtx_)));
0605 }
0606
0607
0608
0609
0610
0611 const_strict_lock_ptr<T,Lockable> operator->() const
0612 {
0613 return BOOST_THREAD_MAKE_RV_REF((const_strict_lock_ptr<T,Lockable>(value_, mtx_)));
0614 }
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630 template <typename F>
0631 inline
0632 typename boost::result_of<F(value_type&)>::type
0633 operator()(BOOST_THREAD_RV_REF(F) fct)
0634 {
0635 strict_lock<mutex_type> lk(mtx_);
0636 return fct(value_);
0637 }
0638 template <typename F>
0639 inline
0640 typename boost::result_of<F(value_type const&)>::type
0641 operator()(BOOST_THREAD_RV_REF(F) fct) const
0642 {
0643 strict_lock<mutex_type> lk(mtx_);
0644 return fct(value_);
0645 }
0646
0647
0648 #if defined BOOST_NO_CXX11_RVALUE_REFERENCES
0649 template <typename F>
0650 inline
0651 typename boost::result_of<F(value_type&)>::type
0652 operator()(F const & fct)
0653 {
0654 strict_lock<mutex_type> lk(mtx_);
0655 return fct(value_);
0656 }
0657 template <typename F>
0658 inline
0659 typename boost::result_of<F(value_type const&)>::type
0660 operator()(F const & fct) const
0661 {
0662 strict_lock<mutex_type> lk(mtx_);
0663 return fct(value_);
0664 }
0665
0666 template <typename R>
0667 inline
0668 R operator()(R(*fct)(value_type&))
0669 {
0670 strict_lock<mutex_type> lk(mtx_);
0671 return fct(value_);
0672 }
0673 template <typename R>
0674 inline
0675 R operator()(R(*fct)(value_type const&)) const
0676 {
0677 strict_lock<mutex_type> lk(mtx_);
0678 return fct(value_);
0679 }
0680 #endif
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695 strict_lock_ptr<T,Lockable> synchronize()
0696 {
0697 return BOOST_THREAD_MAKE_RV_REF((strict_lock_ptr<T,Lockable>(value_, mtx_)));
0698 }
0699 const_strict_lock_ptr<T,Lockable> synchronize() const
0700 {
0701 return BOOST_THREAD_MAKE_RV_REF((const_strict_lock_ptr<T,Lockable>(value_, mtx_)));
0702 }
0703
0704 unique_lock_ptr<T,Lockable> unique_synchronize()
0705 {
0706 return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_)));
0707 }
0708 const_unique_lock_ptr<T,Lockable> unique_synchronize() const
0709 {
0710 return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_)));
0711 }
0712 unique_lock_ptr<T,Lockable> unique_synchronize(defer_lock_t tag)
0713 {
0714 return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_, tag)));
0715 }
0716 const_unique_lock_ptr<T,Lockable> unique_synchronize(defer_lock_t tag) const
0717 {
0718 return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_, tag)));
0719 }
0720 unique_lock_ptr<T,Lockable> defer_synchronize() BOOST_NOEXCEPT
0721 {
0722 return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_, defer_lock)));
0723 }
0724 const_unique_lock_ptr<T,Lockable> defer_synchronize() const BOOST_NOEXCEPT
0725 {
0726 return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_, defer_lock)));
0727 }
0728 unique_lock_ptr<T,Lockable> try_to_synchronize() BOOST_NOEXCEPT
0729 {
0730 return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_, try_to_lock)));
0731 }
0732 const_unique_lock_ptr<T,Lockable> try_to_synchronize() const BOOST_NOEXCEPT
0733 {
0734 return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_, try_to_lock)));
0735 }
0736 unique_lock_ptr<T,Lockable> adopt_synchronize() BOOST_NOEXCEPT
0737 {
0738 return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_, adopt_lock)));
0739 }
0740 const_unique_lock_ptr<T,Lockable> adopt_synchronize() const BOOST_NOEXCEPT
0741 {
0742 return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_, adopt_lock)));
0743 }
0744
0745
0746 #if ! defined __IBMCPP__
0747 private:
0748 #endif
0749 class deref_value
0750 {
0751 private:
0752 friend class synchronized_value;
0753
0754 boost::unique_lock<mutex_type> lk_;
0755 T& value_;
0756
0757 explicit deref_value(synchronized_value& outer):
0758 lk_(outer.mtx_),value_(outer.value_)
0759 {}
0760
0761 public:
0762 BOOST_THREAD_MOVABLE_ONLY(deref_value)
0763
0764 deref_value(BOOST_THREAD_RV_REF(deref_value) other):
0765 lk_(boost::move(BOOST_THREAD_RV(other).lk_)),value_(BOOST_THREAD_RV(other).value_)
0766 {}
0767 operator T&()
0768 {
0769 return value_;
0770 }
0771
0772 deref_value& operator=(T const& newVal)
0773 {
0774 value_=newVal;
0775 return *this;
0776 }
0777 };
0778 class const_deref_value
0779 {
0780 private:
0781 friend class synchronized_value;
0782
0783 boost::unique_lock<mutex_type> lk_;
0784 const T& value_;
0785
0786 explicit const_deref_value(synchronized_value const& outer):
0787 lk_(outer.mtx_), value_(outer.value_)
0788 {}
0789
0790 public:
0791 BOOST_THREAD_MOVABLE_ONLY(const_deref_value)
0792
0793 const_deref_value(BOOST_THREAD_RV_REF(const_deref_value) other):
0794 lk_(boost::move(BOOST_THREAD_RV(other).lk_)), value_(BOOST_THREAD_RV(other).value_)
0795 {}
0796
0797 operator const T&()
0798 {
0799 return value_;
0800 }
0801 };
0802
0803 public:
0804 deref_value operator*()
0805 {
0806 return BOOST_THREAD_MAKE_RV_REF(deref_value(*this));
0807 }
0808
0809 const_deref_value operator*() const
0810 {
0811 return BOOST_THREAD_MAKE_RV_REF(const_deref_value(*this));
0812 }
0813
0814
0815
0816
0817
0818
0819 template <typename OStream>
0820 void save(OStream& os) const
0821 {
0822 strict_lock<mutex_type> lk(mtx_);
0823 os << value_;
0824 }
0825
0826
0827
0828
0829 template <typename IStream>
0830 void load(IStream& is)
0831 {
0832 strict_lock<mutex_type> lk(mtx_);
0833 is >> value_;
0834 }
0835
0836
0837
0838
0839
0840
0841 bool operator==(synchronized_value const& rhs) const
0842 {
0843 unique_lock<mutex_type> lk1(mtx_, defer_lock);
0844 unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
0845 lock(lk1,lk2);
0846
0847 return value_ == rhs.value_;
0848 }
0849
0850
0851
0852
0853 bool operator<(synchronized_value const& rhs) const
0854 {
0855 unique_lock<mutex_type> lk1(mtx_, defer_lock);
0856 unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
0857 lock(lk1,lk2);
0858
0859 return value_ < rhs.value_;
0860 }
0861
0862
0863
0864
0865 bool operator>(synchronized_value const& rhs) const
0866 {
0867 unique_lock<mutex_type> lk1(mtx_, defer_lock);
0868 unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
0869 lock(lk1,lk2);
0870
0871 return value_ > rhs.value_;
0872 }
0873 bool operator<=(synchronized_value const& rhs) const
0874 {
0875 unique_lock<mutex_type> lk1(mtx_, defer_lock);
0876 unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
0877 lock(lk1,lk2);
0878
0879 return value_ <= rhs.value_;
0880 }
0881 bool operator>=(synchronized_value const& rhs) const
0882 {
0883 unique_lock<mutex_type> lk1(mtx_, defer_lock);
0884 unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
0885 lock(lk1,lk2);
0886
0887 return value_ >= rhs.value_;
0888 }
0889 bool operator==(value_type const& rhs) const
0890 {
0891 unique_lock<mutex_type> lk1(mtx_);
0892
0893 return value_ == rhs;
0894 }
0895 bool operator!=(value_type const& rhs) const
0896 {
0897 unique_lock<mutex_type> lk1(mtx_);
0898
0899 return value_ != rhs;
0900 }
0901 bool operator<(value_type const& rhs) const
0902 {
0903 unique_lock<mutex_type> lk1(mtx_);
0904
0905 return value_ < rhs;
0906 }
0907 bool operator<=(value_type const& rhs) const
0908 {
0909 unique_lock<mutex_type> lk1(mtx_);
0910
0911 return value_ <= rhs;
0912 }
0913 bool operator>(value_type const& rhs) const
0914 {
0915 unique_lock<mutex_type> lk1(mtx_);
0916
0917 return value_ > rhs;
0918 }
0919 bool operator>=(value_type const& rhs) const
0920 {
0921 unique_lock<mutex_type> lk1(mtx_);
0922
0923 return value_ >= rhs;
0924 }
0925
0926 };
0927
0928
0929
0930
0931
0932 template <typename T, typename L>
0933 inline void swap(synchronized_value<T,L> & lhs, synchronized_value<T,L> & rhs)
0934 {
0935 lhs.swap(rhs);
0936 }
0937 template <typename T, typename L>
0938 inline void swap(synchronized_value<T,L> & lhs, T & rhs)
0939 {
0940 lhs.swap(rhs);
0941 }
0942 template <typename T, typename L>
0943 inline void swap(T & lhs, synchronized_value<T,L> & rhs)
0944 {
0945 rhs.swap(lhs);
0946 }
0947
0948
0949
0950
0951
0952
0953
0954
0955 template <typename T, typename L>
0956 bool operator!=(synchronized_value<T,L> const&lhs, synchronized_value<T,L> const& rhs)
0957 {
0958 return ! (lhs==rhs);
0959 }
0960
0961 template <typename T, typename L>
0962 bool operator==(T const& lhs, synchronized_value<T,L> const&rhs)
0963 {
0964 return rhs==lhs;
0965 }
0966 template <typename T, typename L>
0967 bool operator!=(T const& lhs, synchronized_value<T,L> const&rhs)
0968 {
0969 return rhs!=lhs;
0970 }
0971 template <typename T, typename L>
0972 bool operator<(T const& lhs, synchronized_value<T,L> const&rhs)
0973 {
0974 return rhs>lhs;
0975 }
0976 template <typename T, typename L>
0977 bool operator<=(T const& lhs, synchronized_value<T,L> const&rhs)
0978 {
0979 return rhs>=lhs;
0980 }
0981 template <typename T, typename L>
0982 bool operator>(T const& lhs, synchronized_value<T,L> const&rhs)
0983 {
0984 return rhs<lhs;
0985 }
0986 template <typename T, typename L>
0987 bool operator>=(T const& lhs, synchronized_value<T,L> const&rhs)
0988 {
0989 return rhs<=lhs;
0990 }
0991
0992
0993
0994
0995 template <typename OStream, typename T, typename L>
0996 inline OStream& operator<<(OStream& os, synchronized_value<T,L> const& rhs)
0997 {
0998 rhs.save(os);
0999 return os;
1000 }
1001 template <typename IStream, typename T, typename L>
1002 inline IStream& operator>>(IStream& is, synchronized_value<T,L>& rhs)
1003 {
1004 rhs.load(is);
1005 return is;
1006 }
1007
1008 #if ! defined(BOOST_THREAD_NO_SYNCHRONIZE)
1009 #if ! defined BOOST_NO_CXX11_VARIADIC_TEMPLATES
1010
1011 template <typename ...SV>
1012 std::tuple<typename synchronized_value_strict_lock_ptr<SV>::type ...> synchronize(SV& ...sv)
1013 {
1014 boost::lock(sv.mtx_ ...);
1015 typedef std::tuple<typename synchronized_value_strict_lock_ptr<SV>::type ...> t_type;
1016
1017 return t_type(typename synchronized_value_strict_lock_ptr<SV>::type(sv.value_, sv.mtx_, adopt_lock) ...);
1018 }
1019 #else
1020
1021 template <typename SV1, typename SV2>
1022 std::tuple<
1023 typename synchronized_value_strict_lock_ptr<SV1>::type,
1024 typename synchronized_value_strict_lock_ptr<SV2>::type
1025 >
1026 synchronize(SV1& sv1, SV2& sv2)
1027 {
1028 boost::lock(sv1.mtx_, sv2.mtx_);
1029 typedef std::tuple<
1030 typename synchronized_value_strict_lock_ptr<SV1>::type,
1031 typename synchronized_value_strict_lock_ptr<SV2>::type
1032 > t_type;
1033
1034 return t_type(
1035 typename synchronized_value_strict_lock_ptr<SV1>::type(sv1.value_, sv1.mtx_, adopt_lock),
1036 typename synchronized_value_strict_lock_ptr<SV2>::type(sv2.value_, sv2.mtx_, adopt_lock)
1037 );
1038
1039 }
1040 template <typename SV1, typename SV2, typename SV3>
1041 std::tuple<
1042 typename synchronized_value_strict_lock_ptr<SV1>::type,
1043 typename synchronized_value_strict_lock_ptr<SV2>::type,
1044 typename synchronized_value_strict_lock_ptr<SV3>::type
1045 >
1046 synchronize(SV1& sv1, SV2& sv2, SV3& sv3)
1047 {
1048 boost::lock(sv1.mtx_, sv2.mtx_);
1049 typedef std::tuple<
1050 typename synchronized_value_strict_lock_ptr<SV1>::type,
1051 typename synchronized_value_strict_lock_ptr<SV2>::type,
1052 typename synchronized_value_strict_lock_ptr<SV3>::type
1053 > t_type;
1054
1055 return t_type(
1056 typename synchronized_value_strict_lock_ptr<SV1>::type(sv1.value_, sv1.mtx_, adopt_lock),
1057 typename synchronized_value_strict_lock_ptr<SV2>::type(sv2.value_, sv2.mtx_, adopt_lock),
1058 typename synchronized_value_strict_lock_ptr<SV3>::type(sv3.value_, sv3.mtx_, adopt_lock)
1059 );
1060
1061 }
1062 #endif
1063 #endif
1064 }
1065
1066 #include <boost/config/abi_suffix.hpp>
1067
1068 #endif