diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 7036fe5..3d6da1b 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -107,7 +107,7 @@ namespace chaiscript public: static Boxed_Value cast(const Boxed_Value &t_from) { - if (t_from.get_type_info().bare_equal(user_type())) + if (t_from.get_type_info().bare_equal(chaiscript::user_type())) { if (t_from.is_pointer()) { @@ -157,7 +157,7 @@ namespace chaiscript { public: Dynamic_Conversion_Impl() - : Type_Conversion_Base(user_type(), user_type()) + : Type_Conversion_Base(chaiscript::user_type(), chaiscript::user_type()) { } @@ -173,10 +173,11 @@ namespace chaiscript }; + template class Type_Conversion_Impl : public Type_Conversion_Base { public: - Type_Conversion_Impl(Type_Info t_from, Type_Info t_to, std::function t_func) + Type_Conversion_Impl(Type_Info t_from, Type_Info t_to, Callable t_func) : Type_Conversion_Base(std::move(t_to), std::move(t_from)), m_func(std::move(t_func)) { @@ -194,7 +195,7 @@ namespace chaiscript } private: - std::function m_func; + Callable m_func; }; } @@ -329,16 +330,26 @@ namespace chaiscript static_assert(std::is_polymorphic::value, "Base class must be polymorphic"); static_assert(std::is_polymorphic::value, "Derived class must be polymorphic"); - return std::shared_ptr(new detail::Dynamic_Conversion_Impl()); + return std::make_shared>(); } - namespace { + template Type_Conversion type_conversion(const Type_Info &t_from, const Type_Info &t_to, - const std::function &t_func) + const Callable &t_func) { - return std::shared_ptr(new detail::Type_Conversion_Impl(t_from, t_to, t_func)); + return std::make_shared>(t_from, t_to, t_func); + } + + template + Type_Conversion type_conversion(const Callable &t_function) + { + auto func = [t_function](const Boxed_Value &t_bv) -> Boxed_Value { + // not even attempting to call boxed_cast so that we don't get caught in some call recursion + return chaiscript::Boxed_Value(t_function(detail::Cast_Helper::cast(t_bv, nullptr))); + }; + + return std::make_shared>(user_type(), user_type(), func); } - } } diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 95c4932..b5393c5 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -359,7 +359,7 @@ namespace chaiscript m_engine.add(chaiscript::type_conversion(t_from, t_to, t_func)); } ), "add_type_conversion"); - + typedef std::string (ChaiScript::*load_mod_1)(const std::string&); typedef void (ChaiScript::*load_mod_2)(const std::string&, const std::string&); diff --git a/src/test_module.cpp b/src/test_module.cpp index 7b6ff75..5dac6f4 100644 --- a/src/test_module.cpp +++ b/src/test_module.cpp @@ -2,6 +2,8 @@ #include #include + + class TestBaseType { public: @@ -22,6 +24,23 @@ class TestBaseType TestBaseType &operator=(const TestBaseType &); }; +class Type2 +{ + public: + Type2(TestBaseType t_bt) + : m_bt(std::move(t_bt)) + { + } + + int get_val() const + { + return m_bt.val; + } + + private: + TestBaseType m_bt; +}; + enum TestEnum { TestValue1 = 1 @@ -95,6 +114,7 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_test_mo m->add(chaiscript::user_type(), "TestBaseType"); m->add(chaiscript::user_type(), "TestDerivedType"); m->add(chaiscript::user_type(), "TestMoreDerivedType"); + m->add(chaiscript::user_type(), "Type2"); m->add(chaiscript::constructor(), "TestBaseType"); // m->add(chaiscript::constructor(), "TestBaseType"); @@ -135,7 +155,9 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_test_mo m->add(chaiscript::fun(&to_int), "to_int"); m->add(chaiscript::fun(&TestBaseType::constMe), "constMe"); + m->add(chaiscript::type_conversion([](const TestBaseType &t_bt) { return Type2(t_bt); })); + m->add(chaiscript::fun(&Type2::get_val), "get_val"); return m; } diff --git a/unittests/user_defined_conversions_2.chai b/unittests/user_defined_conversions_2.chai new file mode 100644 index 0000000..8a349e1 --- /dev/null +++ b/unittests/user_defined_conversions_2.chai @@ -0,0 +1,9 @@ +load_module("test_module") + +auto t := TestBaseType(); + +// This uses the TestBaseType to Type2 user type +// conversion which was added in the module and then calls +// "get_val()" which exists on the Type2 type +assert_equal(t.get_val(), 10); +