Embedded Artistry Framework
Embedded Systems C++ Framework
Classes | Typedefs | Functions
Scope-bound Resource Management

Utilties that enable SBRM techniques. More...

Collaboration diagram for Scope-bound Resource Management:

Classes

class  embutil::ScopeGuard< TFunc >
 Provides a scope guard idiom to enable custom SBRM behaviors. More...
 

Typedefs

template<typename TType >
using embutil::unique_ptr_aligned = std::unique_ptr< TType, decltype(&aligned_free)>
 Unique pointer alias for aligned memory (calls aligned_free()). More...
 

Functions

template<typename TType >
unique_ptr_aligned< TType > embutil::aligned_uptr (size_t align, size_t size) noexcept
 Create a unique pointer to aligned memory. More...
 
template<typename TType >
std::shared_ptr< TType > embutil::aligned_sptr (size_t align, size_t size) noexcept
 Create a shared pointer to aligned memory. More...
 
template<typename T , typename AcquisitionFunc , typename ReleaseFunc , typename... Args>
std::unique_ptr< T, ReleaseFunc > embutil::unique_resource (AcquisitionFunc acquire, ReleaseFunc release, Args &&... args) noexcept
 Enable Scope-Bound Resource Management (SBRM) for C-style resources (std::unique_ptr variant). More...
 
template<typename T , typename AcquisitionFunc , typename ReleaseFunc , typename... Args>
std::shared_ptr< Tembutil::shared_resource (AcquisitionFunc acquire, ReleaseFunc release, Args &&... args) noexcept
 Enable Scope-Bound Resource Management (SBRM) for C-style resources (std::shared_ptr variant). More...
 
template<typename TFunctor >
ScopeGuard< TFunctor > makeScopeGuard (TFunctor &&func) noexcept
 Create scope guard with provided functor. More...
 
template<typename TFunc , typename... TParams>
auto makeScopeGuard (TFunc &&func, TParams... args) noexcept -> ScopeGuard< decltype(std::bind(std::forward< TFunc >(func), std::forward< TParams >(args)...))>
 Create scope guard by binding the provided function and all the arguments. More...
 

Detailed Description

Utilties that enable SBRM techniques.


Class Documentation

◆ embutil::ScopeGuard

class embutil::ScopeGuard

template<typename TFunc>
class embutil::ScopeGuard< TFunc >

Provides a scope guard idiom to enable custom SBRM behaviors.

The scope guard idiom allows a user to call a function when the guard object is destructed. The guard class enables developes to implement custom SBRM behaviors.

The scope guard uses static memory allocation on the stack. The guard takes as much space on the stack as needed to bind the provided function with all its arguments.

Using the scope guard

In order to properly create a scope guard, you must use the makeScopeGuard() function.

// Binding function with parameters:
auto guard = makeScopeGuard(&func, std::ref(arg1), arg2);
// Binding lamda function:
auto guard = makeScopeGuard([&argByRef, argByValue]()
{
//guard code goes here
});

Note that all the bound parameters are passed by value. To use references with the bound object, use std::ref() (or std::cref() for const reference).

The guard function can be manually called using the release() function.

A guard object only supports move semantics.

Template Parameters
TFuncFunctor object type. The template parameter must be type of the functor that doesn't receive any parameters and doesn't return any value.

Public Member Functions

 ScopeGuard (TFunc &&func) noexcept
 Constructor. More...
 
 ScopeGuard (ScopeGuard &&guard) noexcept
 Move constructor. More...
 
 ScopeGuard (const ScopeGuard &)=delete
 Deleted copy constructor. More...
 
const ScopeGuardoperator= (const ScopeGuard &)=delete
 Deleted copy assignment operator. More...
 
 ~ScopeGuard () noexcept
 Destructor. More...
 
void release () noexcept
 Release the bound functor. More...
 
bool isReleased () const noexcept
 Check whether the functor is released. More...
 

Private Attributes

std::remove_reference< TFunc >::type func_
 
bool active_
 

Related Functions

(Note that these are not member functions.)

