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
41namespace GpgFrontend {
42
48template <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
141
146 SingletonFunctionObject(const T&) = delete;
147
152 void operator=(const T&) = delete;
153
154 protected:
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
229template <typename T>
230int SingletonFunctionObject<T>::_default_channel =
231 GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL;
232
233template <typename T>
234std::mutex SingletonFunctionObject<T>::_instance_mutex;
235
236template <typename T>
237std::shared_mutex SingletonFunctionObject<T>::_instances_mutex;
238
239template <typename T>
240std::unique_ptr<T> SingletonFunctionObject<T>::_instance = nullptr;
241
242template <typename T>
243std::map<int, std::unique_ptr<T>> SingletonFunctionObject<T>::_instances_map;
244
245} // namespace GpgFrontend
246
247#endif // GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
Definition: GpgFunctionObject.h:49
SingletonFunctionObject()=default
Construct a new Singleton Function Object object.
static T & CreateInstance(int channel, std::unique_ptr< T > p_obj=nullptr)
Create a Instance object.
Definition: GpgFunctionObject.h:95
static T & CreateInstance(int channel, std::function< std::unique_ptr< T >(void)> factory)
Create a Instance object.
Definition: GpgFunctionObject.h:76
SingletonFunctionObject(int channel)
Construct a new Singleton Function Object object.
Definition: GpgFunctionObject.h:166
static int GetDefaultChannel()
Get the Default Channel object.
Definition: GpgFunctionObject.h:127
static T * set_object_in_channel(int channel, std::unique_ptr< T > p_obj)
Set the object in channel object.
Definition: GpgFunctionObject.h:215
void SetChannel(int channel)
Set the Channel object.
Definition: GpgFunctionObject.h:179
SingletonFunctionObject(const T &)=delete
Construct a new Singleton Function Object object.
static T * find_object_in_channel(int channel)
Definition: GpgFunctionObject.h:195
virtual ~SingletonFunctionObject()=default
Destroy the Singleton Function Object object.
static T & GetInstance(int channel=GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL)
Get the Instance object.
Definition: GpgFunctionObject.h:57
int GetChannel() const
Get the Channel object.
Definition: GpgFunctionObject.h:134
SingletonFunctionObject(T &&)=delete
Construct a new Singleton Function Object object.
static T & ReleaseChannel(int channel)
Definition: GpgFunctionObject.h:112
Definition: CoreCommonUtil.cpp:29