$search
00001 // Copyright Vladimir Prus 2004. 00002 // Distributed under the Boost Software License, Version 1.0. 00003 // (See accompanying file LICENSE_1_0.txt 00004 // or copy at http://www.boost.org/LICENSE_1_0.txt) 00005 00006 #ifndef BOOST_PLUGIN_FACTORY_VP_2004_08_25 00007 #define BOOST_PLUGIN_FACTORY_VP_2004_08_25 00008 00009 #include <utilmm/plugin/virtual_constructors.hh> 00010 #include <utilmm/plugin/dll.hh> 00011 #include <utilmm/plugin/abstract_factory.hh> 00012 #include <utility> 00013 #include <stdexcept> 00014 #include <string> 00015 #include <utility> 00016 00017 namespace utilmm { namespace plugin { 00018 00019 namespace { 00020 typedef std::map<std::string, boost::any> exported_plugins_t; 00021 typedef exported_plugins_t& (*get_plugins_list_t)(); 00022 typedef exported_plugins_t& (get_plugins_list_np)(); 00023 00024 template<class BasePlugin> 00025 std::pair<abstract_factory<BasePlugin>*, 00026 dll_handle > 00027 get_abstract_factory(const dll& d, const std::string& klass) 00028 { 00029 boost::shared_ptr<get_plugins_list_np> f; 00030 f = d.template get<exported_plugins_t& (*)()>("boost_exported_plugins_list"); 00031 exported_plugins_t& e = (*f)(); 00032 00033 if (e.count(klass)) { 00034 00035 abstract_factory<BasePlugin>** xw = 00036 boost::any_cast<abstract_factory<BasePlugin>*>(&(e[klass])); 00037 00038 if (!xw) { 00039 throw std::logic_error("Can't cast to the right factor type\n"); 00040 } 00041 abstract_factory<BasePlugin>* w = *xw; 00042 return make_pair(w, f); 00043 } else { 00044 throw std::logic_error("Class of the specified name is not found"); 00045 } 00046 } 00047 00048 } 00049 00050 00051 00052 struct empty_plugin_factory_item { 00053 void create(int****); 00054 protected: 00055 dll m_dll; 00056 }; 00057 00058 template<class BasePlugin, class Base, class Parameters> 00059 struct plugin_factory_item { 00060 }; 00061 00062 template<class BasePlugin, class Base> 00063 struct plugin_factory_item<BasePlugin, Base, boost::mpl::list<> > : public Base { 00064 using Base::create; 00065 BasePlugin* create(const std::string& name) 00066 { 00067 std::pair<abstract_factory<BasePlugin>*, 00068 dll_handle > r = get_abstract_factory<BasePlugin>(this->m_dll, name); 00069 return r.first->create(r.second); 00070 } 00071 }; 00072 00073 template<class BasePlugin, class Base, class A1> 00074 struct plugin_factory_item<BasePlugin, Base, boost::mpl::list<A1> > : public Base { 00075 using Base::create; 00076 BasePlugin* create(const std::string& name, A1 a1) 00077 { 00078 std::pair<abstract_factory<BasePlugin>*, 00079 dll_handle > r = get_abstract_factory<BasePlugin>(this->m_dll, name); 00080 return r.first->create(r.second, a1); 00081 } 00082 }; 00083 00084 template<class BasePlugin, class Base, class A1, class A2> 00085 struct plugin_factory_item<BasePlugin, Base, boost::mpl::list<A1, A2> > : public Base { 00086 using Base::create; 00087 BasePlugin* create(const std::string& name, A1 a1, A2 a2) 00088 { 00089 std::pair<abstract_factory<BasePlugin>*, 00090 dll_handle > r = get_abstract_factory<BasePlugin>(this->m_dll, name); 00091 return r.first->create(r.second, a1, a2); 00092 } 00093 }; 00094 00095 #if 0 00096 00097 template<class BasePlugin, class Base, class Parameters> 00098 struct plugin_factory_item 00099 : public Base, 00100 public plugin_factory_item_N<BasePlugin, Parameters> 00101 00102 { 00103 using Base::create; 00104 using plugin_factory_item_N<BasePlugin, Parameters>::create; 00105 }; 00106 #endif 00107 00108 using namespace boost::mpl::placeholders; 00109 00110 template<class BasePlugin> 00111 struct plugin_factory : 00112 public boost::mpl::inherit_linearly< 00113 typename virtual_constructors<BasePlugin>::type, 00114 plugin_factory_item<BasePlugin, _, _>, 00115 empty_plugin_factory_item>::type 00116 { 00117 plugin_factory(const dll& d) 00118 { 00119 this->m_dll = d; 00120 } 00121 }; 00122 00123 }} 00124 00125 #endif