From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,91c7c63c23ef2d0c X-Google-Attributes: gid103376,public From: Dale Stanbrough Subject: Re: Beware: Rep spec on an enumeration type ... Date: 1997/12/17 Message-ID: <677rko$a0c$1@goanna.cs.rmit.edu.au>#1/1 X-Deja-AN: 308503486 Distribution: world Content-Transfer-Encoding: 8bit References: <6723st$mnt$1@goanna.cs.rmit.edu.au> Content-Type: text/plain; charset=ISO-8859-1 X-XXMessage-ID: Organization: Royal Melbourne Institute of Technology Mime-Version: 1.0 Newsgroups: comp.lang.ada Date: 1997-12-17T00:00:00+00:00 List-Id: An interesting posting on this very issue from a few years ago... From: emery@goldfinger.mitre.org (David Emery) Newsgroups: comp.lang.ada Subject: Re: UNCHECKED_CONVERSION Date: 24 Jan 94 16:11:44 Organization: The Mitre Corp., Bedford, MA. The 'right way' to do such things is to completely avoid representation specs on the enumeration type, and use mapping arrays, (The following has not been compiled, but should be considered as an 'outline' of the actual approach...) -- public (package spec) type color is (r,g,b); function int_to_color (int : integer) return color; function color_to_int (c : color) return integer; -- private (package body) subtype color_values is integer range 1..5; type int_color_element (valid : boolean := false) is record case valid is when true => c : color; when others => null; end case; end record; color_to_int_map : array (color) of integer := (r => 1, g => 3, b => 5); int_to_color_map : array (color_values) of color := (1 => (true, r), 2 => (false), 3 => (true, g), 4 => (false), 5 => (true, b)); -- note: This may require qualified notation, etc, to compile. function int_to_color (int : integer) return color is answer : int_color_element; begin answer := int_to_color_map (int); if answer.valid then return answer.c; else raise Constraint_Error; end if; exception when others => raise constraint_error; end int_to_color; function color_to_int (c : color return integer is begin return color_to_int_map (c); end color_to_int; There are several advantages with this approach. First is that all representation information is encoded in the package body, and not in the specification. This makes it much easier to change the underlying representation without breaking the existing code. Also, note that Constraint_Error is raised for out-of-value integers, preserving the basic Ada semantics of type conversion. Second, it's portable, and doesn't depend on any unchecked_conversion semantics. It's also type-safe, if you go to the effort (as shown) to check the incoming integer value. (Unchecked_Conversion of the value "4" for instance, would result in an erroneous program.) This costs a couple of extra instructions, but the type safety, etc, is well worth it. For large enumeration types, there are plenty of search and validation techniques. See your favorite data structures book :-) I discuss this (with more reasons why this is the right solution) in my paper on my POSIX/Ada port, Proceedings Tri-Ada '90. dave ----------------- Dale