diff --git a/chaiscript/chaiscript_engine.hpp b/chaiscript/chaiscript_engine.hpp index 01962f3..7327adc 100644 --- a/chaiscript/chaiscript_engine.hpp +++ b/chaiscript/chaiscript_engine.hpp @@ -23,11 +23,11 @@ public: return engine; } - const Boxed_Value eval(const std::vector &vals) { + const dispatchkit::Boxed_Value eval(const std::vector &vals) { std::string val; try { - val = Cast_Helper()(vals[0]); + val = dispatchkit::Cast_Helper()(vals[0]); } catch (std::exception &e) { throw EvalError("Can not evaluate string: " + val, langkit::TokenPtr()); @@ -191,11 +191,11 @@ public: Eval_Engine build_eval_system(langkit::Lexer &lexer, langkit::Rule &parser) { using namespace langkit; Eval_Engine ss; - Bootstrap::bootstrap(ss); - bootstrap_vector >(ss, "Vector"); + dispatchkit::Bootstrap::bootstrap(ss); + dispatchkit::bootstrap_vector >(ss, "Vector"); - ss.register_function(boost::shared_ptr( - new Dynamic_Proxy_Function(boost::bind(&ChaiScript_System::eval, boost::ref(*this), _1), 1)), "eval"); + ss.register_function(boost::shared_ptr( + new dispatchkit::Dynamic_Proxy_Function(boost::bind(&ChaiScript_System::eval, boost::ref(*this), _1), 1)), "eval"); evaluate_string("def print(x) { print_string(x.to_string()) } "); @@ -220,10 +220,10 @@ public: } } - Boxed_Value evaluate_string(const std::string &input, const char *filename = "__EVAL__") { + dispatchkit::Boxed_Value evaluate_string(const std::string &input, const char *filename = "__EVAL__") { using namespace langkit; std::vector tokens = lexer.lex(input, filename); - Boxed_Value value; + dispatchkit::Boxed_Value value; for (unsigned int i = 0; i < tokens.size(); ++i) { if ((tokens[i]->identifier == TokenType::Quoted_String) || (tokens[i]->identifier == TokenType::Single_Quoted_String)) { @@ -262,12 +262,12 @@ public: return value; } - Boxed_Value evaluate_file(const char *filename) { + dispatchkit::Boxed_Value evaluate_file(const char *filename) { return evaluate_string(load_file(filename), filename); } }; -typedef ChaiScript_System ChaiScript_Engine; +typedef ChaiScript_System ChaiScript_Engine; #endif /* CHAISCRIPT_ENGINE_HPP_ */ diff --git a/chaiscript/chaiscript_eval.hpp b/chaiscript/chaiscript_eval.hpp index 9b37598..0ff63e0 100644 --- a/chaiscript/chaiscript_eval.hpp +++ b/chaiscript/chaiscript_eval.hpp @@ -21,10 +21,10 @@ struct EvalError { }; struct ReturnValue { - Boxed_Value retval; + dispatchkit::Boxed_Value retval; langkit::TokenPtr location; - ReturnValue(const Boxed_Value &return_value, const langkit::TokenPtr where) : retval(return_value), location(where) { } + ReturnValue(const dispatchkit::Boxed_Value &return_value, const langkit::TokenPtr where) : retval(return_value), location(where) { } }; struct BreakLoop { @@ -34,21 +34,21 @@ struct BreakLoop { }; template -const Boxed_Value eval_function (Eval_System &ss, langkit::TokenPtr node, const std::vector ¶m_names, const std::vector &vals) { +const dispatchkit::Boxed_Value eval_function (Eval_System &ss, langkit::TokenPtr node, const std::vector ¶m_names, const std::vector &vals) { ss.new_scope(); for (unsigned int i = 0; i < param_names.size(); ++i) { ss.add_object(param_names[i], vals[i]); } - Boxed_Value retval = eval_token(ss, node); + dispatchkit::Boxed_Value retval = eval_token(ss, node); ss.pop_scope(); return retval; } template -Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { - Boxed_Value retval; +dispatchkit::Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { + dispatchkit::Boxed_Value retval; unsigned int i, j; switch (node->identifier) { @@ -60,10 +60,10 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { break; case (TokenType::Identifier) : if (node->text == "true") { - retval = Boxed_Value(true); + retval = dispatchkit::Boxed_Value(true); } else if (node->text == "false") { - retval = Boxed_Value(false); + retval = dispatchkit::Boxed_Value(false); } else { try { @@ -75,22 +75,22 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { } break; case (TokenType::Real_Number) : - retval = Boxed_Value(double(atof(node->text.c_str()))); + retval = dispatchkit::Boxed_Value(double(atof(node->text.c_str()))); break; case (TokenType::Integer) : - retval = Boxed_Value(atoi(node->text.c_str())); + retval = dispatchkit::Boxed_Value(atoi(node->text.c_str())); break; case (TokenType::Quoted_String) : - retval = Boxed_Value(node->text); + retval = dispatchkit::Boxed_Value(node->text); break; case (TokenType::Single_Quoted_String) : - retval = Boxed_Value(node->text); + retval = dispatchkit::Boxed_Value(node->text); break; case (TokenType::Equation) : retval = eval_token(ss, node->children.back()); if (node->children.size() > 1) { for (i = node->children.size()-3; ((int)i) >= 0; i -= 2) { - Param_List_Builder plb; + dispatchkit::Param_List_Builder plb; plb << eval_token(ss, node->children[i]); plb << retval; try { @@ -103,7 +103,7 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { } break; case (TokenType::Variable_Decl): { - ss.add_object(node->children[0]->text, Boxed_Value()); + ss.add_object(node->children[0]->text, dispatchkit::Boxed_Value()); retval = ss.get_object(node->children[0]->text); } break; @@ -115,7 +115,7 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { retval = eval_token(ss, node->children[0]); if (node->children.size() > 1) { for (i = 1; i < node->children.size(); i += 2) { - Param_List_Builder plb; + dispatchkit::Param_List_Builder plb; plb << retval; plb << eval_token(ss, node->children[i + 1]); @@ -132,7 +132,7 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { case (TokenType::Array_Call) : { retval = eval_token(ss, node->children[0]); for (i = 1; i < node->children.size(); ++i) { - Param_List_Builder plb; + dispatchkit::Param_List_Builder plb; plb << retval; plb << eval_token(ss, node->children[i]); try { @@ -149,9 +149,9 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { break; case (TokenType::Negate) : { retval = eval_token(ss, node->children[1]); - Param_List_Builder plb; + dispatchkit::Param_List_Builder plb; plb << retval; - plb << Boxed_Value(-1); + plb << dispatchkit::Boxed_Value(-1); try { retval = dispatch(ss.get_function("*"), plb); @@ -165,17 +165,17 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { bool cond; try { retval = eval_token(ss, node->children[1]); - cond = Cast_Helper()(retval); + cond = dispatchkit::Cast_Helper()(retval); } catch (std::exception) { throw EvalError("Boolean not('!') condition not boolean", node->children[0]); } - retval = Boxed_Value(!cond); + retval = dispatchkit::Boxed_Value(!cond); } break; case (TokenType::Prefix) : { retval = eval_token(ss, node->children[1]); - Param_List_Builder plb; + dispatchkit::Param_List_Builder plb; plb << retval; try { @@ -188,11 +188,11 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { break; case (TokenType::Array_Init) : { try { - retval = dispatch(ss.get_function("Vector"), Param_List_Builder()); + retval = dispatch(ss.get_function("Vector"), dispatchkit::Param_List_Builder()); for (i = 0; i < node->children.size(); ++i) { try { - Boxed_Value tmp = eval_token(ss, node->children[i]); - dispatch(ss.get_function("push_back"), Param_List_Builder() << retval << tmp); + dispatchkit::Boxed_Value tmp = eval_token(ss, node->children[i]); + dispatch(ss.get_function("push_back"), dispatchkit::Param_List_Builder() << retval << tmp); } catch (std::exception inner_e) { throw EvalError("Can not find appropriate 'push_back'", node->children[i]); @@ -206,13 +206,13 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { break; case (TokenType::Fun_Call) : { - std::vector > fn; - Dispatch_Engine::Stack prev_stack = ss.get_stack(); + std::vector > fn; + dispatchkit::Dispatch_Engine::Stack prev_stack = ss.get_stack(); - Dispatch_Engine::Stack new_stack; - new_stack.push_back(Dispatch_Engine::Scope()); + dispatchkit::Dispatch_Engine::Stack new_stack; + new_stack.push_back(dispatchkit::Dispatch_Engine::Scope()); - Param_List_Builder plb; + dispatchkit::Param_List_Builder plb; for (i = 1; i < node->children.size(); ++i) { plb << eval_token(ss, node->children[i]); } @@ -237,16 +237,16 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { } break; case (TokenType::Method_Call) : { - std::vector > fn; - Dispatch_Engine::Stack prev_stack = ss.get_stack(); + std::vector > fn; + dispatchkit::Dispatch_Engine::Stack prev_stack = ss.get_stack(); - Dispatch_Engine::Stack new_stack; - new_stack.push_back(Dispatch_Engine::Scope()); + dispatchkit::Dispatch_Engine::Stack new_stack; + new_stack.push_back(dispatchkit::Dispatch_Engine::Scope()); retval = eval_token(ss, node->children[0]); if (node->children.size() > 1) { for (i = 1; i < node->children.size(); ++i) { - Param_List_Builder plb; + dispatchkit::Param_List_Builder plb; plb << retval; for (j = 1; j < node->children[i]->children.size(); ++j) { @@ -279,7 +279,7 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { retval = eval_token(ss, node->children[0]); bool cond; try { - cond = Cast_Helper()(retval); + cond = dispatchkit::Cast_Helper()(retval); } catch (std::exception &e) { throw EvalError("If condition not boolean", node->children[0]); @@ -298,7 +298,7 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { else if (node->children[i]->text == "elseif") { retval = eval_token(ss, node->children[i+1]); try { - cond = Cast_Helper()(retval); + cond = dispatchkit::Cast_Helper()(retval); } catch (std::exception &e) { throw EvalError("Elseif condition not boolean", node->children[i+1]); @@ -317,7 +317,7 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { retval = eval_token(ss, node->children[0]); bool cond; try { - cond = Cast_Helper()(retval); + cond = dispatchkit::Cast_Helper()(retval); } catch (std::exception) { throw EvalError("While condition not boolean", node->children[0]); @@ -327,7 +327,7 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { eval_token(ss, node->children[1]); retval = eval_token(ss, node->children[0]); try { - cond = Cast_Helper()(retval); + cond = dispatchkit::Cast_Helper()(retval); } catch (std::exception) { throw EvalError("While condition not boolean", node->children[0]); @@ -337,11 +337,11 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { cond = false; } } - retval = Boxed_Value(); + retval = dispatchkit::Boxed_Value(); } break; case(TokenType::For_Block) : { - Boxed_Value condition; + dispatchkit::Boxed_Value condition; bool cond; try { @@ -352,7 +352,7 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { else if (node->children.size() == 3){ condition = eval_token(ss, node->children[0]); } - cond = Cast_Helper()(condition); + cond = dispatchkit::Cast_Helper()(condition); } catch (std::exception &e) { throw EvalError("For condition not boolean", node); @@ -369,7 +369,7 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { eval_token(ss, node->children[1]); condition = eval_token(ss, node->children[0]); } - cond = Cast_Helper()(condition); + cond = dispatchkit::Cast_Helper()(condition); } catch (std::exception &e) { @@ -379,7 +379,7 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { cond = false; } } - retval = Boxed_Value(); + retval = dispatchkit::Boxed_Value(); } break; case (TokenType::Function_Def) : { @@ -389,8 +389,8 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { param_names.push_back(node->children[i+1]->text); } - ss.register_function(boost::shared_ptr( - new Dynamic_Proxy_Function(boost::bind(&eval_function, boost::ref(ss), node->children.back(), param_names, _1))), node->children[0]->text); + ss.register_function(boost::shared_ptr( + new dispatchkit::Dynamic_Proxy_Function(boost::bind(&eval_function, boost::ref(ss), node->children.back(), param_names, _1))), node->children[0]->text); } break; case (TokenType::Lambda_Def) : { @@ -400,8 +400,9 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { param_names.push_back(node->children[i]->text); } - //retval = boost::shared_ptr(new Proxy_Function_Impl >(&test)); - retval = Boxed_Value(boost::shared_ptr(new Dynamic_Proxy_Function( + //retval = boost::shared_ptr(new dispatchkit::Proxy_Function_Impl >(&test)); + retval = dispatchkit::Boxed_Value(boost::shared_ptr( + new dispatchkit::Dynamic_Proxy_Function( boost::bind(&eval_function, boost::ref(ss), node->children.back(), param_names, _1)))); } break; @@ -418,7 +419,7 @@ Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { retval = eval_token(ss, node->children[0]); } else { - retval = Boxed_Value(); + retval = dispatchkit::Boxed_Value(); } throw ReturnValue(retval, node); } diff --git a/chaiscript/main.cpp b/chaiscript/main.cpp index 1683478..f935b1b 100644 --- a/chaiscript/main.cpp +++ b/chaiscript/main.cpp @@ -3,6 +3,8 @@ #include "chaiscript.hpp" int main(int argc, char *argv[]) { + using namespace dispatchkit; + std::string input; ChaiScript_Engine chai; diff --git a/dispatchkit/bootstrap.hpp b/dispatchkit/bootstrap.hpp index f67b7e4..677d7e4 100644 --- a/dispatchkit/bootstrap.hpp +++ b/dispatchkit/bootstrap.hpp @@ -4,456 +4,460 @@ #include "dispatchkit.hpp" #include "bootstrap_pod.hpp" -template -Ret add(P1 p1, P2 p2) +namespace dispatchkit { - return p1 + p2; -} - - -template -Ret subtract(P1 p1, P2 p2) -{ - return p1 - p2; -} - - -template -Ret divide(P1 p1, P2 p2) -{ - return p1 / p2; -} - - -template -Ret multiply(P1 p1, P2 p2) -{ - return p1 * p2; -} - - -template -bool bool_and(P1 p1, P2 p2) -{ - return p1 && p2; -} - -template -bool bool_or(P1 p1, P2 p2) -{ - return p1 || p2; -} - -template -P1 &assign(P1 &p1, const P2 &p2) -{ - return (p1 = p2); -} - -template -P1 &assign_pod(P1 &p1, Boxed_POD_Value v) -{ - if (v.m_isfloat) + template + Ret add(P1 p1, P2 p2) { - return (p1 = v.d); - } else { - return (p1 = v.i); + return p1 + p2; } -} -template -bool equals(P1 p1, P2 p2) -{ - return p1 == p2; -} - - - -template -bool not_equals(P1 p1, P2 p2) -{ - return p1 != p2; -} - - -template -bool less_than(P1 p1, P2 p2) -{ - return p1 < p2; -} - -template -bool greater_than(P1 p1, P2 p2) -{ - return p1 > p2; -} - -template -bool less_than_equals(P1 p1, P2 p2) -{ - return p1 <= p2; -} - -template -bool greater_than_equals(P1 p1, P2 p2) -{ - return p1 >= p2; -} - -template -P1 ×equal(P1 &p1, const P2 &p2) -{ - return (p1 *= p2); -} - -template -P1 ×equal_pod(P1 &p1, Boxed_POD_Value r) -{ - if (r.m_isfloat) + template + Ret subtract(P1 p1, P2 p2) { - return (p1 *= r.d); - } else { - return (p1 *= r.i); + return p1 - p2; } -} -template -P1 ÷sequal(P1 &p1, const P2 &p2) -{ - return (p1 /= p2); -} - -template -P1 ÷sequal_pod(P1 &p1, Boxed_POD_Value r) -{ - if (r.m_isfloat) + template + Ret divide(P1 p1, P2 p2) { - return (p1 /= r.d); - } else { - return (p1 /= r.i); + return p1 / p2; } -} -template -P1 &addsequal(P1 &p1, const P2 &p2) -{ - return (p1 += p2); -} - -template -P1 &addsequal_pod(P1 &p1, Boxed_POD_Value r) -{ - if (r.m_isfloat) + template + Ret multiply(P1 p1, P2 p2) { - return (p1 += r.d); - } else { - return (p1 += r.i); + return p1 * p2; } -} -template -P1 &subtractsequal(P1 &p1, const P2 &p2) -{ - return (p1 -= p2); -} -template -P1 &subtractsequal_pod(P1 &p1, Boxed_POD_Value r) -{ - if (r.m_isfloat) + template + bool bool_and(P1 p1, P2 p2) { - return (p1 -= r.d); - } else { - return (p1 -= r.i); + return p1 && p2; } -} -template -P1 &prefixincrement(P1 &p1) -{ - return (++p1); -} + template + bool bool_or(P1 p1, P2 p2) + { + return p1 || p2; + } -template -P1 &prefixdecrement(P1 &p1) -{ - return (--p1); -} + template + P1 &assign(P1 &p1, const P2 &p2) + { + return (p1 = p2); + } -template -P1 &prefixnegate(P1 &p1) -{ - return (p1); -} - -template -P1 &prefixnot(P1 &p1) -{ - return (p1); -} - - -//Add canonical forms of operators -template -void add_oper_equals(Dispatch_Engine &s) -{ - register_function(s, &equals, "="); -} - -template -void add_oper_add(Dispatch_Engine &s) -{ - register_function(s, &add, "+"); -} - -template -void add_oper_add_equals(Dispatch_Engine &s) -{ - register_function(s, &addsequal, "+="); -} - -template -void add_oper_subtract(Dispatch_Engine &s) -{ - register_function(s, &subtract, "-"); -} - -template -void add_oper_divide(Dispatch_Engine &s) -{ - register_function(s, ÷, "-"); -} - -template -void add_oper_multiply(Dispatch_Engine &s) -{ - register_function(s, &multiply, "*"); -} - -template -void add_oper_not_equals(Dispatch_Engine &s) -{ - register_function(s, ¬_equals, "!="); -} - -template -void add_oper_assign_overload(Dispatch_Engine &s) -{ - register_function(s, &assign, "="); -} - - -template -void add_oper_assign(Dispatch_Engine &s) -{ - register_function(s, &assign, "="); -} - - -template -void add_oper_assign_pod(Dispatch_Engine &s) -{ - register_function(s, &assign_pod, "="); -} - - -template -void add_oper_less_than(Dispatch_Engine &s) -{ - register_function(s, &less_than, "<"); -} - -template -void add_oper_greater_than(Dispatch_Engine &s) -{ - register_function(s, &greater_than, ">"); -} - -template -void add_oper_less_than_equals(Dispatch_Engine &s) -{ - register_function(s, &less_than_equals, "<="); -} - -template -void add_oper_greater_than_equals(Dispatch_Engine &s) -{ - register_function(s, &greater_than_equals, ">="); -} - - -template -void add_opers_comparison_overload(Dispatch_Engine &s) -{ - register_function(s, &equals, "=="); - register_function(s, ¬_equals, "!="); - register_function(s, &less_than, "<"); - register_function(s, &greater_than, ">"); - register_function(s, &less_than_equals, "<="); - register_function(s, &greater_than_equals, ">="); -} - -template -void add_opers_comparison(Dispatch_Engine &s) -{ - add_opers_comparison_overload(s); -} - -template -void add_opers_arithmetic_overload(Dispatch_Engine &s) -{ - register_function(s, &add, "+"); - register_function(s, &subtract, "-"); - register_function(s, ÷, "/"); - register_function(s, &multiply, "*"); - register_function(s, ×equal, "*="); - register_function(s, ÷sequal, "/="); - register_function(s, &subtractsequal, "-="); - register_function(s, &addsequal, "+="); - register_function(s, &prefixincrement, "++"); - register_function(s, &prefixdecrement, "--"); - register_function(s, &prefixnegate, "-"); - register_function(s, &prefixnot, "!"); -} - -template -void add_opers_arithmetic_modify_pod(Dispatch_Engine &s) -{ - register_function(s, ×equal_pod, "*="); - register_function(s, ÷sequal_pod, "/="); - register_function(s, &subtractsequal_pod, "-="); - register_function(s, &addsequal_pod, "+="); -} - -template -void add_basic_constructors(Dispatch_Engine &s, const std::string &type) -{ - s.register_function(build_constructor(), type); - s.register_function(build_constructor(), type); - s.register_function(build_constructor(), "clone"); -} - -template -void add_constructor_overload(Dispatch_Engine &s, const std::string &type) -{ - s.register_function(build_constructor(), type); -} - -template -void add_opers_arithmetic(Dispatch_Engine &s) -{ - add_opers_arithmetic_overload(s); - -} - -class bad_boxed_value_cast : public std::bad_cast -{ - public: - bad_boxed_value_cast(const std::string &val) throw() - : m_val(val) + template + P1 &assign_pod(P1 &p1, Boxed_POD_Value v) + { + if (v.m_isfloat) { - } - - virtual ~bad_boxed_value_cast() throw() - { - } - - virtual const char * what() const throw() - { - return m_val.c_str(); - } - - private: - std::string m_val; -}; - - - -//Built in to_string operator -template -std::string to_string(Input i) -{ - return boost::lexical_cast(i); -} - -template<> std::string to_string(bool b) -{ - if (b) - { - return "true"; - } else { - return "false"; - } -} - -template -void bootstrap_pod_type(Dispatch_Engine &s, const std::string &name) -{ - s.register_type(name); - add_basic_constructors(s, name); - add_oper_assign(s); - add_oper_assign_pod(s); - add_opers_arithmetic(s); - add_opers_arithmetic_modify_pod(s); - register_function(s, &to_string, "to_string"); -} - -struct Bootstrap -{ - static Boxed_Value unknown_assign(Boxed_Value lhs, Boxed_Value rhs) - { - if (lhs.is_unknown()) - { - return (lhs.assign(rhs)); + return (p1 = v.d); } else { - throw bad_boxed_value_cast("boxed_value has a set type alread"); + return (p1 = v.i); } } - static void print(const std::string &s) + + template + bool equals(P1 p1, P2 p2) { - std::cout << s << std::endl; + return p1 == p2; } - static void bootstrap(Dispatch_Engine &s) + + + template + bool not_equals(P1 p1, P2 p2) { - s.register_type("void"); - - s.register_type("string"); - - add_basic_constructors(s, "bool"); - add_basic_constructors(s, "string"); - add_oper_assign(s); - - register_function(s, &to_string, "to_string"); - register_function(s, &to_string, "to_string"); - register_function(s, &unknown_assign, "="); - - bootstrap_pod_type(s, "double"); - bootstrap_pod_type(s, "int"); - bootstrap_pod_type(s, "size_t"); - bootstrap_pod_type(s, "char"); - bootstrap_pod_type(s, "int64_t"); - - - - Pod_Bootstrap::add_opers_comparison(s); - Pod_Bootstrap::add_opers_arithmetic(s); - - add_oper_add(s); - add_oper_add_equals (s); - - register_function(s, &print, "print_string"); - - s.register_function(boost::function(boost::bind(&dump_system, boost::ref(s))), "dump_system"); - s.register_function(boost::function(boost::bind(&dump_object, _1)), "dump_object"); - - register_function(s, &bool_and, "&&"); - register_function(s, &bool_or, "||"); + return p1 != p2; } -}; + + + template + bool less_than(P1 p1, P2 p2) + { + return p1 < p2; + } + + template + bool greater_than(P1 p1, P2 p2) + { + return p1 > p2; + } + + template + bool less_than_equals(P1 p1, P2 p2) + { + return p1 <= p2; + } + + template + bool greater_than_equals(P1 p1, P2 p2) + { + return p1 >= p2; + } + + template + P1 ×equal(P1 &p1, const P2 &p2) + { + return (p1 *= p2); + } + + template + P1 ×equal_pod(P1 &p1, Boxed_POD_Value r) + { + if (r.m_isfloat) + { + return (p1 *= r.d); + } else { + return (p1 *= r.i); + } + } + + + template + P1 ÷sequal(P1 &p1, const P2 &p2) + { + return (p1 /= p2); + } + + template + P1 ÷sequal_pod(P1 &p1, Boxed_POD_Value r) + { + if (r.m_isfloat) + { + return (p1 /= r.d); + } else { + return (p1 /= r.i); + } + } + + + template + P1 &addsequal(P1 &p1, const P2 &p2) + { + return (p1 += p2); + } + + template + P1 &addsequal_pod(P1 &p1, Boxed_POD_Value r) + { + if (r.m_isfloat) + { + return (p1 += r.d); + } else { + return (p1 += r.i); + } + } + + template + P1 &subtractsequal(P1 &p1, const P2 &p2) + { + return (p1 -= p2); + } + + template + P1 &subtractsequal_pod(P1 &p1, Boxed_POD_Value r) + { + if (r.m_isfloat) + { + return (p1 -= r.d); + } else { + return (p1 -= r.i); + } + } + + template + P1 &prefixincrement(P1 &p1) + { + return (++p1); + } + + template + P1 &prefixdecrement(P1 &p1) + { + return (--p1); + } + + template + P1 &prefixnegate(P1 &p1) + { + return (p1); + } + + template + P1 &prefixnot(P1 &p1) + { + return (p1); + } + + + //Add canonical forms of operators + template + void add_oper_equals(Dispatch_Engine &s) + { + register_function(s, &equals, "="); + } + + template + void add_oper_add(Dispatch_Engine &s) + { + register_function(s, &add, "+"); + } + + template + void add_oper_add_equals(Dispatch_Engine &s) + { + register_function(s, &addsequal, "+="); + } + + template + void add_oper_subtract(Dispatch_Engine &s) + { + register_function(s, &subtract, "-"); + } + + template + void add_oper_divide(Dispatch_Engine &s) + { + register_function(s, ÷, "-"); + } + + template + void add_oper_multiply(Dispatch_Engine &s) + { + register_function(s, &multiply, "*"); + } + + template + void add_oper_not_equals(Dispatch_Engine &s) + { + register_function(s, ¬_equals, "!="); + } + + template + void add_oper_assign_overload(Dispatch_Engine &s) + { + register_function(s, &assign, "="); + } + + + template + void add_oper_assign(Dispatch_Engine &s) + { + register_function(s, &assign, "="); + } + + + template + void add_oper_assign_pod(Dispatch_Engine &s) + { + register_function(s, &assign_pod, "="); + } + + + template + void add_oper_less_than(Dispatch_Engine &s) + { + register_function(s, &less_than, "<"); + } + + template + void add_oper_greater_than(Dispatch_Engine &s) + { + register_function(s, &greater_than, ">"); + } + + template + void add_oper_less_than_equals(Dispatch_Engine &s) + { + register_function(s, &less_than_equals, "<="); + } + + template + void add_oper_greater_than_equals(Dispatch_Engine &s) + { + register_function(s, &greater_than_equals, ">="); + } + + + template + void add_opers_comparison_overload(Dispatch_Engine &s) + { + register_function(s, &equals, "=="); + register_function(s, ¬_equals, "!="); + register_function(s, &less_than, "<"); + register_function(s, &greater_than, ">"); + register_function(s, &less_than_equals, "<="); + register_function(s, &greater_than_equals, ">="); + } + + template + void add_opers_comparison(Dispatch_Engine &s) + { + add_opers_comparison_overload(s); + } + + template + void add_opers_arithmetic_overload(Dispatch_Engine &s) + { + register_function(s, &add, "+"); + register_function(s, &subtract, "-"); + register_function(s, ÷, "/"); + register_function(s, &multiply, "*"); + register_function(s, ×equal, "*="); + register_function(s, ÷sequal, "/="); + register_function(s, &subtractsequal, "-="); + register_function(s, &addsequal, "+="); + register_function(s, &prefixincrement, "++"); + register_function(s, &prefixdecrement, "--"); + register_function(s, &prefixnegate, "-"); + register_function(s, &prefixnot, "!"); + } + + template + void add_opers_arithmetic_modify_pod(Dispatch_Engine &s) + { + register_function(s, ×equal_pod, "*="); + register_function(s, ÷sequal_pod, "/="); + register_function(s, &subtractsequal_pod, "-="); + register_function(s, &addsequal_pod, "+="); + } + + template + void add_basic_constructors(Dispatch_Engine &s, const std::string &type) + { + s.register_function(build_constructor(), type); + s.register_function(build_constructor(), type); + s.register_function(build_constructor(), "clone"); + } + + template + void add_constructor_overload(Dispatch_Engine &s, const std::string &type) + { + s.register_function(build_constructor(), type); + } + + template + void add_opers_arithmetic(Dispatch_Engine &s) + { + add_opers_arithmetic_overload(s); + + } + + class bad_boxed_value_cast : public std::bad_cast + { + public: + bad_boxed_value_cast(const std::string &val) throw() + : m_val(val) + { + } + + virtual ~bad_boxed_value_cast() throw() + { + } + + virtual const char * what() const throw() + { + return m_val.c_str(); + } + + private: + std::string m_val; + }; + + + + //Built in to_string operator + template + std::string to_string(Input i) + { + return boost::lexical_cast(i); + } + + template<> std::string to_string(bool b) + { + if (b) + { + return "true"; + } else { + return "false"; + } + } + + template + void bootstrap_pod_type(Dispatch_Engine &s, const std::string &name) + { + s.register_type(name); + add_basic_constructors(s, name); + add_oper_assign(s); + add_oper_assign_pod(s); + add_opers_arithmetic(s); + add_opers_arithmetic_modify_pod(s); + register_function(s, &to_string, "to_string"); + } + + struct Bootstrap + { + static Boxed_Value unknown_assign(Boxed_Value lhs, Boxed_Value rhs) + { + if (lhs.is_unknown()) + { + return (lhs.assign(rhs)); + } else { + throw bad_boxed_value_cast("boxed_value has a set type alread"); + } + } + + static void print(const std::string &s) + { + std::cout << s << std::endl; + } + + static void bootstrap(Dispatch_Engine &s) + { + s.register_type("void"); + + s.register_type("string"); + + add_basic_constructors(s, "bool"); + add_basic_constructors(s, "string"); + add_oper_assign(s); + + register_function(s, &to_string, "to_string"); + register_function(s, &to_string, "to_string"); + register_function(s, &unknown_assign, "="); + + bootstrap_pod_type(s, "double"); + bootstrap_pod_type(s, "int"); + bootstrap_pod_type(s, "size_t"); + bootstrap_pod_type(s, "char"); + bootstrap_pod_type(s, "int64_t"); + + + + Pod_Bootstrap::add_opers_comparison(s); + Pod_Bootstrap::add_opers_arithmetic(s); + + add_oper_add(s); + add_oper_add_equals (s); + + register_function(s, &print, "print_string"); + + s.register_function(boost::function(boost::bind(&dump_system, boost::ref(s))), "dump_system"); + s.register_function(boost::function(boost::bind(&dump_object, _1)), "dump_object"); + + register_function(s, &bool_and, "&&"); + register_function(s, &bool_or, "||"); + } + }; +} #endif + diff --git a/dispatchkit/bootstrap_pod.hpp b/dispatchkit/bootstrap_pod.hpp index aca3d99..d5ca600 100644 --- a/dispatchkit/bootstrap_pod.hpp +++ b/dispatchkit/bootstrap_pod.hpp @@ -4,77 +4,79 @@ #include "register_function.hpp" - -struct Pod_Bootstrap +namespace dispatchkit { - static Boxed_Value add(Boxed_POD_Value l, Boxed_POD_Value r) + struct Pod_Bootstrap { - return l + r; - } + static Boxed_Value add(Boxed_POD_Value l, Boxed_POD_Value r) + { + return l + r; + } - static Boxed_Value subtract(Boxed_POD_Value l, Boxed_POD_Value r) - { - return l - r; - } + static Boxed_Value subtract(Boxed_POD_Value l, Boxed_POD_Value r) + { + return l - r; + } - static Boxed_Value divide(Boxed_POD_Value l, Boxed_POD_Value r) - { - return l / r; - } + static Boxed_Value divide(Boxed_POD_Value l, Boxed_POD_Value r) + { + return l / r; + } - static Boxed_Value multiply(Boxed_POD_Value l, Boxed_POD_Value r) - { - return l * r; - } + static Boxed_Value multiply(Boxed_POD_Value l, Boxed_POD_Value r) + { + return l * r; + } - static bool equals(Boxed_POD_Value l, Boxed_POD_Value r) - { - return l == r; - } + static bool equals(Boxed_POD_Value l, Boxed_POD_Value r) + { + return l == r; + } - static bool not_equals(Boxed_POD_Value l, Boxed_POD_Value r) - { - return l != r; - } + static bool not_equals(Boxed_POD_Value l, Boxed_POD_Value r) + { + return l != r; + } - static bool less_than(Boxed_POD_Value l, Boxed_POD_Value r) - { - return l < r; - } + static bool less_than(Boxed_POD_Value l, Boxed_POD_Value r) + { + return l < r; + } - static bool greater_than(Boxed_POD_Value l, Boxed_POD_Value r) - { - return l > r; - } + static bool greater_than(Boxed_POD_Value l, Boxed_POD_Value r) + { + return l > r; + } - static bool less_than_equals(Boxed_POD_Value l, Boxed_POD_Value r) - { - return l <= r; - } + static bool less_than_equals(Boxed_POD_Value l, Boxed_POD_Value r) + { + return l <= r; + } - static bool greater_than_equals(Boxed_POD_Value l, Boxed_POD_Value r) - { - return l >= r; - } + static bool greater_than_equals(Boxed_POD_Value l, Boxed_POD_Value r) + { + return l >= r; + } - static void add_opers_comparison(Dispatch_Engine &s) - { - register_function(s, &equals, "=="); - register_function(s, ¬_equals, "!="); - register_function(s, &less_than, "<"); - register_function(s, &greater_than, ">"); - register_function(s, &less_than_equals, "<="); - register_function(s, &greater_than_equals, ">="); - } + static void add_opers_comparison(Dispatch_Engine &s) + { + register_function(s, &equals, "=="); + register_function(s, ¬_equals, "!="); + register_function(s, &less_than, "<"); + register_function(s, &greater_than, ">"); + register_function(s, &less_than_equals, "<="); + register_function(s, &greater_than_equals, ">="); + } - static void add_opers_arithmetic(Dispatch_Engine &s) - { - register_function(s, &add, "+"); - register_function(s, &subtract, "-"); - register_function(s, ÷, "/"); - register_function(s, &multiply, "*"); - } -}; + static void add_opers_arithmetic(Dispatch_Engine &s) + { + register_function(s, &add, "+"); + register_function(s, &subtract, "-"); + register_function(s, ÷, "/"); + register_function(s, &multiply, "*"); + } + }; +} #endif diff --git a/dispatchkit/bootstrap_stl.hpp b/dispatchkit/bootstrap_stl.hpp index 47f1924..02e476b 100644 --- a/dispatchkit/bootstrap_stl.hpp +++ b/dispatchkit/bootstrap_stl.hpp @@ -3,82 +3,85 @@ #include "dispatchkit.hpp" -template -void bootstrap_reversible_container(Dispatch_Engine &system, const std::string &type) +namespace dispatchkit { -} + template + void bootstrap_reversible_container(Dispatch_Engine &system, const std::string &type) + { + } -template -void bootstrap_random_access_container(Dispatch_Engine &system, const std::string &type) -{ - bootstrap_reversible_container(system, type); + template + void bootstrap_random_access_container(Dispatch_Engine &system, const std::string &type) + { + bootstrap_reversible_container(system, type); - typedef typename ContainerType::reference(ContainerType::*indexoper)(size_t); + typedef typename ContainerType::reference(ContainerType::*indexoper)(size_t); - //In the interest of runtime safety for the system, we prefer the at() method for [] access, - //to throw an exception in an out of bounds condition. - system.register_function( - boost::function(indexoper(&ContainerType::at)), "[]"); - system.register_function( - boost::function(indexoper(&ContainerType::operator[])), "at"); -} + //In the interest of runtime safety for the system, we prefer the at() method for [] access, + //to throw an exception in an out of bounds condition. + system.register_function( + boost::function(indexoper(&ContainerType::at)), "[]"); + system.register_function( + boost::function(indexoper(&ContainerType::operator[])), "at"); + } -template -void bootstrap_assignable(Dispatch_Engine &system, const std::string &type) -{ - system.register_function( - boost::function(&Assignable::operator=), "="); -} + template + void bootstrap_assignable(Dispatch_Engine &system, const std::string &type) + { + system.register_function( + boost::function(&Assignable::operator=), "="); + } -template -void bootstrap_container(Dispatch_Engine &system, const std::string &type) -{ - bootstrap_assignable(system, type); + template + void bootstrap_container(Dispatch_Engine &system, const std::string &type) + { + bootstrap_assignable(system, type); - system.register_function( - boost::function(&ContainerType::size), "size"); - system.register_function( - boost::function(&ContainerType::size), "maxsize"); -} + system.register_function( + boost::function(&ContainerType::size), "size"); + system.register_function( + boost::function(&ContainerType::size), "maxsize"); + } -template -void bootstrap_forward_container(Dispatch_Engine &system, const std::string &type) -{ - bootstrap_container(system, type); -} + template + void bootstrap_forward_container(Dispatch_Engine &system, const std::string &type) + { + bootstrap_container(system, type); + } -template -void bootstrap_default_constructible(Dispatch_Engine &system, const std::string &type) -{ - system.register_function(build_constructor(), type); -} + template + void bootstrap_default_constructible(Dispatch_Engine &system, const std::string &type) + { + system.register_function(build_constructor(), type); + } -template -void bootstrap_sequence(Dispatch_Engine &system, const std::string &type) -{ - bootstrap_forward_container(system, type); - bootstrap_default_constructible(system, type); -} + template + void bootstrap_sequence(Dispatch_Engine &system, const std::string &type) + { + bootstrap_forward_container(system, type); + bootstrap_default_constructible(system, type); + } -template -void bootstrap_back_insertion_sequence(Dispatch_Engine &system, const std::string &type) -{ - bootstrap_sequence(system, type); + template + void bootstrap_back_insertion_sequence(Dispatch_Engine &system, const std::string &type) + { + bootstrap_sequence(system, type); - typedef typename SequenceType::reference (SequenceType::*backptr)(); + typedef typename SequenceType::reference (SequenceType::*backptr)(); - system.register_function(boost::function(backptr(&SequenceType::back)), "back"); - system.register_function(boost::function(&SequenceType::push_back), "push_back"); - system.register_function(boost::function(&SequenceType::pop_back), "pop_back"); -} + system.register_function(boost::function(backptr(&SequenceType::back)), "back"); + system.register_function(boost::function(&SequenceType::push_back), "push_back"); + system.register_function(boost::function(&SequenceType::pop_back), "pop_back"); + } -template -void bootstrap_vector(Dispatch_Engine &system, const std::string &type) -{ - system.register_type(type); - bootstrap_random_access_container(system, type); - bootstrap_back_insertion_sequence(system, type); + template + void bootstrap_vector(Dispatch_Engine &system, const std::string &type) + { + system.register_type(type); + bootstrap_random_access_container(system, type); + bootstrap_back_insertion_sequence(system, type); + } } #endif diff --git a/dispatchkit/boxed_value.hpp b/dispatchkit/boxed_value.hpp index c7a1125..8de6957 100644 --- a/dispatchkit/boxed_value.hpp +++ b/dispatchkit/boxed_value.hpp @@ -8,28 +8,30 @@ #include #include -class Boxed_Value +namespace dispatchkit { - public: - struct Void_Type - { - }; - - private: - struct Data - { - struct Shared_Ptr_Proxy + class Boxed_Value + { + public: + struct Void_Type { - virtual ~Shared_Ptr_Proxy() - { - } - - virtual bool unique(boost::any *) = 0; - virtual long use_count(boost::any *) = 0; }; - template - struct Shared_Ptr_Proxy_Impl : Shared_Ptr_Proxy + private: + struct Data + { + struct Shared_Ptr_Proxy + { + virtual ~Shared_Ptr_Proxy() + { + } + + virtual bool unique(boost::any *) = 0; + virtual long use_count(boost::any *) = 0; + }; + + template + struct Shared_Ptr_Proxy_Impl : Shared_Ptr_Proxy { virtual ~Shared_Ptr_Proxy_Impl() { @@ -46,454 +48,452 @@ class Boxed_Value boost::shared_ptr *ptr = boost::any_cast >(a); return ptr->use_count(); } - }; + }; - Data(const Type_Info &ti, - const boost::any &to, - bool tr, - const boost::shared_ptr &t_proxy = boost::shared_ptr()) - : m_type_info(ti), m_obj(to), + Data(const Type_Info &ti, + const boost::any &to, + bool tr, + const boost::shared_ptr &t_proxy = boost::shared_ptr()) + : m_type_info(ti), m_obj(to), m_is_ref(tr), m_ptr_proxy(t_proxy) + { + } + + Data &operator=(const Data &rhs) + { + m_type_info = rhs.m_type_info; + m_obj = rhs.m_obj; + m_is_ref = rhs.m_is_ref; + m_ptr_proxy = rhs.m_ptr_proxy; + + return *this; + } + + static bool get_false() + { + return false; + } + + Type_Info m_type_info; + boost::any m_obj; + bool m_is_ref; + boost::shared_ptr m_ptr_proxy; + }; + + struct Object_Cache + { + boost::shared_ptr get(Boxed_Value::Void_Type) + { + return boost::shared_ptr (new Data( + Get_Type_Info::get(), + boost::any(), + false) + ); + } + + template + boost::shared_ptr get(boost::shared_ptr obj) + { + boost::shared_ptr data(new Data( + Get_Type_Info::get(), + boost::any(obj), + false, + boost::shared_ptr(new Data::Shared_Ptr_Proxy_Impl())) + ); + + std::map::iterator itr + = m_ptrs.find(obj.get()); + + if (itr != m_ptrs.end()) + { + (*data) = (itr->second); + } else { + m_ptrs.insert(std::make_pair(obj.get(), *data)); + } + + return data; + } + + template + boost::shared_ptr get(boost::reference_wrapper obj) + { + boost::shared_ptr data(new Data( + Get_Type_Info::get(), + boost::any(obj), + true) + ); + + std::map::iterator itr + = m_ptrs.find(obj.get_pointer()); + + if (itr != m_ptrs.end()) + { + std::cout << "Reference wrapper ptr found, using it" << std::endl; + (*data) = (itr->second); + } + + return data; + } + + template + boost::shared_ptr get(const T& t) + { + boost::shared_ptr data(new Data( + Get_Type_Info::get(), + boost::any(boost::shared_ptr(new T(t))), + false, + boost::shared_ptr(new Data::Shared_Ptr_Proxy_Impl())) + ); + + boost::shared_ptr *ptr = boost::any_cast >(&data->m_obj); + + m_ptrs.insert(std::make_pair(ptr->get(), *data)); + return data; + } + + boost::shared_ptr get() + { + return boost::shared_ptr (new Data( + Type_Info(), + boost::any(), + false) + ); + } + + void cull() + { + std::map::iterator itr = m_ptrs.begin(); + + while (itr != m_ptrs.end()) + { + if (itr->second.m_ptr_proxy->unique(&itr->second.m_obj) == 1) + { + std::map::iterator todel = itr; + // std::cout << "Releasing unique ptr " << std::endl; + ++itr; + m_ptrs.erase(todel); + } else { + ++itr; + } + } + + // std::cout << "References held: " << m_ptrs.size() << std::endl; + } + + + std::map m_ptrs; + }; + + public: + template + explicit Boxed_Value(T t) + : m_data(get_object_cache().get(t)) + { + } + + Boxed_Value(const Boxed_Value &t_so) + : m_data(t_so.m_data) { } - Data &operator=(const Data &rhs) + Boxed_Value() + : m_data(get_object_cache().get()) { - m_type_info = rhs.m_type_info; - m_obj = rhs.m_obj; - m_is_ref = rhs.m_is_ref; - m_ptr_proxy = rhs.m_ptr_proxy; + } + ~Boxed_Value() + { + get_object_cache().cull(); + } + + + Object_Cache &get_object_cache() + { + static Object_Cache oc; + return oc; + } + + + Boxed_Value assign(const Boxed_Value &rhs) + { + (*m_data) = (*rhs.m_data); return *this; } - static bool get_false() + Boxed_Value &operator=(const Boxed_Value &rhs) { - return false; + m_data = rhs.m_data; + return *this; } - Type_Info m_type_info; - boost::any m_obj; - bool m_is_ref; - boost::shared_ptr m_ptr_proxy; + const Type_Info &get_type_info() const + { + return m_data->m_type_info; + } + + bool is_unknown() const + { + return m_data->m_type_info.m_is_unknown; + } + + boost::any get() const + { + return m_data->m_obj; + } + + bool is_ref() const + { + return m_data->m_is_ref; + } + + private: + boost::shared_ptr m_data; + }; + + + //cast_help specializations + template + struct Cast_Helper + { + typename boost::reference_wrapper::type > operator()(Boxed_Value ob) + { + if (ob.is_ref()) + { + return boost::cref((boost::any_cast >(ob.get())).get()); + } else { + return boost::cref(*(boost::any_cast >(ob.get()))); + } + } }; - struct Object_Cache + template + struct Cast_Helper { - boost::shared_ptr get(Boxed_Value::Void_Type) + typename boost::reference_wrapper::type > operator()(Boxed_Value ob) { - return boost::shared_ptr (new Data( - Get_Type_Info::get(), - boost::any(), - false) - ); - } - - template - boost::shared_ptr get(boost::shared_ptr obj) + if (ob.is_ref()) { - boost::shared_ptr data(new Data( - Get_Type_Info::get(), - boost::any(obj), - false, - boost::shared_ptr(new Data::Shared_Ptr_Proxy_Impl())) - ); - - std::map::iterator itr - = m_ptrs.find(obj.get()); - - if (itr != m_ptrs.end()) - { - (*data) = (itr->second); - } else { - m_ptrs.insert(std::make_pair(obj.get(), *data)); - } - - return data; + return boost::cref((boost::any_cast >(ob.get())).get()); + } else { + return boost::cref(*(boost::any_cast >(ob.get()))); } - - template - boost::shared_ptr get(boost::reference_wrapper obj) - { - boost::shared_ptr data(new Data( - Get_Type_Info::get(), - boost::any(obj), - true) - ); - - std::map::iterator itr - = m_ptrs.find(obj.get_pointer()); - - if (itr != m_ptrs.end()) - { - std::cout << "Reference wrapper ptr found, using it" << std::endl; - (*data) = (itr->second); - } - - return data; } - - template - boost::shared_ptr get(const T& t) - { - boost::shared_ptr data(new Data( - Get_Type_Info::get(), - boost::any(boost::shared_ptr(new T(t))), - false, - boost::shared_ptr(new Data::Shared_Ptr_Proxy_Impl())) - ); - - boost::shared_ptr *ptr = boost::any_cast >(&data->m_obj); - - m_ptrs.insert(std::make_pair(ptr->get(), *data)); - return data; - } - - boost::shared_ptr get() - { - return boost::shared_ptr (new Data( - Type_Info(), - boost::any(), - false) - ); - } - - void cull() - { - std::map::iterator itr = m_ptrs.begin(); - - while (itr != m_ptrs.end()) - { - if (itr->second.m_ptr_proxy->unique(&itr->second.m_obj) == 1) - { - std::map::iterator todel = itr; - // std::cout << "Releasing unique ptr " << std::endl; - ++itr; - m_ptrs.erase(todel); - } else { - ++itr; - } - } - - // std::cout << "References held: " << m_ptrs.size() << std::endl; - } - - - std::map m_ptrs; }; - public: - template - explicit Boxed_Value(T t) - : m_data(get_object_cache().get(t)) + template + struct Cast_Helper + { + const Result *operator()(Boxed_Value ob) { + if (ob.is_ref()) + { + return (boost::any_cast >(ob.get())).get_pointer(); + } else { + return (boost::any_cast >(ob.get())).get(); + } + } + }; + + template + struct Cast_Helper + { + Result *operator()(Boxed_Value ob) + { + if (ob.is_ref()) + { + return (boost::any_cast >(ob.get())).get_pointer(); + } else { + return (boost::any_cast >(ob.get())).get(); + } + } + }; + + template + struct Cast_Helper + { + typename boost::reference_wrapper operator()(Boxed_Value ob) + { + if (ob.is_ref()) + { + return boost::any_cast >(ob.get()); + } else { + return boost::ref(*(boost::any_cast >(ob.get()))); + } + } + }; + + template + struct Cast_Helper > + { + typename boost::shared_ptr operator()(Boxed_Value ob) + { + return boost::any_cast >(ob.get()); + } + }; + + + template<> + struct Cast_Helper + { + Boxed_Value operator()(Boxed_Value ob) + { + return ob; + } + }; + + + struct Boxed_POD_Value + { + Boxed_POD_Value(const Boxed_Value &v) + : d(0), i(0), m_isfloat(false) + { + const int inp_ = int(v.get_type_info().m_type_info); + + const int char_ = int(&typeid(char)); + const int bool_ = int(&typeid(bool)); + + const int double_ = int(&typeid(double)); + const int float_ = int(&typeid(float)); + + const int long_ = int(&typeid(long)); + const int unsigned_long_ = int(&typeid(unsigned long)); + const int int_ = int(&typeid(int)); + const int unsigned_int_ = int(&typeid(unsigned int)); + + const int uint8_t_ = int(&typeid(uint8_t)); + const int uint16_t_ = int(&typeid(uint16_t)); + const int uint32_t_ = int(&typeid(uint32_t)); + // const int uint64_t_ = int(&typeid(uint64_t)); + + const int int8_t_ = int(&typeid(int8_t)); + const int int16_t_ = int(&typeid(int16_t)); + const int int32_t_ = int(&typeid(int32_t)); + const int int64_t_ = int(&typeid(int64_t)); + + if (inp_ == double_) + { + d = Cast_Helper()(v); + m_isfloat = true; + } else if (inp_ == float_) { + d = Cast_Helper()(v); + m_isfloat = true; + } else if (inp_ == bool_ ) { + i = Cast_Helper()(v); + } else if (inp_ == char_) { + i = Cast_Helper()(v); + } else if (inp_ == int_) { + i = Cast_Helper()(v); + } else if (inp_ == unsigned_int_) { + i = Cast_Helper()(v); + } else if (inp_ == long_) { + i = Cast_Helper()(v); + } else if (inp_ == unsigned_long_) { + i = Cast_Helper()(v); + } else if (inp_ == int8_t_) { + i = Cast_Helper()(v); + } else if (inp_ == int16_t_) { + i = Cast_Helper()(v); + } else if (inp_ == int32_t_) { + i = Cast_Helper()(v); + } else if (inp_ == int64_t_) { + i = Cast_Helper()(v); + } else if (inp_ == uint8_t_) { + i = Cast_Helper()(v); + } else if (inp_ == uint16_t_) { + i = Cast_Helper()(v); + } else if (inp_ == uint32_t_) { + i = Cast_Helper()(v); + } else { + throw boost::bad_any_cast(); + } + } + + + bool operator==(const Boxed_POD_Value &r) const + { + return ((m_isfloat)?d:i) == ((r.m_isfloat)?r.d:r.i); + } + + bool operator<(const Boxed_POD_Value &r) const + { + return ((m_isfloat)?d:i) < ((r.m_isfloat)?r.d:r.i); + } + + bool operator>(const Boxed_POD_Value &r) const + { + return ((m_isfloat)?d:i) > ((r.m_isfloat)?r.d:r.i); + } + + bool operator>=(const Boxed_POD_Value &r) const + { + return ((m_isfloat)?d:i) >= ((r.m_isfloat)?r.d:r.i); + } + + bool operator<=(const Boxed_POD_Value &r) const + { + return ((m_isfloat)?d:i) <= ((r.m_isfloat)?r.d:r.i); + } + + bool operator!=(const Boxed_POD_Value &r) const + { + return ((m_isfloat)?d:i) != ((r.m_isfloat)?r.d:r.i); + } + + Boxed_Value operator+(const Boxed_POD_Value &r) const + { + if (!m_isfloat && !r.m_isfloat) + { + return Boxed_Value(i + r.i); } - Boxed_Value(const Boxed_Value &t_so) - : m_data(t_so.m_data) - { + return Boxed_Value(((m_isfloat)?d:i) + ((r.m_isfloat)?r.d:r.i)); } - Boxed_Value() - : m_data(get_object_cache().get()) + Boxed_Value operator*(const Boxed_POD_Value &r) const { + if (!m_isfloat && !r.m_isfloat) + { + return Boxed_Value(i * r.i); + } + + return Boxed_Value(((m_isfloat)?d:i) * ((r.m_isfloat)?r.d:r.i)); } - ~Boxed_Value() + Boxed_Value operator/(const Boxed_POD_Value &r) const { - get_object_cache().cull(); + if (!m_isfloat && !r.m_isfloat) + { + return Boxed_Value(i / r.i); + } + + return Boxed_Value(((m_isfloat)?d:i) / ((r.m_isfloat)?r.d:r.i)); } - - Object_Cache &get_object_cache() + Boxed_Value operator-(const Boxed_POD_Value &r) const { - static Object_Cache oc; - return oc; - } + if (!m_isfloat && !r.m_isfloat) + { + return Boxed_Value(i - r.i); + } - - Boxed_Value assign(const Boxed_Value &rhs) - { - (*m_data) = (*rhs.m_data); - return *this; + return Boxed_Value(((m_isfloat)?d:i) - ((r.m_isfloat)?r.d:r.i)); } - Boxed_Value &operator=(const Boxed_Value &rhs) + double d; + int64_t i; + + bool m_isfloat; + }; + + template<> + struct Cast_Helper { - m_data = rhs.m_data; - return *this; - } - - const Type_Info &get_type_info() const - { - return m_data->m_type_info; - } - - bool is_unknown() const - { - return m_data->m_type_info.m_is_unknown; - } - - boost::any get() const - { - return m_data->m_obj; - } - - bool is_ref() const - { - return m_data->m_is_ref; - } - - private: - boost::shared_ptr m_data; -}; - - -//cast_help specializations -template -struct Cast_Helper -{ - typename boost::reference_wrapper::type > operator()(Boxed_Value ob) - { - if (ob.is_ref()) - { - return boost::cref((boost::any_cast >(ob.get())).get()); - } else { - return boost::cref(*(boost::any_cast >(ob.get()))); - } - } -}; - -template -struct Cast_Helper -{ - typename boost::reference_wrapper::type > operator()(Boxed_Value ob) - { - if (ob.is_ref()) - { - return boost::cref((boost::any_cast >(ob.get())).get()); - } else { - return boost::cref(*(boost::any_cast >(ob.get()))); - } - } -}; - -template -struct Cast_Helper -{ - const Result *operator()(Boxed_Value ob) - { - if (ob.is_ref()) - { - return (boost::any_cast >(ob.get())).get_pointer(); - } else { - return (boost::any_cast >(ob.get())).get(); - } - } -}; - -template -struct Cast_Helper -{ - Result *operator()(Boxed_Value ob) - { - if (ob.is_ref()) - { - return (boost::any_cast >(ob.get())).get_pointer(); - } else { - return (boost::any_cast >(ob.get())).get(); - } - } -}; - -template -struct Cast_Helper -{ - typename boost::reference_wrapper operator()(Boxed_Value ob) - { - if (ob.is_ref()) - { - return boost::any_cast >(ob.get()); - } else { - return boost::ref(*(boost::any_cast >(ob.get()))); - } - } -}; - -template -struct Cast_Helper > -{ - typename boost::shared_ptr operator()(Boxed_Value ob) - { - return boost::any_cast >(ob.get()); - } -}; - - -template<> -struct Cast_Helper -{ - Boxed_Value operator()(Boxed_Value ob) - { - return ob; - } -}; - - -struct Boxed_POD_Value -{ - Boxed_POD_Value(const Boxed_Value &v) - : d(0), i(0), m_isfloat(false) - { - const int inp_ = int(v.get_type_info().m_type_info); - - const int char_ = int(&typeid(char)); - const int bool_ = int(&typeid(bool)); - - const int double_ = int(&typeid(double)); - const int float_ = int(&typeid(float)); - - const int long_ = int(&typeid(long)); - const int unsigned_long_ = int(&typeid(unsigned long)); - const int int_ = int(&typeid(int)); - const int unsigned_int_ = int(&typeid(unsigned int)); - - const int uint8_t_ = int(&typeid(uint8_t)); - const int uint16_t_ = int(&typeid(uint16_t)); - const int uint32_t_ = int(&typeid(uint32_t)); -// const int uint64_t_ = int(&typeid(uint64_t)); - - const int int8_t_ = int(&typeid(int8_t)); - const int int16_t_ = int(&typeid(int16_t)); - const int int32_t_ = int(&typeid(int32_t)); - const int int64_t_ = int(&typeid(int64_t)); - - if (inp_ == double_) - { - d = Cast_Helper()(v); - m_isfloat = true; - } else if (inp_ == float_) { - d = Cast_Helper()(v); - m_isfloat = true; - } else if (inp_ == bool_ ) { - i = Cast_Helper()(v); - } else if (inp_ == char_) { - i = Cast_Helper()(v); - } else if (inp_ == int_) { - i = Cast_Helper()(v); - } else if (inp_ == unsigned_int_) { - i = Cast_Helper()(v); - } else if (inp_ == long_) { - i = Cast_Helper()(v); - } else if (inp_ == unsigned_long_) { - i = Cast_Helper()(v); - } else if (inp_ == int8_t_) { - i = Cast_Helper()(v); - } else if (inp_ == int16_t_) { - i = Cast_Helper()(v); - } else if (inp_ == int32_t_) { - i = Cast_Helper()(v); - } else if (inp_ == int64_t_) { - i = Cast_Helper()(v); - } else if (inp_ == uint8_t_) { - i = Cast_Helper()(v); - } else if (inp_ == uint16_t_) { - i = Cast_Helper()(v); - } else if (inp_ == uint32_t_) { - i = Cast_Helper()(v); - } else { - throw boost::bad_any_cast(); - } - } - - - bool operator==(const Boxed_POD_Value &r) const - { - return ((m_isfloat)?d:i) == ((r.m_isfloat)?r.d:r.i); - } - - bool operator<(const Boxed_POD_Value &r) const - { - return ((m_isfloat)?d:i) < ((r.m_isfloat)?r.d:r.i); - } - - bool operator>(const Boxed_POD_Value &r) const - { - return ((m_isfloat)?d:i) > ((r.m_isfloat)?r.d:r.i); - } - - bool operator>=(const Boxed_POD_Value &r) const - { - return ((m_isfloat)?d:i) >= ((r.m_isfloat)?r.d:r.i); - } - - bool operator<=(const Boxed_POD_Value &r) const - { - return ((m_isfloat)?d:i) <= ((r.m_isfloat)?r.d:r.i); - } - - bool operator!=(const Boxed_POD_Value &r) const - { - return ((m_isfloat)?d:i) != ((r.m_isfloat)?r.d:r.i); - } - - Boxed_Value operator+(const Boxed_POD_Value &r) const - { - if (!m_isfloat && !r.m_isfloat) - { - return Boxed_Value(i + r.i); - } - - return Boxed_Value(((m_isfloat)?d:i) + ((r.m_isfloat)?r.d:r.i)); - } - - Boxed_Value operator*(const Boxed_POD_Value &r) const - { - if (!m_isfloat && !r.m_isfloat) - { - return Boxed_Value(i * r.i); - } - - return Boxed_Value(((m_isfloat)?d:i) * ((r.m_isfloat)?r.d:r.i)); - } - - Boxed_Value operator/(const Boxed_POD_Value &r) const - { - if (!m_isfloat && !r.m_isfloat) - { - return Boxed_Value(i / r.i); - } - - return Boxed_Value(((m_isfloat)?d:i) / ((r.m_isfloat)?r.d:r.i)); - } - - Boxed_Value operator-(const Boxed_POD_Value &r) const - { - if (!m_isfloat && !r.m_isfloat) - { - return Boxed_Value(i - r.i); - } - - return Boxed_Value(((m_isfloat)?d:i) - ((r.m_isfloat)?r.d:r.i)); - } - - double d; - int64_t i; - - bool m_isfloat; -}; - -template<> -struct Cast_Helper -{ - Boxed_POD_Value operator()(Boxed_Value ob) - { - return Boxed_POD_Value(ob); - } -}; - - - + Boxed_POD_Value operator()(Boxed_Value ob) + { + return Boxed_POD_Value(ob); + } + }; +} #endif diff --git a/dispatchkit/dispatchkit.hpp b/dispatchkit/dispatchkit.hpp index 645ddf4..f600293 100644 --- a/dispatchkit/dispatchkit.hpp +++ b/dispatchkit/dispatchkit.hpp @@ -16,194 +16,196 @@ #include "proxy_functions.hpp" #include "proxy_constructors.hpp" -class Dispatch_Engine +namespace dispatchkit { - public: - typedef std::multimap > Function_Map; - typedef std::map Type_Name_Map; - typedef std::map Scope; - typedef std::deque Stack; + class Dispatch_Engine + { + public: + typedef std::multimap > Function_Map; + typedef std::map Type_Name_Map; + typedef std::map Scope; + typedef std::deque Stack; - Dispatch_Engine() - { - m_scopes.push_back(Scope()); - } - - void register_function(const boost::shared_ptr &f, const std::string &name) - { - m_functions.insert(std::make_pair(name, f)); - } - - - template - void register_function(const Function &func, const std::string &name) + Dispatch_Engine() { - m_functions.insert(std::make_pair(name, boost::shared_ptr(new Proxy_Function_Impl(func)))); + m_scopes.push_back(Scope()); + } + + void register_function(const boost::shared_ptr &f, const std::string &name) + { + m_functions.insert(std::make_pair(name, f)); } - template - void set_object(const std::string &name, const Class &obj) + template + void register_function(const Function &func, const std::string &name) + { + m_functions.insert(std::make_pair(name, boost::shared_ptr(new Proxy_Function_Impl(func)))); + } + + + template + void set_object(const std::string &name, const Class &obj) + { + for (int i = m_scopes.size()-1; i >= 0; --i) + { + std::map::const_iterator itr = m_scopes[i].find(name); + if (itr != m_scopes[i].end()) + { + m_scopes[i][name] = Boxed_Value(obj); + return; + } + } + + add_object(name, obj); + } + + template + void add_object(const std::string &name, const Class &obj) + { + m_scopes.back()[name] = Boxed_Value(obj); + } + + void new_scope() + { + m_scopes.push_back(Scope()); + } + + void pop_scope() + { + if (m_scopes.size() > 1) + { + m_scopes.pop_back(); + } else { + throw std::range_error("Unable to pop global stack"); + } + } + + Stack get_stack() + { + return m_scopes; + } + + Stack set_stack(Stack s) + { + swap(s, m_scopes); + return s; + } + + + Boxed_Value get_object(const std::string &name) const { for (int i = m_scopes.size()-1; i >= 0; --i) { std::map::const_iterator itr = m_scopes[i].find(name); if (itr != m_scopes[i].end()) { - m_scopes[i][name] = Boxed_Value(obj); - return; + return itr->second; } } - add_object(name, obj); + throw std::range_error("Object not known: " + name); } - template - void add_object(const std::string &name, const Class &obj) - { - m_scopes.back()[name] = Boxed_Value(obj); - } - - void new_scope() - { - m_scopes.push_back(Scope()); - } - - void pop_scope() - { - if (m_scopes.size() > 1) - { - m_scopes.pop_back(); - } else { - throw std::range_error("Unable to pop global stack"); - } - } - - Stack get_stack() - { - return m_scopes; - } - - Stack set_stack(Stack s) - { - swap(s, m_scopes); - return s; - } - - - Boxed_Value get_object(const std::string &name) const - { - for (int i = m_scopes.size()-1; i >= 0; --i) - { - std::map::const_iterator itr = m_scopes[i].find(name); - if (itr != m_scopes[i].end()) + template + void register_type(const std::string &name) { - return itr->second; + m_types.insert(std::make_pair(name, Get_Type_Info::get())); } - } - throw std::range_error("Object not known: " + name); - } - - template - void register_type(const std::string &name) + std::vector get_types() const { - m_types.insert(std::make_pair(name, Get_Type_Info::get())); + return std::vector(m_types.begin(), m_types.end()); } - std::vector get_types() const - { - return std::vector(m_types.begin(), m_types.end()); - } + std::vector > + get_function(const std::string &t_name) const + { + std::vector > funcs; - std::vector > - get_function(const std::string &t_name) const - { - std::vector > funcs; + try { + funcs.insert(funcs.end(), + Function_Map::value_type( + t_name, + Cast_Helper()(get_object(t_name))) + ); + } catch (const std::bad_cast &) { + } catch (const std::range_error &) { + } - try { - funcs.insert(funcs.end(), - Function_Map::value_type( - t_name, - Cast_Helper()(get_object(t_name))) - ); - } catch (const std::bad_cast &) { - } catch (const std::range_error &) { + std::pair range + = m_functions.equal_range(t_name); + + funcs.insert(funcs.end(), range.first, range.second); + return funcs; } - std::pair range - = m_functions.equal_range(t_name); + std::vector get_functions() const + { + return std::vector(m_functions.begin(), m_functions.end()); + } - funcs.insert(funcs.end(), range.first, range.second); - return funcs; - } + private: + std::deque m_scopes; - std::vector get_functions() const - { - return std::vector(m_functions.begin(), m_functions.end()); - } + Function_Map m_functions; + Type_Name_Map m_types; + }; - private: - std::deque m_scopes; - - Function_Map m_functions; - Type_Name_Map m_types; -}; - -void dump_object(Boxed_Value o) -{ - std::cout << o.get_type_info().m_type_info->name() << std::endl; -} - -void dump_type(const Type_Info &type) -{ - std::cout << type.m_bare_type_info->name(); -} - -void dump_function(const Dispatch_Engine::Function_Map::value_type &f) -{ - std::vector params = f.second->get_param_types(); - - dump_type(params.front()); - std::cout << " " << f.first << "("; - - for (std::vector::const_iterator itr = params.begin() + 1; - itr != params.end(); - ++itr) + void dump_object(Boxed_Value o) { - dump_type(*itr); - std::cout << ", "; + std::cout << o.get_type_info().m_type_info->name() << std::endl; } - std::cout << ")" << std::endl; -} - -void dump_system(const Dispatch_Engine &s) -{ - std::cout << "Registered Types: " << std::endl; - std::vector types = s.get_types(); - for (std::vector::const_iterator itr = types.begin(); - itr != types.end(); - ++itr) + void dump_type(const Type_Info &type) { - std::cout << itr->first << ": "; - dump_type(itr->second); + std::cout << type.m_bare_type_info->name(); + } + + void dump_function(const Dispatch_Engine::Function_Map::value_type &f) + { + std::vector params = f.second->get_param_types(); + + dump_type(params.front()); + std::cout << " " << f.first << "("; + + for (std::vector::const_iterator itr = params.begin() + 1; + itr != params.end(); + ++itr) + { + dump_type(*itr); + std::cout << ", "; + } + + std::cout << ")" << std::endl; + } + + void dump_system(const Dispatch_Engine &s) + { + std::cout << "Registered Types: " << std::endl; + std::vector types = s.get_types(); + for (std::vector::const_iterator itr = types.begin(); + itr != types.end(); + ++itr) + { + std::cout << itr->first << ": "; + dump_type(itr->second); + std::cout << std::endl; + } + + + std::cout << std::endl; std::vector funcs = s.get_functions(); + + std::cout << "Functions: " << std::endl; + for (std::vector::const_iterator itr = funcs.begin(); + itr != funcs.end(); + ++itr) + { + dump_function(*itr); + } std::cout << std::endl; } - - - std::cout << std::endl; std::vector funcs = s.get_functions(); - - std::cout << "Functions: " << std::endl; - for (std::vector::const_iterator itr = funcs.begin(); - itr != funcs.end(); - ++itr) - { - dump_function(*itr); - } - std::cout << std::endl; } - - #endif + diff --git a/dispatchkit/proxy_constructors.hpp b/dispatchkit/proxy_constructors.hpp index cbb2b3e..e66edcf 100644 --- a/dispatchkit/proxy_constructors.hpp +++ b/dispatchkit/proxy_constructors.hpp @@ -8,17 +8,20 @@ #include #include -template -boost::shared_ptr constructor() +namespace dispatchkit { - return boost::shared_ptr(new Class()); -} + template + boost::shared_ptr constructor() + { + return boost::shared_ptr(new Class()); + } -template -boost::function ()> build_constructor() -{ - typedef boost::shared_ptr (*func)(); - return boost::function ()>(func(&(constructor))); + template + boost::function ()> build_constructor() + { + typedef boost::shared_ptr (*func)(); + return boost::function ()>(func(&(constructor))); + } } #define BOOST_PP_ITERATION_LIMITS ( 1, 10 ) @@ -28,18 +31,20 @@ boost::function ()> build_constructor() #else # define n BOOST_PP_ITERATION() - -template -boost::shared_ptr constructor( BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) ) +namespace dispatchkit { - return boost::shared_ptr(new Class( BOOST_PP_ENUM_PARAMS(n, p) )); -} + template + boost::shared_ptr constructor( BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) ) + { + return boost::shared_ptr(new Class( BOOST_PP_ENUM_PARAMS(n, p) )); + } -template -boost::function (BOOST_PP_ENUM_PARAMS(n, Param))> build_constructor() -{ - typedef boost::shared_ptr (*func)(BOOST_PP_ENUM_PARAMS(n, Param)); - return boost::function (BOOST_PP_ENUM_PARAMS(n, Param))>(func(&(constructor))); + template + boost::function (BOOST_PP_ENUM_PARAMS(n, Param))> build_constructor() + { + typedef boost::shared_ptr (*func)(BOOST_PP_ENUM_PARAMS(n, Param)); + return boost::function (BOOST_PP_ENUM_PARAMS(n, Param))>(func(&(constructor))); + } } #endif diff --git a/dispatchkit/proxy_functions.hpp b/dispatchkit/proxy_functions.hpp index d4820cb..2885435 100644 --- a/dispatchkit/proxy_functions.hpp +++ b/dispatchkit/proxy_functions.hpp @@ -16,212 +16,220 @@ #include #include -// handle_return implementations -template -struct Handle_Return +namespace dispatchkit { - Boxed_Value operator()(const boost::function &f) - { - return Boxed_Value(f()); - } -}; - -template -struct Handle_Return -{ - Boxed_Value operator()(const boost::function &f) - { - return Boxed_Value(boost::ref(f())); - } -}; - -template<> -struct Handle_Return -{ - Boxed_Value operator()(const boost::function &f) - { - return f(); - } -}; - -template<> -struct Handle_Return -{ - Boxed_Value operator()(const boost::function &f) - { - return f(); - } -}; - -template<> -struct Handle_Return -{ - Boxed_Value operator()(const boost::function &f) - { - f(); - return Boxed_Value(Boxed_Value::Void_Type()); - } -}; - - -// Build param type list (variadic) -template -std::vector build_param_type_list(const boost::function &f) -{ - std::vector ti; - ti.push_back(Get_Type_Info::get()); - return ti; -} - -// call_func implementations (variadic) -template -Boxed_Value call_func(const boost::function &f, const std::vector ¶ms) -{ - if (params.size() != 0) - { - throw std::range_error("Incorrect number of parameters"); - } else { - return Handle_Return()(f); - } -} - -struct Param_List_Builder -{ - Param_List_Builder &operator<<(const Boxed_Value &so) - { - objects.push_back(so); - return *this; - } - - template - Param_List_Builder &operator<<(T t) + // handle_return implementations + template + struct Handle_Return { - objects.push_back(Boxed_Value(t)); + Boxed_Value operator()(const boost::function &f) + { + return Boxed_Value(f()); + } + }; + + template + struct Handle_Return + { + Boxed_Value operator()(const boost::function &f) + { + return Boxed_Value(boost::ref(f())); + } + }; + + template<> + struct Handle_Return + { + Boxed_Value operator()(const boost::function &f) + { + return f(); + } + }; + + template<> + struct Handle_Return + { + Boxed_Value operator()(const boost::function &f) + { + return f(); + } + }; + + template<> + struct Handle_Return + { + Boxed_Value operator()(const boost::function &f) + { + f(); + return Boxed_Value(Boxed_Value::Void_Type()); + } + }; + + + // Build param type list (variadic) + template + std::vector build_param_type_list(const boost::function &f) + { + std::vector ti; + ti.push_back(Get_Type_Info::get()); + return ti; + } + + // call_func implementations (variadic) + template + Boxed_Value call_func(const boost::function &f, const std::vector ¶ms) + { + if (params.size() != 0) + { + throw std::range_error("Incorrect number of parameters"); + } else { + return Handle_Return()(f); + } + } + + struct Param_List_Builder + { + Param_List_Builder &operator<<(const Boxed_Value &so) + { + objects.push_back(so); return *this; } - operator const std::vector &() const - { - return objects; - } + template + Param_List_Builder &operator<<(T t) + { + objects.push_back(Boxed_Value(t)); + return *this; + } - std::vector objects; -}; + operator const std::vector &() const + { + return objects; + } + std::vector objects; + }; +} #define BOOST_PP_ITERATION_LIMITS ( 1, 10 ) #define BOOST_PP_FILENAME_1 "proxy_functions.hpp" #include BOOST_PP_ITERATE() -class Proxy_Function +namespace dispatchkit { - public: - virtual ~Proxy_Function() {} - virtual Boxed_Value operator()(const std::vector ¶ms) = 0; - virtual std::vector get_param_types() = 0; - -}; - -class Dynamic_Proxy_Function : public Proxy_Function -{ - public: - Dynamic_Proxy_Function(const boost::function &)> &t_f, int arity=-1) - : m_f(t_f), m_arity(arity) - { - } - - virtual ~Dynamic_Proxy_Function() {} - - virtual Boxed_Value operator()(const std::vector ¶ms) - { - if (m_arity < 0 || params.size() == size_t(m_arity)) - { - return m_f(params); - } else { - throw std::range_error("Incorrect number of parameters"); - } - } - - virtual std::vector get_param_types() - { - return build_param_type_list(m_f); - } - - private: - boost::function &)> m_f; - int m_arity; -}; - -template -class Proxy_Function_Impl : public Proxy_Function -{ - public: - Proxy_Function_Impl(const Func &f) - : m_f(f) - { - } - - virtual ~Proxy_Function_Impl() {} - - - virtual Boxed_Value operator()(const std::vector ¶ms) - { - return call_func(m_f, params); - } - - virtual std::vector get_param_types() - { - return build_param_type_list(m_f); - } - - private: - Func m_f; -}; - -Boxed_Value dispatch(const std::vector > > &funcs, - const std::vector &plist) -{ - for (std::vector > >::const_iterator itr = funcs.begin(); - itr != funcs.end(); - ++itr) + class Proxy_Function { - try { - return (*itr->second)(plist); - } catch (const std::bad_cast &) { - //try again - } catch (const std::range_error &) { - //invalid num params, try again - } - } + public: + virtual ~Proxy_Function() {} + virtual Boxed_Value operator()(const std::vector ¶ms) = 0; + virtual std::vector get_param_types() = 0; - throw std::runtime_error("No matching function to dispatch to"); + }; + + class Dynamic_Proxy_Function : public Proxy_Function + { + public: + Dynamic_Proxy_Function(const boost::function &)> &t_f, int arity=-1) + : m_f(t_f), m_arity(arity) + { + } + + virtual ~Dynamic_Proxy_Function() {} + + virtual Boxed_Value operator()(const std::vector ¶ms) + { + if (m_arity < 0 || params.size() == size_t(m_arity)) + { + return m_f(params); + } else { + throw std::range_error("Incorrect number of parameters"); + } + } + + virtual std::vector get_param_types() + { + return build_param_type_list(m_f); + } + + private: + boost::function &)> m_f; + int m_arity; + }; + + template + class Proxy_Function_Impl : public Proxy_Function + { + public: + Proxy_Function_Impl(const Func &f) + : m_f(f) + { + } + + virtual ~Proxy_Function_Impl() {} + + + virtual Boxed_Value operator()(const std::vector ¶ms) + { + return call_func(m_f, params); + } + + virtual std::vector get_param_types() + { + return build_param_type_list(m_f); + } + + private: + Func m_f; + }; + + Boxed_Value dispatch(const std::vector > > &funcs, + const std::vector &plist) + { + for (std::vector > >::const_iterator itr = funcs.begin(); + itr != funcs.end(); + ++itr) + { + try { + return (*itr->second)(plist); + } catch (const std::bad_cast &) { + //try again + } catch (const std::range_error &) { + //invalid num params, try again + } + } + + throw std::runtime_error("No matching function to dispatch to"); + } } # endif #else # define n BOOST_PP_ITERATION() -template -std::vector build_param_type_list(const boost::function &f) +namespace dispatchkit { - std::vector ti; - ti.push_back(Get_Type_Info::get()); + template + std::vector build_param_type_list(const boost::function &f) + { + std::vector ti; + ti.push_back(Get_Type_Info::get()); - BOOST_PP_REPEAT(n, gettypeinfo, ~) + BOOST_PP_REPEAT(n, gettypeinfo, ~) - return ti; -} + return ti; + } -template -Boxed_Value call_func(const boost::function &f, - const std::vector ¶ms) -{ - if (params.size() != n) - { - throw std::range_error("Incorrect number of parameters"); - } else { - return Handle_Return()(boost::bind(f BOOST_PP_REPEAT(n, casthelper, ~))); - } + template + Boxed_Value call_func(const boost::function &f, + const std::vector ¶ms) + { + if (params.size() != n) + { + throw std::range_error("Incorrect number of parameters"); + } else { + return Handle_Return()(boost::bind(f BOOST_PP_REPEAT(n, casthelper, ~))); + } + } } #endif diff --git a/dispatchkit/register_function.hpp b/dispatchkit/register_function.hpp index 62ae4bd..940156c 100644 --- a/dispatchkit/register_function.hpp +++ b/dispatchkit/register_function.hpp @@ -18,18 +18,20 @@ #else # define n BOOST_PP_ITERATION() -template -void register_function(Dispatch_Engine &s, Ret (*f)(BOOST_PP_ENUM_PARAMS(n, Param)), const std::string &name) +namespace dispatchkit { - s.register_function(boost::function(f), name); -} + template + void register_function(Dispatch_Engine &s, Ret (*f)(BOOST_PP_ENUM_PARAMS(n, Param)), const std::string &name) + { + s.register_function(boost::function(f), name); + } -template -void register_function(Dispatch_Engine &s, Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param)), const std::string &name) -{ - s.register_function(boost::function(f), name); + template + void register_function(Dispatch_Engine &s, Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param)), const std::string &name) + { + s.register_function(boost::function(f), name); + } } - #endif diff --git a/dispatchkit/test.cpp b/dispatchkit/test.cpp index f8f6d49..2460924 100644 --- a/dispatchkit/test.cpp +++ b/dispatchkit/test.cpp @@ -8,6 +8,8 @@ #include "bootstrap.hpp" #include "bootstrap_stl.hpp" +using namespace dispatchkit; + struct Test { Test(const std::string &s) diff --git a/dispatchkit/type_info.hpp b/dispatchkit/type_info.hpp index 48e806c..5841a56 100644 --- a/dispatchkit/type_info.hpp +++ b/dispatchkit/type_info.hpp @@ -3,78 +3,83 @@ #include #include -struct Type_Info + +namespace dispatchkit { - Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void, - const std::type_info *t_ti, const std::type_info *t_bareti) - : m_is_const(t_is_const), m_is_reference(t_is_reference), m_is_pointer(t_is_pointer), + struct Type_Info + { + Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void, + const std::type_info *t_ti, const std::type_info *t_bareti) + : m_is_const(t_is_const), m_is_reference(t_is_reference), m_is_pointer(t_is_pointer), m_type_info(t_ti), m_bare_type_info(t_bareti), m_is_unknown(false) - { - } + { + } - Type_Info() - : m_is_const(false), m_is_reference(false), m_is_pointer(false), + Type_Info() + : m_is_const(false), m_is_reference(false), m_is_pointer(false), m_is_void(false), m_type_info(0), m_bare_type_info(0), m_is_unknown(true) - { - } + { + } - Type_Info &operator=(const Type_Info &ti) - { - m_is_const = ti.m_is_const; - m_is_reference = ti.m_is_reference; - m_is_pointer = ti.m_is_pointer; - m_is_void = ti.m_is_void; - m_type_info = ti.m_type_info; - m_bare_type_info = ti.m_bare_type_info; - m_is_unknown = ti.m_is_unknown; - return *this; - } + Type_Info &operator=(const Type_Info &ti) + { + m_is_const = ti.m_is_const; + m_is_reference = ti.m_is_reference; + m_is_pointer = ti.m_is_pointer; + m_is_void = ti.m_is_void; + m_type_info = ti.m_type_info; + m_bare_type_info = ti.m_bare_type_info; + m_is_unknown = ti.m_is_unknown; + return *this; + } - bool m_is_const; - bool m_is_reference; - bool m_is_pointer; - bool m_is_void; - const std::type_info *m_type_info; - const std::type_info *m_bare_type_info; - bool m_is_unknown; - }; + bool m_is_const; + bool m_is_reference; + bool m_is_pointer; + bool m_is_void; + const std::type_info *m_type_info; + const std::type_info *m_bare_type_info; + bool m_is_unknown; + }; -template -struct Get_Type_Info -{ - static Type_Info get() - { - return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, - boost::is_void::value, - &typeid(T), - &typeid(typename boost::remove_const::type>::type>::type)); - } -}; + template + struct Get_Type_Info + { + static Type_Info get() + { + return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, + boost::is_void::value, + &typeid(T), + &typeid(typename boost::remove_const::type>::type>::type)); + } + }; -template -struct Get_Type_Info > -{ - static Type_Info get() - { - return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, - boost::is_void::value, - &typeid(boost::shared_ptr ), - &typeid(typename boost::remove_const::type>::type>::type)); - } -}; + template + struct Get_Type_Info > + { + static Type_Info get() + { + return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, + boost::is_void::value, + &typeid(boost::shared_ptr ), + &typeid(typename boost::remove_const::type>::type>::type)); + } + }; -template -struct Get_Type_Info > -{ - static Type_Info get() - { - return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, - boost::is_void::value, - &typeid(boost::reference_wrapper ), - &typeid(typename boost::remove_const::type>::type>::type)); - } -}; + template + struct Get_Type_Info > + { + static Type_Info get() + { + return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, + boost::is_void::value, + &typeid(boost::reference_wrapper ), + &typeid(typename boost::remove_const::type>::type>::type)); + } + }; +} #endif + diff --git a/dispatchkit/unittest.cpp b/dispatchkit/unittest.cpp index ef92859..42b707e 100644 --- a/dispatchkit/unittest.cpp +++ b/dispatchkit/unittest.cpp @@ -7,6 +7,8 @@ BOOST_AUTO_TEST_CASE( add_operators ) { + using namespace dispatchkit; + Dispatch_Engine ss; Bootstrap::bootstrap(ss); dump_system(ss);