]> git.donarmstrong.com Git - rsem.git/blob - boost/smart_ptr/detail/shared_ptr_nmt.hpp
RSEM Source Codes
[rsem.git] / boost / smart_ptr / detail / shared_ptr_nmt.hpp
1 #ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
2 #define BOOST_SMART_PTR_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 //  Distributed under the Boost Software License, Version 1.0. (See
11 //  accompanying file LICENSE_1_0.txt or copy at
12 //  http://www.boost.org/LICENSE_1_0.txt)
13 //
14 //  See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
15 //
16
17 #include <boost/assert.hpp>
18 #include <boost/checked_delete.hpp>
19 #include <boost/throw_exception.hpp>
20 #include <boost/smart_ptr/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 #include <new>              // for std::bad_alloc
29
30 namespace boost
31 {
32
33 template<class T> class shared_ptr
34 {
35 private:
36
37     typedef detail::atomic_count count_type;
38
39 public:
40
41     typedef T element_type;
42     typedef T value_type;
43
44     explicit shared_ptr(T * p = 0): px(p)
45     {
46 #ifndef BOOST_NO_EXCEPTIONS
47
48         try  // prevent leak if new throws
49         {
50             pn = new count_type(1);
51         }
52         catch(...)
53         {
54             boost::checked_delete(p);
55             throw;
56         }
57
58 #else
59
60         pn = new count_type(1);
61
62         if(pn == 0)
63         {
64             boost::checked_delete(p);
65             boost::throw_exception(std::bad_alloc());
66         }
67
68 #endif
69     }
70
71     ~shared_ptr()
72     {
73         if(--*pn == 0)
74         {
75             boost::checked_delete(px);
76             delete pn;
77         }
78     }
79
80     shared_ptr(shared_ptr const & r): px(r.px)  // never throws
81     {
82         pn = r.pn;
83         ++*pn;
84     }
85
86     shared_ptr & operator=(shared_ptr const & r)
87     {
88         shared_ptr(r).swap(*this);
89         return *this;
90     }
91
92 #ifndef BOOST_NO_AUTO_PTR
93
94     explicit shared_ptr(std::auto_ptr<T> & r)
95     { 
96         pn = new count_type(1); // may throw
97         px = r.release(); // fix: moved here to stop leak if new throws
98     } 
99
100     shared_ptr & operator=(std::auto_ptr<T> & r)
101     {
102         shared_ptr(r).swap(*this);
103         return *this;
104     }
105
106 #endif
107
108     void reset(T * p = 0)
109     {
110         BOOST_ASSERT(p == 0 || p != px);
111         shared_ptr(p).swap(*this);
112     }
113
114     T & operator*() const  // never throws
115     {
116         BOOST_ASSERT(px != 0);
117         return *px;
118     }
119
120     T * operator->() const  // never throws
121     {
122         BOOST_ASSERT(px != 0);
123         return px;
124     }
125
126     T * get() const  // never throws
127     {
128         return px;
129     }
130
131     long use_count() const  // never throws
132     {
133         return *pn;
134     }
135
136     bool unique() const  // never throws
137     {
138         return *pn == 1;
139     }
140     
141     void swap(shared_ptr<T> & other)  // never throws
142     {
143         std::swap(px, other.px);
144         std::swap(pn, other.pn);
145     }
146
147 private:
148
149     T * px;            // contained pointer
150     count_type * pn;   // ptr to reference counter
151 };
152
153 template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
154 {
155     return a.get() == b.get();
156 }
157
158 template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
159 {
160     return a.get() != b.get();
161 }
162
163 template<class T> inline bool operator<(shared_ptr<T> const & a, shared_ptr<T> const & b)
164 {
165     return std::less<T*>()(a.get(), b.get());
166 }
167
168 template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b)
169 {
170     a.swap(b);
171 }
172
173 // get_pointer() enables boost::mem_fn to recognize shared_ptr
174
175 template<class T> inline T * get_pointer(shared_ptr<T> const & p)
176 {
177     return p.get();
178 }
179
180 } // namespace boost
181
182 #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED