notify_on_write.hpp
Go to the documentation of this file.
00001 /* 00002 notifyright 2005-2007 Adobe Systems Incorporated 00003 Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt 00004 or a notify at http://stlab.adobe.com/licenses.html) 00005 */ 00006 00007 /*************************************************************************************************/ 00008 00009 #ifndef ADOBE_NOTIFY_ON_WRITE_HPP 00010 #define ADOBE_NOTIFY_ON_WRITE_HPP 00011 00012 /*************************************************************************************************/ 00013 00014 #include <adobe/config.hpp> 00015 00016 #include <boost/function.hpp> 00017 00018 /*************************************************************************************************/ 00019 00020 namespace adobe { 00021 00022 /*************************************************************************************************/ 00023 00024 template <typename T, typename Notifier> 00025 class notify_on_write 00026 { 00027 public: 00028 typedef T value_type; 00029 typedef Notifier notifier_type; 00030 typedef notify_on_write<value_type, notifier_type> self_type; 00031 00032 explicit notify_on_write(const value_type& x = value_type(), 00033 const Notifier& notifier = notifier_type()) : 00034 value_m(x), 00035 notifier_m(notifier) 00036 { notifier_m.ctor(const_cast<const self_type&>(*this)); } 00037 00038 notify_on_write(const notify_on_write& rhs) : 00039 value_m(rhs.value_m), 00040 notifier_m(rhs.notifier_m) 00041 { notifier_m.ctor(const_cast<const self_type&>(*this)); } 00042 00043 ~notify_on_write() 00044 { notifier_m.dtor(const_cast<const self_type&>(*this)); } 00045 00046 notify_on_write& operator=(const value_type& x) 00047 { 00048 if (value_m == x) 00049 return *this; 00050 00051 value_m = x; 00052 00053 notifier_m.modify(const_cast<const self_type&>(*this)); 00054 00055 return *this; 00056 } 00057 00058 notify_on_write& operator=(const notify_on_write& x) 00059 { return *this = x.value_m; } 00060 00061 template <typename UnaryFunction> 00062 void write(UnaryFunction proc) 00063 { 00064 proc(value_m); 00065 00066 notifier_m.modify(const_cast<const self_type&>(*this)); 00067 } 00068 00069 operator const value_type& () const 00070 { return value_m; } 00071 00072 const value_type& operator*() const { return value_m; } 00073 const value_type* operator->() const { return &value_m; } 00074 00075 private: 00076 #if !defined(ADOBE_NO_DOCUMENTATION) 00077 value_type value_m; 00078 notifier_type notifier_m; 00079 #endif 00080 }; 00081 00082 /*************************************************************************************************/ 00083 #if !defined(ADOBE_NO_DOCUMENTATION) 00084 /* 00085 NOTE (sparent) : We cannot use boost::totaly_ordered to implement these operations portably 00086 (although it works with most compilers, it doesn't with CW 9.6). The problem is that 00087 we do not know if T satifies the requirements for totally ordered or not - notify_on_write is 00088 only totally ordered if T is. By splitting the operations out to seperate template functions 00089 they are only instantiated if and where they are used. 00090 */ 00091 00092 template <typename T, typename Notifier1, typename Notifier2> 00093 inline bool operator<(const notify_on_write<T, Notifier1>& x, const notify_on_write<T, Notifier2>& y) 00094 { return *x < *y; } 00095 00096 template <typename T, typename Notifier1, typename Notifier2> 00097 inline bool operator>(const notify_on_write<T, Notifier1>& x, const notify_on_write<T, Notifier2>& y) 00098 { return y < x; } 00099 00100 template <typename T, typename Notifier1, typename Notifier2> 00101 inline bool operator<=(const notify_on_write<T, Notifier1>& x, const notify_on_write<T, Notifier2>& y) 00102 { return !(y < x); } 00103 00104 template <typename T, typename Notifier1, typename Notifier2> 00105 inline bool operator>=(const notify_on_write<T, Notifier1>& x, const notify_on_write<T, Notifier2>& y) 00106 { return !(x < y); } 00107 00108 template <typename T, typename Notifier1, typename Notifier2> 00109 inline bool operator==(const notify_on_write<T, Notifier1>& x, const notify_on_write<T, Notifier2>& y) 00110 { return *x == *y; } 00111 00112 template <typename T, typename Notifier1, typename Notifier2> 00113 inline bool operator!=(const notify_on_write<T, Notifier1>& x, const notify_on_write<T, Notifier2>& y) 00114 { return !(x == y); } 00115 #endif 00116 /*************************************************************************************************/ 00117 00118 } // namespace adobe 00119 00120 /*************************************************************************************************/ 00121 00122 #endif 00123 00124 /*************************************************************************************************/ |