diff --git a/CMakeLists.txt b/CMakeLists.txt index bf573db..adb8ff1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -159,6 +159,14 @@ IF(BUILD_TESTING) target_link_libraries(object_lifetime_test ${LIBS}) add_test(NAME Object_Lifetime_Test COMMAND object_lifetime_test) + add_executable(function_ordering_test unittests/function_ordering_test.cpp) + target_link_libraries(function_ordering_test ${LIBS}) + add_test(NAME Function_Ordering_Test COMMAND function_ordering_test) + + add_executable(type_info_test unittests/type_info_test.cpp) + target_link_libraries(type_info_test ${LIBS}) + add_test(NAME Type_Info_Test COMMAND type_info_test) + add_executable(multifile_test unittests/multifile_test_main.cpp unittests/multifile_test_chai.cpp unittests/multifile_test_module.cpp) target_link_libraries(multifile_test ${LIBS}) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 5246747..053a721 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -814,6 +814,35 @@ namespace chaiscript const Type_Info boxed_type = user_type(); const Type_Info boxed_pod_type = user_type(); + boost::shared_ptr dynamic_lhs(boost::dynamic_pointer_cast(lhs)); + boost::shared_ptr dynamic_rhs(boost::dynamic_pointer_cast(rhs)); + + if (dynamic_lhs && dynamic_rhs) + { + if (dynamic_lhs->get_guard()) + { + if (dynamic_rhs->get_guard()) + { + return false; + } else { + return true; + } + } else { + return false; + } + } + + if (dynamic_lhs && !dynamic_rhs) + { + return false; + } + + if (!dynamic_lhs && dynamic_rhs) + { + return true; + } + + for (int i = 1; i < lhssize && i < rhssize; ++i) { diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index e3a994f..0710fe7 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -221,6 +221,11 @@ namespace chaiscript return m_arity; } + Proxy_Function get_guard() const + { + return m_guard; + } + virtual std::string annotation() const { return m_description; diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index d0e3515..1f3bf32 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -7,6 +7,9 @@ #ifndef __type_info_hpp__ #define __type_info_hpp__ +#include +#include +#include #include #include #include @@ -139,7 +142,7 @@ namespace chaiscript static Type_Info get() { - return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, + return Type_Info(boost::is_const::type>::type>::value, boost::is_reference::value, boost::is_pointer::value, boost::is_void::value, &typeid(T), &typeid(typename Bare_Type::type)); diff --git a/unittests/function_ordering_test.cpp b/unittests/function_ordering_test.cpp new file mode 100644 index 0000000..0a9652c --- /dev/null +++ b/unittests/function_ordering_test.cpp @@ -0,0 +1,38 @@ +// Tests to make sure that the order in which function dispatches occur is correct + +#include + +int test_one(const int &) +{ + return 1; +} + +int test_two(int &) +{ + return 2; +} + +int main() +{ + chaiscript::ChaiScript chai; + chai.eval("def test_fun(x) { return 3; }"); + chai.eval("def test_fun(x) : x == \"hi\" { return 4; }"); + chai.eval("def test_fun(x) { return 5; }"); + chai.add(chaiscript::fun(&test_one), "test_fun"); + chai.add(chaiscript::fun(&test_two), "test_fun"); + + int res1 = chai.eval("test_fun(1)"); + int res2 = chai.eval("var i = 1; test_fun(i)"); + int res3 = chai.eval("test_fun(\"bob\")"); + int res4 = chai.eval("test_fun(\"hi\")"); + + if (res1 == 1 + && res2 == 2 + && res3 == 3 + && res4 == 4 ) + { + return EXIT_SUCCESS; + } else { + return EXIT_FAILURE; + } +} diff --git a/unittests/type_info_test.cpp b/unittests/type_info_test.cpp new file mode 100644 index 0000000..361be80 --- /dev/null +++ b/unittests/type_info_test.cpp @@ -0,0 +1,32 @@ +// Tests to make sure that the order in which function dispatches occur is correct + +#include + +void test_type(const chaiscript::Type_Info &ti, bool t_is_const, bool t_is_pointer, bool t_is_reference, bool t_is_void, + bool t_is_undef) +{ + if (ti.is_const() == t_is_const + && ti.is_pointer() == t_is_pointer + && ti.is_reference() == t_is_reference + && ti.is_void() == t_is_void + && ti.is_undef() == t_is_undef) + { + return; + } else { + exit(EXIT_FAILURE); + } +} + + +int main() +{ + test_type(chaiscript::user_type(), false, false, false, true, false); + test_type(chaiscript::user_type(), true, false, false, false, false); + test_type(chaiscript::user_type(), true, false, true, false, false); + test_type(chaiscript::user_type(), false, false, false, false, false); + test_type(chaiscript::user_type(), false, true, false, false, false); + test_type(chaiscript::user_type(), true, true, false, false, false); + test_type(chaiscript::Type_Info(), false, false, false, false, true); + + return EXIT_SUCCESS; +}