diff --git a/include/chaiscript/dispatchkit/handle_return.hpp b/include/chaiscript/dispatchkit/handle_return.hpp index 4ae6dc5b..aeee80e4 100644 --- a/include/chaiscript/dispatchkit/handle_return.hpp +++ b/include/chaiscript/dispatchkit/handle_return.hpp @@ -167,17 +167,33 @@ namespace chaiscript } }; - - - template - struct Handle_Return + template + struct Handle_Return_Ref { - static Boxed_Value handle(const Ret &r) + template + static Boxed_Value handle(T &&r) { return Boxed_Value(std::cref(r), true); } }; + template + struct Handle_Return_Ref + { + template + static Boxed_Value handle(T &&r) + { + return Boxed_Value(typename std::remove_reference::type{r}, true); + } + }; + + template + struct Handle_Return : Handle_Return_Ref::type>::value> + { + + }; + + template struct Handle_Return { diff --git a/releasenotes.md b/releasenotes.md index c4ab63be..cdccd888 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -1,6 +1,10 @@ Notes: ======= -Current Version: 6.1.0 +Current Version: 6.1.1 + +### Changes since 6.1.0 + + * Handle the returning of `&` to `*` types. This specifically comes up with `std::vector` and similar containers ### Changes since 6.0.0 diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index 8723d23d..705d34b3 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -204,6 +204,41 @@ TEST_CASE("Throw int or double") } } +TEST_CASE("Deduction of pointer return types") +{ + int val = 5; + int *val_ptr = &val; + auto &val_ptr_ref = val_ptr; + const auto &val_ptr_const_ref = val_ptr; + + auto get_val_ptr = [&]() -> int * { return val_ptr; }; + auto get_val_const_ptr = [&]() -> int const * { return val_ptr; }; + auto get_val_ptr_ref = [&]() -> int *& { return val_ptr_ref; }; + auto get_val_ptr_const_ref = [&]() -> int * const & { return val_ptr_const_ref; }; +// auto get_val_const_ptr_const_ref = [ref=std::cref(val_ptr)]() -> int const * const & { return ref.get(); }; + + chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(), create_chaiscript_parser()); + chai.add(chaiscript::fun(get_val_ptr), "get_val_ptr"); + chai.add(chaiscript::fun(get_val_const_ptr), "get_val_const_ptr"); + chai.add(chaiscript::fun(get_val_ptr_ref), "get_val_ptr_ref"); + chai.add(chaiscript::fun(get_val_ptr_const_ref), "get_val_ptr_const_ref"); +// chai.add(chaiscript::fun(get_val_const_ptr_const_ref), "get_val_const_ptr_const_ref"); + + CHECK(chai.eval("get_val_ptr()") == &val); + CHECK(*chai.eval("get_val_ptr()") == val); + CHECK(chai.eval("get_val_const_ptr()") == &val); + CHECK(*chai.eval("get_val_const_ptr()") == val); + + // note that we cannot maintain the references here, + // chaiscript internals cannot handle that, effectively pointer to pointer + CHECK(chai.eval("get_val_ptr_ref()") == &val); + CHECK(*chai.eval("get_val_ptr_ref()") == val); + CHECK(chai.eval("get_val_ptr_const_ref()") == &val); + CHECK(*chai.eval("get_val_ptr_const_ref()") == val); +// CHECK(chai.eval("get_val_const_ptr_const_ref()") == &val); +} + + TEST_CASE("Throw a runtime_error") { chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(),create_chaiscript_parser());