xref: /aosp_15_r20/external/intel-media-driver/media_common/agnostic/common/cp/cp_factory.h (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2020, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     cp_factory.h
24 //! \brief    Helps with cp specific factory creation.
25 //!
26 
27 #ifndef _CP_FACTORY_H_
28 #define _CP_FACTORY_H_
29 
30 #include <map>
31 #include "mos_utilities.h"
32 
33 //!
34 //! \class    CpFactory
35 //! \brief    Cp factory
36 //!
37 template <class T, typename... Args>
38 class CpFactory
39 {
40 public:
41     typedef T *Type;
42     typedef uint32_t KeyType;
43     typedef Type (*Creator)(Args... args);
44     typedef std::map<KeyType, Creator>  Creators;
45     typedef typename Creators::iterator Iterator;
46 
47     //!
48     //! \brief    register one Class C with key.
49     //! \details  Use the member template to register class C with key and C is the
50     //!           derived class of base class T.
51     //!
52     //! \param    [in] key
53     //!           KeyType, the type alias of uint32_t.
54     //!
55     //! \return   true is returned if class C is successfully registered with key
56     //!           false is returned if key is already registered and doesn't register
57     //!           class C with key.
58     //!
59     template <class C>
Register(KeyType key)60     static bool Register(KeyType key)
61     {
62         Creators &creators = GetCreators();
63         Iterator creator = creators.find(key);
64         if (creator == creators.end())
65         {
66             std::pair<Iterator, bool> result =
67                 GetCreators().insert(std::make_pair(key, Create<C>));
68             return result.second;
69         }
70         else
71         {
72             return true;
73         }
74     }
75 
76     //!
77     //! \brief    create a new object that is registered with key.
78     //! \details  create and return one new object that is registered with key. And Args is passed to create
79     //!           the new object.
80     //!
81     //! \param    [in] key
82     //!           KeyType, the type alias of uint32_t.
83     //!
84     //! \return   the derived object of T is returned if key is found and the object is created.
85     //!           nullptr is returned if key is not found
86     //!
Create(KeyType key,Args...args)87     static Type Create(
88         KeyType key, Args... args)
89     {
90         Creators &creators = GetCreators();
91         Iterator creator = creators.find(key);
92         if (creator != creators.end())
93         {
94             return (creator->second)(args...);
95         }
96         return nullptr;
97     }
98 
99 private:
100 
101     //!
102     //! \brief    the callback function with key.
103     //! \details  The member template to create the derived object
104     //!
105     //! \param    [in] arg
106     //!           ArgType, the type alias of class template parameter.
107     //!
108     //! \return   the created object with arg input for C constructor.
109     //!
110     template <class C>
Create(Args...args)111     static Type Create(Args... args)
112     {
113         return MOS_New(C, args...);
114     }
115 
116 
117     //!
118     //! \brief    obtain the static pair table of param@ key and callback function
119     //! \details  obtain the static pair table that is registered with param@key and callback function
120     //!
121     //! \return   return the static pair table about the param @key and callback function
GetCreators()122     static Creators &GetCreators()
123     {
124         static Creators creators;
125         return creators;
126     }
127 };
128 
129 
130 //!
131 //! \class  CpFactoryWithoutArgs
132 //! \brief  Cp factory no argument class
133 //!
134 template <class T>
135 class CpFactoryWithoutArgs
136 {
137 public:
138     typedef T *Type;
139     typedef uint32_t KeyType;
140     typedef Type (*Creator)();
141     typedef std::map<KeyType, Creator>  Creators;
142     typedef typename Creators::iterator Iterator;
143 
144     //!
145     //! \brief    register one Class C with key.
146     //! \details  Use the member template to register class C with key and C is the
147     //!           derived class of base class T.
148     //!
149     //! \param    [in] key
150     //!           KeyType, the type alias of uint32_t.
151     //!
152     //! \param    [in] forceReplace
153     //!           if force to replace the exsiting Creator, default is false.
154     //!
155     //! \return   true is returned if class C is successfully registered with key
156     //!           false is returned if key is already registered and doesn't register
157     //!           class C with key.
158     //!
159     template <class C>
160     static bool Register(KeyType key, bool forceReplace = false)
161     {
162         Creators &creators = GetCreators();
163         Iterator creator = creators.find(key);
164         if (creator == creators.end())
165         {
166             std::pair<Iterator, bool> result =
167                 GetCreators().insert(std::make_pair(key, Create<C>));
168             return result.second;
169         }
170         else
171         {
172             if (forceReplace)
173             {
174                 creators.erase(creator);
175                 std::pair<Iterator, bool> result =
176                     GetCreators().insert(std::make_pair(key, Create<C>));
177                 return result.second;
178             }
179             return true;
180         }
181     }
182 
183     //!
184     //! \brief    create a new object that is registered with key.
185     //! \details  create and return one new object that is registered with key. And Args is passed to create
186     //!           the new object.
187     //!
188     //! \param    [in] key
189     //!           KeyType, the type alias of uint32_t.
190     //!
191     //! \return   the derived object of T is returned if key is found and the object is created.
192     //!           nullptr is returned if key is not found
193     //!
Create(KeyType key)194     static Type Create(KeyType key)
195     {
196         Creators &creators = GetCreators();
197         Iterator creator = creators.find(key);
198         if (creator != creators.end())
199         {
200             return (creator->second)();
201         }
202         return nullptr;
203     }
204 
205 private:
206 
207     //!
208     //! \brief    the callback function with key.
209     //! \details  The member template to create the derived object
210     //!
211     //! \return   the created object
212     //!
213     template <class C>
Create()214     static Type Create()
215     {
216         return MOS_New(C);
217     }
218 
219     //!
220     //! \brief    obtain the static pair table of param@ key and callback function
221     //! \details  obtain the static pair table that is registered with param@key and callback function
222     //!
223     //! \return   return the static pair table about the param @key and callback function
GetCreators()224     static Creators &GetCreators()
225     {
226         static Creators creators;
227         return creators;
228     }
229 };
230 
231 #endif // _CP_FACTORY_H_
232