]> git.lyx.org Git - lyx.git/blob - boost/boost/detail/shared_ptr_nmt.hpp
2002-05-24 Lars Gullik Bj�nnes <larsbj@birdstep.com>
[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/detail/atomic_count.hpp>
21
22 #ifndef BOOST_NO_AUTO_PTR
23 #include <memory>             // for std::auto_ptr
24 #endif
25
26 #include <algorithm>          // for std::swap
27 #include <functional>         // for std::less
28
29 namespace boost
30 {
31
32 template<class T> class shared_ptr
33 {
34 private:
35
36     typedef detail::atomic_count count_type;
37
38 public:
39
40     typedef T element_type;
41
42     explicit shared_ptr(T * p = 0): px(p)
43     {
44         try  // prevent leak if new throws
45         {
46             pn = new count_type(1);
47         }
48         catch(...)
49         {
50             checked_delete(p);
51             throw;
52         } 
53     }
54
55     ~shared_ptr()
56     {
57         if(--*pn == 0)
58         {
59             checked_delete(px);
60             delete pn;
61         }
62     }
63
64     shared_ptr(shared_ptr const & r): px(r.px)  // never throws
65     {
66         pn = r.pn;
67         ++*pn;
68     }
69
70     shared_ptr & operator=(shared_ptr const & r)
71     {
72         shared_ptr(r).swap(*this);
73         return *this;
74     }
75
76 #ifndef BOOST_NO_AUTO_PTR
77
78     explicit shared_ptr(std::auto_ptr<T> & r)
79     { 
80         pn = new count_type(1); // may throw
81         px = r.release(); // fix: moved here to stop leak if new throws
82     } 
83
84     shared_ptr & operator=(std::auto_ptr<T> & r)
85     {
86         shared_ptr(r).swap(*this);
87         return *this;
88     }
89
90 #endif
91
92     void reset(T * p = 0)
93     {
94         BOOST_ASSERT(p == 0 || p != px);
95         shared_ptr(p).swap(*this);
96     }
97
98     T & operator*() const  // never throws
99     {
100         BOOST_ASSERT(px != 0);
101         return *px;
102     }
103
104     T * operator->() const  // never throws
105     {
106         BOOST_ASSERT(px != 0);
107         return px;
108     }
109
110     T * get() const  // never throws
111     {
112         return px;
113     }
114
115     long use_count() const  // never throws
116     {
117         return *pn;
118     }
119
120     bool unique() const  // never throws
121     {
122         return *pn == 1;
123     }
124     
125     void swap(shared_ptr<T> & other)  // never throws
126     {
127         std::swap(px, other.px);
128         std::swap(pn, other.pn);
129     }
130
131 private:
132
133     T * px;            // contained pointer
134     count_type * pn;   // ptr to reference counter
135 };
136
137 template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
138 {
139     return a.get() == b.get();
140 }
141
142 template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
143 {
144     return a.get() != b.get();
145 }
146
147 template<class T> inline bool operator<(shared_ptr<T> const & a, shared_ptr<T> const & b)
148 {
149     return std::less<T*>()(a.get(), b.get());
150 }
151
152 template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b)
153 {
154     a.swap(b);
155 }
156
157 // get_pointer() enables boost::mem_fn to recognize shared_ptr
158
159 template<class T> inline T * get_pointer(shared_ptr<T> const & p)
160 {
161     return p.get();
162 }
163
164 } // namespace boost
165
166 #endif  // #ifndef BOOST_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED