OwningMutex

mrs_lib::OwningMutex

template<typename T, typename Mutex = std::mutex>
class OwningMutex

A thread-safe wrapper for shared data with mutex protection.

Template Parameters:
  • T – The type of data to be protected by the mutex.

  • Mutex – The mutex type to use (defaults to std::mutex).

Public Functions

OwningMutex() = default

Construct with default-initialized data.

Note

This constructor is only available if the type of the contained object is default constructible.

inline OwningMutex(const T &val)

Construct by copying the data.

Parameters:

val – The value to copy into the OwningMutex.

inline OwningMutex(T &&val)

Construct by moving the data.

Parameters:

val – The value to move into the OwningMutex.

~OwningMutex() = default

Default destructor.

OwningMutex(const OwningMutex&) = delete

OwningMutex is immovable.

OwningMutex &operator=(const OwningMutex&) = delete

OwningMutex is immovable.

OwningMutex(OwningMutex&&) = delete

OwningMutex is immovable.

OwningMutex &operator=(OwningMutex&&) = delete

OwningMutex is immovable.

inline OwningMutexGuard<true> acquire()

Acquires a mutable guard for the OwningMutex.

Returns:

A mutable guard that allows modification of the data.

inline OwningMutexGuard<false> acquire() const

Acquires a const guard for the OwningMutex.

Returns:

A const guard that allows read-only access to the data.

inline T load() const

Loads the current value of the data.

Returns:

The current value of the data.

inline void store(T val)

Stores a new value into the data.

Note

This method requires the type of the contained class to be noexcept move constructible.

Parameters:

val – The value to store.

mrs_lib::OwningMutex::OwningMutexGuard

template<bool Mutable>
class OwningMutexGuard

A mutex guard for OwningMutex to ensure thread-safe access.

The OwningMutexGuard class provides RAII-style mutex locking and unlocking. It ensures that the mutex is locked when the guard is constructed and unlocked when the guard is destroyed.

Note

To obtain instance of this class, use OwningMutex::acquire.

Template Parameters:
  • Mutable – Whether the guard can modify the data (true) or only read (false).

  • T – The type of data to be protected by the mutex.

  • Mutex – The mutex type.

Public Functions

~OwningMutexGuard() = default

Default destructor.

OwningMutexGuard(const OwningMutexGuard&) = delete

OwningMutexGuard is immovable.

OwningMutexGuard &operator=(const OwningMutexGuard&) = delete

OwningMutexGuard is immovable.

OwningMutexGuard(OwningMutexGuard&&) = delete

OwningMutexGuard is immovable.

OwningMutexGuard &operator=(OwningMutexGuard&&) = delete

OwningMutexGuard is immovable.

inline T &operator*() &

Dereference operator for mutable access.

Note

This method is only available if Mutable is true.

Returns:

Reference to the data.

inline const T &operator*() const &

Dereference operator for const access.

Returns:

Reference to the data.

T &operator*() && = delete

Rvalue overloads are deleted to prevent accidental unlocking.

const T &operator*() const && = delete

Rvalue overloads are deleted to prevent accidental unlocking.

inline T *operator->() &

Arrow operator for mutable access.

Note

This method is only available if Mutable is true.

Returns:

Pointer to the data.

inline const T *operator->() const &

Arrow operator for const access.

Returns:

Pointer to the data.

T *operator->() && = delete

Rvalue overloads are deleted to prevent accidental unlocking.

const T *operator->() const && = delete

Rvalue overloads are deleted to prevent accidental unlocking.

Example

Example of the OwningMutex usage.
 1struct PrinterData
 2{
 3  std::size_t count = 1;
 4  std::string text = "hi";
 5};
 6
 7class MyRepeatedPrinter
 8{
 9public:
10  void set_count(std::size_t count)
11  {
12    // non const `data_` -> mutable guard
13    auto guard = data_.acquire();
14    guard->count = count;
15  }
16
17  void set_text(std::string text)
18  {
19    // non const `data_` -> mutable guard
20    auto guard = data_.acquire();
21    guard->text = std::move(text);
22  }
23
24  void print(std::ostream& os) const
25  {
26    // const `data_` -> const guard
27    auto guard = data_.acquire();
28
29    // guard->count += 1; // This would cause compilation error.
30    //                    // We only get const access.
31
32    for (std::size_t i = 0; i < guard->count; ++i)
33    {
34      os << guard->text << "\n";
35    }
36  }
37
38private:
39  mrs_lib::OwningMutex<PrinterData> data_{};
40};