Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- typedef std::map<std::string, std::string, std::string, int> actions_type;
- typedef actions_type::iterator actions_iterator;
- actions_type actions;
- actions.insert(make_pair(class_name, attribute_name, identifier, method_pointer));
- //after which I want call the appropriate method in the loop
- while (the_app_is_running)
- {
- std::string requested_class = get_requested_class();
- std::string requested_method = get_requested_method();
- //determine class
- for(actions_iterator ita = actions.begin(); ita != actions.end(); ++ita)
- {
- if (ita->first == requested_class && ita->second == requested_method)
- {
- //class and method match
- //create a new class instance
- //call method
- }
- }
- }
- $actions = array
- (
- "first_identifier" => array("Class1","method1"),
- "second_identifier" => array("Class2","method2"),
- "third_identifier" => array("Class3","method3")
- );
- while ($the_app_is_running)
- {
- $id = get_identifier();
- foreach($actions as $identifier => $action)
- {
- if ($id == $identifier)
- {
- $className = $action[0];
- $methodName = $action[1];
- $object = new $className() ;
- $method = new ReflectionMethod($className , $methodName);
- $method -> invoke($object);
- }
- }
- }
- return_type operator()(variant<possible types...>)
- #include <boost/variant.hpp>
- #include <boost/function.hpp>
- #include <boost/bind.hpp>
- #include <boost/tuple/tuple.hpp>
- #include <boost/mpl/identity.hpp>
- #include <boost/function_types/parameter_types.hpp>
- #include <boost/function_types/result_type.hpp>
- #include <boost/function_types/function_arity.hpp>
- #include <boost/preprocessor/repetition.hpp>
- #include <map>
- #include <string>
- #include <iostream>
- // three totally unrelated classes
- //
- struct foo {
- std::string one() {
- return "I ";
- }
- };
- struct bar {
- std::string two() {
- return "am ";
- }
- };
- struct baz {
- std::string three() const {
- return "happy!";
- }
- };
- // The following are the parameters you have to set
- //
- // return type
- typedef std::string return_type;
- // variant storing an object. It contains the list of possible types you
- // can store.
- typedef boost::variant< foo, bar, baz > variant_type;
- // type used to call a function on the object currently active in
- // the given variant
- typedef boost::function<return_type (variant_type&)> variant_call_type;
- // returned variant will know what type is stored. C++ got no reflection,
- // so we have to have a function that returns the correct type based on
- // compile time knowledge (here it's the template parameter)
- template<typename Class>
- variant_type factory() {
- return Class();
- }
- namespace detail {
- namespace fn = boost::function_types;
- namespace mpl = boost::mpl;
- // transforms T to a boost::bind
- template<typename T>
- struct build_caller {
- // type of this pointer, pointer removed, possibly cv qualified.
- typedef typename mpl::at_c<
- fn::parameter_types< T, mpl::identity<mpl::_> >,
- 0>::type actual_type;
- // type of boost::get we use
- typedef actual_type& (*get_type)(variant_type&);
- // prints _2 if n is 0
- #define PLACEHOLDER_print(z, n, unused) BOOST_PP_CAT(_, BOOST_PP_ADD(n, 2))
- #define GET_print(z, n, unused)
- template<typename U>
- static variant_call_type get(
- typename boost::enable_if_c<fn::function_arity<U>::value ==
- BOOST_PP_INC(n), U>::type t
- ) {
- /* (boost::get<actual_type>(some_variant).*t)(n1,...,nN) */
- return boost::bind(
- t, boost::bind(
- (get_type)&boost::get<actual_type>,
- _1) BOOST_PP_ENUM_TRAILING(n, PLACEHOLDER_print, ~)
- );
- }
- // generate functions for up to 8 parameters
- BOOST_PP_REPEAT(9, GET_print, ~)
- #undef GET_print
- #undef PLACEHOLDER_print
- };
- }
- // incoming type T is a member function type. we return a boost::bind object that
- // will call boost::get on the variant passed and calls the member function
- template<typename T>
- variant_call_type make_caller(T t) {
- return detail::build_caller<T>::template get<T>(t);
- }
- // actions stuff. maps an id to a class and method.
- typedef std::map<std::string,
- std::pair< std::string, std::string >
- > actions_type;
- // this map maps (class, method) => (factory, function pointer)
- typedef variant_type (*factory_function)();
- typedef std::map< std::pair<std::string, std::string>,
- std::pair<factory_function, variant_call_type>
- > class_method_map_type;
- // this will be our test function. it's supplied with the actions map,
- // and the factory map
- std::string test(std::string const& id,
- actions_type& actions, class_method_map_type& factory) {
- // pair containing the class and method name to call
- std::pair<std::string, std::string> const& class_method =
- actions[id];
- // real code should take the maps by const parameter and use
- // the find function of std::map to lookup the values, and store
- // results of factory lookups. we try to be as short as possible.
- variant_type v(factory[class_method].first());
- // execute the function associated, giving it the object created
- return factory[class_method].second(v);
- }
- int main() {
- // possible actions
- actions_type actions;
- actions["first"] = std::make_pair("foo", "one");
- actions["second"] = std::make_pair("bar", "two");
- actions["third"] = std::make_pair("baz", "three");
- // connect the strings to the actual entities. This is the actual
- // heart of everything.
- class_method_map_type factory_map;
- factory_map[actions["first"]] =
- std::make_pair(&factory<foo>, make_caller(&foo::one));
- factory_map[actions["second"]] =
- std::make_pair(&factory<bar>, make_caller(&bar::two));
- factory_map[actions["third"]] =
- std::make_pair(&factory<baz>, make_caller(&baz::three));
- // outputs "I am happy!"
- std::cout << test("first", actions, factory_map)
- << test("second", actions, factory_map)
- << test("third", actions, factory_map) << std::endl;
- }
- typedef boost::function<return_type (variant_type&, int)> variant_call_type;
- return factory[class_method].second(v, 42);
- struct my_object {
- typedef std::string return_type;
- virtual ~my_object() { }
- virtual std::string one() { not_implemented(); }
- virtual std::string two() { not_implemented(); }
- private:
- void not_implemented() { throw std::runtime_error("not implemented"); }
- };
- struct object_factory {
- boost::shared_ptr<my_object> create_instance(std::string const& name) {
- // ...
- }
- };
- typedef boost::function<my_object::return_type(my_object&)> function_type;
- typedef std::map< std::pair<std::string, std::string>, function_type>
- class_method_map_type;
- class_method_map[actions["first"]] = &my_object::one;
- class_method_map[actions["second"]] = &my_object::two;
- boost::shared_ptr<my_object> p(get_factory().
- create_instance(actions["first"].first));
- std::cout << class_method_map[actions["first"]](*p);
- class MyClass
- {
- public:
- void function();
- };
- void (MyClass:*function_ptr)() = MyClass::function;
- MyClass instance;
- instance.*function_ptr;
- class MyClass
- {
- public:
- void function();
- static void call_function(MyClass *instance); // Or you can use a reference here.
- };
- MyClass instance;
- MyClass::call_function(&instance);
- class MyClass
- {
- public:
- enum Method
- {
- fp_function,
- };
- void function();
- static void invoke_method(MyClass *instance, Method method); // Or you can use a reference here.
- };
- void MyClass::invoke_method(MyClass *instance, Method method)
- {
- switch(method)
- {
- default:
- // Error or something here.
- return;
- case fp_function:
- instance->function();
- break;
- // Or, if you have a lot of methods:
- #define METHOD_CASE(x) case fp_##x: instance->x(); break;
- METHOD_CASE(function);
- #undef METHOD_CASE
- }
- // Free logging! =D
- }
- MyClass instance;
- MyClass::invoke_method(instance, MyClass::fp_function);
- #include<iostream>
- #include<map>
- #include<string>
- using std::map;
- using std::string;
- using std::cout;
- using std::pair;
- class MVCHandler
- {
- public:
- virtual void operator()(const string& somekindofrequestinfo) = 0;
- };
- class MyMVCHandler : public MVCHandler
- {
- public:
- virtual void operator()(const string& somekindofrequestinfo)
- {
- cout<<somekindofrequestinfo;
- }
- };
- void main()
- {
- MyMVCHandler myhandler;
- map<string, MVCHandler*> handlerMap;
- handlerMap.insert(pair<string, MVCHandler*>("mysuperhandler", &myhandler));
- (*handlerMap["mysuperhandler"])("somekindofrequestdata");
- }
Add Comment
Please, Sign In to add comment