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