template<typename TFunctor >
ScopeGuard< TFunctor > makeScopeGuard (TFunctor &&func) noexcept
 Create scope guard with provided functor. More...
 
template<typename TFunc , typename... TParams>
auto makeScopeGuard (TFunc &&func, TParams... args) noexcept -> ScopeGuard< decltype(std::bind(std::forward< TFunc >(func), std::forward< TParams >(args)...))>
 Create scope guard by binding the provided function and all the arguments. More...
 

Constructor & Destructor Documentation

◆ ScopeGuard() [1/3]

template<typename TFunc >
embutil::ScopeGuard< TFunc >::ScopeGuard ( TFunc &&  func)
inlineexplicitnoexcept

Constructor.

Parameters
[in]funcFunctor that will be executed when the scope guard is destructed (unless it is manually released). Functor must provide move/copy constructor.
Note
Thread safety: Safe for distinct functors.
Exception guarantee: nothrow if copy/move constructors of the bind arguments do not throw, Strong otherwise.

◆ ScopeGuard() [2/3]

template<typename TFunc >
embutil::ScopeGuard< TFunc >::ScopeGuard ( ScopeGuard< TFunc > &&  guard)
inlinenoexcept

Move constructor.

After the functor is moved, it will be released in the provided guard.

Parameters
[in]guardThe other scope guard of the same type.
Note
Thread safety: Unsafe
Exception guarantee: nothrow if copy/move constructors of the bind arguments do not throw, Strong otherwise.

◆ ScopeGuard() [3/3]

template<typename TFunc >
embutil::ScopeGuard< TFunc >::ScopeGuard ( const ScopeGuard< TFunc > &  )
delete

Deleted copy constructor.

◆ ~ScopeGuard()

template<typename TFunc >
embutil::ScopeGuard< TFunc >::~ScopeGuard ( )
inlinenoexcept

Destructor.

This function is marked noexcept because we want the program to terminate if an exception results from this call.

Postcondition
The functor is called unless it was released with the release() function prior to destruction.

References embutil::ScopeGuard< TFunc >::func_, and embutil::ScopeGuard< TFunc >::isReleased().

Member Function Documentation

◆ isReleased()

template<typename TFunc >
bool embutil::ScopeGuard< TFunc >::isReleased ( ) const
inlinenoexcept

Check whether the functor is released.

Returns
true in case of being released.
Note
Thread safety: Unsafe
Exception guarantee: No throw

References embutil::ScopeGuard< TFunc >::active_.

Referenced by embutil::ScopeGuard< TFunc >::~ScopeGuard().

◆ operator=()

template<typename TFunc >
const ScopeGuard& embutil::ScopeGuard< TFunc >::operator= ( const ScopeGuard< TFunc > &  )
delete

Deleted copy assignment operator.

◆ release()

template<typename TFunc >
void embutil::ScopeGuard< TFunc >::release ( )
inlinenoexcept

Release the bound functor.

Postcondition
The functor won't be called when the scope guard is out of scope.
Note
Thread safety: Safe on distinct objects.
Exception guarantee: No throw.

References embutil::ScopeGuard< TFunc >::active_.

Member Data Documentation

◆ active_

template<typename TFunc >
bool embutil::ScopeGuard< TFunc >::active_
private

◆ func_

template<typename TFunc >
std::remove_reference<TFunc>::type embutil::ScopeGuard< TFunc >::func_
private

Typedef Documentation

◆ unique_ptr_aligned

template<typename TType >
using embutil::unique_ptr_aligned = typedef std::unique_ptr<TType, decltype(&aligned_free)>

Unique pointer alias for aligned memory (calls aligned_free()).

This is an alias to aid the aligned pointer declaration. We specify that our alias has a fixed value: the deleter function type (aligned_free()). We use this for the unique_ptr declaration, as it requires us to specify the type of the deleter.

Template Parameters
TTypeThe type of data being allocated.

Function Documentation

◆ aligned_sptr()

