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>
49 class SingletonFunctionObject {
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