# Differences

This shows you the differences between two versions of the page.

thomaslocke [One Solution]
thomaslocke [A Full Program]
Line 1: Line 1:
=====  Introduction ​ ===== =====  Introduction ​ =====

=====  Caveat ​ ===== =====  Caveat ​ =====

-The following ​is an example ​of how to do something. It's not meant to be used in any real capacity. If you need a portable [[http://​adaic.org/​standards/​05rm/​html/​RM-3-6-3.html#​I1889|String]] representation of [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Ada.Calendar.Clock]],​ then you're better off using the many nice features of [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6-1.html#​I3773|Ada.Calendar.Formatting]].+The following ​are examples ​of how to do something. It's not meant to be used in any real capacity. If you need a portable [[http://​adaic.org/​standards/​05rm/​html/​RM-3-6-3.html#​I1889|String]] representation of [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Ada.Calendar.Clock]],​ then you're better off using the many nice features of [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6-1.html#​I3773|Ada.Calendar.Formatting]].

=====  The Problem ​ ===== =====  The Problem ​ =====
Line 11: Line 11:
The problem of outputting the return value from [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Ada.Calendar.Clock]] as a string is one of privacy. The returned type, [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Time]],​ is declared //​private//​. Also it's implementation defined: The problem of outputting the return value from [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Ada.Calendar.Clock]] as a string is one of privacy. The returned type, [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Time]],​ is declared //​private//​. Also it's implementation defined:

-<​blockquote>​ +
-The time base associated with the type Time of package Calendar is implementation defined. The function Clock of package Calendar returns a value representing the current time for this time base. The implementation-defined value of the named number System.Tick (see 13.7) is an approximation of the length of the real-time interval during which the value of Calendar.Clock remains constant. +The time base associated with the type Time of package Calendar is implementation defined. The function Clock of package Calendar returns a value representing the current time for this time base. The implementation-defined value of the named number System.Tick (see 13.7) is an approximation of the length of the real-time interval during which the value of Calendar.Clock remains constant.
-</​blockquote>​+

So we can't see it, and we don't know how it's implemented. But there are ways around these issues. So we can't see it, and we don't know how it's implemented. But there are ways around these issues.

-=====  One Solution ​ =====+===== One Solution =====

-For my experiment I've used the [[http://​libre.adacore.com/​libre/​|GNAT GPL 2010]] compiler, and in this compiler the [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Time]] type is declared as:+In this first solution, we're going to make use of the //'​Address//​ attribute. ​For my experiment I've used the [[http://​libre.adacore.com/​libre/​|GNAT GPL 2010]] compiler, and in this compiler the [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Time]] type is declared as:

Line 29: Line 28:

