@@ -3578,6 +3578,123 @@ 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.
3584+ // / The syntax is: 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 select_value
3616+ void add_case (const exprt &case_value, const exprt &result_value)
3617+ {
3618+ operands ().reserve (operands ().size () + 2 );
3619+ operands ().push_back (case_value);
3620+ operands ().push_back (result_value);
3621+ }
3622+
3623+ // / Get the number of cases (excluding the select value)
3624+ std::size_t number_of_cases () const
3625+ {
3626+ PRECONDITION (operands ().size () >= 1 );
3627+ return (operands ().size () - 1 ) / 2 ;
3628+ }
3629+
3630+ // / Get the case value for the i-th case
3631+ const exprt &case_value (std::size_t i) const
3632+ {
3633+ PRECONDITION (i < number_of_cases ());
3634+ return operands ()[1 + 2 * i];
3635+ }
3636+
3637+ // / Get the case value for the i-th case
3638+ exprt &case_value (std::size_t i)
3639+ {
3640+ PRECONDITION (i < number_of_cases ());
3641+ return operands ()[1 + 2 * i];
3642+ }
3643+
3644+ // / Get the result value for the i-th case
3645+ const exprt &result_value (std::size_t i) const
3646+ {
3647+ PRECONDITION (i < number_of_cases ());
3648+ return operands ()[1 + 2 * i + 1 ];
3649+ }
3650+
3651+ // / Get the result value for the i-th case
3652+ exprt &result_value (std::size_t i)
3653+ {
3654+ PRECONDITION (i < number_of_cases ());
3655+ return operands ()[1 + 2 * i + 1 ];
3656+ }
3657+ };
3658+
3659+ template <>
3660+ inline bool can_cast_expr<case_exprt>(const exprt &base)
3661+ {
3662+ return base.id () == ID_case;
3663+ }
3664+
3665+ inline void validate_expr (const case_exprt &value)
3666+ {
3667+ DATA_INVARIANT (
3668+ value.operands ().size () >= 1 ,
3669+ " case expression must have at least one operand" );
3670+ DATA_INVARIANT (
3671+ value.operands ().size () % 2 == 1 ,
3672+ " case expression must have odd number of operands" );
3673+ }
3674+
3675+ // / \brief Cast an exprt to a \ref case_exprt
3676+ // /
3677+ // / \a expr must be known to be \ref case_exprt.
3678+ // /
3679+ // / \param expr: Source expression
3680+ // / \return Object of type \ref case_exprt
3681+ inline const case_exprt &to_case_expr (const exprt &expr)
3682+ {
3683+ PRECONDITION (expr.id () == ID_case);
3684+ const case_exprt &ret = static_cast <const case_exprt &>(expr);
3685+ validate_expr (ret);
3686+ return ret;
3687+ }
3688+
3689+ // / \copydoc to_case_expr(const exprt &)
3690+ inline case_exprt &to_case_expr (exprt &expr)
3691+ {
3692+ PRECONDITION (expr.id () == ID_case);
3693+ case_exprt &ret = static_cast <case_exprt &>(expr);
3694+ validate_expr (ret);
3695+ return ret;
3696+ }
3697+
35813698// / \brief Expression to define a mapping from an argument (index) to elements.
35823699// / This enables constructing an array via an anonymous function.
35833700// / Not all kinds of array comprehension can be expressed, only those of the
0 commit comments