Go to the documentation of this file.00001
00002
00003
00004
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