Buran Motion Planning Framework
safe_ptr.h
1 #pragma once
2 
3 #include <iostream>
4 #include <string>
5 #include <vector>
6 #include <memory>
7 #include <mutex>
8 #include <thread>
9 #include <map>
10 
16 template<typename T, typename mutex_t = std::recursive_mutex, typename x_lock_t =
17 std::unique_lock<mutex_t>, typename s_lock_t = std::unique_lock<mutex_t >>
18 class safe_ptr {
19  typedef mutex_t mtx_t;
20  const std::shared_ptr<T> ptr;
21  std::shared_ptr<mutex_t> mtx_ptr;
22 
23  template<typename req_lock>
24  class auto_lock_t {
25  T *const ptr;
26  req_lock lock;
27  public:
28  auto_lock_t(auto_lock_t &&o) : ptr(std::move(o.ptr)), lock(std::move(o.lock)) {}
29 
30  auto_lock_t(T *const _ptr, mutex_t &_mtx) : ptr(_ptr), lock(_mtx) {}
31 
32  T *operator->() { return ptr; }
33 
34  const T *operator->() const { return ptr; }
35  };
36 
37  template<typename req_lock>
38  class auto_lock_obj_t {
39  T *const ptr;
40  req_lock lock;
41  public:
42  auto_lock_obj_t(auto_lock_obj_t &&o) :
43  ptr(std::move(o.ptr)), lock(std::move(o.lock)) {}
44 
45  auto_lock_obj_t(T *const _ptr, mutex_t &_mtx) : ptr(_ptr), lock(_mtx) {}
46 
47  template<typename arg_t>
48  auto operator[](arg_t arg) -> decltype((*ptr)[arg]) { return (*ptr)[arg]; }
49  };
50 
51  void lock() { mtx_ptr->lock(); }
52 
53  void unlock() { mtx_ptr->unlock(); }
54 
55  friend struct link_safe_ptrs;
56 
57  template<typename mutex_type> friend
58  class std::lock_guard;
59  //template<class... mutex_types> friend class std::lock_guard; // C++17
60 public:
61 
62  const std::shared_ptr<T> &getPtr() const { return ptr; }
63 
64  template<typename... Args>
65  safe_ptr(Args... args) : ptr(std::make_shared<T>(args...)), mtx_ptr(std::make_shared<mutex_t>()) {}
66 
67  auto_lock_t<x_lock_t> operator->() { return auto_lock_t<x_lock_t>(ptr.get(), *mtx_ptr); }
68 
69  auto_lock_obj_t<x_lock_t> operator*() { return auto_lock_obj_t<x_lock_t>(ptr.get(), *mtx_ptr); }
70 
71  const auto_lock_t<s_lock_t> operator->() const { return auto_lock_t<s_lock_t>(ptr.get(), *mtx_ptr); }
72 
73  const auto_lock_obj_t<s_lock_t> operator*() const { return auto_lock_obj_t<s_lock_t>(ptr.get(), *mtx_ptr); }
74 };
75 
76 
77 //
78 //safe_ptr<std::map<std::string, std::pair<std::string, int> >> safe_map_strings_global;
79 //
80 //
81 //void func(decltype(safe_map_strings_global) safe_map_strings)
82 //{
83 // //std::lock_guard<decltype(safe_map_strings)> lock(safe_map_strings);
84 //
85 // (*safe_map_strings)["apple"].first = "fruit";
86 // (*safe_map_strings)["potato"].first = "vegetable";
87 //
88 // for (size_t i = 0; i < 10000; ++i) {
89 // safe_map_strings->at("apple").second++;
90 // safe_map_strings->find("potato")->second.second++;
91 // }
92 //
93 // auto const readonly_safe_map_string = safe_map_strings;
94 //
95 // std::cout << "potato is " << readonly_safe_map_string->at("potato").first <<
96 // " " << readonly_safe_map_string->at("potato").second <<
97 // ", apple is " << readonly_safe_map_string->at("apple").first <<
98 // " " << readonly_safe_map_string->at("apple").second << std::endl;
99 //}
100 //
101 //
102 //int main() {
103 //
104 // std::vector<std::thread> vec_thread(10);
105 // for (auto &i : vec_thread) i = std::move(std::thread(func, safe_map_strings_global));
106 // for (auto &i : vec_thread) i.join();
107 //
108 // std::cout << "end";
109 // int b; std::cin >> b;
110 //
111 // return 0;
112 //}
safe_ptr
Definition: safe_ptr.h:18