Belle II Software development
ScopeGuard Class Reference

Simple ScopeGuard to execute a function at the end of the object lifetime. More...

#include <ScopeGuard.h>

Public Member Functions

template<class Callable >
 ScopeGuard (Callable &&f)
 Construct a object with a callable function to be called on destruction.
 
 ScopeGuard (const ScopeGuard &)=delete
 No copies.
 
 ScopeGuard (ScopeGuard &&sg)=delete
 No move construction.
 
ScopeGuardoperator= (const ScopeGuard &)=delete
 No assignment.
 
ScopeGuardoperator= (ScopeGuard &&)=delete
 No move assignment.
 
 ~ScopeGuard ()
 Call function on destruct unless released has been called.
 
void release ()
 Release the guard without calling the cleanup function.
 

Static Public Member Functions

template<class T >
static ScopeGuard guardValue (T &reference)
 Create a ScopeGuard for a value: The content of reference will be copied and reset when the returned object goes out of scope.
 
template<class T , class V >
static ScopeGuard guardValue (T &reference, const V &newValue)
 Create a ScopeGuard for a value: The content of reference will be copied and reset when the returned object goes out of scope.
 
template<class Getter , class Setter >
static ScopeGuard guardGetterSetter (Getter getter, Setter setter)
 Create a ScopeGuard from a getter and setter: On construction the getter object is called to obtain a value which is handed to the setter when the guard object goes out of scope.
 
template<class Getter , class Setter >
static ScopeGuard guardGetterSetter (const Getter &getter, Setter setter, const typename std::result_of< Getter()>::type newValue)
 Create a ScopeGuard from a getter and setter: On construction first the getter is called to get the original value, then the setter is called to set the new value and when the guard object is destructed the setter is called with the original value again.
 
template<class Functor >
static ScopeGuard guardFunctor (Functor functor)
 Create a ScopeGuard from a functor object with appropriately overloaded operator() calls to get and set the values.
 
template<class Functor >
static ScopeGuard guardFunctor (Functor functor, const typename std::result_of< Functor()>::type &newValue)
 Create a ScopeGuard from a functor object with appropriately overloaded operator() calls to get and set the values.
 
template<class T >
static ScopeGuard guardDeletion (T *&pointer)
 Create a ScopeGuard to delete a raw pointer at the end of the scope.
 
template<class CharT , class Traits = typename std::char_traits<CharT>>
static ScopeGuard guardStreamState (std::basic_ios< CharT, Traits > &stream)
 Create a ScopeGuard for the state of a stream to reset all the formatting at the end of the object lifetime.
 
static ScopeGuard guardWorkingDirectory ()
 Create a ScopeGuard of the current working directory.
 
static ScopeGuard guardWorkingDirectory (const std::string &newDirectory)
 Create a ScopeGuard of the current working directory and change into a new directory.
 
static ScopeGuard guardBatchMode (bool batchMode=true)
 Create a ScopeGuard to turn ROOT into batch mode and restore the initial batch mode status after the guard object is destroyed.
 

Private Attributes

std::function< void()> m_exitfunc
 Function to be called on exit.
 
bool m_engaged {true}
 Indicate whether function should be called.
 

Detailed Description

Simple ScopeGuard to execute a function at the end of the object lifetime.

This should be used when you want to make sure some cleanup is performed at the end of the current scope even if you might have multiple possible ways to exit the scope (return statements, exceptions).

Optionally you can call release() to indicate that cleanup will not be needed after all but the state should remain as it is.

For many common use cases there are factory functions to create the correct ScopeGuard object automatically

See also
guardValue(), guardGetterSetter(), guardFunctor(), guardDeletion(), guardStreamState(), guardWorkingDirectory()

Definition at line 36 of file ScopeGuard.h.

Constructor & Destructor Documentation

◆ ScopeGuard()

ScopeGuard ( Callable &&  f)
inlineexplicit

Construct a object with a callable function to be called on destruction.

Definition at line 44 of file ScopeGuard.h.