template<typename TType >
std::shared_ptr<TType> embutil::aligned_sptr ( size_t  align,
size_t  size 
)
noexcept

Create a shared pointer to aligned memory.

This template function simplifies our declarations of aligned shared pointers. Alignment and size are passed to aligned_malloc(), and aligned_free() is always used as the deleter.

Notice here that the shared pointer doesn't need a special type declaration to work with a deleter.

Template Parameters
TTypeThe type of the data being allocated.
Parameters
alignThe desired alignment. align must be a power of 2.
sizeThe size of the allocation in bytes.
Returns
a std::shared_ptr to aligned memory with aligned_free() configured as the deleter func.

References aligned_free(), and aligned_malloc().

◆ aligned_uptr()

template<typename TType >
unique_ptr_aligned<TType> embutil::aligned_uptr ( size_t  align,
size_t  size 
)
noexcept

Create a unique pointer to aligned memory.

This template function simplifies our declarations of aligned unique pointers. Alignment and size are passed to aligned_malloc(). aligned_free() is always used as the deleter.

Template Parameters
TTypeThe type of the data being allocated.
Parameters
alignThe desired alignment. align must be a power of 2.
sizeThe size of the allocation in bytes.
Returns
a std::unique_ptr to aligned memory with aligned_free() configured as the deleter func.

References aligned_free(), and aligned_malloc().

◆ makeScopeGuard() [1/2]

template<typename TFunctor >
ScopeGuard< TFunctor > makeScopeGuard ( TFunctor &&  func)
related

Create scope guard with provided functor.

Use this function to create a scope guard with lambda function.

Example:

auto guard = embxx::util::makeScopeGuard([&argByRef, argByValue]()
{
//Some code here
});
Template Parameters
TFunctorFunctor type, should be deduced automatically
Parameters
[in]funcFunctor
Returns
Scope guard.
Note
Thread safety: Safe on distinct functors
Exception guarantee: nothrow in case copy/move constructors of the bind arguments do not throw, Basic otherwise.

◆ makeScopeGuard() [2/2]

template<typename TFunc , typename... TParams>
auto makeScopeGuard ( TFunc &&  func,
TParams...  args 
) -> ScopeGuard<decltype(std::bind(std::forward<TFunc>(func), std::forward<TParams>(args)...))>
related

Create scope guard by binding the provided function and all the arguments.

Use this function to create a scope guard when a function with one or more arguments needs to be called.

Example:

// Binding function with parameters:
auto guard = makeScopeGuard(&func, std::ref(arg1), arg2);

Note that all the bound parameters are passed by value. If there is any need to use references with the bound object, use std::ref() (or std::cref() to create a const reference).

This function is marked noexcept because we want the program to terminate if an exception results from this call.

Template Parameters
TFuncPointer to function type
TParamsTypes of other arguments. Variadic, so supports any number of arguments.
Parameters
[in]funcFunctor
[in]argsFunction arguments
Returns
Scope guard.
Note
Thread safety: Unsafe
Exception guarantee: nothrow in case copy/move constructors of the bind arguments do not throw, Basic otherwise.

◆ shared_resource()

template<typename T , typename AcquisitionFunc , typename ReleaseFunc , typename... Args>
std::shared_ptr<T> embutil::shared_resource ( AcquisitionFunc  acquire,
ReleaseFunc  release,
Args &&...  args 
)
noexcept

Enable Scope-Bound Resource Management (SBRM) for C-style resources (std::shared_ptr variant).

The shared_resource() function creates unique pointers that manage C-style Resources. The function takes in an acquisiton function and release function (e.g. fopen and fclose). Remaining arguments are optional. If specified, they will be forwarded to the acquisition function.

The resource is created via the acquisition function and stored in a shared_ptr. When the shared_ptr refcount reaches 0, the delete function will be automatically called.

The shared_resource() function returns a std::shared, and is intended for resources that have multiple owners.

Using shared_resource

You specify the storage type when invoking shared_resource(). For example, if we want to manage a FILE:

shared_resource<FILE>(...);

