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