44: m_exitfunc{std::forward<Callable>(f)} {}
std::function< void()> m_exitfunc
Function to be called on exit.
Definition: ScopeGuard.h:39

◆ ~ScopeGuard()

~ScopeGuard ( )
inline

Call function on destruct unless released has been called.

Definition at line 54 of file ScopeGuard.h.

54{ if (m_engaged) m_exitfunc(); }
bool m_engaged
Indicate whether function should be called.
Definition: ScopeGuard.h:41

Member Function Documentation

◆ guardBatchMode()

static ScopeGuard guardBatchMode ( bool  batchMode = true)
inlinestatic

Create a ScopeGuard to turn ROOT into batch mode and restore the initial batch mode status after the guard object is destroyed.

Restoring the initial status is important if your code e..g should run with and without the display module.

{
// the default is to turn on batch mode. You can also pass "false" to turn off
// the batch mode for the scope of this guard.
// now batch mode is turned on
}
// now back to what it was before.
static ScopeGuard guardBatchMode(bool batchMode=true)
Create a ScopeGuard to turn ROOT into batch mode and restore the initial batch mode status after the ...
Definition: ScopeGuard.h:352
Warning
Do not just call this function and discard the return value. You have to assign the return value to an object in the current scope to the scope guard to work as intended.

Definition at line 352 of file ScopeGuard.h.

353 {
354 auto getBatchMode = []() {
355 return gROOT->IsBatch();
356 };
357
358 auto setBatchMode = [](bool batchMode_) {
359 gROOT->SetBatch(batchMode_);
360 };
361
362 return guardGetterSetter(getBatchMode, setBatchMode, batchMode);
363 }
static ScopeGuard guardGetterSetter(Getter getter, Setter setter)
Create a ScopeGuard from a getter and setter: On construction the getter object is called to obtain a...
Definition: ScopeGuard.h:137

◆ guardDeletion()

static ScopeGuard guardDeletion ( T *&  pointer)
inlinestatic

Create a ScopeGuard to delete a raw pointer at the end of the scope.

Sometimes with ROOT we cannot use std::unique_ptr as ROOT wants the address of the pointer to modify it and allocate objects but ROOT still gives us ownership :/.

This class is thus a very simplified scope guard which will just delete the pointer on destruction but still allows using a raw pointer so that ROOT can do whatever it does while this guard is alive.

Warning
Most of the time you don't want this but std::unique_ptr instead. Only use this if you know what you are doing.
Do not just call this function and discard the return value. You have to assign the return value to an object in the current scope to the scope guard to work as intended.
Parameters
pointerreference to a raw pointer to be deleted when the returned guard object goes out of scope

Definition at line 239 of file ScopeGuard.h.

240 {
241 return ScopeGuard([&pointer]() { delete pointer; pointer = nullptr; });
242 }
ScopeGuard(Callable &&f)
Construct a object with a callable function to be called on destruction.
Definition: ScopeGuard.h:44

◆ guardFunctor() [1/2]

static ScopeGuard guardFunctor ( Functor  functor)
inlinestatic

Create a ScopeGuard from a functor object with appropriately overloaded operator() calls to get and set the values.

Otherwise it behaves exactly like guardGetterSetter()

Warning
Do not just call this function and discard the return value. You have to assign the return value to an object in the current scope to the scope guard to work as intended.
Parameters
functorAn object which has a suitable overloaded operator() to be able to
  • get a value ( const T& operator()(); )
  • set a value ( void operator()(const T&); )

Definition at line 188 of file ScopeGuard.h.

189 {
190 typedef typename std::invoke_result<Functor>::type value_type;
191 std::function<void(const value_type&)> setter(functor);
192 const auto old = functor();
193 return ScopeGuard([setter, old] {setter(old);});
194 }

◆ guardFunctor() [2/2]

static ScopeGuard guardFunctor ( Functor  functor,
const typename std::result_of< Functor()>::type &  newValue 
)
inlinestatic

Create a ScopeGuard from a functor object with appropriately overloaded operator() calls to get and set the values.

Otherwise it behaves exactly like guardGetterSetter()

