]> git.lyx.org Git - lyx.git/blob - boost/boost/intrusive_ptr.hpp
major boost update
[lyx.git] / boost / boost / intrusive_ptr.hpp
1 #ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED
2 #define BOOST_INTRUSIVE_PTR_HPP_INCLUDED
3
4 //
5 //  intrusive_ptr.hpp
6 //
7 //  Copyright (c) 2001, 2002 Peter Dimov
8 //
9 //  Permission to copy, use, modify, sell and distribute this software
10 //  is granted provided this copyright notice appears in all copies.
11 //  This software is provided "as is" without express or implied
12 //  warranty, and with no claim as to its suitability for any purpose.
13 //
14 //  See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation.
15 //
16
17 #ifdef BOOST_MSVC  // moved here to work around VC++ compiler crash
18 # pragma warning(push)
19 # pragma warning(disable:4284) // odd return type for operator->
20 #endif
21
22 #include <functional> // std::less
23
24 namespace boost
25 {
26
27 //
28 //  intrusive_ptr
29 //
30 //  A smart pointer that uses intrusive reference counting.
31 //
32 //  Relies on unqualified calls to
33 //  
34 //      void intrusive_ptr_add_ref(T * p);
35 //      void intrusive_ptr_release(T * p);
36 //
37 //          (p != 0)
38 //
39 //  The object is responsible for destroying itself.
40 //
41
42 template<class T> class intrusive_ptr
43 {
44 private:
45
46     typedef intrusive_ptr this_type;
47
48 public:
49
50     intrusive_ptr(): p_(0)
51     {
52     }
53
54     intrusive_ptr(T * p): p_(p)
55     {
56         if(p_ != 0) intrusive_ptr_add_ref(p_);
57     }
58
59     ~intrusive_ptr()
60     {
61         if(p_ != 0) intrusive_ptr_release(p_);
62     }
63
64 #ifdef BOOST_MSVC6_MEMBER_TEMPLATES
65
66     template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs): p_(rhs.get())
67     {
68         if(p_ != 0) intrusive_ptr_add_ref(p_);
69     }
70
71 #endif
72
73     intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.p_)
74     {
75         if(p_ != 0) intrusive_ptr_add_ref(p_);
76     }
77
78 #ifdef BOOST_MSVC6_MEMBER_TEMPLATES
79
80     template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs)
81     {
82         this_type(rhs).swap(*this);
83         return *this;
84     }
85
86 #endif
87
88     intrusive_ptr & operator=(intrusive_ptr const & rhs)
89     {
90         this_type(rhs).swap(*this);
91         return *this;
92     }
93
94     intrusive_ptr & operator=(T * rhs)
95     {
96         this_type(rhs).swap(*this);
97         return *this;
98     }
99
100     void swap(intrusive_ptr & rhs)
101     {
102         T * tmp = p_;
103         p_ = rhs.p_;
104         rhs.p_ = tmp;
105     }
106
107     T * get() const
108     {
109         return p_;
110     }
111
112     T & operator*() const
113     {
114         return *p_;
115     }
116
117     T * operator->() const
118     {
119         return p_;
120     }
121
122     bool empty() const
123     {
124         return p_ == 0;
125     }
126
127     typedef bool (intrusive_ptr::*bool_type) () const;
128
129     operator bool_type () const
130     {
131         return p_ == 0? 0: &intrusive_ptr::empty;
132     }
133
134 private:
135
136     T * p_;
137 };
138
139 template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)
140 {
141     lhs.swap(rhs);
142 }
143
144 template<class T, class U> intrusive_ptr<T> shared_dynamic_cast(intrusive_ptr<U> const & p)
145 {
146     return dynamic_cast<T *>(p.get());
147 }
148
149 template<class T, class U> intrusive_ptr<T> shared_static_cast(intrusive_ptr<U> const & p)
150 {
151     return static_cast<T *>(p.get());
152 }
153
154 template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
155 {
156     return a.get() == b.get();
157 }
158
159 template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
160 {
161     return a.get() != b.get();
162 }
163
164 template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
165 {
166     return std::less<T *>(a.get(), b.get());
167 }
168
169 template<class T> inline bool operator==(intrusive_ptr<T> const & a, T * b)
170 {
171     return a.get() == b;
172 }
173
174 template<class T> inline bool operator!=(intrusive_ptr<T> const & a, T * b)
175 {
176     return a.get() != b;
177 }
178
179 template<class T> inline bool operator==(T * a, intrusive_ptr<T> const & b)
180 {
181     return a == b.get();
182 }
183
184 template<class T> inline bool operator!=(T * a, intrusive_ptr<T> const & b)
185 {
186     return a != b.get();
187 }
188
189 // mem_fn support
190
191 template<class T> T * get_pointer(intrusive_ptr<T> const & p)
192 {
193     return p.get();
194 }
195
196 } // namespace boost
197
198 #ifdef BOOST_MSVC
199 # pragma warning(pop)
200 #endif    
201
202 #endif  // #ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED