Skip to content
Snippets Groups Projects
Select Git revision
  • 953e1548b64772abf483190112b6686526dd4780
  • 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_ForProcessor.cpp

Blame
  • BinaryExpressionProcessor.hpp 5.32 KiB
    #ifndef BINARY_EXPRESSION_PROCESSOR_HPP
    #define BINARY_EXPRESSION_PROCESSOR_HPP
    
    #include <node_processor/INodeProcessor.hpp>
    
    #include <Demangle.hpp>
    
    #include <type_traits>
    
    template <typename Op>
    struct BinOp;
    
    template <>
    struct BinOp<language::and_op>
    {
      template <typename A, typename B>
      PUGS_INLINE auto
      eval(const A& a, const B& b) -> decltype(a and b)
      {
        return a and b;
      }
    };
    
    template <>
    struct BinOp<language::or_op>
    {
      template <typename A, typename B>
      PUGS_INLINE auto
      eval(const A& a, const B& b) -> decltype(a or b)
      {
        return a or b;
      }
    };
    
    template <>
    struct BinOp<language::xor_op>
    {
      template <typename A, typename B>
      PUGS_INLINE auto
      eval(const A& a, const B& b) -> decltype(a xor b)
      {
        return a xor b;
      }
    };
    
    template <>
    struct BinOp<language::eqeq_op>
    {
      template <typename A, typename B>
      PUGS_INLINE auto
      eval(const A& a, const B& b) -> decltype(a == b)
      {
        return a == b;
      }
    };
    
    template <>
    struct BinOp<language::not_eq_op>
    {
      template <typename A, typename B>
      PUGS_INLINE auto
      eval(const A& a, const B& b) -> decltype(a != b)
      {
        return a != b;
      }
    };
    
    template <>
    struct BinOp<language::lesser_op>
    {
      template <typename A, typename B>
      PUGS_INLINE auto
      eval(const A& a, const B& b) -> decltype(a < b)
      {
        return a < b;
      }
    };
    
    template <>
    struct BinOp<language::lesser_or_eq_op>
    {
      template <typename A, typename B>
      PUGS_INLINE auto
      eval(const A& a, const B& b) -> decltype(a <= b)
      {
        return a <= b;
      }
    };
    
    template <>
    struct BinOp<language::greater_op>
    {
      template <typename A, typename B>
      PUGS_INLINE auto
      eval(const A& a, const B& b) -> decltype(a > b)
      {
        return a > b;
      }
    };
    
    template <>
    struct BinOp<language::greater_or_eq_op>
    {
      template <typename A, typename B>
      PUGS_INLINE auto
      eval(const A& a, const B& b) -> decltype(a >= b)
      {
        return a >= b;
      }
    };
    
    template <>
    struct BinOp<language::plus_op>
    {
      template <typename A, typename B>
      PUGS_INLINE auto
      eval(const A& a, const B& b) -> decltype(a + b)
      {
        return a + b;
      }
    };
    
    template <>
    struct BinOp<language::minus_op>
    {
      template <typename A, typename B>
      PUGS_INLINE auto
      eval(const A& a, const B& b) -> decltype(a - b)
      {
        return a - b;
      }
    };
    
    template <>
    struct BinOp<language::multiply_op>
    {
      template <typename A, typename B>
      PUGS_INLINE auto
      eval(const A& a, const B& b) -> decltype(a * b)
      {
        return a * b;
      }
    };
    
    template <>
    struct BinOp<language::divide_op>
    {
      template <typename A, typename B>
      PUGS_INLINE auto
      eval(const A& a, const B& b) -> decltype(a / b)
      {
        return a / b;
      }
    };
    
    template <typename BinaryOpT, typename A_DataT, typename B_DataT>
    class BinaryExpressionProcessor final : public INodeProcessor
    {
      ASTNode& m_node;
    
      PUGS_INLINE auto
      _eval(const ASTNodeDataVariant& a, const ASTNodeDataVariant& b, ASTNodeDataVariant& value)
      {
        // Add 'signed' when necessary to avoid signed/unsigned comparison warnings
        if constexpr ((not(std::is_same_v<A_DataT, bool> or std::is_same_v<B_DataT, bool>)) and
                      (std::is_same_v<BinaryOpT, language::and_op> or std::is_same_v<BinaryOpT, language::or_op> or
                       std::is_same_v<BinaryOpT, language::xor_op> or std::is_same_v<BinaryOpT, language::eqeq_op> or
                       std::is_same_v<BinaryOpT, language::not_eq_op> or std::is_same_v<BinaryOpT, language::lesser_op> or
                       std::is_same_v<BinaryOpT, language::lesser_or_eq_op> or
                       std::is_same_v<BinaryOpT, language::greater_op> or
                       std::is_same_v<BinaryOpT, language::greater_or_eq_op>) and
                      (std::is_signed_v<A_DataT> xor std::is_signed_v<B_DataT>)) {
          if constexpr (std::is_unsigned_v<A_DataT>) {
            using signed_A_DataT          = std::make_signed_t<A_DataT>;
            const signed_A_DataT signed_a = static_cast<signed_A_DataT>(std::get<A_DataT>(a));
            value                         = BinOp<BinaryOpT>().eval(signed_a, std::get<B_DataT>(b));
          } else {
            using signed_B_DataT          = std::make_signed_t<B_DataT>;
            const signed_B_DataT signed_b = static_cast<signed_B_DataT>(std::get<B_DataT>(b));
            value                         = BinOp<BinaryOpT>().eval(std::get<A_DataT>(a), signed_b);
          }
        } else {
          auto result = BinOp<BinaryOpT>().eval(std::get<A_DataT>(a), std::get<B_DataT>(b));
          if constexpr (std::is_same_v<decltype(result), int>) {
            value = static_cast<int64_t>(result);
          } else {
            value = result;
          }
        }
      }
    
      static inline const bool _is_defined{[] {
        if constexpr (std::is_same_v<BinaryOpT, language::xor_op>) {
          return std::is_same_v<std::decay_t<A_DataT>, std::decay_t<B_DataT>> and std::is_integral_v<std::decay_t<A_DataT>>;
        }
        return true;
      }()};
    
     public:
      std::string
      describe() const
      {
        return demangle<decltype(*this)>();
      }
    
      void
      execute(ExecUntilBreakOrContinue& exec_policy)
      {
        if constexpr (_is_defined) {
          m_node.children[0]->execute(exec_policy);
          m_node.children[1]->execute(exec_policy);
    
          this->_eval(m_node.children[0]->m_value, m_node.children[1]->m_value, m_node.m_value);
        }
      }
    
      BinaryExpressionProcessor(ASTNode& node) : m_node{node}
      {
        if constexpr (not _is_defined) {
          throw parse_error("invalid operands to binary expression", std::vector{m_node.begin()});
        }
      }
    };
    
    #endif // BINARY_EXPRESSION_PROCESSOR_HPP