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.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED.Oh2LSLzxQ4+YU0Htrufc+A.user.gioia.aioe.org!not-for-mail From: Simon Wright Newsgroups: comp.lang.ada Subject: Re: Creating several types from a base type and conversion Date: Fri, 24 Jan 2020 15:54:42 +0000 Organization: Aioe.org NNTP Server Message-ID: References: NNTP-Posting-Host: Oh2LSLzxQ4+YU0Htrufc+A.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain X-Complaints-To: abuse@aioe.org User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (darwin) X-Notice: Filtered by postfilter v. 0.9.2 Cancel-Lock: sha1:VxXy+0uDApzsJl0PwW0aIrrYFIk= Xref: reader01.eternal-september.org comp.lang.ada:57937 Date: 2020-01-24T15:54:42+00:00 List-Id: Optikos writes: > Instead of depending on a big-language solution of a very-feature-rich > compiler, there is a common industrial practice in both Ada and other > languages that I mentioned in my 2 replies: use 2 different packages > with same-named identifiers (especially functions or procedures) to > link in either the little-endian implementation or big-endian > implementation An alternative approach (which I've now abandoned in favour of the GNAT Scalar_Storage_Order) was, given e.g. type SNTP_Timestamp is delta 2.0 ** (-32) range -2.0 ** 31 .. 2.0 ** 31; for SNTP_Timestamp'Size use 64; subtype Timestamp_Slice is Ada.Streams.Stream_Element_Array (1 .. 8); to provide conversion functions like function To_Timestamp_Slice (T : SNTP_Timestamp) return Timestamp_Slice is function Convert is new Ada.Unchecked_Conversion (SNTP_Timestamp, Timestamp_Slice); Tmp : constant Timestamp_Slice := Convert (T); begin if Big_Endian then return Tmp; else return (1 => Tmp (8), 2 => Tmp (7), 3 => Tmp (6), 4 => Tmp (5), 5 => Tmp (4), 6 => Tmp (3), 7 => Tmp (2), 8 => Tmp (1)); end if; end To_Timestamp_Slice; (Big_Endian was a compile-time constant; GNAT is clever enough not to generate any object code for the "other" branch). It got a bit more interesting where there were bit fields involved; the two branches can declare appropriately-represented derived types and use type conversion between base and derived type to get the compiler to do the hard work. See e.g. [1] starting at line 43. [1] https://sourceforge.net/p/coldframe/adasntp/code/ci/Rel_20070311/tree/SNTP.impl/sntp_support.adb