PVData C++ 8.0.7
Loading...
Searching...
No Matches
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
98namespace std {
99 namespace tr1 {
100 using ::std::shared_ptr;
101 using ::std::weak_ptr;
102 using ::std::static_pointer_cast;
103 using ::std::dynamic_pointer_cast;
104 using ::std::const_pointer_cast;
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
114namespace std {
115 namespace tr1 {
116 using ::epics::debug::shared_ptr;
117 using ::epics::debug::weak_ptr;
118 using ::epics::debug::static_pointer_cast;
119 using ::epics::debug::dynamic_pointer_cast;
120 using ::epics::debug::const_pointer_cast;
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
162namespace detail {
163template<typename T>
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
181template<typename T>
182inline ::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
187namespace std{
188template<typename T>
189inline 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
204namespace epics{
218#if __cplusplus>=201103L
219template<typename T>
220using auto_ptr = std::unique_ptr<T>;
221template<typename T>
222static inline void swap(auto_ptr<T>& lhs, auto_ptr<T>& rhs) {
223 lhs.swap(rhs);
224}
225#else
226using std::auto_ptr;
227template<typename T>
228static 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
void swap(any &__x, any &__y) noexcept
__rvalue_stream_insertion_t< _Ostream, _Tp > operator<<(_Ostream &&__os, const _Tp &__x)
epics
Definition convert.h:21
inline ::detail::ref_shower< T > show_referrers(const std::tr1::shared_ptr< T > &ptr, bool self=true, bool weak=false)
Definition sharedPtr.h:182