stlab.adobe.com Adobe Systems Incorporated

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 /*************************************************************************************************/

Copyright © 2006-2007 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google