-function ​Time_Image ​+function ​Time_Image_One
​return String    ​return String
is is
-   ​type ​Time is mod 2 ** 64; +   ​type ​New_Time ​is mod 2 ** 64;
-   ​pragma Assert (Time'Size = Item'​Size);​ +   ​pragma Assert (New_Time'Size = Item'​Size);​
-   ​ +
-   ​Time_Stamp : Time;+   ​Time_Stamp : New_Time;
begin begin
-   ​return Trim (Source => Time'Image (Time_Stamp),​+   ​return Trim (Source => New_Time'Image (Time_Stamp),​
-end Time_Image;+end Time_Image_One;
</​code>​ </​code>​

Line 49: Line 48:

-type Time is mod 2 ** 64;+type New_Time ​is mod 2 ** 64;
</​code>​ </​code>​

-We declare a new //Time// type with the same size as the [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Ada.Calendar.Time]] type (as defined by the GNAT GPL 2010 compiler). I've used //mod 2 <​nowiki>​**</​nowiki>​ 64// instead of //range -2 ** 63 .. +2 ** 63 -1//, but that's mostly because I don't care about the sign. You can just as well go with //range -2 ** 63 .. +2 ** 63 -1//. The important thing to bear in mind, is that the two types should have the same size. Which brings us to this:+We declare a new //Time// type with the same size as the [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Ada.Calendar.Time]] type (as defined by the GNAT GPL 2010 compiler). I've used //mod 2 <​nowiki>​**</​nowiki>​ 64// instead of //range -2 <​nowiki>​**</​nowiki> ​63 .. +2 <​nowiki>​**</​nowiki> ​63 -1//, but that's mostly because I don't care about the sign. You can just as well go with //range -2 <​nowiki>​**</​nowiki> ​63 .. +2 <​nowiki>​**</​nowiki> ​63 -1//. The important thing to bear in mind, is that the two types should have the same size. Which brings us to this:

-pragma Assert (Time'Size = Item'​Size);​+pragma Assert (New_Time'Size = Item'​Size);​
</​code>​ </​code>​

Line 65: Line 64:

-Time_Stamp : Time;+Time_Stamp : New_Time;
</​code>​ </​code>​
Line 74: Line 73:

-return Trim (Source => Time'Image (Time_Stamp),​+return Trim (Source => New_Time'Image (Time_Stamp),​
</​code>​ </​code>​
Line 80: Line 79:
And voila! We have a neat [[http://​adaic.org/​standards/​05rm/​html/​RM-3-6-3.html#​I1889|String]] representation of the [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Ada.Calendar.Clock]] return value. Whether or not this is useful for anything, well, I'll leave that decision to the reader. And voila! We have a neat [[http://​adaic.org/​standards/​05rm/​html/​RM-3-6-3.html#​I1889|String]] representation of the [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Ada.Calendar.Clock]] return value. Whether or not this is useful for anything, well, I'll leave that decision to the reader.

-=====  ​Thanks ​ =====+===== Another Solution =====
+
+The above solution is not the only way to accomplish the goal of outputting the return value of //​Ada.Calendar.Clock//​. There'​s another, and probably better, method: Using [[http://​www.adaic.org/​resources/​add_content/​standards/​05rm/​html/​RM-13-9.html|Ada.Unchecked_Conversion]]. Here's how the above //​Time_Image_One//​ function would look if we used //​Ada.Unchecked_Conversion//​ instead:
+
+function Time_Image_Two
+   ​return String
+is
+   type New_Time is mod 2 ** 64;
+   ​pragma Assert (New_Time'​Size = Ada.Calendar.Time'​Size);​
+
+   ​function To_Time
+                                    Target => New_Time);​
+
+   ​Time_Stamp : constant New_Time := To_Time (Item);
+begin
+   ​return Trim (Source => New_Time'​Image (Time_Stamp),​
+end Time_Image_Two;​
+</​code>​
+
+A great boon of this method over the first one, is this fantastic warning message the GNAT compiler will dump on you when you compile the program:
+
+  warning: representation of Time values may change between GNAT versions
+
+You're not going to get that with the first method, and in my humble opinion that warning alone makes it worthwhile to use //​Ada.Unchecked_Conversion//​ instead of the //'​Address//​ attribute used in the first solution.
+===== The Full Program =====
+
+Lets end with a little program that utilizes both solutions to output the value of //​Ada.Calendar.Clock//:​
+
+
+procedure Time_Image_Test is
+
+   ​----------------------
+   ​-- ​ Time_Image_One ​ --
+   ​----------------------
+
+   ​function Time_Image_One
+      return String
+   is
+      type New_Time is mod 2 ** 64;
+      pragma Assert (New_Time'​Size = Item'​Size);​
+
+      Time_Stamp : New_Time;
+   ​begin
+      return Trim (Source => New_Time'​Image (Time_Stamp),​
+   end Time_Image_One;​
+
+   ​----------------------
+   ​-- ​ Time_Image_Two ​ --
+   ​----------------------
+
+   ​function Time_Image_Two
+      return String
+   is
+      type New_Time is mod 2 ** 64;
+      pragma Assert (New_Time'​Size = Ada.Calendar.Time'​Size);​
+
+      function To_Time
+                                       ​Target => New_Time);​
+
+      Time_Stamp : constant New_Time := To_Time (Item);
+   ​begin
+      return Trim (Source => New_Time'​Image (Time_Stamp),​
+   end Time_Image_Two;​
+
+begin
+   ​Put_Line (Time_Image_One (Now));
+   ​Put_Line (Time_Image_Two (Now));
+end Time_Image_Test;​
+</​code>​
+
+Elegant stuff!
+
+===== Thanks ​=====

-I'd like to extend my thanks to [[http://​edb.jacob-sparre.dk/​Ada/​|Jacob Sparre]] for gently pushing me in the right direction. As usual the [[http://​freenode.net/​|freenode #ada IRC channel]] proved an invaluable help in learning something new.+I'd like to extend my thanks to [[http://​edb.jacob-sparre.dk/​Ada/​|Jacob Sparre]] for gently pushing me in the right direction ​in regards to solution one, and [[http://​identi.ca/​simonj|Simon J. Wright]] for giving me the second solution. As usual the [[http://​freenode.net/​|freenode #ada IRC channel]] and the [[http://​identi.ca/​thomaslocke/​all/​ada| identi.ca Ada group]] proved an invaluable help in learning something new.