Note that we use FILE in the template invocation, rather than FILE*. std::shared_resource will actually manage a FILE* under the hood, and that's what the acquire function returns.

The full invocation requires us to specify arguments. In order to open a file we would normally use fopen(), and to close the file we use fclose(). fopen() requires two arguments: a filename and the mode (e.g., read or write). We open a file filename for writing in the following way:

auto sfile = embutil::shared_resource<FILE>(fopen, fclose, filename, "w");

The resulting sfile can be passed into the C-style APIs using the std::shared_ptr .get() member function.

fwrite(test_content, 1, strlen(test_content), sfile.get());

When sfile goes out of scope, the resource will be automatically cleaned up by calling the release function on the managed pointer.

Template Parameters
TThe type of the resource that will be created and managed. This type will actually be converted to a T*, which std::shared_ptr manages.
AcquisitionFuncThe function prototype for the function which is used to create or open the resource (e.g. fopen()). This type will be deduced from the function arguments.
ReleaseFuncThe function prototype for the function which is used to create or destroy the resource (e.g. fclose()). This type will be deduced from the function arguments.
ArgsVariadic list of arguments which will be forwarded to the AcquisitionFunc. This type will be deduced from the function arguments.
Parameters
acquireThe function used to acquire the resource.
releaseThe function used to release the resource.
argsA variadic list of arguments which will be forwarded to the acquire function.
Returns
a std::shared_ptr which manages an instance of type T, configurd with release as the deleter function. When the std::shared_ptr refcount reaches 0, it will be automatically cleaned up via the release function.

◆ unique_resource()

template<typename T , typename AcquisitionFunc , typename ReleaseFunc , typename... Args>
std::unique_ptr<T, ReleaseFunc> embutil::unique_resource ( AcquisitionFunc  acquire,
ReleaseFunc  release,
Args &&...  args 
)
noexcept

Enable Scope-Bound Resource Management (SBRM) for C-style resources (std::unique_ptr variant).

The unique_resource() function creates unique pointers that manage C-style Resources. The function takes in an acquisiton function and release function (e.g. fopen and fclose). Remaining arguments are optional. If specified, they will be forwarded to the acquisition function.

The resource is created via the acquisition function and stored in a unique_ptr. When the unique_ptr goes out of scope, the delete function will be automatically called.

The unique_resource() function returns a std::unique_ptr, and is intended for resources that have a single owner.

Using unique_resource

You specify the storage type when invoking unique_resource(). For example, if we want to manage a FILE:

unique_resource<FILE>(...);

Note that we use FILE in the template invocation, rather than FILE*. std::unique_ptr will actually manage a FILE* under the hood, and that's what the acquire function returns.

The full invocation requires us to specify arguments. In order to open a file we would normally use fopen(), and to close the file we use fclose(). fopen() requires two arguments: a filename and the mode (e.g., read or write). We open a file filename for writing in the following way:

auto ufile = embutil::unique_resource<FILE>(fopen, fclose, filename, "w");

The resulting ufile can be passed into the C-style APIs using the std::unique_ptr .get() member function.

fwrite(test_content, 1, strlen(test_content), ufile.get());

When ufile goes out of scope, the resource will be automatically cleaned up by calling the release function on the managed pointer.

Template Parameters
TThe type of the resource that will be created and managed. This type will actually be converted to a T*, which std::unique_ptr manages.
AcquisitionFuncThe function prototype for the function which is used to create or open the resource (e.g. fopen()). This type will be deduced from the function arguments.
ReleaseFuncThe function prototype for the function which is used to create or destroy the resource (e.g. fclose()). This type will be deduced from the function arguments.
ArgsVariadic list of arguments which will be forwarded to the AcquisitionFunc. This type will be deduced from the function arguments.
Parameters
acquireThe function used to acquire the resource.
releaseThe function used to release the resource.
argsA variadic list of arguments which will be forwarded to the acquire function.
Returns
a std::unique_ptr which manages an instance of type T, configurd with release as the deleter function. When the resource goes out of scope, it will be automatically cleaned up via the release function.