Skip to content
Snippets Groups Projects
Select Git revision
  • 2cef88915d422583d2e941c6eb7a1f56b8f717a6
  • develop default protected
  • feature/advection
  • feature/composite-scheme-other-fluxes
  • origin/stage/bouguettaia
  • save_clemence
  • feature/local-dt-fsi
  • feature/variational-hydro
  • feature/gmsh-reader
  • feature/reconstruction
  • feature/kinetic-schemes
  • feature/composite-scheme-sources
  • feature/serraille
  • feature/composite-scheme
  • hyperplastic
  • feature/polynomials
  • feature/gks
  • feature/implicit-solver-o2
  • feature/coupling_module
  • feature/implicit-solver
  • feature/merge-local-dt-fsi
  • v0.5.0 protected
  • v0.4.1 protected
  • v0.4.0 protected
  • v0.3.0 protected
  • v0.2.0 protected
  • v0.1.0 protected
  • Kidder
  • v0.0.4 protected
  • v0.0.3 protected
  • v0.0.2 protected
  • v0 protected
  • v0.0.1 protected
33 results

test_Polynomial.cpp

Blame
  • FunctionArgumentConverter.hpp 16.75 KiB
    #ifndef FUNCTION_ARGUMENT_CONVERTER_HPP
    #define FUNCTION_ARGUMENT_CONVERTER_HPP
    
    #include <language/node_processor/ExecutionPolicy.hpp>
    #include <language/utils/DataVariant.hpp>
    #include <utils/Demangle.hpp>
    #include <utils/Exceptions.hpp>
    #include <utils/PugsTraits.hpp>
    
    #include <sstream>
    
    class IFunctionArgumentConverter
    {
     public:
      virtual DataVariant convert(ExecutionPolicy& exec_policy, DataVariant&& value) = 0;
    
      IFunctionArgumentConverter() = default;
    
      IFunctionArgumentConverter(const IFunctionArgumentConverter&) = delete;
      IFunctionArgumentConverter(IFunctionArgumentConverter&&)      = delete;
    
      virtual ~IFunctionArgumentConverter() = default;
    };
    
    class FunctionArgumentToStringConverter final : public IFunctionArgumentConverter
    {
     private:
      size_t m_argument_id;
    
     public:
      DataVariant
      convert(ExecutionPolicy& exec_policy, DataVariant&& value)
      {
        std::visit(
          [&](auto&& v) {
            using T = std::decay_t<decltype(v)>;
            if constexpr (std::is_arithmetic_v<T>) {
              exec_policy.currentContext()[m_argument_id] = std::to_string(v);
            } else if constexpr (std::is_same_v<T, std::string>) {
              exec_policy.currentContext()[m_argument_id] = v;
            } else {
              std::ostringstream sout;
              sout << value;
              exec_policy.currentContext()[m_argument_id] = sout.str();
            }
          },
          value);
        return {};
      }
    
      FunctionArgumentToStringConverter(size_t argument_id) : m_argument_id{argument_id} {}
    };
    
    template <typename ExpectedValueType, typename ProvidedValueType>
    class FunctionArgumentConverter final : public IFunctionArgumentConverter
    {
     private:
      size_t m_argument_id;
    
     public:
      DataVariant
      convert(ExecutionPolicy& exec_policy, DataVariant&& value)
      {
        static_assert(not std::is_same_v<ExpectedValueType, std::string>, "use FunctionArgumentToStringConverter");
        if constexpr (std::is_same_v<ExpectedValueType, ProvidedValueType>) {
          exec_policy.currentContext()[m_argument_id] = std::move(value);
        } else {
          exec_policy.currentContext()[m_argument_id] =
            std::move(static_cast<ExpectedValueType>(std::get<ProvidedValueType>(value)));
        }
        return {};
      }
    
      FunctionArgumentConverter(size_t argument_id) : m_argument_id{argument_id} {}
    };
    
    template <typename ExpectedValueType, typename ProvidedValueType>
    class FunctionTinyVectorArgumentConverter 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, 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 {
          static_assert(std::is_same_v<ExpectedValueType, TinyVector<1>>);
          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 ExpectedValueType, typename ProvidedValueType>
    class FunctionTinyMatrixArgumentConverter 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, ExpectedValueType>) {
                exec_policy.currentContext()[m_argument_id] = std::move(value);
              } else if constexpr (std::is_same_v<ValueT, AggregateDataVariant>) {
                ExpectedValueType matrix_value{};
                for (size_t i = 0, l = 0; i < matrix_value.numberOfRows(); ++i) {
                  for (size_t j = 0; j < matrix_value.numberOfColumns(); ++j, ++l) {
                    std::visit(
                      [&](auto&& A_ij) {
                        using Vi_T = std::decay_t<decltype(A_ij)>;
                        if constexpr (std::is_arithmetic_v<Vi_T>) {
                          matrix_value(i, j) = A_ij;
                        } else {
                          throw UnexpectedError(demangle<Vi_T>() + " unexpected aggregate value type");
                        }
                      },
                      v[l]);
                  }
                }
                exec_policy.currentContext()[m_argument_id] = std::move(matrix_value);
              }
            },
            value);
        } else if constexpr (std::is_same_v<ProvidedValueType, ZeroType>) {
          exec_policy.currentContext()[m_argument_id] = ExpectedValueType{ZeroType::zero};
        } else {
          static_assert(std::is_same_v<ExpectedValueType, TinyMatrix<1>>);
          exec_policy.currentContext()[m_argument_id] =
            std::move(static_cast<ExpectedValueType>(std::get<ProvidedValueType>(value)));
        }
        return {};
      }
    
      FunctionTinyMatrixArgumentConverter(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_convertible_v<ProvidedValueType, ContentType>) {
          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_std_vector_v<ValueT>) {
                using ContentT = typename ValueT::value_type;
                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(std::move(v[i]));
                  }
                  exec_policy.currentContext()[m_argument_id] = std::move(list_value);
                } else if constexpr ((std::is_convertible_v<ContentT, ContentType>)and not is_tiny_vector_v<ContentType> and
                                     not is_tiny_matrix_v<ContentType>) {
                  TupleType list_value;
                  list_value.reserve(v.size());
                  for (size_t i = 0; i < v.size(); ++i) {
                    list_value.push_back(static_cast<ContentType>(v[i]));
                  }
                  exec_policy.currentContext()[m_argument_id] = std::move(list_value);
                } else {
                  // LCOV_EXCL_START
                  throw UnexpectedError(std::string{"cannot convert '"} + demangle<ValueT>() + "' to '" +
                                        demangle<ContentType>() + "'");
                  // LCOV_EXCL_STOP
                }
              } else if constexpr (std::is_convertible_v<ValueT, ContentType> and not is_tiny_vector_v<ContentType> and
                                   not is_tiny_matrix_v<ContentType>) {
                exec_policy.currentContext()[m_argument_id] = std::move(TupleType{static_cast<ContentType>(v)});
              } else {
                throw UnexpectedError(std::string{"cannot convert '"} + demangle<ValueT>() + "' to '" +
                                      demangle<ContentType>() + "'");
              }
            },
            value);
        } else if constexpr (std::is_same_v<std::string, ContentType>) {
          std::visit(
            [&](auto&& v) {
              using ValueT = std::decay_t<decltype(v)>;
              Assert(not std::is_same_v<ValueT, ContentType>, "should have been treated before");
              if constexpr (is_std_vector_v<ValueT>) {
                using ContentT = typename ValueT::value_type;
                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(std::move(v[i]));
                  }
                  exec_policy.currentContext()[m_argument_id] = std::move(list_value);
                } else if constexpr (not is_shared_ptr_v<ContentT>) {
                  TupleType list_value;
                  list_value.reserve(v.size());
                  for (size_t i = 0; i < v.size(); ++i) {
                    std::ostringstream os;
                    const ContentT& content = v[i];   // useless helper for clang10
                    os << content;
                    list_value.push_back(std::move(os.str()));
                  }
                  exec_policy.currentContext()[m_argument_id] = std::move(list_value);
                } else {
                  // LCOV_EXCL_START
                  throw UnexpectedError(std::string{"cannot convert '"} + demangle<ValueT>() + "' to '" +
                                        demangle<ContentType>() + "'");
                  // LCOV_EXCL_STOP
                }
              } else if constexpr (not is_shared_ptr_v<ContentType>) {
                std::ostringstream os;
                os << v;
                exec_policy.currentContext()[m_argument_id] = std::move(TupleType{std::move(os.str())});
              } else {
                // LCOV_EXCL_START
                throw UnexpectedError(std::string{"cannot convert '"} + demangle<ValueT>() + "' to '" +
                                      demangle<ContentType>() + "'");
                // LCOV_EXCL_STOP
              }
            },
            value);
    
        } else {
          // LCOV_EXCL_START
          throw UnexpectedError(std::string{"cannot convert '"} + demangle<ProvidedValueType>() + "' to '" +
                                demangle<ContentType>() + "'");
          // LCOV_EXCL_STOP
        }
        return {};
      }
    
      FunctionTupleArgumentConverter(size_t argument_id) : m_argument_id{argument_id} {}
    };
    
    template <typename ContentType, typename ProvidedValueType>
    class FunctionListArgumentConverter final : public IFunctionArgumentConverter
    {
     private:
      size_t m_argument_id;
    
     public:
      DataVariant
      convert(ExecutionPolicy& exec_policy, DataVariant&& value)
      {
        static_assert(not std::is_same_v<ContentType, FunctionSymbolId>);
        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>) {
                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 (std::is_same_v<Vi_T, ContentType>) {
                        list_value.emplace_back(vi);
                      } else if constexpr (is_tiny_vector_v<ContentType> or is_tiny_matrix_v<ContentType>) {
                        // LCOV_EXCL_START
                        throw UnexpectedError(std::string{"invalid conversion of '"} + demangle<Vi_T>() + "' to '" +
                                              demangle<ContentType>() + "'");
                        // LCOV_EXCL_STOP
                      } else if constexpr (std::is_convertible_v<Vi_T, ContentType>) {
                        list_value.emplace_back(vi);
                      } else {
                        // LCOV_EXCL_START
                        throw UnexpectedError("unexpected types");
                        // LCOV_EXCL_STOP
                      }
                    },
                    (v[i]));
                }
                exec_policy.currentContext()[m_argument_id] = std::move(list_value);
              } else if constexpr (is_std_vector_v<ValueT>) {
                using ContentT = typename ValueT::value_type;
                if constexpr (std::is_same_v<ContentT, ContentType>) {
                  exec_policy.currentContext()[m_argument_id] = v;
                } else {
                  // LCOV_EXCL_START
                  throw UnexpectedError(std::string{"invalid conversion of '"} + demangle<ContentT>() + "' to '" +
                                        demangle<ContentType>() + "'");
                  // LCOV_EXCL_STOP
                }
              } else if constexpr (std::is_same_v<ValueT, ContentType>) {
                exec_policy.currentContext()[m_argument_id] = std::move(TupleType{v});
              } else if constexpr (std::is_convertible_v<ValueT, ContentType> and not is_tiny_vector_v<ValueT> and
                                   not is_tiny_vector_v<ContentType> and not is_tiny_matrix_v<ValueT> and
                                   not is_tiny_matrix_v<ContentType>) {
                exec_policy.currentContext()[m_argument_id] = std::move(TupleType{static_cast<ContentType>(v)});
              } else {
                // LCOV_EXCL_START
                throw UnexpectedError(demangle<ValueT>() + " unexpected value type");
                // LCOV_EXCL_STOP
              }
            },
            value);
        }
        static_assert(std::is_same_v<ContentType, ProvidedValueType>, "conversion is not implemented");
    
        return {};
      }
    
      FunctionListArgumentConverter(size_t argument_id) : m_argument_id{argument_id} {}
    };
    
    template <>
    class FunctionListArgumentConverter<FunctionSymbolId, FunctionSymbolId> final : public IFunctionArgumentConverter
    {
     private:
      size_t m_argument_id;
      std::shared_ptr<SymbolTable> m_symbol_table;
    
     public:
      DataVariant
      convert(ExecutionPolicy& exec_policy, DataVariant&& value)
      {
        using TupleType = std::vector<FunctionSymbolId>;
        std::visit(
          [&](auto&& v) {
            using ValueT = std::decay_t<decltype(v)>;
            if constexpr (std::is_same_v<ValueT, AggregateDataVariant>) {
              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 (std::is_same_v<Vi_T, uint64_t>) {
                      list_value.emplace_back(FunctionSymbolId{vi, m_symbol_table});
                    } else {
                      // LCOV_EXCL_START
                      throw UnexpectedError(std::string{"invalid conversion of '"} + demangle<Vi_T>() + "' to '" +
                                            demangle<FunctionSymbolId>() + "'");
                      // LCOV_EXCL_STOP
                    }
                  },
                  (v[i]));
              }
              exec_policy.currentContext()[m_argument_id] = std::move(list_value);
            } else {
              // LCOV_EXCL_START
              throw UnexpectedError(std::string{"invalid conversion of '"} + demangle<ValueT>() + "' to '" +
                                    demangle<FunctionSymbolId>() + "' list");
              // LCOV_EXCL_STOP
            }
          },
          value);
    
        return {};
      }
    
      FunctionListArgumentConverter(size_t argument_id, const std::shared_ptr<SymbolTable>& symbol_table)
        : m_argument_id{argument_id}, m_symbol_table{symbol_table}
      {}
    };
    
    class FunctionArgumentToFunctionSymbolIdConverter final : public IFunctionArgumentConverter
    {
     private:
      size_t m_argument_id;
      std::shared_ptr<SymbolTable> m_symbol_table;
    
     public:
      DataVariant
      convert(ExecutionPolicy& exec_policy, DataVariant&& value)
      {
        exec_policy.currentContext()[m_argument_id] = FunctionSymbolId{std::get<uint64_t>(value), m_symbol_table};
    
        return {};
      }
    
      FunctionArgumentToFunctionSymbolIdConverter(size_t argument_id, const std::shared_ptr<SymbolTable>& symbol_table)
        : m_argument_id{argument_id}, m_symbol_table{symbol_table}
      {}
    };
    
    class FunctionArgumentToTupleFunctionSymbolIdConverter final : public IFunctionArgumentConverter
    {
     private:
      size_t m_argument_id;
      std::shared_ptr<SymbolTable> m_symbol_table;
    
     public:
      DataVariant
      convert(ExecutionPolicy& exec_policy, DataVariant&& value)
      {
        exec_policy.currentContext()[m_argument_id] =
          std::vector{FunctionSymbolId{std::get<uint64_t>(value), m_symbol_table}};
    
        return {};
      }
    
      FunctionArgumentToTupleFunctionSymbolIdConverter(size_t argument_id, const std::shared_ptr<SymbolTable>& symbol_table)
        : m_argument_id{argument_id}, m_symbol_table{symbol_table}
      {}
    };
    
    #endif   // FUNCTION_ARGUMENT_CONVERTER_HPP