00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #define STRINGIFY(x) #x
00037 #define TOSTRING(x) STRINGIFY(x)
00038
00039 #include <iostream>
00040 #include <vector>
00041 #include <utility>
00042 #include <string>
00043 #include <stdexcept>
00044 #include <memory>
00045 #include <boost/mpl/for_each.hpp>
00046 #include <boost/mpl/transform.hpp>
00047 #include <boost/type_traits/add_pointer.hpp>
00048
00049 #include <boost/preprocessor/cat.hpp>
00050 #include "JLOG.hh"
00051
00052 #ifdef _MSC_VER
00053
00054 #pragma warning(disable:4190)
00055 #endif
00056
00057 #ifndef FUNNAME_SUFFIX
00058 #error "FUNNAME_SUFFIX must be specified."
00059 #endif
00060
00061 #undef CREATE_OBJ_FUNNAME
00062 #undef DESTROY_OBJ_FUNNAME
00063 #undef GETNAMES_FUNNAME
00064 #undef GETPROPERTY_FUNNAME
00065
00066 #define CREATE_OBJ_PREFIX create_
00067 #define DESTROY_OBJ_PREFIX destroy_
00068 #define GETNAMES_PREFIX getNames_
00069 #define GETPROPERTY_PREFIX getProperty_
00070
00071 #define CREATE_OBJ_FUNNAME BOOST_PP_CAT( CREATE_OBJ_PREFIX, FUNNAME_SUFFIX )
00072 #define DESTROY_OBJ_FUNNAME BOOST_PP_CAT( DESTROY_OBJ_PREFIX, FUNNAME_SUFFIX )
00073 #define GETNAMES_FUNNAME BOOST_PP_CAT( GETNAMES_PREFIX, FUNNAME_SUFFIX )
00074 #define GETPROPERTY_FUNNAME BOOST_PP_CAT( GETPROPERTY_PREFIX, FUNNAME_SUFFIX )
00075
00076 #ifndef __MITIE_LIB_TEMPLATE_H_
00077 #define __MITIE_LIB_TEMPLATE_H_ 1
00078
00080 struct append_name_to_list {
00081 std::vector< std::string > & m_v;
00082 append_name_to_list(std::vector< std::string > & v):m_v(v) {};
00083 template<typename U> void operator()(U *) {
00084 std::string n(U::getName_static());
00085 JLOG(5, std::cout << "Adding " << n << " to list." << std::endl; )
00086 m_v.push_back( n );
00087 }
00088 };
00089
00091
00095 struct lookup_property {
00096 const std::string & m_name;
00097 const std::string & m_prop_name;
00098 std::string & m_prop;
00099
00100 lookup_property( const std::string & class_name, const std::string & prop_name, std::string & prop ):m_name(class_name), m_prop_name(prop_name), m_prop(prop) {
00101 JLOG(4, std::cout << "Will be looking for: " << prop_name << " of class " << m_name << std::endl; )
00102 };
00103 template<typename U> void operator()(U *) {
00104 JLOG(6, std::cout << "_" << m_name << "_ compared against _" << U::getName_static() << "_" << std::endl; )
00105 if((m_prop.empty())&&(m_name.compare(U::getName_static())==0)) {
00106 JLOG(4, std::cout << "Found it, getting property.." << std::endl; )
00107 m_prop = U::getProperty_static(m_prop_name);
00108 }
00109 }
00110 };
00111
00112 #endif
00113
00114
00115
00117 struct LOOKUP_CREATE_FUNNAME {
00118 const std::string & m_name;
00119 std::auto_ptr < CREATED_OBJ_TYPE > & m_obj_ptr;
00120 const std::string & m_args;
00121 const CREATED_OBJ_TYPE::ctor_va_t & m_var_arg;
00122 LOOKUP_CREATE_FUNNAME( const std::string & name, std::auto_ptr < CREATED_OBJ_TYPE > & obj_ptr, const std::string & args, const CREATED_OBJ_TYPE::ctor_va_t & var_arg ):m_name(name),m_obj_ptr(obj_ptr),m_args(args),m_var_arg(var_arg) {};
00123 template<typename U> void operator()(U *) {
00124 JLOG(5, std::cout << "_" << m_name << "_ compared against _" << U::getName_static() << "_" << std::endl; )
00125 if( (m_obj_ptr.get()==0) && (m_name.compare(U::getName_static())==0) ) {
00126 m_obj_ptr = std::auto_ptr < CREATED_OBJ_TYPE >(new U(m_args, m_var_arg));
00127
00128 }
00129 }
00130 };
00131
00132 extern "C" {
00133
00135 CREATED_OBJ_TYPE * CREATE_OBJ_FUNNAME (const std::string & name, const std::string & args, const CREATED_OBJ_TYPE::ctor_va_t & var_arg) {
00136 std::auto_ptr < CREATED_OBJ_TYPE > created(0);
00137 LOOKUP_CREATE_FUNNAME real_factory(name, created, args, var_arg);
00138 boost::mpl::for_each< boost::mpl::transform< CREATED_OBJ_LIST, boost::add_pointer<boost::mpl::_1> >::type >(real_factory);
00139 if(created.get()==0) throw std::runtime_error("Unknown type (" + name + ") requested of " + TOSTRING(CREATE_OBJ_FUNNAME) );
00140 return created.release();
00141 }
00142
00144 void DESTROY_OBJ_FUNNAME (CREATED_OBJ_TYPE * p) {
00145 JLOG(4, std::cout << "void " << TOSTRING(DESTROY_OBJ_FUNNAME) << "(" << TOSTRING(CREATED_OBJ_TYPE) << " * p (" << p << ")) called." << std::endl; )
00146 delete p;
00147 }
00148
00150 std::vector< std::string > GETNAMES_FUNNAME () {
00151 std::vector< std::string > output;
00152 append_name_to_list output_inserter(output);
00153 boost::mpl::for_each< boost::mpl::transform<CREATED_OBJ_LIST,boost::add_pointer<boost::mpl::_1> >::type >(output_inserter);
00154 return output;
00155 }
00156
00158
00160 std::string GETPROPERTY_FUNNAME (const std::string & name, const std::string & prop_name ) {
00161 std::string prop;
00162 lookup_property real_factory(name, prop_name, prop );
00163 boost::mpl::for_each< boost::mpl::transform<CREATED_OBJ_LIST,boost::add_pointer<boost::mpl::_1> >::type >(real_factory);
00164 return prop;
00165 }
00166
00167 }