Skip to content
Snippets Groups Projects
Commit 619d2751 authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Fix tuple to TinyVector conversion when used as arguments

parent 82799df3
No related branches found
No related tags found
1 merge request!37Feature/language
......@@ -42,7 +42,7 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData
switch (argument_node_sub_data_type.m_data_type) {
case ASTNodeDataType::vector_t: {
if (argument_node_sub_data_type.m_data_type.dimension() == parameter_v.dimension()) {
return std::make_unique<FunctionArgumentConverter<ParameterT, ParameterT>>(argument_number);
return std::make_unique<FunctionTinyVectorArgumentConverter<ParameterT, ParameterT>>(argument_number);
} else {
// LCOV_EXCL_START
throw parse_error("unexpected error: invalid argument dimension",
......@@ -52,7 +52,7 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData
}
case ASTNodeDataType::list_t: {
if (argument_node_sub_data_type.m_parent_node.children.size() == parameter_v.dimension()) {
return std::make_unique<FunctionArgumentConverter<ParameterT, ParameterT>>(argument_number);
return std::make_unique<FunctionTinyVectorArgumentConverter<ParameterT, ParameterT>>(argument_number);
} else {
// LCOV_EXCL_START
throw parse_error("unexpected error: invalid argument dimension",
......@@ -63,7 +63,7 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData
case ASTNodeDataType::int_t: {
if (argument_node_sub_data_type.m_parent_node.is_type<language::integer>()) {
if (std::stoi(argument_node_sub_data_type.m_parent_node.string()) == 0) {
return std::make_unique<FunctionArgumentConverter<ParameterT, ZeroType>>(argument_number);
return std::make_unique<FunctionTinyVectorArgumentConverter<ParameterT, ZeroType>>(argument_number);
}
}
[[fallthrough]];
......@@ -120,10 +120,11 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData
auto get_function_argument_to_tuple_converter =
[&](const auto& parameter_content_v) -> std::unique_ptr<IFunctionArgumentConverter> {
using ParameterContentT = std::decay_t<decltype(parameter_content_v)>;
switch (argument_node_sub_data_type.m_data_type) {
const auto& arg_data_type = argument_node_sub_data_type.m_data_type;
switch (arg_data_type) {
case ASTNodeDataType::tuple_t: {
const auto& arg_content_type = argument_node_sub_data_type.m_data_type.contentType();
switch (arg_content_type) {
const auto& tuple_content_type = arg_data_type.contentType();
switch (tuple_content_type) {
case ASTNodeDataType::type_id_t: {
return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, EmbeddedData>>(argument_number);
}
......@@ -143,7 +144,7 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData
return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, std::string>>(argument_number);
}
case ASTNodeDataType::vector_t: {
switch (arg_content_type.dimension()) {
switch (tuple_content_type.dimension()) {
case 1: {
return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, TinyVector<1>>>(argument_number);
}
......@@ -154,21 +155,55 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData
return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, TinyVector<3>>>(argument_number);
}
default: {
throw UnexpectedError(dataTypeName(arg_content_type) +
throw UnexpectedError(dataTypeName(tuple_content_type) +
" unexpected content of argument, invalid dimension of vector");
}
}
}
default: {
throw UnexpectedError(dataTypeName(arg_content_type) + " unexpected tuple content type of argument ");
throw UnexpectedError(dataTypeName(tuple_content_type) + " unexpected tuple content type of argument ");
}
}
}
case ASTNodeDataType::list_t: {
return std::make_unique<FunctionListArgumentConverter<ParameterContentT, ParameterContentT>>(argument_number);
}
case ASTNodeDataType::type_id_t: {
return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, EmbeddedData>>(argument_number);
}
case ASTNodeDataType::bool_t: {
return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, bool>>(argument_number);
}
case ASTNodeDataType::unsigned_int_t: {
return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, uint64_t>>(argument_number);
}
case ASTNodeDataType::int_t: {
return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, int64_t>>(argument_number);
}
case ASTNodeDataType::double_t: {
return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, double>>(argument_number);
}
case ASTNodeDataType::string_t: {
return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, std::string>>(argument_number);
}
case ASTNodeDataType::vector_t: {
switch (arg_data_type.dimension()) {
case 1: {
return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, TinyVector<1>>>(argument_number);
}
case 2: {
return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, TinyVector<2>>>(argument_number);
}
case 3: {
return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, TinyVector<3>>>(argument_number);
}
default: {
throw UnexpectedError(dataTypeName(arg_data_type) + " unexpected dimension of vector");
}
}
}
default: {
throw UnexpectedError(dataTypeName(argument_node_sub_data_type.m_data_type) + " argument to tuple ");
throw UnexpectedError(dataTypeName(arg_data_type) + " argument to tuple ");
}
}
};
......
......@@ -113,6 +113,8 @@ isNaturalConversion(const ASTNodeDataType& data_type, const ASTNodeDataType& tar
(data_type == ASTNodeDataType::bool_t));
} else if (target_data_type == ASTNodeDataType::string_t) {
return ((data_type >= ASTNodeDataType::bool_t) and (data_type < ASTNodeDataType::string_t));
} else if (target_data_type == ASTNodeDataType::tuple_t) {
return isNaturalConversion(data_type, target_data_type.contentType());
}
return false;
}
......@@ -48,7 +48,7 @@ ASTNodeFunctionExpressionBuilder::_getArgumentConverter(SymbolType& parameter_sy
switch (node_sub_data_type.m_data_type) {
case ASTNodeDataType::vector_t: {
if (node_sub_data_type.m_data_type.dimension() == parameter_v.dimension()) {
return std::make_unique<FunctionArgumentConverter<ParameterT, ParameterT>>(parameter_id);
return std::make_unique<FunctionTinyVectorArgumentConverter<ParameterT, ParameterT>>(parameter_id);
} else {
// LCOV_EXCL_START
throw parse_error("unexpected error: invalid argument dimension",
......@@ -58,7 +58,7 @@ ASTNodeFunctionExpressionBuilder::_getArgumentConverter(SymbolType& parameter_sy
}
case ASTNodeDataType::list_t: {
if (node_sub_data_type.m_parent_node.children.size() == parameter_v.dimension()) {
return std::make_unique<FunctionArgumentConverter<ParameterT, ParameterT>>(parameter_id);
return std::make_unique<FunctionTinyVectorArgumentConverter<ParameterT, ParameterT>>(parameter_id);
} else {
// LCOV_EXCL_START
throw parse_error("unexpected error: invalid argument dimension",
......@@ -69,7 +69,7 @@ ASTNodeFunctionExpressionBuilder::_getArgumentConverter(SymbolType& parameter_sy
case ASTNodeDataType::int_t: {
if (node_sub_data_type.m_parent_node.is_type<language::integer>()) {
if (std::stoi(node_sub_data_type.m_parent_node.string()) == 0) {
return std::make_unique<FunctionArgumentConverter<ParameterT, ZeroType>>(parameter_id);
return std::make_unique<FunctionTinyVectorArgumentConverter<ParameterT, ZeroType>>(parameter_id);
}
}
[[fallthrough]];
......
......@@ -34,8 +34,6 @@ class FunctionArgumentConverter final : public IFunctionArgumentConverter
exec_policy.currentContext()[m_argument_id] = std::move(value);
} else if constexpr (std::is_same_v<ExpectedValueType, std::string>) {
exec_policy.currentContext()[m_argument_id] = std::move(std::to_string(std::get<ProvidedValueType>(value)));
} else if constexpr (std::is_same_v<ProvidedValueType, ZeroType>) {
exec_policy.currentContext()[m_argument_id] = ExpectedValueType{ZeroType::zero};
} else {
exec_policy.currentContext()[m_argument_id] =
std::move(static_cast<ExpectedValueType>(std::get<ProvidedValueType>(value)));
......@@ -47,7 +45,7 @@ class FunctionArgumentConverter final : public IFunctionArgumentConverter
};
template <typename ExpectedValueType, typename ProvidedValueType>
class FunctionTupleArgumentConverter final : public IFunctionArgumentConverter
class FunctionTinyVectorArgumentConverter final : public IFunctionArgumentConverter
{
private:
size_t m_argument_id;
......@@ -60,14 +58,59 @@ class FunctionTupleArgumentConverter final : public IFunctionArgumentConverter
std::visit(
[&](auto&& v) {
using ValueT = std::decay_t<decltype(v)>;
if constexpr (std::is_same_v<ValueT, AggregateDataVariant>) {
throw NotImplementedError("AggregateDataVariant case");
} else if constexpr (std::is_same_v<ValueT, ExpectedValueType>) {
exec_policy.currentContext()[m_argument_id] = std::move(v);
if constexpr (std::is_same_v<ValueT, ExpectedValueType>) {
exec_policy.currentContext()[m_argument_id] = std::move(value);
} else if constexpr (std::is_same_v<ValueT, AggregateDataVariant>) {
ExpectedValueType vector_value{};
for (size_t i = 0; i < vector_value.dimension(); ++i) {
std::visit(
[&](auto&& v_i) {
using Vi_T = std::decay_t<decltype(v_i)>;
if constexpr (std::is_arithmetic_v<Vi_T>) {
vector_value[i] = v_i;
} else {
throw UnexpectedError(demangle<Vi_T>() + " unexpected aggregate value type");
}
},
v[i]);
}
exec_policy.currentContext()[m_argument_id] = std::move(vector_value);
}
},
value);
} else if constexpr (std::is_same_v<ProvidedValueType, ZeroType>) {
exec_policy.currentContext()[m_argument_id] = ExpectedValueType{ZeroType::zero};
} else {
exec_policy.currentContext()[m_argument_id] =
std::move(static_cast<ExpectedValueType>(std::get<ProvidedValueType>(value)));
}
return {};
}
FunctionTinyVectorArgumentConverter(size_t argument_id) : m_argument_id{argument_id} {}
};
template <typename ContentType, typename ProvidedValueType>
class FunctionTupleArgumentConverter final : public IFunctionArgumentConverter
{
private:
size_t m_argument_id;
public:
DataVariant
convert(ExecutionPolicy& exec_policy, DataVariant&& value)
{
using TupleType = std::vector<ContentType>;
if constexpr (std::is_same_v<ContentType, ProvidedValueType>) {
std::visit(
[&](auto&& v) {
using ValueT = std::decay_t<decltype(v)>;
if constexpr (std::is_same_v<ValueT, ContentType>) {
exec_policy.currentContext()[m_argument_id] = std::move(TupleType{std::move(v)});
} else if constexpr (is_vector_v<ValueT>) {
using ContentT = typename ValueT::value_type;
if constexpr (std::is_same_v<ContentT, ExpectedValueType>) {
std::vector<ExpectedValueType> list_value;
if constexpr (std::is_same_v<ContentT, ContentType>) {
TupleType list_value;
list_value.reserve(v.size());
for (size_t i = 0; i < v.size(); ++i) {
list_value.emplace_back(v[i]);
......@@ -80,7 +123,6 @@ class FunctionTupleArgumentConverter final : public IFunctionArgumentConverter
},
value);
} else {
// static_assert(std::is_same_v<ExpectedValueType, ProvidedValueType>, "conversion is not implemented");
throw UnexpectedError(demangle<std::decay_t<decltype(*this)>>() + ": did nothing!");
}
return {};
......@@ -89,7 +131,7 @@ class FunctionTupleArgumentConverter final : public IFunctionArgumentConverter
FunctionTupleArgumentConverter(size_t argument_id) : m_argument_id{argument_id} {}
};
template <typename ExpectedValueType, typename ProvidedValueType>
template <typename ContentType, typename ProvidedValueType>
class FunctionListArgumentConverter final : public IFunctionArgumentConverter
{
private:
......@@ -99,20 +141,21 @@ class FunctionListArgumentConverter final : public IFunctionArgumentConverter
DataVariant
convert(ExecutionPolicy& exec_policy, DataVariant&& value)
{
if constexpr (std::is_same_v<ExpectedValueType, ProvidedValueType>) {
using TupleType = std::vector<ContentType>;
if constexpr (std::is_same_v<ContentType, ProvidedValueType>) {
std::visit(
[&](auto&& v) {
using ValueT = std::decay_t<decltype(v)>;
if constexpr (std::is_same_v<ValueT, AggregateDataVariant>) {
std::vector<ExpectedValueType> list_value;
TupleType list_value;
list_value.reserve(v.size());
for (size_t i = 0; i < v.size(); ++i) {
std::visit(
[&](auto&& vi) {
using Vi_T = std::decay_t<decltype(vi)>;
if constexpr (is_tiny_vector_v<ExpectedValueType>) {
if constexpr (is_tiny_vector_v<ContentType>) {
throw NotImplementedError("TinyVector case");
} else if constexpr (std::is_convertible_v<Vi_T, ExpectedValueType>) {
} else if constexpr (std::is_convertible_v<Vi_T, ContentType>) {
list_value.emplace_back(vi);
} else {
throw UnexpectedError("unexpected types");
......@@ -121,12 +164,12 @@ class FunctionListArgumentConverter final : public IFunctionArgumentConverter
(v[i]));
}
exec_policy.currentContext()[m_argument_id] = std::move(list_value);
} else if constexpr (std::is_same_v<ValueT, ExpectedValueType>) {
} else if constexpr (std::is_same_v<ValueT, ContentType>) {
exec_policy.currentContext()[m_argument_id] = std::move(v);
} else if constexpr (is_vector_v<ValueT>) {
using ContentT = typename ValueT::value_type;
if constexpr (std::is_same_v<ContentT, ExpectedValueType>) {
std::vector<ExpectedValueType> list_value;
if constexpr (std::is_same_v<ContentT, ContentType>) {
TupleType list_value;
list_value.reserve(v.size());
for (size_t i = 0; i < v.size(); ++i) {
list_value.emplace_back(v[i]);
......@@ -139,7 +182,7 @@ class FunctionListArgumentConverter final : public IFunctionArgumentConverter
},
value);
}
static_assert(std::is_same_v<ExpectedValueType, ProvidedValueType>, "conversion is not implemented");
static_assert(std::is_same_v<ContentType, ProvidedValueType>, "conversion is not implemented");
return {};
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment