The Gaudi Framework  master (b9786168)
Loading...
Searching...
No Matches
ContextSpecificPtr.h
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
3* *
4* This software is distributed under the terms of the Apache version 2 licence, *
5* copied verbatim in the file "LICENSE". *
6* *
7* In applying this licence, CERN does not waive the privileges and immunities *
8* granted to it by virtue of its status as an Intergovernmental Organization *
9* or submit itself to any jurisdiction. *
10\***********************************************************************************/
11#pragma once
12
13#include <functional>
14#include <mutex>
15#include <numeric>
16#include <type_traits>
17#include <unordered_map>
18
19// For the definition of GAUDI_API
20#include <GaudiKernel/Kernel.h>
22
23class EventContext;
24
25namespace Gaudi {
26 namespace Hive {
38 template <typename T>
40 private:
42 typedef std::unordered_map<ContextIdType, T*> StorageType;
43
44 public:
46 T* get() const {
47 auto lock = std::scoped_lock{ m_ptrs_lock };
48 return m_ptrs[currentContextId()];
49 }
50
51 T*& set( T* ptr ) {
52 auto lock = std::scoped_lock{ m_ptrs_lock };
53 return m_ptrs[currentContextId()] = ptr;
54 }
55
57 T*& operator=( T* ptr ) { return set( ptr ); }
58
60 bool isValid() const { return get(); }
61
63 operator bool() const { return isValid(); }
64
66 bool operator==( T* rhs ) const { return get() == rhs; }
67
69 T& operator*() { return *get(); }
70 const T& operator*() const { return *get(); }
71 T* operator->() { return get(); }
72 const T* operator->() const { return get(); }
74
76
78 void clear() { m_ptrs.clear(); }
79
83 template <class Mapper>
84 auto accumulate( Mapper f, std::invoke_result_t<Mapper, const T*> init ) const -> decltype( init ) {
85 return accumulate( f, init, std::plus<>() );
86 }
87
91 template <class Mapper, class BinaryOperation>
92 auto accumulate( Mapper f, std::invoke_result_t<Mapper, const T*> init, BinaryOperation op ) const
93 -> decltype( init ) {
94 auto lock = std::scoped_lock{ m_ptrs_lock };
95 return std::accumulate( m_ptrs.begin(), m_ptrs.end(), init, [&f, &op]( const auto& partial, const auto& p ) {
96 return op( partial, f( p.second ) );
97 } );
98 }
99
101 template <class F>
102 void for_each( F f ) const {
103 auto lock = std::scoped_lock{ m_ptrs_lock };
104 for ( auto& i : m_ptrs ) f( i.second );
105 }
106
108 template <class F>
109 void for_each( F f ) {
110 auto lock = std::scoped_lock{ m_ptrs_lock };
111 for ( auto& i : m_ptrs ) f( i.second );
112 }
113
115 template <class F>
116 void for_all( F f ) const {
117 auto lock = std::scoped_lock{ m_ptrs_lock };
118 for ( auto& i : m_ptrs ) f( i.first, i.second );
119 }
120 template <class F>
121 void for_all( F f ) {
122 auto lock = std::scoped_lock{ m_ptrs_lock };
123 for ( auto& i : m_ptrs ) f( i.first, i.second );
124 }
125
126 void deleteAll() {
127 for_each( []( T*& p ) {
128 delete p;
129 p = nullptr;
130 } );
131 }
132
133 private:
137 mutable std::mutex m_ptrs_lock;
138 };
139
146 template <typename T>
148 public:
150 ContextSpecificData( T proto = {} ) : m_proto( std::move( proto ) ) {}
151
153 ~ContextSpecificData() { m_ptr.deleteAll(); }
154
156 T& get() const {
157 if ( !m_ptr ) m_ptr.set( new T( m_proto ) );
158 return *m_ptr;
159 }
160
162 operator T&() { return get(); }
163 operator const T&() const { return get(); }
164
166 get(); // ensure there is a value for this thread
167 return m_ptr;
168 }
170 get(); // ensure there is a value for this thread
171 return m_ptr;
172 }
173
174
176 T& operator=( const T& other ) { return static_cast<T&>( *this ) = other; }
177
179 T accumulate( T init ) const { return accumulate( init, std::plus<>() ); }
180
183 template <class T1, class BinaryOperation>
184 T1 accumulate( T1 init, BinaryOperation op ) const {
185 return m_ptr.accumulate( []( const T* p ) { return *p; }, init, op );
186 }
187
189 template <class F>
190 void for_each( F f ) const {
191 m_ptr.for_each( [&f]( const T* p ) { f( *p ); } );
192 }
193
195 template <class F>
196 void for_each( F f ) {
197 m_ptr.for_each( [&f]( T* p ) { f( *p ); } );
198 }
199
201 template <class F>
202 void for_all( F f ) const {
203 m_ptr.for_all( [&f]( size_t s, const T* p ) { f( s, *p ); } );
204 }
205 template <class F>
206 void for_all( F f ) {
207 m_ptr.for_all( [&f]( size_t s, T* p ) { f( s, *p ); } );
208 }
209
210 private:
211 // FIXME: implement a proper copy constructor
213
215 T m_proto = {};
218 };
219 } // namespace Hive
220} // namespace Gaudi
This class represents an entry point to all the event specific data.
ContextSpecificData(T proto={})
Constructor with prototype value.
ContextSpecificPtr< T > & operator->()
void for_all(F f) const
Call a function on each element, passing slot# as well.
ContextSpecificData(const ContextSpecificData &)=delete
T & get() const
Access contained value.
ContextSpecificPtr< T > m_ptr
Internal implementation.
T & operator=(const T &other)
Assignment operator.
void for_each(F f) const
Call a function on each contained value.
const ContextSpecificPtr< T > & operator->() const
T accumulate(T init) const
Return the sum of all the contained values using init as first value.
T1 accumulate(T1 init, BinaryOperation op) const
Return the accumulated result, through the operation 'op', of all the contained values using init as ...
void for_each(F f)
Call a function on each contained value. (non-const version)
Simple implementation of a smart pointer with different values for different event contexts (slots).
T & operator*()
Dereference operators.
T * get() const
Return the pointer for the current context (null for a new context).
auto accumulate(Mapper f, std::invoke_result_t< Mapper, const T * > init, BinaryOperation op) const -> decltype(init)
Taking a function f that from a T* produces a value, return the accumulated result,...
std::mutex m_ptrs_lock
Mutex for the m_ptrs container.
T *& set(T *ptr)
Set the pointer for the current context.
void for_all(F f) const
Call a function on each element, passing slot# as well.
std::unordered_map< ContextIdType, T * > StorageType
Type used for the internal storage.
void for_each(F f) const
Call a function on each contained pointer.
StorageType m_ptrs
Internal storage for the different internal pointers.
T *& operator=(T *ptr)
Assignment operator (.
auto accumulate(Mapper f, std::invoke_result_t< Mapper, const T * > init) const -> decltype(init)
Taking a function f that from a T* produces a value, return the sum of all the values corresponding t...
bool isValid() const
Return true if the pointer is not null.
bool operator==(T *rhs) const
Comparison with another pointer.
void for_each(F f)
Call a function on each contained pointer. (non-const version)
void clear()
Non thread-safe methods.
GAUDI_API ContextIdType currentContextId()
Return the current context id.
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition __init__.py:1
STL namespace.