]> git.lyx.org Git - lyx.git/blob - boost/boost/detail/shared_ptr_nmt.hpp
update boost
[lyx.git] / boost / boost / detail / shared_ptr_nmt.hpp
1 #ifndef BOOST_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
2 #define BOOST_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
3
4 //
5 //  detail/shared_ptr_nmt.hpp - shared_ptr.hpp without member templates
6 //
7 //  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
8 //  Copyright (c) 2001, 2002 Peter Dimov
9 //
10 //  Permission to copy, use, modify, sell and distribute this software
11 //  is granted provided this copyright notice appears in all copies.
12 //  This software is provided "as is" without express or implied
13 //  warranty, and with no claim as to its suitability for any purpose.
14 //
15 //  See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
16 //
17
18 #include <boost/assert.hpp>
19 #include <boost/checked_delete.hpp>
20 #include <boost/throw_exception.hpp>
21 #include <boost/detail/atomic_count.hpp>
22
23 #ifndef BOOST_NO_AUTO_PTR
24 # include <memory>          // for std::auto_ptr
25 #endif
26
27 #include <algorithm>        // for std::swap
28 #include <functional>       // for std::less
29 #include <new>              // for std::bad_alloc
30
31 namespace boost
32 {
33
34 template<class T> class shared_ptr
35 {
36 private:
37
38     typedef detail::atomic_count count_type;
39
40 public:
41
42     typedef T element_type;
43     typedef T value_type;
44
45     explicit shared_ptr(T * p = 0): px(p)
46     {
47 #ifndef BOOST_NO_EXCEPTIONS
48
49         try  // prevent leak if new throws
50         {
51             pn = new count_type(1);
52         }
53         catch(...)
54         {
55             boost::checked_delete(p);
56             throw;
57         }
58
59 #else
60
61         pn = new count_type(1);
62
63         if(pn == 0)
64         {
65             boost::checked_delete(p);
66             boost::throw_exception(std::bad_alloc());
67         }
68
69 #endif
70     }
71
72     ~shared_ptr()
73     {
74         if(--*pn == 0)
75         {
76             boost::checked_delete(px);
77             delete pn;
78         }
79     }
80
81     shared_ptr(shared_ptr const & r): px(r.px)  // never throws
82     {
83         pn = r.pn;
84         ++*pn;
85     }
86
87     shared_ptr & operator=(shared_ptr const & r)
88     {
89         shared_ptr(r).swap(*this);
90         return *this;
91     }
92
93 #ifndef BOOST_NO_AUTO_PTR
94
95     explicit shared_ptr(std::auto_ptr<T> & r)
96     { 
97         pn = new count_type(1); // may throw
98         px = r.release(); // fix: moved here to stop leak if new throws
99     } 
100
101     shared_ptr & operator=(std::auto_ptr<T> & r)
102     {
103         shared_ptr(r).swap(*this);
104         return *this;
105     }
106
107 #endif
108
109     void reset(T * p = 0)
110     {
111         BOOST_ASSERT(p == 0 || p != px);
112         shared_ptr(p).swap(*this);
113     }
114
115     T & operator*() const  // never throws
116     {
117         BOOST_ASSERT(px != 0);
118         return *px;
119     }
120
121     T * operator->() const  // never throws
122     {
123         BOOST_ASSERT(px != 0);
124         return px;
125     }
126
127     T * get() const  // never throws
128     {
129         return px;
130     }
131
132     long use_count() const  // never throws
133     {
134         return *pn;
135     }
136
137     bool unique() const  // never throws
138     {
139         return *pn == 1;
140     }
141     
142     void swap(shared_ptr<T> & other)  // never throws
143     {
144         std::swap(px, other.px);
145         std::swap(pn, other.pn);
146     }
147
148 private:
149
150     T * px;            // contained pointer
151     count_type * pn;   // ptr to reference counter
152 };
153
154 template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
155 {
156     return a.get() == b.get();
157 }
158
159 template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
160 {
161     return a.get() != b.get();
162 }
163
164 template<class T> inline bool operator<(shared_ptr<T> const & a, shared_ptr<T> const & b)
165 {
166     return std::less<T*>()(a.get(), b.get());
167 }
168
169 template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b)
170 {
171     a.swap(b);
172 }
173
174 // get_pointer() enables boost::mem_fn to recognize shared_ptr
175
176 template<class T> inline T * get_pointer(shared_ptr<T> const & p)
177 {
178     return p.get();
179 }
180
181 } // namespace boost
182
183 #endif  // #ifndef BOOST_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED