source: NonGTP/Boost/boost/serialization/detail/shared_ptr_nmt_132.hpp @ 857

Revision 857, 3.9 KB checked in by igarcia, 19 years ago (diff)
Line 
1#ifndef BOOST_DETAIL_SHARED_PTR_NMT_132_HPP_INCLUDED
2#define BOOST_DETAIL_SHARED_PTR_NMT_132_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/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
30namespace boost
31{
32
33template<class T> class shared_ptr
34{
35private:
36
37    typedef detail::atomic_count count_type;
38
39public:
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
147private:
148
149    T * px;            // contained pointer
150    count_type * pn;   // ptr to reference counter
151};
152
153template<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
158template<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
163template<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
168template<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
175template<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_DETAIL_SHARED_PTR_NMT_132_HPP_INCLUDED
Note: See TracBrowser for help on using the repository browser.