Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <functional>
- #include <memory>
- #include <mutex>
- #include <utility>
- namespace ift630 {
- using std::unique_ptr;
- template <typename T>
- class Monitor {
- mutable unique_ptr<std::mutex> mtx;
- T resource;
- public:
- template <typename... Args>
- explicit Monitor(Args&&... args) noexcept
- : mtx{std::make_unique<std::mutex>()}, resource(std::forward<Args>(args)...) {}
- explicit Monitor(T&& resource) noexcept
- : mtx{std::make_unique<std::mutex>()}, resource{resource} {}
- Monitor(const Monitor&) = delete;
- Monitor(Monitor&& other) noexcept = default;
- ~Monitor() noexcept = default;
- auto operator=(const Monitor&) -> Monitor& = delete;
- auto operator=(Monitor&&) noexcept -> Monitor& = default;
- template <typename F>
- auto operator()(F f) {
- const auto _ = std::lock_guard{*mtx};
- return f(resource);
- }
- template <typename F>
- auto operator()(F f) const {
- const auto _ = std::lock_guard{*mtx};
- return f(resource);
- }
- };
- template <typename T>
- auto make_monitor(T&& resource) -> Monitor<T> {
- return Monitor{std::forward(resource)};
- }
- template <typename T>
- auto make_monitor(T& resource) -> Monitor<T> {
- return Monitor{resource};
- }
- } // namespace ift630
- // Example usage
- // using std::vector;
- // using std::string;
- // using ift630::Monitor;
- // const auto messages = vector<string>{"first", "second", "third"};
- // auto sync_vec = Monitor<vector<string>>{std::move(messages)};
- // sync_vec([](vector<string>&messages) {
- // for(const auto& m : messages)
- // std::cout << m << '\n';
- // });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement