Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I cast an enum to an Integer to handle overflow/wraparound?

Tags:

ada

I'm learning ada and I'm trying to implement an addition overload for an enum.

Basically I want to be able to add an Integer to a Day type and get the resulting Day value. So MONDAY + 2 => WEDNESDAY.

Here is my simplified code:

procedure overload is                                                                                                             
    type Day is (                                                                                                                 
        Sunday,                                                                                                                   
        Monday,                                                                                                                   
        Tuesday,                                                                                                                  
        Wednesday,                                                                                                                
        Thursday,                                                                                                                 
        Friday,                                                                                                                   
        Saturday                                                                                                                  
    );
    day1 : Day := Monday;
    function "+" (left: Day; right: Integer) return Day is                                                                        
        -- how would I handle this here? I want to basically say
        -- if Day + Integer > Saturday then
        --   wraparound back to Sunday
        return DayValue;
    begin
       for x in 0 .. 7 loop
          Ada.text_io.put_line("Monday + " & Integer'Image(x) & " = " & Day'Image(day1 + x));
       end loop;
end overload;
like image 931
KaibutsuX Avatar asked Sep 20 '21 02:09

KaibutsuX


People also ask

How do I assign an integer to an enum?

Use the Type Casting to Convert an Int to Enum in C# The correct syntax to use type casting is as follows. Copy YourEnum variableName = (YourEnum)yourInt; The program below shows how we can use the type casting to cast an int to enum in C#. We have cast our integer value to enum constant One .

Can enum be treated as int?

An Enum value cannot be treated as an int by default because then you would be able to provide any integer and there would be no compile time check to validate that the provided integer does in fact exist as a value in the Enumeration.

Can enum be Typecasted?

Yes. In C enum types are just int s under the covers. Typecast them to whatever you want. enums are not always ints in C.

How do I find the enum of a number?

You can use: int i = Convert. ToInt32(e); int i = (int)(object)e; int i = (int)Enum. Parse(e.

How to cast an int value to a enum object in C#?

To cast an int value to a enum object in C#, it's simple to use MyEnum e = (MyEnum)number. public enum MyEnum { First = 1, Second = 2, Third = 3 } static void Main (string [] args) { int number1 = 1; var enum1 = (MyEnum)number1; Console.WriteLine (enum1); int number4 = 4; var enum4 = (MyEnum)number4; Console.WriteLine (enum4); }

Why is enum parse not working?

Be aware that Enum.Parse will NOT work if your code is obfuscated. At run time after obfuscation the string is compared to the enum names, and at this point the names of the enums aren't what you would expect them to be. Your parse will fail where they succeeded before as a result.

How to convert enum myenum to decimals?

enum MyEnum { First = 1, Second = 2, Third = 3 }; string enumStr = MyEnum.First.ToString (); enum MyEnum { First = 1, Second = 2, Third = 3 }; var myEnum = MyEnum.Second; string enumStr = Convert.ToDecimal (myEnum).ToString ("0");

What is the value of bitflag in Enum?

which is a value of 4, this is more pronounced when you define the enum as a bitflag. You define this in the right scope based on if it is used only within a class or if it is used in a certain namespace...


3 Answers

You can use the 'Pos and 'Val attributes to do it. 'Pos returns the position of the supplied day relative to the first option (0 indexed) while 'Val takes a Pos value and returns the day type value:

return Day'Val(Day'Pos(Left) + Right);

For wraparound check the 'Pos value of Saturday vs the 'Pos value of left + the right value and use Day'Val(0) for Sunday

Or switch your input type of Right from Integer to Natural and use modulus math:

return Day'Val((Day'Pos(left) + Right) mod 7);

You can even get fancy and make a constant for the 7:

Day_Mod : constant := Day'Pos(Day'Last) - Day'Pos(Day'First) + 1;

and then it becomes

return Day'Val((Day'Pos(left) + Right) mod Day_Mod);
like image 64
Jere Avatar answered Oct 16 '22 09:10

Jere


While you have an answer to get the position value associated with a enumeration value, do not think this is the same as an enum in C. Ada enumerations are not numeric types.

You can iterate through a range of enumeration values using a for loop as in

for the_day in Day loop in loop
   Put_Line(Day'Image(the_day));
end loop;

If you want to print the current day and the next day you can use the 'Succ attribute.

for the_day in Day loop
   Put(Day'Image(the_day) & " the next day is ");
   if the_day = Day'Last then
      Put_Line(Day'Image(Day'First));
   else
      Put_Line(Day'Image(the_day'Succ));
   end if;
end loop;
like image 30
Jim Rogers Avatar answered Oct 16 '22 09:10

Jim Rogers


I would use PragmARC.Wrapping:

with PragmARC.Wrapping;

function "+" (Left : Day; Right : Integer) return Day is
   package Wrapping is new PragmARC.Wrapping (Item => Day);
   use Wrapping;

   Result : Day := Left;
begin -- "+"
   Change : for I in 1 .. abs Right loop
      Result := (if Right < 0 then Wrap_Pred (Result) else Wrap_Succ (Result) );
   end loop Change;

   return Result;
end "+";
like image 1
Jeffrey R. Carter Avatar answered Oct 16 '22 10:10

Jeffrey R. Carter