diff --git a/src/language/ast/ASTNodeBuiltinFunctionExpressionBuilder.cpp b/src/language/ast/ASTNodeBuiltinFunctionExpressionBuilder.cpp index 0ccb025730f0605af9119589f37ac71da5ae37da..c01d3b29c3f983c40931e16fab4f72eefb3ef312 100644 --- a/src/language/ast/ASTNodeBuiltinFunctionExpressionBuilder.cpp +++ b/src/language/ast/ASTNodeBuiltinFunctionExpressionBuilder.cpp @@ -36,6 +36,47 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData } }; + auto get_function_argument_converter_for_vector = + [&](const auto& parameter_v) -> std::unique_ptr<IFunctionArgumentConverter> { + using ParameterT = std::decay_t<decltype(parameter_v)>; + 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); + } else { + // LCOV_EXCL_START + throw parse_error("unexpected error: invalid argument dimension", + std::vector{argument_node_sub_data_type.m_parent_node.begin()}); + // LCOV_EXCL_STOP + } + } + 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); + } else { + // LCOV_EXCL_START + throw parse_error("unexpected error: invalid argument dimension", + std::vector{argument_node_sub_data_type.m_parent_node.begin()}); + // LCOV_EXCL_STOP + } + } + 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); + } + } + [[fallthrough]]; + } + // LCOV_EXCL_START + default: { + throw parse_error("unexpected error: invalid argument type", + std::vector{argument_node_sub_data_type.m_parent_node.begin()}); + } + // LCOV_EXCL_STOP + } + }; + auto get_function_argument_to_string_converter = [&]() -> std::unique_ptr<IFunctionArgumentConverter> { switch (argument_node_sub_data_type.m_data_type) { case ASTNodeDataType::bool_t: { @@ -76,13 +117,24 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData } }; - auto get_function_argument_to_tuple_converter = [&]() -> std::unique_ptr<IFunctionArgumentConverter> { + 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) { case ASTNodeDataType::tuple_t: { - return std::make_unique<FunctionArgumentConverter<EmbeddedData, EmbeddedData>>(argument_number); + switch (argument_node_sub_data_type.m_data_type.contentType()) { + case ASTNodeDataType::type_id_t: { + return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, EmbeddedData>>(argument_number); + } + default: { + throw UnexpectedError(dataTypeName(argument_node_sub_data_type.m_data_type.contentType()) + + " unexpected tuple content type of argument "); + // return get_function_argument_converter_to_tuple_from_tuple(parameter_content_v); + } + } } case ASTNodeDataType::list_t: { - return std::make_unique<FunctionListArgumentConverter<EmbeddedData, EmbeddedData>>(argument_number); + return std::make_unique<FunctionListArgumentConverter<ParameterContentT, ParameterContentT>>(argument_number); } default: { throw UnexpectedError(dataTypeName(argument_node_sub_data_type.m_data_type) + " argument to tuple "); @@ -121,6 +173,25 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData case ASTNodeDataType::double_t: { return get_function_argument_converter_for(double{}); } + case ASTNodeDataType::vector_t: { + switch (parameter_type.dimension()) { + case 1: { + return get_function_argument_converter_for_vector(TinyVector<1>{}); + } + case 2: { + return get_function_argument_converter_for_vector(TinyVector<2>{}); + } + case 3: { + return get_function_argument_converter_for_vector(TinyVector<3>{}); + } + // LCOV_EXCL_START + default: { + throw parse_error("unexpected error: undefined parameter type for function", + std::vector{argument_node_sub_data_type.m_parent_node.begin()}); + } + // LCOV_EXCL_STOP + } + } case ASTNodeDataType::string_t: { return get_function_argument_to_string_converter(); } @@ -131,10 +202,46 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData return get_function_argument_to_function_id_converter(); } case ASTNodeDataType::tuple_t: { - if (parameter_type.contentType() != ASTNodeDataType::type_id_t) { - throw NotImplementedError(dataTypeName(parameter_type.contentType()) + " argument to tuple "); + switch (parameter_type.contentType()) { + case ASTNodeDataType::type_id_t: { + return get_function_argument_to_tuple_converter(EmbeddedData{}); + } + case ASTNodeDataType::unsigned_int_t: { + return get_function_argument_to_tuple_converter(uint64_t{}); + } + case ASTNodeDataType::int_t: { + return get_function_argument_to_tuple_converter(int64_t{}); + } + case ASTNodeDataType::double_t: { + return get_function_argument_to_tuple_converter(double{}); + } + case ASTNodeDataType::vector_t: { + switch (parameter_type.dimension()) { + case 1: { + return get_function_argument_to_tuple_converter(TinyVector<1>{}); + } + case 2: { + return get_function_argument_to_tuple_converter(TinyVector<2>{}); + } + case 3: { + return get_function_argument_to_tuple_converter(TinyVector<3>{}); + } + // LCOV_EXCL_START + default: { + throw parse_error("unexpected error: unexpected tuple content for function", + std::vector{argument_node_sub_data_type.m_parent_node.begin()}); + } + // LCOV_EXCL_STOP + } + } + case ASTNodeDataType::string_t: { + return get_function_argument_to_string_converter(); + } + default: { + throw parse_error("unexpected error: unexpected tuple content type for function", + std::vector{argument_node_sub_data_type.m_parent_node.begin()}); + } } - return get_function_argument_to_tuple_converter(); } // LCOV_EXCL_START default: { diff --git a/src/language/ast/ASTNodeExpressionBuilder.cpp b/src/language/ast/ASTNodeExpressionBuilder.cpp index 1f73444e167a5524e6d4cb818ca76fe3885ece80..9b9a0efbcb206b164ad31d6db18b3ca3727e09f9 100644 --- a/src/language/ast/ASTNodeExpressionBuilder.cpp +++ b/src/language/ast/ASTNodeExpressionBuilder.cpp @@ -40,20 +40,7 @@ ASTNodeExpressionBuilder::_buildExpression(ASTNode& n) } } else if (n.is_type<language::tuple_expression>()) { - switch (n.children.size()) { - // tuples are made of at least two elements - case 2: { - n.m_node_processor = std::make_unique<TupleToTinyVectorProcessor<ASTNodeExpressionListProcessor, 2>>(n); - break; - } - case 3: { - n.m_node_processor = std::make_unique<TupleToTinyVectorProcessor<ASTNodeExpressionListProcessor, 3>>(n); - break; - } - default: { - n.m_node_processor = std::make_unique<TupleToVectorProcessor<ASTNodeExpressionListProcessor>>(n); - } - } + n.m_node_processor = std::make_unique<TupleToVectorProcessor<ASTNodeExpressionListProcessor>>(n); } else if (n.is_type<language::function_definition>()) { n.m_node_processor = std::make_unique<FakeProcessor>(); diff --git a/src/language/ast/ASTNodeFunctionExpressionBuilder.cpp b/src/language/ast/ASTNodeFunctionExpressionBuilder.cpp index 597347ab8ed36b7300f3887c70065d4363587800..2ae74e8a6e488f0af73b75101e8a8d6c2e7c704a 100644 --- a/src/language/ast/ASTNodeFunctionExpressionBuilder.cpp +++ b/src/language/ast/ASTNodeFunctionExpressionBuilder.cpp @@ -261,7 +261,8 @@ ASTNodeFunctionExpressionBuilder::_getFunctionProcessor(const ASTNodeDataType& r } case ASTNodeDataType::list_t: { if (function_component_expression.children.size() == return_v.dimension()) { - return std::make_unique<FunctionExpressionProcessor<ReturnT, ReturnT>>(function_component_expression); + return std::make_unique<FunctionExpressionProcessor<ReturnT, AggregateDataVariant>>( + function_component_expression); } else { // LCOV_EXCL_START throw parse_error("unexpected error: invalid dimension for returned vector", diff --git a/src/language/ast/ASTNodeListAffectationExpressionBuilder.cpp b/src/language/ast/ASTNodeListAffectationExpressionBuilder.cpp index b3a8df8e69692edcb5f1214c6f2747304179b46d..48b7e4f5ddacd4b788ff38bf0bceb82442230f70 100644 --- a/src/language/ast/ASTNodeListAffectationExpressionBuilder.cpp +++ b/src/language/ast/ASTNodeListAffectationExpressionBuilder.cpp @@ -51,11 +51,12 @@ ASTNodeListAffectationExpressionBuilder::_buildAffectationProcessor( add_affectation_processor_for_data(value, node_sub_data_type); } } else if constexpr (std::is_same_v<ValueT, TinyVector<2>> or std::is_same_v<ValueT, TinyVector<3>>) { - if (((node_sub_data_type.m_data_type == ASTNodeDataType::vector_t) and - (node_sub_data_type.m_data_type.dimension() == value.dimension())) or - ((node_sub_data_type.m_data_type == ASTNodeDataType::list_t) and - (node_sub_data_type.m_parent_node.children.size() == value.dimension()))) { + if ((node_sub_data_type.m_data_type == ASTNodeDataType::vector_t) and + (node_sub_data_type.m_data_type.dimension() == value.dimension())) { list_affectation_processor->template add<ValueT, ValueT>(value_node); + } else if ((node_sub_data_type.m_data_type == ASTNodeDataType::list_t) and + (node_sub_data_type.m_parent_node.children.size() == value.dimension())) { + list_affectation_processor->template add<ValueT, AggregateDataVariant>(value_node); } else if (node_sub_data_type.m_parent_node.is_type<language::integer>()) { if (std::stoi(node_sub_data_type.m_parent_node.string()) == 0) { list_affectation_processor->template add<ValueT, ZeroType>(value_node); diff --git a/src/language/modules/MeshModule.cpp b/src/language/modules/MeshModule.cpp index 3fc354faff4170a05b5861454d84a6fc3c7c46be..2e434b9d0db6c9af9a59bd78a41cc36a7dcbfda0 100644 --- a/src/language/modules/MeshModule.cpp +++ b/src/language/modules/MeshModule.cpp @@ -104,4 +104,23 @@ MeshModule::MeshModule() }} )); + + this->_addBuiltinFunction("cartesian3dMesh", + std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IMesh>, TinyVector<3>, + TinyVector<3>, std::vector<uint64_t>>>( + + std::function<std::shared_ptr<const IMesh>(TinyVector<3>, TinyVector<3>, + std::vector<uint64_t>)>{ + + [](const TinyVector<3>& a, const TinyVector<3>& b, + const std::vector<uint64_t>& box_sizes) -> std::shared_ptr<const IMesh> { + std::cout << a << " -> " << b << " "; + for (auto i : box_sizes) { + std::cout << i << ' '; + } + std::cout << '\n'; + return nullptr; + }} + + )); } diff --git a/src/language/node_processor/AffectationProcessor.hpp b/src/language/node_processor/AffectationProcessor.hpp index 93d1396afc97da5eb39a24b7b25dc3ad6506b665..9e1508a80eacf3609270714f44aa2445b38b6a23 100644 --- a/src/language/node_processor/AffectationProcessor.hpp +++ b/src/language/node_processor/AffectationProcessor.hpp @@ -4,6 +4,8 @@ #include <language/PEGGrammar.hpp> #include <language/node_processor/INodeProcessor.hpp> #include <language/utils/SymbolTable.hpp> +#include <utils/Exceptions.hpp> +#include <utils/PugsTraits.hpp> template <typename Op> struct AffOp; @@ -118,10 +120,34 @@ class AffectationExecutor final : public IAffectationExecutor } } else { if constexpr (std::is_same_v<OperatorT, language::eq_op>) { - if constexpr (std::is_same_v<ValueT, DataT>) { + if constexpr (std::is_convertible_v<ValueT, DataT>) { m_lhs = std::get<DataT>(rhs); - } else { - m_lhs = static_cast<ValueT>(std::get<DataT>(rhs)); + } else if constexpr (std::is_same_v<DataT, AggregateDataVariant>) { + const AggregateDataVariant& v = std::get<AggregateDataVariant>(rhs); + static_assert(is_tiny_vector_v<ValueT>, "expecting lhs TinyVector"); + for (size_t i = 0; i < m_lhs.dimension(); ++i) { + std::visit( + [&](auto&& vi) { + using Vi_T = std::decay_t<decltype(vi)>; + if constexpr (std::is_convertible_v<Vi_T, double>) { + m_lhs[i] = vi; + } else { + throw UnexpectedError("unexpected rhs type in affectation"); + } + }, + v[i]); + } + } else if constexpr (std::is_same_v<TinyVector<1>, ValueT>) { + std::visit( + [&](auto&& v) { + using Vi_T = std::decay_t<decltype(v)>; + if constexpr (std::is_convertible_v<Vi_T, double>) { + m_lhs = v; + } else { + throw UnexpectedError("unexpected rhs type in affectation"); + } + }, + rhs); } } else { AffOp<OperatorT>().eval(m_lhs, std::get<DataT>(rhs)); diff --git a/src/language/node_processor/FunctionArgumentConverter.hpp b/src/language/node_processor/FunctionArgumentConverter.hpp index 445bf7ea975aaa2409a2ee0691613a1b2911dadc..8b63a818b35e4859d59f645162223154f9557851 100644 --- a/src/language/node_processor/FunctionArgumentConverter.hpp +++ b/src/language/node_processor/FunctionArgumentConverter.hpp @@ -3,7 +3,9 @@ #include <language/node_processor/ExecutionPolicy.hpp> #include <language/utils/DataVariant.hpp> +#include <utils/Demangle.hpp> #include <utils/Exceptions.hpp> +#include <utils/PugsTraits.hpp> class IFunctionArgumentConverter { @@ -44,6 +46,49 @@ class FunctionArgumentConverter final : public IFunctionArgumentConverter FunctionArgumentConverter(size_t argument_id) : m_argument_id{argument_id} {} }; +template <typename ExpectedValueType, typename ProvidedValueType> +class FunctionTupleArgumentConverter final : public IFunctionArgumentConverter +{ + private: + size_t m_argument_id; + + public: + DataVariant + convert(ExecutionPolicy& exec_policy, DataVariant&& value) + { + if constexpr (std::is_same_v<ExpectedValueType, ProvidedValueType>) { + 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); + } 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; + list_value.reserve(v.size()); + for (size_t i = 0; i < v.size(); ++i) { + list_value.emplace_back(v[i]); + } + exec_policy.currentContext()[m_argument_id] = std::move(list_value); + } + } else { + throw UnexpectedError(demangle<ValueT>() + " unexpected value type"); + } + }, + 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 {}; + } + + FunctionTupleArgumentConverter(size_t argument_id) : m_argument_id{argument_id} {} +}; + template <typename ExpectedValueType, typename ProvidedValueType> class FunctionListArgumentConverter final : public IFunctionArgumentConverter { @@ -57,15 +102,39 @@ class FunctionListArgumentConverter final : public IFunctionArgumentConverter if constexpr (std::is_same_v<ExpectedValueType, ProvidedValueType>) { std::visit( [&](auto&& v) { - using Value_T = std::decay_t<decltype(v)>; - if constexpr (std::is_same_v<Value_T, AggregateDataVariant>) { + using ValueT = std::decay_t<decltype(v)>; + if constexpr (std::is_same_v<ValueT, AggregateDataVariant>) { std::vector<ExpectedValueType> list_value; + list_value.reserve(v.size()); for (size_t i = 0; i < v.size(); ++i) { - list_value.emplace_back(std::get<ProvidedValueType>(v[i])); + std::visit( + [&](auto&& vi) { + using Vi_T = std::decay_t<decltype(vi)>; + if constexpr (is_tiny_vector_v<ExpectedValueType>) { + throw NotImplementedError("TinyVector case"); + } else if constexpr (std::is_convertible_v<Vi_T, ExpectedValueType>) { + list_value.emplace_back(vi); + } else { + throw UnexpectedError("unexpected types"); + } + }, + (v[i])); } exec_policy.currentContext()[m_argument_id] = std::move(list_value); + } else if constexpr (std::is_same_v<ValueT, ExpectedValueType>) { + 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; + list_value.reserve(v.size()); + for (size_t i = 0; i < v.size(); ++i) { + list_value.emplace_back(v[i]); + } + exec_policy.currentContext()[m_argument_id] = std::move(list_value); + } } else { - throw UnexpectedError("unexpected value type"); + throw UnexpectedError(demangle<ValueT>() + " unexpected value type"); } }, value); diff --git a/src/language/node_processor/FunctionProcessor.hpp b/src/language/node_processor/FunctionProcessor.hpp index 0542f138c31f65be4d7cb3eb76d25cd7af41ef1b..b28c2ce499538818ce60b1ac36a1d158114409de 100644 --- a/src/language/node_processor/FunctionProcessor.hpp +++ b/src/language/node_processor/FunctionProcessor.hpp @@ -20,12 +20,29 @@ class FunctionExpressionProcessor final : public INodeProcessor { if constexpr (std::is_same_v<ReturnType, ExpressionValueType>) { return m_function_expression.execute(exec_policy); + } else if constexpr (std::is_same_v<AggregateDataVariant, ExpressionValueType>) { + static_assert(is_tiny_vector_v<ReturnType>, "unexpected return type"); + ReturnType return_value{}; + auto value = std::get<ExpressionValueType>(m_function_expression.execute(exec_policy)); + for (size_t i = 0; i < ReturnType::Dimension; ++i) { + std::visit( + [&](auto&& vi) { + using Vi_T = std::decay_t<decltype(vi)>; + if constexpr (std::is_convertible_v<Vi_T, double>) { + return_value[i] = vi; + } + }, + value[i]); + } + return return_value; } else if constexpr (std::is_same_v<ReturnType, std::string>) { return std::to_string(std::get<ExpressionValueType>(m_function_expression.execute(exec_policy))); } else if constexpr (std::is_same_v<ExpressionValueType, ZeroType>) { return ReturnType{ZeroType::zero}; - } else { + } else if constexpr (std::is_convertible_v<ExpressionValueType, ReturnType>) { return static_cast<ReturnType>(std::get<ExpressionValueType>(m_function_expression.execute(exec_policy))); + } else { + throw UnexpectedError("invalid conversion"); } } diff --git a/src/language/node_processor/TupleToVectorProcessor.hpp b/src/language/node_processor/TupleToVectorProcessor.hpp index 4908bfaa58d582e441cd2500e16da8b5c685582b..74ad59acb95e0e853a880fb171e93d77c55dcd74 100644 --- a/src/language/node_processor/TupleToVectorProcessor.hpp +++ b/src/language/node_processor/TupleToVectorProcessor.hpp @@ -19,7 +19,7 @@ class TupleToVectorProcessor final : public INodeProcessor AggregateDataVariant v = std::get<AggregateDataVariant>(m_tuple_processor->execute(exec_policy)); v.setIsFlattenable(false); - return DataVariant{std::move(v)}; + return v; } TupleToVectorProcessor(ASTNode& node) : m_node{node}, m_tuple_processor{std::make_unique<TupleProcessorT>(node)} {} diff --git a/src/language/utils/BuiltinFunctionEmbedder.hpp b/src/language/utils/BuiltinFunctionEmbedder.hpp index 4df112ac258f7aea6e673c4395d8aece63723502..9a77fec82e6bfa3b9496a2e600144d014753f67c 100644 --- a/src/language/utils/BuiltinFunctionEmbedder.hpp +++ b/src/language/utils/BuiltinFunctionEmbedder.hpp @@ -64,13 +64,18 @@ class BuiltinFunctionEmbedder : public IBuiltinFunctionEmbedder } else if constexpr (std::is_same_v<Vi_Type, std::vector<EmbeddedData>>) { if constexpr (is_vector_v<Ti_Type>) { using Ti_value_type = typename Ti_Type::value_type; - static_assert(is_shared_ptr_v<Ti_value_type>, "expecting shared_ptr"); - - using Ti_handeled_type = typename Ti_value_type::element_type; - std::get<I>(t).resize(v_i.size()); - for (size_t j = 0; j < v_i.size(); ++j) { - auto& data_handler = dynamic_cast<const DataHandler<Ti_handeled_type>&>(v_i[j].get()); - std::get<I>(t)[j] = data_handler.data_ptr(); + if constexpr (is_shared_ptr_v<Ti_value_type>) { + static_assert(is_shared_ptr_v<Ti_value_type>, "expecting shared_ptr"); + + using Ti_handeled_type = typename Ti_value_type::element_type; + std::get<I>(t).resize(v_i.size()); + for (size_t j = 0; j < v_i.size(); ++j) { + auto& data_handler = dynamic_cast<const DataHandler<Ti_handeled_type>&>(v_i[j].get()); + std::get<I>(t)[j] = data_handler.data_ptr(); + } + } else { + throw UnexpectedError("Unexpected argument types while casting " + demangle<Vi_Type>() + " -> " + + demangle<Ti_Type>()); } } else { throw UnexpectedError("Unexpected argument types while casting " + demangle<Vi_Type>() + " -> " + diff --git a/src/language/utils/DataVariant.hpp b/src/language/utils/DataVariant.hpp index eac6388e0226c0b2500de8e591578a87b32f2549..b8d45704d08e4a8c3d6f91b22e7d3f34c5f6964f 100644 --- a/src/language/utils/DataVariant.hpp +++ b/src/language/utils/DataVariant.hpp @@ -18,13 +18,21 @@ using DataVariant = std::variant<std::monostate, int64_t, double, std::string, + TinyVector<1>, + TinyVector<2>, + TinyVector<3>, EmbeddedData, + std::vector<bool>, + std::vector<uint64_t>, + std::vector<int64_t>, + std::vector<double>, + std::vector<std::string>, + std::vector<TinyVector<1>>, + std::vector<TinyVector<2>>, + std::vector<TinyVector<3>>, std::vector<EmbeddedData>, AggregateDataVariant, - FunctionSymbolId, - TinyVector<1>, - TinyVector<2>, - TinyVector<3>>; + FunctionSymbolId>; std::ostream& operator<<(std::ostream& os, const DataVariant& v); diff --git a/src/utils/PugsTraits.hpp b/src/utils/PugsTraits.hpp index b6e627200725198a1fb0c088b81779cf478c6521..c4545781212684e9dd83d2dd98ba3599c2cc60b8 100644 --- a/src/utils/PugsTraits.hpp +++ b/src/utils/PugsTraits.hpp @@ -47,4 +47,12 @@ inline constexpr bool is_vector_v = false; template <typename T> inline constexpr bool is_vector_v<std::vector<T>> = true; +// Traits is_tiny_vector + +template <typename T> +inline constexpr bool is_tiny_vector_v = false; + +template <size_t N, typename T> +inline constexpr bool is_tiny_vector_v<TinyVector<N, T>> = true; + #endif // PUGS_TRAITS_HPP diff --git a/tests/test_ASTNodeExpressionBuilder.cpp b/tests/test_ASTNodeExpressionBuilder.cpp index 136cb587c8c15a06055972621a351f4937af649d..8314e5a74d036c4ad2ff8a22a69ea3f68c6ceced 100644 --- a/tests/test_ASTNodeExpressionBuilder.cpp +++ b/tests/test_ASTNodeExpressionBuilder.cpp @@ -276,7 +276,7 @@ let (t,x): R*R^3, (t,x) = (0,(1,2,3)); | `-(language::name:x:NameProcessor) `-(language::expression_list:ASTNodeExpressionListProcessor) +-(language::integer:0:ValueProcessor) - `-(language::tuple_expression:TupleToTinyVectorProcessor<ASTNodeExpressionListProcessor, 3ul>) + `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) +-(language::integer:1:ValueProcessor) +-(language::integer:2:ValueProcessor) `-(language::integer:3:ValueProcessor) @@ -299,7 +299,7 @@ let (t,x): R*R^2, (t,x) = (0,(1,2)); | `-(language::name:x:NameProcessor) `-(language::expression_list:ASTNodeExpressionListProcessor) +-(language::integer:0:ValueProcessor) - `-(language::tuple_expression:TupleToTinyVectorProcessor<ASTNodeExpressionListProcessor, 2ul>) + `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) +-(language::integer:1:ValueProcessor) `-(language::integer:2:ValueProcessor) )"; diff --git a/tests/test_ASTNodeFunctionExpressionBuilder.cpp b/tests/test_ASTNodeFunctionExpressionBuilder.cpp index 70d8eb738d52e96757ff4e83c2f072a4d4af5fad..7e892c86367a3984cab7cb93a4d27631cda52d28 100644 --- a/tests/test_ASTNodeFunctionExpressionBuilder.cpp +++ b/tests/test_ASTNodeFunctionExpressionBuilder.cpp @@ -593,7 +593,7 @@ f((1,2,3)); (root:ASTNodeListProcessor) `-(language::function_evaluation:FunctionProcessor) +-(language::name:f:NameProcessor) - `-(language::tuple_expression:TupleToTinyVectorProcessor<ASTNodeExpressionListProcessor, 3ul>) + `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) +-(language::integer:1:ValueProcessor) +-(language::integer:2:ValueProcessor) `-(language::integer:3:ValueProcessor) @@ -615,11 +615,11 @@ f(2,(1,2,3),(2,1.3)); +-(language::name:f:NameProcessor) `-(language::function_argument_list:ASTNodeExpressionListProcessor) +-(language::integer:2:ValueProcessor) - +-(language::tuple_expression:TupleToTinyVectorProcessor<ASTNodeExpressionListProcessor, 3ul>) + +-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) | +-(language::integer:1:ValueProcessor) | +-(language::integer:2:ValueProcessor) | `-(language::integer:3:ValueProcessor) - `-(language::tuple_expression:TupleToTinyVectorProcessor<ASTNodeExpressionListProcessor, 2ul>) + `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) +-(language::integer:2:ValueProcessor) `-(language::real:1.3:ValueProcessor) )";