GpgFrontend Project
A Free, Powerful, Easy-to-Use, Compact, Cross-Platform, and Installation-Free OpenPGP(pgp) Crypto Tool.
GpgFunctionObject.h
1 
29 #ifndef GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
30 #define GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
31 
32 #include <map>
33 #include <memory>
34 #include <mutex>
35 #include <shared_mutex>
36 #include <stdexcept>
37 #include <string>
38 
39 #include "GpgConstants.h"
40 
41 namespace GpgFrontend {
42 
48 template <typename T>
50  public:
57  static T& GetInstance(
58  int channel = GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL) {
59  static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
60  "T not derived from SingletonFunctionObject<T>");
61 
62  auto _p_pbj = find_object_in_channel(channel);
63  if (_p_pbj == nullptr)
64  return *set_object_in_channel(channel, std::make_unique<T>(channel));
65  else
66  return *_p_pbj;
67  }
68 
76  static T& CreateInstance(int channel,
77  std::function<std::unique_ptr<T>(void)> factory) {
78  static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
79  "T not derived from SingletonFunctionObject<T>");
80 
81  auto _p_pbj = find_object_in_channel(channel);
82  if (_p_pbj == nullptr)
83  return *set_object_in_channel(channel, std::move(factory()));
84  else
85  return *_p_pbj;
86  }
87 
95  static T& CreateInstance(int channel, std::unique_ptr<T> p_obj = nullptr) {
96  static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
97  "T not derived from SingletonFunctionObject<T>");
98 
99  auto _p_pbj = find_object_in_channel(channel);
100  if (_p_pbj == nullptr)
101  return *set_object_in_channel(channel, std::move(p_obj));
102  else
103  return *_p_pbj;
104  }
105 
112  static T& ReleaseChannel(int channel) {
113  decltype(_instances_map.end()) _it;
114  {
115  std::shared_lock lock(_instances_mutex);
116  _it = _instances_map.find(channel);
117  }
118  if (_it != _instances_map.end()) _instances_map.erase(_it);
119  DLOG(INFO) << "channel" << channel << "released";
120  }
121 
127  static int GetDefaultChannel() { return _default_channel; }
128 
134  [[nodiscard]] int GetChannel() const { return channel_; }
135 
140  SingletonFunctionObject(T&&) = delete;
141 
146  SingletonFunctionObject(const T&) = delete;
147 
152  void operator=(const T&) = delete;
153 
154  protected:
159  SingletonFunctionObject() = default;
160 
166  explicit SingletonFunctionObject(int channel) : channel_(channel) {}
167 
172  virtual ~SingletonFunctionObject() = default;
173 
179  void SetChannel(int channel) { this->channel_ = channel; }
180 
181  private:
182  int channel_ = _default_channel;
183  static int _default_channel;
184  static std::mutex _instance_mutex;
185  static std::shared_mutex _instances_mutex;
186  static std::unique_ptr<T> _instance;
187  static std::map<int, std::unique_ptr<T>> _instances_map;
188 
195  static T* find_object_in_channel(int channel) {
196  // read _instances_map
197  decltype(_instances_map.end()) _it;
198  {
199  std::shared_lock lock(_instances_mutex);
200  _it = _instances_map.find(channel);
201  if (_it == _instances_map.end())
202  return nullptr;
203  else
204  return _it->second.get();
205  }
206  }
207 
215  static T* set_object_in_channel(int channel, std::unique_ptr<T> p_obj) {
216  {
217  if (p_obj == nullptr) p_obj = std::make_unique<T>();
218  T* obj = p_obj.get();
219  obj->SetChannel(channel);
220  {
221  std::unique_lock lock(_instances_mutex);
222  _instances_map.insert({channel, std::move(p_obj)});
223  }
224  return obj;
225  }
226  }
227 };
228 
229 template <typename T>
230 int SingletonFunctionObject<T>::_default_channel =
231  GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL;
232 
233 template <typename T>
234 std::mutex SingletonFunctionObject<T>::_instance_mutex;
235 
236 template <typename T>
237 std::shared_mutex SingletonFunctionObject<T>::_instances_mutex;
238 
239 template <typename T>
240 std::unique_ptr<T> SingletonFunctionObject<T>::_instance = nullptr;
241 
242 template <typename T>
243 std::map<int, std::unique_ptr<T>> SingletonFunctionObject<T>::_instances_map;
244 
245 } // namespace GpgFrontend
246 
247 #endif // GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
GpgFrontend::SingletonFunctionObject::ReleaseChannel
static T & ReleaseChannel(int channel)
Definition: GpgFunctionObject.h:112
GpgFrontend::SingletonFunctionObject
Definition: GpgFunctionObject.h:49
GpgFrontend::SingletonFunctionObject::SetChannel
void SetChannel(int channel)
Set the Channel object.
Definition: GpgFunctionObject.h:179
GpgFrontend
Definition: CoreCommonUtil.cpp:29
GpgFrontend::SingletonFunctionObject::GetInstance
static T & GetInstance(int channel=GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL)
Get the Instance object.
Definition: GpgFunctionObject.h:57
GpgFrontend::SingletonFunctionObject::SingletonFunctionObject
SingletonFunctionObject(int channel)
Construct a new Singleton Function Object object.
Definition: GpgFunctionObject.h:166
GpgFrontend::SingletonFunctionObject::GetChannel
int GetChannel() const
Get the Channel object.
Definition: GpgFunctionObject.h:134
GpgFrontend::SingletonFunctionObject::~SingletonFunctionObject
virtual ~SingletonFunctionObject()=default
Destroy the Singleton Function Object object.
GpgFrontend::SingletonFunctionObject::CreateInstance
static T & CreateInstance(int channel, std::unique_ptr< T > p_obj=nullptr)
Create a Instance object.
Definition: GpgFunctionObject.h:95
GpgFrontend::SingletonFunctionObject::set_object_in_channel
static T * set_object_in_channel(int channel, std::unique_ptr< T > p_obj)
Set the object in channel object.
Definition: GpgFunctionObject.h:215
GpgFrontend::SingletonFunctionObject::SingletonFunctionObject
SingletonFunctionObject()=default
Construct a new Singleton Function Object object.
GpgFrontend::SingletonFunctionObject::GetDefaultChannel
static int GetDefaultChannel()
Get the Default Channel object.
Definition: GpgFunctionObject.h:127
GpgFrontend::SingletonFunctionObject::find_object_in_channel
static T * find_object_in_channel(int channel)
Definition: GpgFunctionObject.h:195
GpgFrontend::SingletonFunctionObject::CreateInstance
static T & CreateInstance(int channel, std::function< std::unique_ptr< T >(void)> factory)
Create a Instance object.
Definition: GpgFunctionObject.h:76