/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
FWCore/Utilities/interface/atomic_value_ptr.h
186 строк
6 KB
W. David Dagenhart
Changes from scram build code-format-all
03 май 2019, 18:48
03 май 2019, 18:48
22c28dc
Код
Авторство
О чём код?
#ifndef FWCore_Utilities_atomic_value_ptr_h #define FWCore_Utilities_atomic_value_ptr_h // ---------------------------------------------------------------------- // // atomic_value_ptr.h - Smart pointer permitting copying of pointed-to object. // // This is an atomic version of value_ptr. // // The prologue of FWCore/Utilities/interface/value_ptr.h // describes the functionality of value_ptr. // // This allows the value of the pointer to be changed atomically. // Note that copy/move construction and copy/move assignment // are *not* atomic, as an object of type T must be copied or moved. // ---------------------------------------------------------------------- #include <atomic> #include <memory> namespace edm { // -------------------------------------------------------------------- // // Auxiliary traits class template providing default clone() // Users should specialize this template for types that have their // own self-copy operations; failure to do so may lead to slicing! // User specified clone methods must be thread safe. // // -------------------------------------------------------------------- template <typename T> struct atomic_value_ptr_traits { static T* clone(T const* p) { return new T(*p); } }; // -------------------------------------------------------------------- // // Copyable smart pointer class template using an atomic pointer. // // -------------------------------------------------------------------- template <typename T> class atomic_value_ptr { public: // -------------------------------------------------- // Default constructor/destructor: // -------------------------------------------------- atomic_value_ptr() : myP(nullptr) {} explicit atomic_value_ptr(T* p) : myP(p) {} ~atomic_value_ptr() { delete myP.load(); } // -------------------------------------------------- // Copy constructor/copy assignment: // -------------------------------------------------- atomic_value_ptr(atomic_value_ptr const& orig) : myP(createFrom(orig.myP.load())) {} atomic_value_ptr& operator=(atomic_value_ptr const& orig) { atomic_value_ptr<T> local(orig); exchangeWithLocal(local); return *this; } atomic_value_ptr(atomic_value_ptr&& orig) : myP(orig.myP.load()) { orig.myP.store(nullptr); } atomic_value_ptr& operator=(atomic_value_ptr&& orig) { atomic_value_ptr<T> local(orig); exchangeWithLocal(local); return *this; } // -------------------------------------------------- // Access mechanisms: // -------------------------------------------------- T& operator*() const { return *myP; } T* operator->() const { return myP.load(); } // -------------------------------------------------- // Copy-like construct/assign from compatible atomic_value_ptr<>: // -------------------------------------------------- template <typename U> atomic_value_ptr(atomic_value_ptr<U> const& orig) : myP(createFrom(orig.operator->())) {} template <typename U> atomic_value_ptr& operator=(atomic_value_ptr<U> const& orig) { atomic_value_ptr<T> local(orig); exchangeWithLocal(local); return *this; } // -------------------------------------------------- // move-like construct/assign from unique_ptr<>: // -------------------------------------------------- atomic_value_ptr(std::unique_ptr<T> orig) : myP(orig.release()) { orig = nullptr; } atomic_value_ptr& operator=(std::unique_ptr<T> orig) { atomic_value_ptr<T> local(std::move(orig)); exchangeWithLocal(local); return *this; } T* load() const { return myP.load(); } bool compare_exchange_strong(T*& oldValue, T* newValue) { return myP.compare_exchange_strong(oldValue, newValue); } // The following typedef, function, and operator definition // support the following syntax: // atomic_value_ptr<T> ptr(..); // if (ptr) { ... // Where the conditional will evaluate as true if and only if the // pointer atomic_value_ptr contains is not null. private: typedef void (atomic_value_ptr::*bool_type)() const; void this_type_does_not_support_comparisons() const {} public: operator bool_type() const { return myP != nullptr ? &atomic_value_ptr<T>::this_type_does_not_support_comparisons : nullptr; } private: // -------------------------------------------------- // Manipulation: // -------------------------------------------------- // This function must be invoked by the object available across threads. // The argument "local" must reference an object local to one thread. void exchangeWithLocal(atomic_value_ptr& local) { T* old = myP.exchange(local.myP.load()); local.myP = old; } // -------------------------------------------------- // Implementation aid: // -------------------------------------------------- template <typename U> static T* createFrom(U const* p) { return p ? atomic_value_ptr_traits<U>::clone(p) : nullptr; } // -------------------------------------------------- // Member data: // -------------------------------------------------- mutable std::atomic<T*> myP; }; // atomic_value_ptr // Do not allow nonsensical comparisons that the bool_type // conversion operator definition above would otherwise allow. // The function call inside the next 4 operator definitions is // private, so compilation will fail if there is an atempt to // instantiate these 4 operators. template <typename T, typename U> inline bool operator==(atomic_value_ptr<T> const& lhs, U const& rhs) { lhs.this_type_does_not_support_comparisons(); return false; } template <typename T, typename U> inline bool operator!=(atomic_value_ptr<T> const& lhs, U const& rhs) { lhs.this_type_does_not_support_comparisons(); return false; } template <typename T, typename U> inline bool operator==(U const& lhs, atomic_value_ptr<T> const& rhs) { rhs.this_type_does_not_support_comparisons(); return false; } template <typename T, typename U> inline bool operator!=(U const& lhs, atomic_value_ptr<T> const& rhs) { rhs.this_type_does_not_support_comparisons(); return false; } } // namespace edm #endif // FWCoreUtilities_atomic_value_ptr_h