The Gaudi Framework  master (37c0b60a)
ContextSpecificPtr.h
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 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 #ifndef _GAUDI_CONTEXTSPECIFICPTR_H_
12 #define _GAUDI_CONTEXTSPECIFICPTR_H_
13 
14 #include <functional>
15 #include <mutex>
16 #include <numeric>
17 #include <type_traits>
18 #include <unordered_map>
19 
20 // For the definition of GAUDI_API
21 #include <GaudiKernel/Kernel.h>
23 
24 class EventContext;
25 
26 namespace Gaudi {
27  namespace Hive {
39  template <typename T>
41  private:
44 
45  public:
47  T* get() const {
48  auto lock = std::scoped_lock{ m_ptrs_lock };
49  return m_ptrs[currentContextId()];
50  }
52  T*& set( T* ptr ) {
53  auto lock = std::scoped_lock{ m_ptrs_lock };
54  return m_ptrs[currentContextId()] = ptr;
55  }
56 
58  T*& operator=( T* ptr ) { return set( ptr ); }
59 
61  bool isValid() const { return get(); }
62 
64  operator bool() const { return isValid(); }
65 
67  bool operator==( T* rhs ) const { return get() == rhs; }
68 
70  T& operator*() { return *get(); }
71  const T& operator*() const { return *get(); }
72  T* operator->() { return get(); }
73  const T* operator->() const { return get(); }
75 
77 
79  void clear() { m_ptrs.clear(); }
80 
84  template <class Mapper>
85 #if __cplusplus >= 201703L
86  auto accumulate( Mapper f, std::invoke_result_t<Mapper, const T*> init ) const -> decltype( init ) {
87 #else
88  auto accumulate( Mapper f, std::result_of_t<Mapper( const T* )> init ) const -> decltype( init ) {
89 #endif
90  return accumulate( f, init, std::plus<>() );
91  }
92 
96  template <class Mapper, class BinaryOperation>
97 #if __cplusplus >= 201703L
98  auto accumulate( Mapper f, std::invoke_result_t<Mapper, const T*> init, BinaryOperation op ) const
99 #else
100  auto accumulate( Mapper f, std::result_of_t<Mapper( const T* )> init, BinaryOperation op ) const
101 #endif
102  -> decltype( init ) {
103  auto lock = std::scoped_lock{ m_ptrs_lock };
104  return std::accumulate( m_ptrs.begin(), m_ptrs.end(), init, [&f, &op]( const auto& partial, const auto& p ) {
105  return op( partial, f( p.second ) );
106  } );
107  }
108 
110  template <class F>
111  void for_each( F f ) const {
112  auto lock = std::scoped_lock{ m_ptrs_lock };
113  for ( auto& i : m_ptrs ) f( i.second );
114  }
115 
117  template <class F>
118  void for_each( F f ) {
119  auto lock = std::scoped_lock{ m_ptrs_lock };
120  for ( auto& i : m_ptrs ) f( i.second );
121  }
122 
124  template <class F>
125  void for_all( F f ) const {
126  auto lock = std::scoped_lock{ m_ptrs_lock };
127  for ( auto& i : m_ptrs ) f( i.first, i.second );
128  }
129  template <class F>
130  void for_all( F f ) {
131  auto lock = std::scoped_lock{ m_ptrs_lock };
132  for ( auto& i : m_ptrs ) f( i.first, i.second );
133  }
134 
135  void deleteAll() {
136  for_each( []( T*& p ) {
137  delete p;
138  p = nullptr;
139  } );
140  }
141 
142  private:
147  };
148 
155  template <typename T>
157  public:
159  ContextSpecificData( T proto = {} ) : m_proto( std::move( proto ) ) {}
160 
162  ~ContextSpecificData() { m_ptr.deleteAll(); }
163 
164  operator T&() {
165  if ( !m_ptr ) m_ptr = new T( m_proto );
166  return *m_ptr;
167  }
168 
169  operator T&() const {
170  if ( !m_ptr ) m_ptr = new T( m_proto );
171  return *m_ptr;
172  }
173 
175  T& operator=( const T& other ) { return (T&)( *this ) = other; }
176 
178  T accumulate( T init ) const { return accumulate( init, std::plus<>() ); }
179 
182  template <class T1, class BinaryOperation>
183  T1 accumulate( T1 init, BinaryOperation op ) const {
184  return m_ptr.accumulate( []( const T* p ) { return *p; }, init, op );
185  }
186 
188  template <class F>
189  void for_each( F f ) const {
190  m_ptr.for_each( [&f]( const T* p ) { f( *p ); } );
191  }
192 
194  template <class F>
195  void for_each( F f ) {
196  m_ptr.for_each( [&f]( T* p ) { f( *p ); } );
197  }
198 
200  template <class F>
201  void for_all( F f ) const {
202  m_ptr.for_all( [&f]( size_t s, const T* p ) { f( s, *p ); } );
203  }
204  template <class F>
205  void for_all( F f ) {
206  m_ptr.for_all( [&f]( size_t s, T* p ) { f( s, *p ); } );
207  }
208 
209  private:
210  // FIXME: implement a proper copy constructor
212 
214  T m_proto = {};
217  };
218  } // namespace Hive
219 } // namespace Gaudi
220 
221 #endif // _GAUDI_CONTEXTSPECIFICPTR_H_
Gaudi::Hive::ContextSpecificPtr::operator==
bool operator==(T *rhs) const
Comparison with another pointer.
Definition: ContextSpecificPtr.h:67
Gaudi::Hive::ContextSpecificPtr::clear
void clear()
Non thread-safe methods.
Definition: ContextSpecificPtr.h:79
Gaudi::Hive::ContextSpecificPtr::operator*
T & operator*()
Dereference operators.
Definition: ContextSpecificPtr.h:70
Gaudi::Hive::ContextSpecificData::ContextSpecificData
ContextSpecificData(T proto={})
Constructor with prototype value.
Definition: ContextSpecificPtr.h:159
std::move
T move(T... args)
Gaudi::Hive::ContextSpecificData::accumulate
T accumulate(T init) const
Return the sum of all the contained values using init as first value.
Definition: ContextSpecificPtr.h:178
gaudirun.s
string s
Definition: gaudirun.py:346
Gaudi::Hive::ContextSpecificPtr::operator->
T * operator->()
Definition: ContextSpecificPtr.h:72
Gaudi::Hive::ContextSpecificPtr::set
T *& set(T *ptr)
Set the pointer for the current context.
Definition: ContextSpecificPtr.h:52
Gaudi::Hive::ContextSpecificData::m_ptr
ContextSpecificPtr< T > m_ptr
Internal implementation.
Definition: ContextSpecificPtr.h:216
Gaudi::Hive::ContextSpecificPtr::m_ptrs_lock
std::mutex m_ptrs_lock
Mutex for the m_ptrs container.
Definition: ContextSpecificPtr.h:146
std::unordered_map::clear
T clear(T... args)
Gaudi::Hive::ContextSpecificData::accumulate
T1 accumulate(T1 init, BinaryOperation op) const
Return the accumulated result, through the operation 'op', of all the contained values using init as ...
Definition: ContextSpecificPtr.h:183
Gaudi::Hive::ContextSpecificData::operator=
T & operator=(const T &other)
Assignment operator.
Definition: ContextSpecificPtr.h:175
Gaudi::Hive::ContextSpecificPtr::operator=
T *& operator=(T *ptr)
Assignment operator (.
Definition: ContextSpecificPtr.h:58
Gaudi::Hive::ContextSpecificPtr::deleteAll
void deleteAll()
Definition: ContextSpecificPtr.h:135
std::plus
Gaudi::Hive::ContextSpecificPtr
Simple implementation of a smart pointer with different values for different event contexts (slots).
Definition: ContextSpecificPtr.h:40
Gaudi::Hive::ContextSpecificData::for_each
void for_each(F f) const
Call a function on each contained value.
Definition: ContextSpecificPtr.h:189
Gaudi::Hive::ContextSpecificData::ContextSpecificData
ContextSpecificData(const ContextSpecificData &)=delete
Gaudi::Hive::ContextSpecificData::for_all
void for_all(F f) const
Call a function on each element, passing slot# as well.
Definition: ContextSpecificPtr.h:201
std::accumulate
T accumulate(T... args)
Gaudi::Hive::ContextSpecificPtr::m_ptrs
StorageType m_ptrs
Internal storage for the different internal pointers.
Definition: ContextSpecificPtr.h:144
Gaudi
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition: __init__.py:1
Gaudi::Hive::ContextSpecificPtr::for_each
void for_each(F f) const
Call a function on each contained pointer.
Definition: ContextSpecificPtr.h:111
Gaudi::Hive::ContextSpecificPtr::get
T * get() const
Return the pointer for the current context (null for a new context).
Definition: ContextSpecificPtr.h:47
Gaudi::Hive::ContextSpecificPtr::for_all
void for_all(F f) const
Call a function on each element, passing slot# as well.
Definition: ContextSpecificPtr.h:125
Gaudi::Hive::ContextSpecificPtr::StorageType
std::unordered_map< ContextIdType, T * > StorageType
Type used for the internal storage.
Definition: ContextSpecificPtr.h:43
Gaudi::Hive::ContextSpecificData::~ContextSpecificData
~ContextSpecificData()
Destructor.
Definition: ContextSpecificPtr.h:162
ThreadLocalContext.h
std::unordered_map::begin
T begin(T... args)
Gaudi::Hive::ContextSpecificData::for_each
void for_each(F f)
Call a function on each contained value. (non-const version)
Definition: ContextSpecificPtr.h:195
Kernel.h
EventContext
Definition: EventContext.h:34
Gaudi::Hive::ContextSpecificPtr::operator->
const T * operator->() const
Definition: ContextSpecificPtr.h:73
Gaudi::Hive::currentContextId
GAUDI_API ContextIdType currentContextId()
Return the current context id.
Definition: ThreadLocalContext.cpp:28
Gaudi::Hive::ContextSpecificPtr::operator*
const T & operator*() const
Definition: ContextSpecificPtr.h:71
std::mutex
STL class.
std::unordered_map::end
T end(T... args)
Gaudi::Hive::ContextSpecificData
Implementation of a context specific storage accessible as a sort of smart reference class.
Definition: ContextSpecificPtr.h:156
Gaudi::Hive::ContextSpecificData::for_all
void for_all(F f)
Definition: ContextSpecificPtr.h:205
Gaudi::Hive::ContextSpecificPtr::isValid
bool isValid() const
Return true if the pointer is not null.
Definition: ContextSpecificPtr.h:61
std::unordered_map< ContextIdType, T * >
Gaudi::Hive::ContextSpecificPtr::accumulate
auto accumulate(Mapper f, std::result_of_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,...
Definition: ContextSpecificPtr.h:100
Gaudi::Hive::ContextSpecificPtr::accumulate
auto accumulate(Mapper f, std::result_of_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...
Definition: ContextSpecificPtr.h:88
Gaudi::Hive::ContextSpecificPtr::for_each
void for_each(F f)
Call a function on each contained pointer. (non-const version)
Definition: ContextSpecificPtr.h:118
Gaudi::Hive::ContextSpecificPtr::for_all
void for_all(F f)
Definition: ContextSpecificPtr.h:130