Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-20 02:31:54

0001 #ifndef FWCore_ServiceRegistry_Signal_h
0002 #define FWCore_ServiceRegistry_Signal_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     ServiceRegistry
0006 // Class  :     Signal
0007 //
0008 /**\class Signal Signal.h FWCore/ServiceRegistry/interface/Signal.h
0009 
0010  Description: A simple implementation of the signal/slot pattern
0011 
0012  Usage:
0013     This is a simple version of the signal/slot pattern and is used by the Framework. It is safe
0014  to call 'emit' from multiple threads simultaneously.
0015  Assumptions:
0016  -The attached slots have a life-time greater than the last 'emit' call issued from the Signal.
0017  -'connect' is not called simultaneously with any other methods of the class.
0018 */
0019 //
0020 // Original Author:  Chris Jones
0021 //         Created:  Thu Jan 17 16:03:51 CST 2013
0022 //
0023 
0024 // system include files
0025 #include <exception>
0026 #include <vector>
0027 #include <functional>
0028 
0029 // user include files
0030 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0031 
0032 // forward declarations
0033 
0034 namespace edm {
0035   namespace signalslot {
0036     template <typename T>
0037     class Signal {
0038     public:
0039       typedef std::function<T> slot_type;
0040       typedef std::vector<slot_type> slot_list_type;
0041 
0042       Signal() = default;
0043       ~Signal() = default;
0044       Signal(Signal&&) = default;
0045       Signal(const Signal&) = delete;
0046       Signal& operator=(const Signal&) = delete;
0047 
0048       // ---------- const member functions ---------------------
0049       template <typename... Args>
0050       void emit(Args&&... args) const {
0051         std::exception_ptr exceptionPtr;
0052         for (auto& slot : m_slots) {
0053           CMS_SA_ALLOW try { slot(std::forward<Args>(args)...); } catch (...) {
0054             if (!exceptionPtr) {
0055               exceptionPtr = std::current_exception();
0056             }
0057           }
0058         }
0059         if (exceptionPtr) {
0060           std::rethrow_exception(exceptionPtr);
0061         }
0062       }
0063 
0064       template <typename... Args>
0065       void operator()(Args&&... args) const {
0066         emit(std::forward<Args>(args)...);
0067       }
0068 
0069       slot_list_type const& slots() const { return m_slots; }
0070       // ---------- static member functions --------------------
0071 
0072       // ---------- member functions ---------------------------
0073       template <typename U>
0074       void connect(U iFunc) {
0075         m_slots.push_back(std::function<T>(iFunc));
0076       }
0077 
0078       template <typename U>
0079       void connect_front(U iFunc) {
0080         m_slots.insert(m_slots.begin(), std::function<T>(iFunc));
0081       }
0082 
0083     private:
0084       // ---------- member data --------------------------------
0085       slot_list_type m_slots;
0086     };
0087   }  // namespace signalslot
0088 }  // namespace edm
0089 
0090 #endif