Warning
Do not just call this function and discard the return value. You have to assign the return value to an object in the current scope to the scope guard to work as intended.
Parameters
functorAn object which has a suitable overloaded operator() to be able to
  • get a value (const T& operator()();)
  • set a value (void operator()(const T&);)
newValuea new value to pass to the functor when this function is called

Definition at line 210 of file ScopeGuard.h.

211 {
212 typedef typename std::invoke_result<Functor>::type value_type;
213 std::function<void(const value_type&)> setter(functor);
214 const auto old = functor();
215 setter(newValue);
216 return ScopeGuard([setter, old] {setter(old);});
217 }

◆ guardGetterSetter() [1/2]

static ScopeGuard guardGetterSetter ( const Getter &  getter,
Setter  setter,
const typename std::result_of< Getter()>::type  newValue 
)
inlinestatic

Create a ScopeGuard from a getter and setter: On construction first the getter is called to get the original value, then the setter is called to set the new value and when the guard object is destructed the setter is called with the original value again.

{
auto numberOfEventsGuard = ScopeGuard::guardGetterSetter(
56);
// now the number of events is set to 56 but when this block is finished
// the number of events will be reset to its original value
}
void setNumberEventsOverride(unsigned int nevents)
Override the number of events in run 1 for EventInfoSetter module.
Definition: Environment.h:64
static Environment & Instance()
Static method to get a reference to the Environment instance.
Definition: Environment.cc:28
unsigned int getNumberEventsOverride() const
Returns number of events in run 1 for EventInfoSetter module, or 0 for no override.
Definition: Environment.h:67
Warning
Do not just call this function and discard the return value. You have to assign the return value to an object in the current scope to the scope guard to work as intended.
Parameters
gettera callable object to return a value
settera callable object to set a value of the same type
newValuea new value to pass to the setter when this function is called

Definition at line 168 of file ScopeGuard.h.

170 {
171 const auto old = getter();
172 setter(newValue);
173 return ScopeGuard([setter, old]() { setter(old); });
174 }

◆ guardGetterSetter() [2/2]

static ScopeGuard guardGetterSetter ( Getter  getter,
Setter  setter 
)
inlinestatic

Create a ScopeGuard from a getter and setter: On construction the getter object is called to obtain a value which is handed to the setter when the guard object goes out of scope.

{
auto numberOfEventsGuard = ScopeGuard::guardGetterSetter(
);
// when this block is finished the number of events will be reset to its
// original value
}
Warning
Do not just call this function and discard the return value. You have to assign the return value to an object in the current scope to the scope guard to work as intended.
Parameters
gettera callable object to return a value
settera callable object to set a value of the same type

Definition at line 137 of file ScopeGuard.h.

138 {
139 const auto old = getter();
140 return ScopeGuard([setter, old]() { setter(old); });
141 }

◆ guardStreamState()

static ScopeGuard guardStreamState ( std::basic_ios< CharT, Traits > &  stream)
inlinestatic

Create a ScopeGuard for the state of a stream to reset all the formatting at the end of the object lifetime.

{
auto guard = ScopeGuard::guardStreamState(std::cout);
std::cout << std::setprecision(56) << std::fixed << "Indiana pi: " << 3.2 << std::endl;
}
// now the formatting changes are reset
static ScopeGuard guardStreamState(std::basic_ios< CharT, Traits > &stream)
Create a ScopeGuard for the state of a stream to reset all the formatting at the end of the object li...
Definition: ScopeGuard.h:262
Warning
Do not just call this function and discard the return value. You have to assign the return value to an object in the current scope to the scope guard to work as intended.
Parameters
streamstream object to reset

Definition at line 262 of file ScopeGuard.h.

263 {
264 const std::ios::fmtflags flags{stream.flags()};
265 const std::streamsize precision{stream.precision()};
266 const std::streamsize width{stream.width()};
267 const CharT fill{stream.fill()};
268
269 return ScopeGuard([ =, &stream]() {
270 stream.flags(flags);
271 stream.precision(precision);
272 stream.width(width);
273 stream.fill(fill);
274 });
275 }

◆ guardValue() [1/2]

