blob: 76e6fdd957ea4b3225fe58c9782decaf83cefc08 [file] [log] [blame]
Jeff Thompsonf7d49942013-08-01 16:47:40 -07001#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
Jeff Thompson2277ce52013-08-01 17:34:11 -070017#include <ndnboost/assert.hpp>
18#include <ndnboost/checked_delete.hpp>
19#include <ndnboost/throw_exception.hpp>
20#include <ndnboost/smart_ptr/detail/atomic_count.hpp>
Jeff Thompsonf7d49942013-08-01 16:47:40 -070021
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 ndnboost
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 ndnboost::checked_delete(p);
55 throw;
56 }
57
58#else
59
60 pn = new count_type(1);
61
62 if(pn == 0)
63 {
64 ndnboost::checked_delete(p);
65 ndnboost::throw_exception(std::bad_alloc());
66 }
67
68#endif
69 }
70
71 ~shared_ptr()
72 {
73 if(--*pn == 0)
74 {
75 ndnboost::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 ndnboost::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 ndnboost
181
182#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED