Created
June 26, 2018 13:28
-
-
Save akindyakov/73b27b39c77ddf5060d2f2fed1819f7e to your computer and use it in GitHub Desktop.
Mutex guarded access controller
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <mutex> | |
#include <shared_mutex> | |
#include <string> | |
#include <thread> | |
template< | |
typename Type | |
, typename MutexType | |
, typename LockType | |
> | |
class AccessController { | |
public: | |
explicit AccessController( | |
Type& value | |
, MutexType& mutex | |
) | |
: value_(value) | |
, lock_(mutex) | |
{ | |
} | |
Type& get() { | |
return value_; | |
} | |
private: | |
Type& value_; | |
LockType lock_; | |
}; | |
template< | |
typename Type | |
, typename MutexType = std::mutex | |
> | |
class MutexAccessController | |
{ | |
public: | |
explicit MutexAccessController( | |
Type value | |
) | |
: value_(std::move(value)) | |
{ | |
} | |
MutexAccessController(MutexAccessController&&) = default; | |
MutexAccessController& operator=(MutexAccessController&&) = default; | |
MutexAccessController(const MutexAccessController&) = delete; | |
MutexAccessController& operator=(const MutexAccessController&) = delete; | |
auto shared_controller() const { | |
return this->controller<std::shared_controller<MutexType>>(); | |
} | |
auto unique_controller() { | |
return this->controller<std::unique_controller<MutexType>>(); | |
} | |
template< | |
typename LockType | |
> | |
auto controller() { | |
return AccessController<Type, MutexType, LockType>(value_, mutex_); | |
} | |
template< | |
typename LockType | |
> | |
auto controller() const { | |
return AccessController<const Type, MutexType, LockType>(value_, mutex_); | |
} | |
MutexType& mutex() const { | |
return mutex_; | |
} | |
Type& unsafe_value() { | |
return mutex_; | |
} | |
const Type& unsafe_value() const { | |
return mutex_; | |
} | |
private: | |
Type value_; | |
mutable MutexType mutex_; | |
}; | |
int main() { | |
MutexAccessController<std::string, std::shared_timed_mutex> ac{"first"}; | |
{ | |
auto rock = ac.shared_controller(); | |
const auto& str = rock.get(); | |
std::cout << "shared rock: " << str << '\n'; | |
} | |
{ | |
auto work = ac.unique_controller(); | |
auto& str = work.get(); | |
str += " second"; | |
std::cout << "shared work: " << str << '\n'; | |
} | |
{ | |
auto work = ac.unique_controller(); | |
std::cout << "shared work: " << work.get() << '\n'; | |
} | |
MutexAccessController<std::string, std::mutex> acUnique{"second"}; | |
{ | |
auto work = acUnique.unique_controller(); | |
auto& str = work.get(); | |
str += " third"; | |
std::cout << "unique work: " << str << '\n'; | |
} | |
{ | |
auto work = acUnique.unique_controller(); | |
std::cout << "unique work: " << work.get() << '\n'; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment