PVData C++  8.0.6
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
sharedPtr.h
Go to the documentation of this file.
1 /*
2  * Copyright information and license terms for this software can be
3  * found in the file LICENSE that is included with the distribution
4  */
9 #ifndef SHAREDPTR_H
10 #define SHAREDPTR_H
11 
12 #include <memory> /* for auto_ptr */
13 
28 /* where should we look? (In decending order of preference)
29  *
30  * # manual (per source file) selection
31  * # c++11 version of <memory>, then alias into tr1
32  * # <tr1/memory>
33  * # boost version of tr1/memory
34  */
35 
36 /* Debugging shared_ptr with debugPtr.h requires >= c++11
37  *
38  * Define DEBUG_SHARED_PTR globally to cause epics::debug::shared_ptr
39  * to be injected as std::tr1::shared_ptr and the macro
40  * HAVE_SHOW_REFS will be defined.
41  *
42  * epics::debug::shared_ptr wraps std::shared_ptr with additional
43  * tracking of backwards references.
44  * std::shared_ptr::use_count() gives the number of shared_ptr
45  * (strong refs) to the referenced object.
46  *
47  * If use_count()==5 then epics::debug::shared_ptr::show_refs() will print
48  * 5 lines of the format
49  *
50  * # <addr>: <IP0> <IP1> ...
51  *
52  * Given the numberic address of each shared_ptr as well as the call stack
53  * at the point where it was initialized.
54  * Use the 'addr2line' utility to interpret the stack addresses.
55  *
56  * On linux w/ ASLR it is necessary to turn on static linking to meaningfully
57  * interpret call stack addresses.
58  * Append "STATIC_BUILD=YES" to configure/CONFIG_SITE
59  */
60 //#define DEBUG_SHARED_PTR
61 
62 #if defined(SHARED_FROM_MANUAL)
63 // define SHARED_FROM_MANUAL if from some reason it is desirable to manually select
64 // which shared_ptr implementation to use
65 #elif __cplusplus>=201103L || (defined(_MSC_VER) && (_MSC_VER>=1600)) || defined(_LIBCPP_VERSION)
66 // MSVC has been bad about incrementing __cplusplus, even when new features are added. shared_ptr from MSVC 2010
67 // the llvm libc++ doesn't bother with tr1, and puts shared_ptr in std:: even with -std=c++98
68 # define SHARED_FROM_STD
69 
70 #elif defined(__GNUC__) && __GNUC__>=4 && !defined(vxWorks)
71  // GCC >=4.0.0
72 # define SHARED_FROM_TR1
73 
74 #elif defined(_MSC_VER) && _MSC_VER==1500
75 // MSVC 2009 (eg. Visual C++ for Python 2.7)
76 // Dinkumware _CPPLIB_VER=505
77 // Has std::tr1::shared_ptr in <memory>
78 # define SHARED_TR1_FROM_STD
79 
80 #elif defined(_MSC_VER) && (_MSC_VER>1500 || defined(_HAS_TR1))
81  // MSVC > 2008, or 2008 w/ SP1
82 # define SHARED_FROM_TR1
83 
84 #else
85 # define SHARED_FROM_BOOST
86 #endif
87 
88 // go and get it
89 
90 #if defined(SHARED_FROM_MANUAL)
91 // no-op
92 #elif defined(SHARED_FROM_STD)
93 
94 #include <memory>
95 
96 #ifndef DEBUG_SHARED_PTR
97 
98 namespace std {
99  namespace tr1 {
100  using ::std::shared_ptr;
101  using ::std::weak_ptr;
105  using ::std::enable_shared_from_this;
106  using ::std::bad_weak_ptr;
107  }
108 }
109 
110 #else // DEBUG_SHARED_PTR
111 
112 #include "debugPtr.h"
113 
114 namespace std {
115  namespace tr1 {
116  using ::epics::debug::shared_ptr;
117  using ::epics::debug::weak_ptr;
121  using ::epics::debug::enable_shared_from_this;
122  using ::std::bad_weak_ptr;
123  }
124 }
125 
126 
127 #endif // DEBUG_SHARED_PTR
128 
129 #elif defined(SHARED_TR1_FROM_STD)
130 # include <memory>
131 
132 #elif defined(SHARED_FROM_TR1)
133 # include <tr1/memory>
134 
135 #elif defined(SHARED_FROM_BOOST)
136 
137 #if defined(__GNUC__) && __GNUC__ < 3
138 #define BOOST_EXCEPTION_DISABLE
139 #define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
140 #endif
141 
142 # include <boost/tr1/memory.hpp>
143 
144 #else
145 # error No shared_ptr selection
146 #endif
147 
148 // cleanup
149 
150 #ifdef SHARED_FROM_STD
151 # undef SHARED_FROM_STD
152 #endif
153 
154 #ifdef SHARED_FROM_TR1
155 # undef SHARED_FROM_TR1
156 #endif
157 
158 #ifdef SHARED_FROM_BOOST
159 # undef SHARED_FROM_BOOST
160 #endif
161 
162 namespace detail {
163 template<typename T>
164 struct ref_shower {
165  const std::tr1::shared_ptr<T>& ptr;
166  bool self, weak;
167  ref_shower(const std::tr1::shared_ptr<T>& ptr, bool self, bool weak) :ptr(ptr),self(self),weak(weak) {}
168 };
169 }
170 
181 template<typename T>
182 inline ::detail::ref_shower<T> show_referrers(const std::tr1::shared_ptr<T>& ptr, bool self=true, bool weak=false)
183 {
184  return ::detail::ref_shower<T>(ptr, self, weak);
185 }
186 
187 namespace std{
188 template<typename T>
189 inline std::ostream& operator<<(std::ostream& strm, const ::detail::ref_shower<T>& refs)
190 {
191 #ifdef HAVE_SHOW_REFS
192  refs.ptr.show_refs(strm, refs.self, refs.weak);
193 #endif // HAVE_SHOW_REFS
194  return strm;
195 }
196 }//namespace std
197 
198 #define POINTER_DEFINITIONS(clazz) \
199  typedef std::tr1::shared_ptr<clazz> shared_pointer; \
200  typedef std::tr1::shared_ptr<const clazz> const_shared_pointer; \
201  typedef std::tr1::weak_ptr<clazz> weak_pointer; \
202  typedef std::tr1::weak_ptr<const clazz> const_weak_pointer
203 
204 namespace epics{
218 #if __cplusplus>=201103L
219 template<typename T>
220 using auto_ptr = std::unique_ptr<T>;
221 template<typename T>
222 static inline void swap(auto_ptr<T>& lhs, auto_ptr<T>& rhs) {
223  lhs.swap(rhs);
224 }
225 #else
226 using std::auto_ptr;
227 template<typename T>
228 static inline void swap(auto_ptr<T>& lhs, auto_ptr<T>& rhs) {
229  auto_ptr<T> temp(lhs);
230  lhs = rhs;
231  rhs = temp;
232 }
233 #endif
234 }
235 
236 #endif // SHAREDPTR_H
shared_ptr< _Tp > const_pointer_cast(const shared_ptr< _Up > &__r) noexcept
inline::detail::ref_shower< T > show_referrers(const std::tr1::shared_ptr< T > &ptr, bool self=true, bool weak=false)
Definition: sharedPtr.h:182
shared_ptr< _Tp > static_pointer_cast(const shared_ptr< _Up > &__r) noexcept
void swap(any &__x, any &__y) noexcept
shared_ptr< _Tp > dynamic_pointer_cast(const shared_ptr< _Up > &__r) noexcept