|
libpsynth 0.2.1
|
00001 00011 /* 00012 * Copyright (C) 2009 Juan Pedro BolĂvar Puente 00013 * 00014 * This program is free software: you can redistribute it and/or modify 00015 * it under the terms of the GNU General Public License as published by 00016 * the Free Software Foundation, either version 3 of the License, or 00017 * (at your option) any later version. 00018 * 00019 * This program is distributed in the hope that it will be useful, 00020 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00022 * GNU General Public License for more details. 00023 * 00024 * You should have received a copy of the GNU General Public License 00025 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00026 * 00027 */ 00028 00029 #ifndef PSYNTH_FACTORY_MANAGER_H_ 00030 #define PSYNTH_FACTORY_MANAGER_H_ 00031 00032 #include <map> 00033 #include <functional> 00034 #include <psynth/base/exception.hpp> 00035 #include <psynth/base/iterator.hpp> 00036 #include <psynth/base/singleton.hpp> 00037 00038 namespace psynth 00039 { 00040 namespace base 00041 { 00042 00043 PSYNTH_DECLARE_ERROR (error, factory_error); 00044 00045 namespace detail 00046 { 00047 00052 template <typename FactoryManager> 00053 struct factory_access 00054 { 00055 typedef typename FactoryManager::key_type key_type; 00056 typedef typename FactoryManager::factory_method factory_method; 00057 00058 template <class Concrete> 00059 static void add (FactoryManager& self, const key_type& k) 00060 { self.add <Concrete> (k); } 00061 00062 static void add (FactoryManager& self, const key_type& k, factory_method fn) 00063 { self.add (k, fn); } 00064 00065 static void del (FactoryManager& self, const key_type& k) 00066 { self.del (k); } 00067 }; 00068 00069 } /* namespace detail */ 00070 00071 00076 template <class Key, class BasePtr, typename ...Args> 00077 class restricted_factory_manager 00078 { 00079 public: 00080 typedef Key key_type; 00081 typedef BasePtr pointer_type; 00082 typedef typename pointee<BasePtr>::type base_type; 00083 00084 typedef std::function<pointer_type (Args ...)> factory_method; 00085 typedef map_key_iterator<Key, factory_method> iterator; 00086 00087 pointer_type create (const Key&, Args...); 00088 00089 size_t size () 00090 { return _map.size (); } 00091 00092 iterator begin () 00093 { return _map.begin (); } 00094 00095 iterator end () 00096 { return _map.end (); } 00097 00098 protected: 00099 template <class Concrete> 00100 void add (const Key& k); 00101 void add (const Key& k, factory_method fn); 00102 void del (const Key& k); 00103 00104 private: 00105 friend class detail::factory_access<restricted_factory_manager>; 00106 typedef std::map<Key, factory_method> factory_map; 00107 factory_map _map; 00108 }; 00109 00110 template <class Key, class BasePtr, typename ...Args> 00111 class factory_manager : 00112 public restricted_factory_manager <Key, BasePtr, Args...> 00113 { 00114 typedef restricted_factory_manager <Key, BasePtr, Args...> base; 00115 typedef typename base::factory_method factory_method; 00116 00117 public: 00118 template <class Concrete> 00119 void add (const Key& k) 00120 { this->base::template add <Concrete> (k); } 00121 00122 void add (const Key& k, factory_method fn) 00123 { this->base::add (k, fn); } 00124 00125 void del (const Key& k) 00126 { this->base::del (k); } 00127 }; 00128 00129 template <class GlobalFactory, class Concrete> 00130 struct factory_registrant : public boost::noncopyable 00131 { 00132 typedef typename GlobalFactory::type factory_type; 00133 typedef typename factory_type::key_type key_type; 00134 00135 factory_registrant (key_type k) 00136 { 00137 detail::factory_access<factory_type>::template add<Concrete> ( 00138 GlobalFactory::self (), k); 00139 } 00140 }; 00141 00142 template <typename Key, typename BasePtr, typename... Args> 00143 struct global_factory_manager : 00144 public singleton_holder<factory_manager< 00145 Key, BasePtr, Args...> > 00146 { 00147 template <class Concrete> 00148 struct registrant : factory_registrant<global_factory_manager, 00149 Concrete> 00150 { 00151 registrant (Key k) 00152 : factory_registrant<global_factory_manager, 00153 Concrete> (k) 00154 {} 00155 }; 00156 }; 00157 00158 template <typename Key, typename BasePtr, typename... Args> 00159 struct restricted_global_factory_manager : 00160 public singleton_holder<restricted_factory_manager< 00161 Key, BasePtr, Args...> > 00162 { 00163 template <class Concrete> 00164 struct registrant : factory_registrant<restricted_global_factory_manager, 00165 Concrete> 00166 { 00167 registrant (Key k) 00168 : factory_registrant<restricted_global_factory_manager, 00169 Concrete> (k) 00170 {} 00171 }; 00172 }; 00173 00174 00175 } /* namespace base */ 00176 } /* namespace psynth */ 00177 00178 #include <psynth/base/factory_manager.tpp> 00179 00180 #endif /* PSYNTH_FACTORY_MANAGER_H_ */
1.7.4