From d9f86a96f035676018b9f3c4bc396015d0c7382c Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 3 Nov 2015 15:59:43 -0700 Subject: [PATCH 01/11] Add initial failing test --- unittests/compiled_tests.cpp | 51 ++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index 9d1df58..ce3bcf9 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -785,3 +785,54 @@ TEST_CASE("Variable Scope When Calling From C++ 2") } + +struct Returned_Converted_Config +{ + int num_iterations; + int something_else; + std::string a_string; + std::function a_function; +}; + + +TEST_CASE("Return of converted type from script") +{ + chaiscript::ChaiScript chai; + + chai.add(chaiscript::constructor(), "Returned_Converted_Config"); + chai.add(chaiscript::fun(&Returned_Converted_Config::num_iterations), "num_iterations"); + chai.add(chaiscript::fun(&Returned_Converted_Config::something_else), "something_else"); + chai.add(chaiscript::fun(&Returned_Converted_Config::a_string), "a_string"); + chai.add(chaiscript::fun(&Returned_Converted_Config::a_function), "a_function"); + chai.add(chaiscript::vector_conversion>()); + + auto c = chai.eval>(R"( + var c = Returned_Converted_Config(); + + c.num_iterations = 5; + c.something_else = c.num_iterations * 2; + c.a_string = "string"; + c.a_function = fun(s) { s.size(); } + + print("making vector"); + var v = []; + print("adding config item"); + v.push_back_ref(c); + print("returning vector"); + v; + + )"); + + + std::cout << typeid(decltype(c)).name() << std::endl; + + std::cout << "Info: " << c.size() << " " << &c[0] << std::endl; + + std::cout << "num_iterations " << c[0].num_iterations << '\n' + << "something_else " << c[0].something_else << '\n' + << "a_string " << c[0].a_string << '\n' + << "a_function " << c[0].a_function("bob") << '\n'; + + chai.add(chaiscript::user_type(), "Returned_Converted_Config"); +} + From 6fe7f5ce98261a4eb8778dacd1adf87bcfd13dcb Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 3 Nov 2015 16:02:25 -0700 Subject: [PATCH 02/11] Don't return reference to copied values --- .../dispatchkit/boxed_cast_helper.hpp | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp index d8df9be..bb6835d 100644 --- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp @@ -33,14 +33,14 @@ namespace chaiscript template struct Cast_Helper_Inner { - typedef std::reference_wrapper::type > Result_Type; + typedef typename std::add_const::type Result_Type; static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *) { if (ob.get_type_info().bare_equal_type_info(typeid(Result))) { auto p = throw_if_null(ob.get_const_ptr()); - return std::cref(*static_cast(p)); + return *static_cast(p); } else { throw chaiscript::detail::exception::bad_any_cast(); } @@ -52,12 +52,6 @@ namespace chaiscript { }; - /// Cast_Helper_Inner for casting to a const & type - template - struct Cast_Helper_Inner : Cast_Helper_Inner - { - }; - /// Cast_Helper_Inner for casting to a const * type template @@ -91,6 +85,24 @@ namespace chaiscript } }; + /// Cast_Helper_Inner for casting to a & type + template + struct Cast_Helper_Inner + { + typedef const Result& Result_Type; + + static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *) + { + if (ob.get_type_info().bare_equal_type_info(typeid(Result))) + { + auto p = throw_if_null(ob.get_const_ptr()); + return *static_cast(p); + } else { + throw chaiscript::detail::exception::bad_any_cast(); + } + } + }; + /// Cast_Helper_Inner for casting to a & type From 4826bddb5ba911c1744ab40e206cd3bd56c793d8 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 20 Nov 2015 07:46:52 -0600 Subject: [PATCH 03/11] Add overloads for cosnt *& casts --- .../dispatchkit/boxed_cast_helper.hpp | 17 ++++++++++++++--- unittests/boxed_cast_test.cpp | 4 ++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp index bb6835d..c72edb7 100644 --- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp @@ -62,7 +62,7 @@ namespace chaiscript { if (ob.get_type_info().bare_equal_type_info(typeid(Result))) { - return static_cast(throw_if_null(ob.get_const_ptr())); + return static_cast(ob.get_const_ptr()); } else { throw chaiscript::detail::exception::bad_any_cast(); } @@ -76,15 +76,26 @@ namespace chaiscript typedef Result * Result_Type; static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *) { - if (!ob.get_type_info().is_const() && ob.get_type_info() == typeid(Result)) + if (!ob.get_type_info().is_const() && ob.get_type_info().bare_equal_type_info(typeid(Result))) { - return static_cast(throw_if_null(ob.get_ptr())); + return static_cast(ob.get_ptr()); } else { throw chaiscript::detail::exception::bad_any_cast(); } } }; + template + struct Cast_Helper_Inner : public Cast_Helper_Inner + { + }; + + template + struct Cast_Helper_Inner : public Cast_Helper_Inner + { + }; + + /// Cast_Helper_Inner for casting to a & type template struct Cast_Helper_Inner diff --git a/unittests/boxed_cast_test.cpp b/unittests/boxed_cast_test.cpp index e575649..1e92874 100644 --- a/unittests/boxed_cast_test.cpp +++ b/unittests/boxed_cast_test.cpp @@ -13,9 +13,9 @@ bool run_test_type_conversion(const Boxed_Value &bv, bool expectedpass) try { To ret = chaiscript::boxed_cast(bv); use(ret); - } catch (const chaiscript::exception::bad_boxed_cast &/*e*/) { + } catch (const chaiscript::exception::bad_boxed_cast &e) { if (expectedpass) { -// std::cerr << "Failure in run_test_type_conversion: " << e.what() << '\n'; + std::cerr << "Failure in run_test_type_conversion: " << e.what() << '\n'; return false; } else { return true; From 49c89a3b884e7f75bbda6e31db90d987c5340658 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 25 Nov 2015 09:49:26 -0500 Subject: [PATCH 04/11] un-break ** cast operation --- include/chaiscript/dispatchkit/boxed_cast_helper.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp index c72edb7..2e08777 100644 --- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp @@ -76,7 +76,7 @@ namespace chaiscript typedef Result * Result_Type; static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *) { - if (!ob.get_type_info().is_const() && ob.get_type_info().bare_equal_type_info(typeid(Result))) + if (!ob.get_type_info().is_const() && ob.get_type_info() == typeid(Result)) { return static_cast(ob.get_ptr()); } else { From f0796b51c8541319378bfa53e180b9ab73be14be Mon Sep 17 00:00:00 2001 From: Viktor Rennert Date: Sat, 2 Jan 2016 14:17:36 +0100 Subject: [PATCH 05/11] Added template specialization in chaiscript::utility::add_class to register bulk constants. --- include/chaiscript/utility/utility.hpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/chaiscript/utility/utility.hpp b/include/chaiscript/utility/utility.hpp index ecd5a3f..2704929 100644 --- a/include/chaiscript/utility/utility.hpp +++ b/include/chaiscript/utility/utility.hpp @@ -8,6 +8,7 @@ #define CHAISCRIPT_UTILITY_UTILITY_HPP_ #include +#include #include #include @@ -62,6 +63,21 @@ namespace chaiscript t_module.add(fun.first, fun.second); } } + + template + typename std::enable_if::value, void>::type + add_class(ModuleType &t_module, + const std::string &t_class_name, + const std::vector &t_constructors, + const std::vector> &t_constants) + { + t_module.add(chaiscript::user_type(), t_class_name); + + for (const auto &constant : t_constants) + { + t_module.add_global_const(constant.first, constant.second); + } + } } } From 316ba45e3c9fa72ff781011a770748fc53f20ec6 Mon Sep 17 00:00:00 2001 From: Viktor Rennert Date: Sat, 2 Jan 2016 20:54:55 +0100 Subject: [PATCH 06/11] Added unittest to cover utility::add_class registration. --- unittests/compiled_tests.cpp | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index da7eb7c..90095ac 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -517,6 +517,41 @@ TEST_CASE("Utility_Test utility class wrapper") } +enum Utility_Test_Numbers +{ + ONE, + TWO, + THREE +}; + +TEST_CASE("Utility_Test utility class wrapper") +{ + + chaiscript::ModulePtr m = chaiscript::ModulePtr(new chaiscript::Module()); + + using namespace chaiscript; + + chaiscript::utility::add_class(*m, + "Utility_Test_Numbers", + { + }, + { { const_var(ONE), "ONE" }, + { const_var(TWO), "TWO" }, + { const_var(THREE), "THREE" } + + } + ); + + + chaiscript::ChaiScript chai; + chai.add(m); + + CHECK(chai.eval("ONE ") == 0); + CHECK(chai.eval("TWO ") == 1); + CHECK(chai.eval("THREE ") == 2); + +} + ////// Object copy count test From d7489358f3b14d580f27bb9fc0bc674dd53318f1 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 2 Jan 2016 19:24:14 -0700 Subject: [PATCH 07/11] Add failing test for vector of enum values --- unittests/compiled_tests.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index 90095ac..ca5e9ec 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -2,6 +2,7 @@ // caught in other cpp files if chaiscript causes them #include +#include #ifdef CHAISCRIPT_MSVC #pragma warning(push) @@ -517,14 +518,19 @@ TEST_CASE("Utility_Test utility class wrapper") } + enum Utility_Test_Numbers { - ONE, + ONE, TWO, THREE }; -TEST_CASE("Utility_Test utility class wrapper") +void do_something_with_enum_vector(const std::vector &) +{ +} + +TEST_CASE("Utility_Test utility class wrapper for enum") { chaiscript::ModulePtr m = chaiscript::ModulePtr(new chaiscript::Module()); @@ -538,7 +544,7 @@ TEST_CASE("Utility_Test utility class wrapper") { { const_var(ONE), "ONE" }, { const_var(TWO), "TWO" }, { const_var(THREE), "THREE" } - + } ); @@ -550,6 +556,12 @@ TEST_CASE("Utility_Test utility class wrapper") CHECK(chai.eval("TWO ") == 1); CHECK(chai.eval("THREE ") == 2); + chai.add(chaiscript::fun(&do_something_with_enum_vector), "do_something_with_enum_vector"); + chai.add(chaiscript::vector_conversion>()); + CHECK_NOTHROW(chai.eval("var a = [ONE, TWO, THREE]")); + CHECK_NOTHROW(chai.eval("do_something_with_enum_vector([ONE])")); + CHECK_NOTHROW(chai.eval("[ONE]")); + } From e1c40f3e8f586abc5e88cf55e90fa28fb2428b50 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 2 Jan 2016 19:26:53 -0700 Subject: [PATCH 08/11] Automatically add copy constuctor for enums added with utility --- include/chaiscript/utility/utility.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/chaiscript/utility/utility.hpp b/include/chaiscript/utility/utility.hpp index 2704929..4dfd079 100644 --- a/include/chaiscript/utility/utility.hpp +++ b/include/chaiscript/utility/utility.hpp @@ -72,7 +72,10 @@ namespace chaiscript const std::vector> &t_constants) { t_module.add(chaiscript::user_type(), t_class_name); - + + t_module.add(chaiscript::constructor(), t_class_name); + t_module.add(chaiscript::constructor(), t_class_name); + for (const auto &constant : t_constants) { t_module.add_global_const(constant.first, constant.second); From e32714c456236327269d6e46dfb10c67fa4280f3 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 2 Jan 2016 19:45:10 -0700 Subject: [PATCH 09/11] Add some operators for Enums made with helper class --- include/chaiscript/utility/utility.hpp | 9 ++++++++- unittests/compiled_tests.cpp | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/chaiscript/utility/utility.hpp b/include/chaiscript/utility/utility.hpp index 4dfd079..05c49c5 100644 --- a/include/chaiscript/utility/utility.hpp +++ b/include/chaiscript/utility/utility.hpp @@ -15,6 +15,7 @@ #include "../chaiscript.hpp" #include "../dispatchkit/proxy_functions.hpp" #include "../dispatchkit/type_info.hpp" +#include "../dispatchkit/operators.hpp" namespace chaiscript @@ -63,7 +64,7 @@ namespace chaiscript t_module.add(fun.first, fun.second); } } - + template typename std::enable_if::value, void>::type add_class(ModuleType &t_module, @@ -76,6 +77,12 @@ namespace chaiscript t_module.add(chaiscript::constructor(), t_class_name); t_module.add(chaiscript::constructor(), t_class_name); + t_module.add([](){ + // add some comparison and assignment operators + using namespace chaiscript::bootstrap::operators; + return assign(not_equal(equal())); + }()); + for (const auto &constant : t_constants) { t_module.add_global_const(constant.first, constant.second); diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index ca5e9ec..a028526 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -562,6 +562,11 @@ TEST_CASE("Utility_Test utility class wrapper for enum") CHECK_NOTHROW(chai.eval("do_something_with_enum_vector([ONE])")); CHECK_NOTHROW(chai.eval("[ONE]")); + CHECK(chai.eval("ONE == ONE")); + CHECK(chai.eval("ONE != TWO")); + CHECK_NOTHROW(chai.eval("var o = ONE; o = TWO")); + + } From 888d897a3eda962e6b765085bb40d115b05a3491 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 2 Jan 2016 19:59:54 -0700 Subject: [PATCH 10/11] Simplify use of enum helper --- include/chaiscript/utility/utility.hpp | 8 +++++--- unittests/compiled_tests.cpp | 10 +++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/include/chaiscript/utility/utility.hpp b/include/chaiscript/utility/utility.hpp index 05c49c5..381afda 100644 --- a/include/chaiscript/utility/utility.hpp +++ b/include/chaiscript/utility/utility.hpp @@ -69,8 +69,7 @@ namespace chaiscript typename std::enable_if::value, void>::type add_class(ModuleType &t_module, const std::string &t_class_name, - const std::vector &t_constructors, - const std::vector> &t_constants) + const std::vector::type, std::string>> &t_constants) { t_module.add(chaiscript::user_type(), t_class_name); @@ -83,9 +82,12 @@ namespace chaiscript return assign(not_equal(equal())); }()); + t_module.add(chaiscript::fun([](const Enum &e, const typename std::underlying_type::type &i) { return e == i; }), "=="); + t_module.add(chaiscript::fun([](const typename std::underlying_type::type &i, const Enum &e) { return i == e; }), "=="); + for (const auto &constant : t_constants) { - t_module.add_global_const(constant.first, constant.second); + t_module.add_global_const(chaiscript::const_var(Enum(constant.first)), constant.second); } } } diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index a028526..6724973 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -539,11 +539,9 @@ TEST_CASE("Utility_Test utility class wrapper for enum") chaiscript::utility::add_class(*m, "Utility_Test_Numbers", - { - }, - { { const_var(ONE), "ONE" }, - { const_var(TWO), "TWO" }, - { const_var(THREE), "THREE" } + { { ONE, "ONE" }, + { TWO, "TWO" }, + { THREE, "THREE" } } ); @@ -556,6 +554,8 @@ TEST_CASE("Utility_Test utility class wrapper for enum") CHECK(chai.eval("TWO ") == 1); CHECK(chai.eval("THREE ") == 2); + CHECK(chai.eval("ONE == 0")); + chai.add(chaiscript::fun(&do_something_with_enum_vector), "do_something_with_enum_vector"); chai.add(chaiscript::vector_conversion>()); CHECK_NOTHROW(chai.eval("var a = [ONE, TWO, THREE]")); From 208107fd7ecb5c898e301e5d3a985b681bd7db20 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 3 Jan 2016 17:58:05 -0700 Subject: [PATCH 11/11] Add additional tests for vector conversion --- unittests/compiled_tests.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index 6724973..2782904 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -526,8 +526,12 @@ enum Utility_Test_Numbers THREE }; -void do_something_with_enum_vector(const std::vector &) +void do_something_with_enum_vector(const std::vector &v) { + CHECK(v.size() == 3); + CHECK(v[0] == ONE); + CHECK(v[1] == THREE); + CHECK(v[2] == TWO); } TEST_CASE("Utility_Test utility class wrapper for enum") @@ -559,9 +563,13 @@ TEST_CASE("Utility_Test utility class wrapper for enum") chai.add(chaiscript::fun(&do_something_with_enum_vector), "do_something_with_enum_vector"); chai.add(chaiscript::vector_conversion>()); CHECK_NOTHROW(chai.eval("var a = [ONE, TWO, THREE]")); - CHECK_NOTHROW(chai.eval("do_something_with_enum_vector([ONE])")); + CHECK_NOTHROW(chai.eval("do_something_with_enum_vector([ONE, THREE, TWO])")); CHECK_NOTHROW(chai.eval("[ONE]")); + const auto v = chai.eval>("a"); + CHECK(v.size() == 3); + CHECK(v.at(1) == TWO); + CHECK(chai.eval("ONE == ONE")); CHECK(chai.eval("ONE != TWO")); CHECK_NOTHROW(chai.eval("var o = ONE; o = TWO"));