mirror of
https://github.com/ChaiScript/ChaiScript.git
synced 2026-04-30 19:09:26 +08:00
vector_conversion's element conversion used Cast_Helper directly, which only performs exact type matching. For nested vectors like std::vector<std::vector<double>>, each inner element is a std::vector<Boxed_Value> that needs its own conversion to std::vector<double>. Added a recursive convert_vector_element helper that detects std::vector value types and converts them from std::vector<Boxed_Value> before falling back to Cast_Helper for leaf types. Co-authored-by: leftibot <leftibot@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b64c930b16
commit
d2ec2a82a9
@ -498,6 +498,29 @@ namespace chaiscript {
|
||||
func);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
struct is_std_vector : std::false_type {};
|
||||
|
||||
template<typename T, typename A>
|
||||
struct is_std_vector<std::vector<T, A>> : std::true_type {};
|
||||
|
||||
template<typename T>
|
||||
T convert_vector_element(const Boxed_Value &bv) {
|
||||
if constexpr (is_std_vector<T>::value) {
|
||||
const auto &inner = Cast_Helper<const std::vector<Boxed_Value> &>::cast(bv, nullptr);
|
||||
T result;
|
||||
result.reserve(inner.size());
|
||||
for (const Boxed_Value &elem : inner) {
|
||||
result.push_back(convert_vector_element<typename T::value_type>(elem));
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
return Cast_Helper<T>::cast(bv, nullptr);
|
||||
}
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template<typename To>
|
||||
Type_Conversion vector_conversion() {
|
||||
auto func = [](const Boxed_Value &t_bv) -> Boxed_Value {
|
||||
@ -506,7 +529,7 @@ namespace chaiscript {
|
||||
To vec;
|
||||
vec.reserve(from_vec.size());
|
||||
for (const Boxed_Value &bv : from_vec) {
|
||||
vec.push_back(detail::Cast_Helper<typename To::value_type>::cast(bv, nullptr));
|
||||
vec.push_back(detail::convert_vector_element<typename To::value_type>(bv));
|
||||
}
|
||||
|
||||
return Boxed_Value(std::move(vec));
|
||||
|
||||
@ -1806,6 +1806,35 @@ TEST_CASE("push_back on script vector with vector_conversion") {
|
||||
== "hello,world");
|
||||
}
|
||||
|
||||
TEST_CASE("vector of vectors conversion (issue #374)") {
|
||||
chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(), create_chaiscript_parser());
|
||||
|
||||
auto m = std::make_shared<chaiscript::Module>();
|
||||
chaiscript::bootstrap::standard_library::vector_type<std::vector<double>>("VectorDouble", *m);
|
||||
chaiscript::bootstrap::standard_library::vector_type<std::vector<std::vector<double>>>("VectorVectorDouble", *m);
|
||||
m->add(chaiscript::vector_conversion<std::vector<double>>());
|
||||
m->add(chaiscript::vector_conversion<std::vector<std::vector<double>>>());
|
||||
chai.add(m);
|
||||
|
||||
chai.add(chaiscript::fun([](const std::vector<std::vector<double>> &v) -> double {
|
||||
double sum = 0;
|
||||
for (const auto &inner : v) {
|
||||
for (const auto d : inner) {
|
||||
sum += d;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}), "sum_nested");
|
||||
|
||||
CHECK(chai.eval<double>("sum_nested([[1.0, 2.0], [3.0, 4.0]])") == Approx(10.0));
|
||||
|
||||
CHECK(chai.eval<bool>(
|
||||
"auto v = VectorVectorDouble();"
|
||||
"v = [[1.0, 2.0], [3.0, 4.0]];"
|
||||
"v.size() == 2"
|
||||
));
|
||||
}
|
||||
|
||||
// Regression test for issue #607: AST_Node_Trace must be a complete type
|
||||
// when used in eval_error's std::vector<AST_Node_Trace> call_stack member.
|
||||
// This failed to compile with C++20 on clang/libc++ when AST_Node_Trace
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user