From fe405a781c6c6b38d7dbf57efdf6d2d643094256 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 21 Nov 2017 16:10:13 -0700 Subject: [PATCH] Revert "Merge branch 'typed_function_ordering' into c++17" This reverts commit 5d5a126bb15b8490ebdb92a8f0a8b2b990d8a067, reversing changes made to dd912822a7979aad101042c62478c2441ae21d1a. --- .../chaiscript/dispatchkit/dispatchkit.hpp | 231 ++++++------------ .../dispatchkit/dynamic_object_detail.hpp | 27 +- .../dispatchkit/proxy_functions.hpp | 38 +-- unittests/compiled_tests.cpp | 4 +- 4 files changed, 82 insertions(+), 218 deletions(-) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 930bff61..f8bbf45f 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -1104,30 +1104,22 @@ namespace chaiscript { const auto params = f.second->get_param_types(); - std::vector> typed_params; - - auto func(std::dynamic_pointer_cast(f.second)); - if (func) { - typed_params = func->get_dynamic_param_types().types(); - } - dump_type(params.front()); std::cout << " " << f.first << "("; - for (size_t i = 1; i < params.size(); ++i) + for (auto itr = params.begin() + 1; + itr != params.end(); + ) { - if (!typed_params.empty() && !typed_params[i-1].first.empty()) { - std::cout << typed_params[i-1].first; - } else { - dump_type(params[i]); - } + dump_type(*itr); + ++itr; - if (i != params.size() - 1) { + if (itr != params.end()) + { std::cout << ", "; } } - std::cout << ") \n"; } @@ -1321,157 +1313,88 @@ namespace chaiscript return m_state.m_functions; } - - static std::vector param_types(const Proxy_Function &t_f) + static bool function_less_than(const Proxy_Function &lhs, const Proxy_Function &rhs) noexcept { - assert(t_f); - return t_f->get_param_types(); - } - static std::vector> param_types(const std::shared_ptr &t_f) - { - assert(t_f); - const auto types = t_f->get_dynamic_param_types().types(); - std::vector> ret(1); - ret.insert(ret.end(), types.begin(), types.end()); - return ret; - } + auto dynamic_lhs(std::dynamic_pointer_cast(lhs)); + auto dynamic_rhs(std::dynamic_pointer_cast(rhs)); - static Type_Info type_info(const std::pair &t_ti) - { - return t_ti.second; - } - - static Type_Info type_info(const Type_Info &t_ti) - { - return t_ti; - } - - static std::string dynamic_type_name(const std::pair &t_ti) - { - return t_ti.first.empty()?t_ti.second.name():t_ti.first; - } - - static std::string dynamic_type_name(const Type_Info &ti) - { - return ti.name(); - } - - - template - static bool params_less_than(const LHS &t_lhs, const RHS &t_rhs) + if (dynamic_lhs && dynamic_rhs) { - assert(t_lhs); - assert(t_rhs); - const auto lhsparamtypes = param_types(t_lhs); - const auto rhsparamtypes = param_types(t_rhs); - - const auto lhssize = lhsparamtypes.size(); - const auto rhssize = rhsparamtypes.size(); - - constexpr auto boxed_type = user_type(); - constexpr auto boxed_pod_type = user_type(); - constexpr auto dynamic_type = user_type(); - - for (size_t i = 1; i < lhssize && i < rhssize; ++i) + if (dynamic_lhs->get_guard()) { - const Type_Info lt = type_info(lhsparamtypes[i]); - const Type_Info rt = type_info(rhsparamtypes[i]); - const std::string ln = dynamic_type_name(lhsparamtypes[i]); - const std::string rn = dynamic_type_name(rhsparamtypes[i]); - - if ( (lt.bare_equal(dynamic_type) || lt.is_undef()) - && (rt.bare_equal(dynamic_type) || rt.is_undef())) - { - - if (!ln.empty() && rn.empty()) { - return true; - } else if (ln.empty() && !rn.empty()) { - return false; - } else if (!ln.empty() && !rn.empty()) { - if (ln < rn) { - return true; - } else if (rn < ln) { - return false; - } - - // the remaining cases are handled by the is_const rules below - } - } - - if (lt.bare_equal(rt) && lt.is_const() == rt.is_const()) - { - continue; // The first two types are essentially the same, next iteration - } - - - // const is after non-const for the same type - if (lt.bare_equal(rt) && lt.is_const() && !rt.is_const()) - { - return false; - } - - if (lt.bare_equal(rt) && !lt.is_const()) - { - return true; - } - - // boxed_values are sorted last - if (lt.bare_equal(boxed_type)) - { - return false; - } - - if (rt.bare_equal(boxed_type)) - { - return true; - } - - if (lt.bare_equal(boxed_pod_type)) - { - return false; - } - - if (rt.bare_equal(boxed_pod_type)) - { - return true; - } - - // otherwise, we want to sort by typeid - return lt < rt; - } - - // if everything else checks out, sort on guard - // - auto dynamic_lhs(std::dynamic_pointer_cast(t_lhs)); - auto dynamic_rhs(std::dynamic_pointer_cast(t_rhs)); - - if (dynamic_lhs && dynamic_rhs) { - if (dynamic_lhs->get_guard() && !dynamic_rhs->get_guard()) { - return true; - } else if (dynamic_rhs->get_guard()) { - return false; - } + return dynamic_rhs->get_guard() ? false : true; + } else { + return false; } + } + if (dynamic_lhs && !dynamic_rhs) + { return false; } - static bool function_less_than(const Proxy_Function &lhs, const Proxy_Function &rhs) noexcept - { - auto dynamic_lhs(std::dynamic_pointer_cast(lhs)); - auto dynamic_rhs(std::dynamic_pointer_cast(rhs)); - - if (dynamic_lhs && dynamic_rhs) + if (!dynamic_lhs && dynamic_rhs) { - return params_less_than(dynamic_lhs, dynamic_rhs); - } else if (dynamic_lhs) { - return params_less_than(dynamic_lhs, rhs); - } else if (dynamic_rhs) { - return params_less_than(lhs, dynamic_rhs); - } else { - return params_less_than(lhs, rhs); + return true; } + + const auto &lhsparamtypes = lhs->get_param_types(); + const auto &rhsparamtypes = rhs->get_param_types(); + + const auto lhssize = lhsparamtypes.size(); + const auto rhssize = rhsparamtypes.size(); + + constexpr const auto boxed_type = user_type(); + constexpr const auto boxed_pod_type = user_type(); + + for (size_t i = 1; i < lhssize && i < rhssize; ++i) + { + const Type_Info < = lhsparamtypes[i]; + const Type_Info &rt = rhsparamtypes[i]; + + if (lt.bare_equal(rt) && lt.is_const() == rt.is_const()) + { + continue; // The first two types are essentially the same, next iteration + } + + // const is after non-const for the same type + if (lt.bare_equal(rt) && lt.is_const() && !rt.is_const()) + { + return false; + } + + if (lt.bare_equal(rt) && !lt.is_const()) + { + return true; + } + + // boxed_values are sorted last + if (lt.bare_equal(boxed_type)) + { + return false; + } + + if (rt.bare_equal(boxed_type)) + { + return true; + } + + if (lt.bare_equal(boxed_pod_type)) + { + return false; + } + + if (rt.bare_equal(boxed_pod_type)) + { + return true; + } + + // otherwise, we want to sort by typeid + return lt < rt; + } + + return false; } diff --git a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp index 7c0364d8..d9e3a15a 100644 --- a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp @@ -39,7 +39,7 @@ namespace chaiscript /// A Proxy_Function implementation designed for calling a function /// that is automatically guarded based on the first param based on the /// param's type name - class Dynamic_Object_Function : public Proxy_Function_Base, public Dynamic_Function_Interface + class Dynamic_Object_Function final : public Proxy_Function_Base { public: Dynamic_Object_Function( @@ -71,17 +71,6 @@ namespace chaiscript Dynamic_Object_Function &operator=(const Dynamic_Object_Function) = delete; Dynamic_Object_Function(Dynamic_Object_Function &) = delete; - Param_Types get_dynamic_param_types() const noexcept override { - auto dynamic(std::dynamic_pointer_cast(m_func)); - - if (dynamic) { - return dynamic->get_dynamic_param_types(); - } else { - return Param_Types(get_param_types()); - } - } - - bool operator==(const Proxy_Function_Base &f) const noexcept override { if (const auto *df = dynamic_cast(&f)) @@ -184,7 +173,7 @@ namespace chaiscript * that is automatically guarded based on the first param based on the * param's type name */ - class Dynamic_Object_Constructor final : public Proxy_Function_Base, public Dynamic_Function_Interface + class Dynamic_Object_Constructor final : public Proxy_Function_Base { public: Dynamic_Object_Constructor( @@ -193,7 +182,6 @@ namespace chaiscript : Proxy_Function_Base(build_type_list(t_func->get_param_types()), t_func->get_arity() - 1), m_type_name(std::move(t_type_name)), m_func(t_func) { - assert( t_func ); assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); } @@ -211,17 +199,6 @@ namespace chaiscript return std::vector(begin, end); } - Param_Types get_dynamic_param_types() const noexcept override { - auto dynamic(std::dynamic_pointer_cast(m_func)); - - if (dynamic) { - return dynamic->get_dynamic_param_types(); - } else { - return Param_Types(get_param_types()); - } - } - - bool operator==(const Proxy_Function_Base &f) const noexcept override { const Dynamic_Object_Constructor *dc = dynamic_cast(&f); diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 3fee032f..7f00f235 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -56,12 +56,6 @@ namespace chaiscript : m_has_types(false) {} - explicit Param_Types(const std::vector &t_types) - : m_types(build_param_types(t_types)), - m_has_types(false) - { - } - explicit Param_Types(std::vector> t_types) : m_types(std::move(t_types)), m_has_types(false) @@ -69,18 +63,6 @@ namespace chaiscript update_has_types(); } - static std::vector> build_param_types(const std::vector &t_types) - { - std::vector> retval; - std::transform(t_types.begin(), t_types.end(), std::back_inserter(retval), - [](const Type_Info &ti){ - return std::make_pair(std::string(), ti); - } - ); - - return retval; - } - void push_front(std::string t_name, Type_Info t_ti) { m_types.emplace(m_types.begin(), std::move(t_name), t_ti); @@ -362,16 +344,9 @@ namespace chaiscript namespace dispatch { - class Dynamic_Function_Interface - { - public: - virtual ~Dynamic_Function_Interface() {} - virtual Param_Types get_dynamic_param_types() const = 0; - }; - /// A Proxy_Function implementation that is not type safe, the called function /// is expecting a vector that it works with how it chooses. - class Dynamic_Proxy_Function : public Proxy_Function_Base, public Dynamic_Function_Interface + class Dynamic_Proxy_Function : public Proxy_Function_Base { public: Dynamic_Proxy_Function( @@ -426,9 +401,6 @@ namespace chaiscript } } - Param_Types get_dynamic_param_types() const override { - return m_param_types; - } protected: bool test_guard(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const @@ -971,9 +943,6 @@ namespace chaiscript std::vector> ordered_funcs; ordered_funcs.reserve(funcs.size()); - const constexpr auto boxed_type = user_type(); - const constexpr auto dynamic_type = user_type(); - for (const auto &func : funcs) { const auto arity = func->get_arity(); @@ -985,10 +954,7 @@ namespace chaiscript size_t numdiffs = 0; for (size_t i = 0; i < plist.size(); ++i) { - const auto &p_type = plist[i].get_type_info(); - const auto &f_type = func->get_param_types()[i+1]; - - if (!(f_type.bare_equal(boxed_type) && p_type.bare_equal(dynamic_type)) && !f_type.bare_equal(p_type)) + if (!func->get_param_types()[i+1].bare_equal(plist[i].get_type_info())) { ++numdiffs; } diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index 48e5b378..6e241572 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -321,8 +321,7 @@ TEST_CASE("Function ordering") chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(),create_chaiscript_parser()); chai.eval("def test_fun(x) { return 3; }"); chai.eval("def test_fun(x) : x == \"hi\" { return 4; }"); - chai.eval("def test_fun(double d) { return 5; }"); - +// chai.eval("def test_fun(x) { return 5; }"); chai.add(chaiscript::fun(&function_ordering_test_one), "test_fun"); chai.add(chaiscript::fun(&function_ordering_test_two), "test_fun"); @@ -330,7 +329,6 @@ TEST_CASE("Function ordering") CHECK(chai.eval("auto i = 1; test_fun(i)") == 2); CHECK(chai.eval("test_fun(\"bob\")") == 3); CHECK(chai.eval("test_fun(\"hi\")") == 4); - CHECK(chai.eval("test_fun(5.0)") == 5); }