void check_operation_feasibility()

in src/core/storage/sframe_interface/unity_sarray_binary_operations.cpp [14:82]


void check_operation_feasibility(flex_type_enum left,
                                 flex_type_enum right,
                                 std::string op) {
  bool operation_is_feasible = false;

  if (op == "+" || op == "-" || op == "*" || op == "/") {
    if (left == flex_type_enum::DATETIME && right == flex_type_enum::DATETIME && op == "-") {
      operation_is_feasible = true;
    } else {
      operation_is_feasible = flex_type_has_binary_op(left, right, op[0]) ||
                            ((left == flex_type_enum::FLOAT
                             || left == flex_type_enum::INTEGER
                             || left == flex_type_enum::VECTOR)
                             && (right == flex_type_enum::FLOAT
                                 || right == flex_type_enum::INTEGER
                                 || right == flex_type_enum::VECTOR)) ||
                            ((left == flex_type_enum::FLOAT
                             || left == flex_type_enum::INTEGER
                             || left == flex_type_enum::ND_VECTOR)
                             && (right == flex_type_enum::FLOAT
                                 || right == flex_type_enum::INTEGER
                                 || right == flex_type_enum::ND_VECTOR));
    }
  } else if (op == "%") {
    operation_is_feasible = left == flex_type_enum::INTEGER &&
                            right == flex_type_enum::INTEGER;
  } else if (op == "**" || op == "//") {
    operation_is_feasible = (
        (left == flex_type_enum::FLOAT
         || left == flex_type_enum::INTEGER
         || left == flex_type_enum::VECTOR)
         && (right == flex_type_enum::FLOAT
             || right == flex_type_enum::INTEGER
             || right == flex_type_enum::VECTOR));
  } else if (op == "<" || op == ">" || op == "<=" || op == ">=") {
    // the comparison operators are all compatible. we just need to check
    // the < operator
    operation_is_feasible = flex_type_has_binary_op(left, right, '<');
  } else if (op == "==" || op == "!=") {
    // equality comparison is always feasible
    operation_is_feasible = true;
  } else if (op == "&" || op == "|") {
    // boolean operations are always feasible
    operation_is_feasible = true;
  } else if (op == "in") {
    // note that while the op is "in", the direction of the operator is
    // [BIGGER_LIST "in" element] rather than ["element" in BIGGER_LIST]
    // yes. slightly disconcerting I know. Sorry.
    operation_is_feasible = (left == flex_type_enum::STRING && right == flex_type_enum::STRING) ||
                            (left == flex_type_enum::VECTOR && right == flex_type_enum::FLOAT) ||
                            (left == flex_type_enum::VECTOR && right == flex_type_enum::INTEGER) ||
                            (left == flex_type_enum::DICT) ||
                            (left == flex_type_enum::LIST);
  } else if (op == "left_abs") {
    // right part of the operator is ignored in this one
    operation_is_feasible = (left == flex_type_enum::FLOAT
                             || left == flex_type_enum::INTEGER
                             || left == flex_type_enum::VECTOR);
  } else {
    log_and_throw("Invalid scalar operation");
  }

  if (!operation_is_feasible) {
    throw std::string("Unsupported type operation. cannot perform operation ") +
          op + " between " +
          flex_type_enum_to_name(left) + " and " +
          flex_type_enum_to_name(right);
  }
}