@@ -3578,6 +3578,124 @@ inline cond_exprt &to_cond_expr(exprt &expr)
35783578 return ret;
35793579}
35803580
3581+ // / \brief Case expression: evaluates to the value corresponding to the first
3582+ // / matching case. The first operand is the value to compare against. Subsequent
3583+ // / operands alternate between compare values and result values. The syntax is:
3584+ // / case(select_value, case1_value, result1, case2_value, result2, ...)
3585+ class case_exprt : public multi_ary_exprt
3586+ {
3587+ public:
3588+ case_exprt (operandst _operands, typet _type)
3589+ : multi_ary_exprt(ID_case, std::move(_operands), std::move(_type))
3590+ {
3591+ }
3592+
3593+ // / Constructor with select value
3594+ case_exprt (exprt _select_value, typet _type)
3595+ : multi_ary_exprt(ID_case, {std::move (_select_value)}, std::move(_type))
3596+ {
3597+ }
3598+
3599+ // / Get the value that is being compared against
3600+ const exprt &select_value () const
3601+ {
3602+ PRECONDITION (!operands ().empty ());
3603+ return operands ()[0 ];
3604+ }
3605+
3606+ // / Get the value that is being compared against
3607+ exprt &select_value ()
3608+ {
3609+ PRECONDITION (!operands ().empty ());
3610+ return operands ()[0 ];
3611+ }
3612+
3613+ // / Add a case: value to compare and corresponding result
3614+ // / \param case_value: the value to compare against select_value
3615+ // / \param result_value: the value to return if case_value matches
3616+ // / select_value
3617+ void add_case (const exprt &case_value, const exprt &result_value)
3618+ {
3619+ operands ().reserve (operands ().size () + 2 );
3620+ operands ().push_back (case_value);
3621+ operands ().push_back (result_value);
3622+ }
3623+
3624+ // / Get the number of cases (excluding the select value)
3625+ std::size_t number_of_cases () const
3626+ {
3627+ PRECONDITION (operands ().size () >= 1 );
3628+ return (operands ().size () - 1 ) / 2 ;
3629+ }
3630+
3631+ // / Get the case value for the i-th case
3632+ const exprt &case_value (std::size_t i) const
3633+ {
3634+ PRECONDITION (i < number_of_cases ());
3635+ return operands ()[1 + 2 * i];
3636+ }
3637+
3638+ // / Get the case value for the i-th case
3639+ exprt &case_value (std::size_t i)
3640+ {
3641+ PRECONDITION (i < number_of_cases ());
3642+ return operands ()[1 + 2 * i];
3643+ }
3644+
3645+ // / Get the result value for the i-th case
3646+ const exprt &result_value (std::size_t i) const
3647+ {
3648+ PRECONDITION (i < number_of_cases ());
3649+ return operands ()[1 + 2 * i + 1 ];
3650+ }
3651+
3652+ // / Get the result value for the i-th case
3653+ exprt &result_value (std::size_t i)
3654+ {
3655+ PRECONDITION (i < number_of_cases ());
3656+ return operands ()[1 + 2 * i + 1 ];
3657+ }
3658+
3659+ static void validate_expr (const case_exprt &value)
3660+ {
3661+ DATA_INVARIANT (
3662+ value.operands ().size () >= 1 ,
3663+ " case expression must have at least one operand" );
3664+ DATA_INVARIANT (
3665+ value.operands ().size () % 2 == 1 ,
3666+ " case expression must have odd number of operands" );
3667+ }
3668+ };
3669+
3670+ template <>
3671+ inline bool can_cast_expr<case_exprt>(const exprt &base)
3672+ {
3673+ return base.id () == ID_case;
3674+ }
3675+
3676+ // / \brief Cast an exprt to a \ref case_exprt
3677+ // /
3678+ // / \a expr must be known to be \ref case_exprt.
3679+ // /
3680+ // / \param expr: Source expression
3681+ // / \return Object of type \ref case_exprt
3682+ inline const case_exprt &to_case_expr (const exprt &expr)
3683+ {
3684+ PRECONDITION (expr.id () == ID_case);
3685+ const case_exprt &ret = static_cast <const case_exprt &>(expr);
3686+ case_exprt::validate_expr (ret);
3687+ return ret;
3688+ }
3689+
3690+ // / \copydoc to_case_expr(const exprt &)
3691+ inline case_exprt &to_case_expr (exprt &expr)
3692+ {
3693+ PRECONDITION (expr.id () == ID_case);
3694+ case_exprt &ret = static_cast <case_exprt &>(expr);
3695+ case_exprt::validate_expr (ret);
3696+ return ret;
3697+ }
3698+
35813699// / \brief Expression to define a mapping from an argument (index) to elements.
35823700// / This enables constructing an array via an anonymous function.
35833701// / Not all kinds of array comprehension can be expressed, only those of the
0 commit comments