From c590204cf9834d5be12cf7eb6aea4a44e0eb10a5 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 6 Nov 2017 12:30:40 -0600 Subject: [PATCH] add epics::auto_ptr and epics::swap() Avoid the flood of auto_ptr deprecation warnings in the common cases of using auto_ptr to automatically delete. --- src/misc/pv/sharedPtr.h | 36 ++++++++++++++++++++++++++++++- src/misc/pv/thread.h | 6 +----- src/misc/reftrack.cpp | 7 +++--- src/pv/valueBuilder.cpp | 6 +++--- testApp/misc/testByteBuffer.cpp | 4 ++-- testApp/misc/testSharedVector.cpp | 14 +++++++++++- 6 files changed, 58 insertions(+), 15 deletions(-) diff --git a/src/misc/pv/sharedPtr.h b/src/misc/pv/sharedPtr.h index f79ddad..3fba962 100644 --- a/src/misc/pv/sharedPtr.h +++ b/src/misc/pv/sharedPtr.h @@ -9,7 +9,9 @@ #ifndef SHAREDPTR_H #define SHAREDPTR_H -/* +#include /* for auto_ptr */ + +/** @file sharedPtr.h * Pulls in the std::tr1 namespace with the following names * * class shared_ptr @@ -190,4 +192,36 @@ inline std::ostream& operator<<(std::ostream& strm, const ::detail::ref_shower weak_pointer; \ typedef std::tr1::weak_ptr const_weak_pointer +/* A semi-hack to help with migration from std::auto_ptr to std::unique_ptr, + * and avoid copious deprecation warning spam + * which may be hiding legitimate issues. + * + * Provides epics::auto_ptr and epics::swap() + * + * epics::auto_ptr is std::auto_ptr for c++98 + * and std::unique_ptr for >= c++11. + * + * epics::swap() is the only supported operation. + * copy/assignment/return are not supported + * (use auto_ptr or unique_ptr explicitly). + */ +namespace epics{ +#if __cplusplus>=201103L +template +using auto_ptr = std::unique_ptr; +template +static inline void swap(auto_ptr& lhs, auto_ptr& rhs) { + lhs.swap(rhs); +} +#else +using std::auto_ptr; +template +static inline void swap(auto_ptr& lhs, auto_ptr& rhs) { + auto_ptr temp(lhs); + lhs = rhs; + rhs = temp; +} +#endif +} + #endif // SHAREDPTR_H diff --git a/src/misc/pv/thread.h b/src/misc/pv/thread.h index 103d434..5b964e5 100644 --- a/src/misc/pv/thread.h +++ b/src/misc/pv/thread.h @@ -141,11 +141,7 @@ public: std::ostringstream p_strm; bool p_autostart; Runnable *p_runner; -#if __cplusplus>=201103L - typedef std::unique_ptr p_owned_runner_t; -#else - typedef std::auto_ptr p_owned_runner_t; -#endif + typedef epics::auto_ptr p_owned_runner_t; p_owned_runner_t p_owned_runner; friend class Thread; Runnable& x_getrunner() diff --git a/src/misc/reftrack.cpp b/src/misc/reftrack.cpp index 562b24b..07a586a 100644 --- a/src/misc/reftrack.cpp +++ b/src/misc/reftrack.cpp @@ -20,6 +20,7 @@ #define epicsExportSharedSymbols #include +#include #include "pv/reftrack.h" namespace { @@ -171,7 +172,7 @@ std::ostream& operator<<(std::ostream& strm, const RefSnapshot& snap) struct RefMonitor::Impl : public epicsThreadRunable { RefMonitor& owner; - std::auto_ptr worker; + epics::auto_ptr worker; epicsMutex lock; epicsEvent wakeup; RefSnapshot prev; @@ -229,11 +230,11 @@ void RefMonitor::start(double period) void RefMonitor::stop() { - std::auto_ptr W; + epics::auto_ptr W; { Guard G(impl->lock); if(!impl->worker.get()) return; - W = impl->worker; + epics::swap(W, impl->worker); impl->done = true; } diff --git a/src/pv/valueBuilder.cpp b/src/pv/valueBuilder.cpp index d2a8ea0..69e9438 100644 --- a/src/pv/valueBuilder.cpp +++ b/src/pv/valueBuilder.cpp @@ -180,7 +180,7 @@ void ValueBuilder::_add(const std::string& name, ScalarType stype, const void *V THROW_EXCEPTION2(std::logic_error, "Not allowed to replace field. wrong type"); } - std::auto_ptr store; + epics::auto_ptr store; switch(stype) { #define STYPE(stype) case stype: store.reset(new child_scalar::type>(V)); break STYPE(pvBoolean); @@ -216,7 +216,7 @@ void ValueBuilder::_add(const std::string& name, const shared_vector THROW_EXCEPTION2(std::logic_error, "Not allowed to replace field. wrong type"); } - std::auto_ptr store(new child_scalar_array(V)); + epics::auto_ptr store(new child_scalar_array(V)); children[name] = store.get(); store.release(); @@ -229,7 +229,7 @@ ValueBuilder& ValueBuilder::addNested(const std::string& name, Type type, const child_struct *sub; children_t::const_iterator it(children.find(name)); if(it==children.end()) { - std::auto_ptr store(new child_struct(this, id)); + epics::auto_ptr store(new child_struct(this, id)); sub = store.get(); children[name] = store.get(); store.release(); diff --git a/testApp/misc/testByteBuffer.cpp b/testApp/misc/testByteBuffer.cpp index b76c6ec..62ed8dd 100644 --- a/testApp/misc/testByteBuffer.cpp +++ b/testApp/misc/testByteBuffer.cpp @@ -26,7 +26,7 @@ using std::cout; static void testBasicOperations() { - std::auto_ptr buff(new ByteBuffer(32)); + epics::auto_ptr buff(new ByteBuffer(32)); testOk1(buff->getSize()==32); @@ -185,7 +185,7 @@ static void testInverseEndianness(int order, const char *expect) { testDiag("check byte swapping features order=%d", order); - std::auto_ptr buf(new ByteBuffer(32,order)); + epics::auto_ptr buf(new ByteBuffer(32,order)); buf->putShort(0x6162); buf->putInt(0x63646566); diff --git a/testApp/misc/testSharedVector.cpp b/testApp/misc/testSharedVector.cpp index 2d02f68..f1bad00 100644 --- a/testApp/misc/testSharedVector.cpp +++ b/testApp/misc/testSharedVector.cpp @@ -620,9 +620,20 @@ void testBad() //I = epics::pvData::that(CF); } +static +void testAutoSwap() +{ + epics::auto_ptr A(new int(42)), B(new int(43)); + + epics::swap(A, B); + + testOk1(43==*A); + testOk1(42==*B); +} + MAIN(testSharedVector) { - testPlan(167); + testPlan(169); testDiag("Tests for shared_vector"); testDiag("sizeof(shared_vector)=%lu", @@ -643,5 +654,6 @@ MAIN(testSharedVector) testWeak(); testICE(); testBad(); + testAutoSwap(); return testDone(); }