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