1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef MAPLE_UTIL_INCLUDE_FACTORY_H
17 #define MAPLE_UTIL_INCLUDE_FACTORY_H
18 #include <map>
19 #include <memory>
20 #include <functional>
21 #include <mutex>
22
23 namespace maple {
24 template <typename TKey, typename TObject, typename... TArgs>
25 class ObjectFactory final {
26 public:
27 using key_type = TKey;
28 using creator_type = std::function<std::unique_ptr<TObject>(TArgs...)>;
29
Register(const key_type &key, creator_type func)30 void Register(const key_type &key, creator_type func)
31 {
32 if (creator.find(key) == creator.end()) {
33 creator[key] = func;
34 }
35 }
36
Create(const key_type &key, TArgs... args) const37 std::unique_ptr<TObject> Create(const key_type &key, TArgs... args) const
38 {
39 auto it = creator.find(key);
40 return it == creator.end() ? std::unique_ptr<TObject>() : (it->second)(std::forward<TArgs>(args)...);
41 }
42
43 template <typename TObjectImpl>
DefaultCreator(TArgs.... args)44 static std::unique_ptr<TObject> DefaultCreator(TArgs... args)
45 {
46 return std::make_unique<TObjectImpl>(std::forward<TArgs>(args)...);
47 }
48
ins()49 static ObjectFactory &ins()
50 {
51 static ObjectFactory factory;
52 return factory;
53 }
54
55 ObjectFactory(const ObjectFactory &) = delete;
56 ObjectFactory &operator=(const ObjectFactory &) = delete;
57 ObjectFactory(const ObjectFactory &&) = delete;
58 ObjectFactory &operator=(const ObjectFactory &&) = delete;
59
60 private:
61 ObjectFactory() = default;
62 ~ObjectFactory() = default;
63
64 private:
65 using CreatorHolder = std::map<key_type, creator_type>;
66 CreatorHolder creator;
67 };
68
69 template <typename TFactory, typename TFactory::key_type Key, typename TObjectImpl>
RegisterFactoryObject()70 inline void RegisterFactoryObject()
71 {
72 TFactory::ins().Register(Key, TFactory::template DefaultCreator<TObjectImpl>);
73 }
74
75 template <typename TFactory, typename... TArgs>
CreateProductObject(const typename TFactory::key_type &key, TArgs &&... args)76 inline auto CreateProductObject(const typename TFactory::key_type &key, TArgs &&... args)
77 {
78 return TFactory::ins().Create(key, std::forward<TArgs>(args)...);
79 }
80
81 template <typename TKey, typename TRet, typename... TArgs>
82 class FunctionFactory final {
83 public:
84 using key_type = TKey;
85 using creator_type = std::function<TRet(TArgs...)>;
86
Register(const key_type &key, creator_type func)87 void Register(const key_type &key, creator_type func)
88 {
89 if (creator.find(key) == creator.end()) {
90 creator[key] = func;
91 }
92 }
93
Create(const key_type &key) const94 creator_type Create(const key_type &key) const
95 {
96 auto it = creator.find(key);
97 return it == creator.end() ? nullptr : it->second;
98 }
99
ins()100 static FunctionFactory &ins()
101 {
102 static FunctionFactory factory;
103 return factory;
104 }
105
106 FunctionFactory(const FunctionFactory &) = delete;
107 FunctionFactory &operator=(const FunctionFactory &) = delete;
108 FunctionFactory(const FunctionFactory &&) = delete;
109 FunctionFactory &operator=(const FunctionFactory &&) = delete;
110
111 private:
112 FunctionFactory() = default;
113 ~FunctionFactory() = default;
114
115 private:
116 using CreatorHolder = std::map<key_type, creator_type>;
117 CreatorHolder creator;
118 };
119
120 template <typename TFactory>
RegisterFactoryFunction(const typename TFactory::key_type &key, typename TFactory::creator_type func)121 inline void RegisterFactoryFunction(const typename TFactory::key_type &key, typename TFactory::creator_type func)
122 {
123 TFactory::ins().Register(key, func);
124 }
125
126 template <typename TFactory>
CreateProductFunction(const typename TFactory::key_type &key)127 inline auto CreateProductFunction(const typename TFactory::key_type &key)
128 {
129 return TFactory::ins().Create(key);
130 }
131 } // namespace maple
132
133 #endif // MAPLE_UTIL_INCLUDE_FACTORY_H
134