static ScopeGuard guardValue ( T &  reference)
inlinestatic

Create a ScopeGuard for a value: The content of reference will be copied and reset when the returned object goes out of scope.

int value{6};
{
auto guard = ScopeGuard::guardValue(value);
value = 45;
// now value=45
}
// now reverted to value=6
static ScopeGuard guardValue(T &reference)
Create a ScopeGuard for a value: The content of reference will be copied and reset when the returned ...
Definition: ScopeGuard.h:76
Warning
Do not just call this function and discard the return value. You have to assign the return value to an object in the current scope to the scope guard to work as intended.
Parameters
referencea reference to a value to be guarded

Definition at line 76 of file ScopeGuard.h.

77 {
78 // the [[nodiscard]] will issue warnings when users just call this
79 // function and don't assign the ScopeGuard
80 const T old = reference;
81 // This works even without any assignment or move constructors since
82 // C++17 guarantees that this temporary object will be constructed in
83 // place and no movement is required (tags: RVO, copy elision)
84 return ScopeGuard([&reference, old]() { reference = old; });
85 }

◆ guardValue() [2/2]

static ScopeGuard guardValue ( T &  reference,
const V &  newValue 
)
inlinestatic

Create a ScopeGuard for a value: The content of reference will be copied and reset when the returned object goes out of scope.

Will also immediately set a new value.

int value{6};
{
auto guard = ScopeGuard::guardValue(value, 45);
// now value=45
}
// now reverted to value=6
Warning
Do not just call this function and discard the return value. You have to assign the return value to an object in the current scope to the scope guard to work as intended.
Parameters
referencea reference to a value to be guarded
newValuethe new value to set the reference to. Has to be assignable to reference

Definition at line 108 of file ScopeGuard.h.

109 {
110 const T old = reference;
111 reference = newValue;
112 return ScopeGuard([&reference, old]() { reference = old; });
113 }

◆ guardWorkingDirectory() [1/2]

static ScopeGuard guardWorkingDirectory ( )
inlinestatic

Create a ScopeGuard of the current working directory.

This makes sure that whatever happens to the current working directory we return to the original working directory when the ScopeGuard is destroyed.

{
// possibly change directory
}
// now back where we were
static ScopeGuard guardWorkingDirectory()
Create a ScopeGuard of the current working directory.
Definition: ScopeGuard.h:296
Warning
Do not just call this function and discard the return value. You have to assign the return value to an object in the current scope to the scope guard to work as intended.

Definition at line 296 of file ScopeGuard.h.

297 {
298 const std::string old{gSystem->GetWorkingDirectory()};
299 return ScopeGuard([old]() {gSystem->ChangeDirectory(old.c_str());});
300 }

◆ guardWorkingDirectory() [2/2]

static ScopeGuard guardWorkingDirectory ( const std::string &  newDirectory)
inlinestatic

Create a ScopeGuard of the current working directory and change into a new directory.

This makes sure that whatever happens to the current working directory we return to the original working directory when the ScopeGuard is destroyed.

{
auto guard = ScopeGuard::guardWorkingDirectory("/tmp");
// now in tmp directory
}
// now back where we were.
Warning
Do not just call this function and discard the return value. You have to assign the return value to an object in the current scope to the scope guard to work as intended.

Definition at line 323 of file ScopeGuard.h.

324 {
325 const std::string old{gSystem->GetWorkingDirectory()};
326 gSystem->ChangeDirectory(newDirectory.c_str());
327 return ScopeGuard([old]() {gSystem->ChangeDirectory(old.c_str());});
328 }

◆ release()

void release ( )
inline

Release the guard without calling the cleanup function.

Definition at line 56 of file ScopeGuard.h.

56{ m_engaged = false; }

Member Data Documentation

◆ m_engaged

bool m_engaged {true}
private

Indicate whether function should be called.

Definition at line 41 of file ScopeGuard.h.

◆ m_exitfunc

std::function<void()> m_exitfunc
private

Function to be called on exit.

Definition at line 39 of file ScopeGuard.h.


The documentation for this class was generated from the following file: