Merge branch 'ChaiScript-feature_enum_utility_helper' into feature_enum_utility_helper

This commit is contained in:
Viktor Rennert 2016-01-04 16:00:57 +01:00
commit d73e715997
3 changed files with 96 additions and 14 deletions

View File

@ -33,14 +33,14 @@ namespace chaiscript
template<typename Result> template<typename Result>
struct Cast_Helper_Inner struct Cast_Helper_Inner
{ {
typedef std::reference_wrapper<typename std::add_const<Result>::type > Result_Type; typedef typename std::add_const<Result>::type Result_Type;
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *) static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
{ {
if (ob.get_type_info().bare_equal_type_info(typeid(Result))) if (ob.get_type_info().bare_equal_type_info(typeid(Result)))
{ {
auto p = throw_if_null(ob.get_const_ptr()); auto p = throw_if_null(ob.get_const_ptr());
return std::cref(*static_cast<const Result *>(p)); return *static_cast<const Result *>(p);
} else { } else {
throw chaiscript::detail::exception::bad_any_cast(); throw chaiscript::detail::exception::bad_any_cast();
} }
@ -52,12 +52,6 @@ namespace chaiscript
{ {
}; };
/// Cast_Helper_Inner for casting to a const & type
template<typename Result>
struct Cast_Helper_Inner<const Result &> : Cast_Helper_Inner<Result>
{
};
/// Cast_Helper_Inner for casting to a const * type /// Cast_Helper_Inner for casting to a const * type
template<typename Result> template<typename Result>
@ -68,7 +62,7 @@ namespace chaiscript
{ {
if (ob.get_type_info().bare_equal_type_info(typeid(Result))) if (ob.get_type_info().bare_equal_type_info(typeid(Result)))
{ {
return static_cast<const Result *>(throw_if_null(ob.get_const_ptr())); return static_cast<const Result *>(ob.get_const_ptr());
} else { } else {
throw chaiscript::detail::exception::bad_any_cast(); throw chaiscript::detail::exception::bad_any_cast();
} }
@ -84,7 +78,36 @@ namespace chaiscript
{ {
if (!ob.get_type_info().is_const() && ob.get_type_info() == typeid(Result)) if (!ob.get_type_info().is_const() && ob.get_type_info() == typeid(Result))
{ {
return static_cast<Result *>(throw_if_null(ob.get_ptr())); return static_cast<Result *>(ob.get_ptr());
} else {
throw chaiscript::detail::exception::bad_any_cast();
}
}
};
template<typename Result>
struct Cast_Helper_Inner<Result * const &> : public Cast_Helper_Inner<Result *>
{
};
template<typename Result>
struct Cast_Helper_Inner<const Result * const &> : public Cast_Helper_Inner<const Result *>
{
};
/// Cast_Helper_Inner for casting to a & type
template<typename Result>
struct Cast_Helper_Inner<const Result &>
{
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<const Result *>(p);
} else { } else {
throw chaiscript::detail::exception::bad_any_cast(); throw chaiscript::detail::exception::bad_any_cast();
} }

View File

@ -13,9 +13,9 @@ bool run_test_type_conversion(const Boxed_Value &bv, bool expectedpass)
try { try {
To ret = chaiscript::boxed_cast<To>(bv); To ret = chaiscript::boxed_cast<To>(bv);
use(ret); use(ret);
} catch (const chaiscript::exception::bad_boxed_cast &/*e*/) { } catch (const chaiscript::exception::bad_boxed_cast &e) {
if (expectedpass) { 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; return false;
} else { } else {
return true; return true;

View File

@ -526,8 +526,12 @@ enum Utility_Test_Numbers
THREE THREE
}; };
void do_something_with_enum_vector(const std::vector<Utility_Test_Numbers> &) void do_something_with_enum_vector(const std::vector<Utility_Test_Numbers> &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") 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::fun(&do_something_with_enum_vector), "do_something_with_enum_vector");
chai.add(chaiscript::vector_conversion<std::vector<Utility_Test_Numbers>>()); chai.add(chaiscript::vector_conversion<std::vector<Utility_Test_Numbers>>());
CHECK_NOTHROW(chai.eval("var a = [ONE, TWO, THREE]")); 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]")); CHECK_NOTHROW(chai.eval("[ONE]"));
const auto v = chai.eval<std::vector<Utility_Test_Numbers>>("a");
CHECK(v.size() == 3);
CHECK(v.at(1) == TWO);
CHECK(chai.eval<bool>("ONE == ONE")); CHECK(chai.eval<bool>("ONE == ONE"));
CHECK(chai.eval<bool>("ONE != TWO")); CHECK(chai.eval<bool>("ONE != TWO"));
CHECK_NOTHROW(chai.eval("var o = ONE; o = TWO")); CHECK_NOTHROW(chai.eval("var o = ONE; o = TWO"));
@ -854,3 +862,54 @@ TEST_CASE("Test long long dispatch")
chai.eval("ulonglong(15)"); chai.eval("ulonglong(15)");
} }
struct Returned_Converted_Config
{
int num_iterations;
int something_else;
std::string a_string;
std::function<int (const std::string &)> a_function;
};
TEST_CASE("Return of converted type from script")
{
chaiscript::ChaiScript chai;
chai.add(chaiscript::constructor<Returned_Converted_Config ()>(), "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<std::vector<Returned_Converted_Config>>());
auto c = chai.eval<std::vector<Returned_Converted_Config>>(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>(), "Returned_Converted_Config");
}