Differences

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

Link to this comparison view

ada.calendar.clock_to_string [2012/01/03 10:10]
thomaslocke [The Problem]
ada.calendar.clock_to_string [2012/01/03 21:48] (current)
thomaslocke [A Full Program]
Line 1: Line 1:
 =====  Introduction ​ ===== =====  Introduction ​ =====
  
-While messing around with [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3741|Ada.Calendar]],​ a need to output the return value of [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Ada.Calendar.Clock]] as a [[http://​adaic.org/​standards/​05rm/​html/​RM-3-6-3.html#​I1889|String]],​ took me on an adventure in the land of [[http://​adaic.org/​standards/​05rm/​html/​RM-11-4-2.html|pragma Assert]], [[http://​adaic.org/​standards/​05rm/​html/​RM-13-3.html#​I4496|the '​Address attribute]],​ [[http://​adaic.org/​standards/​05rm/​html/​RM-13-3.html#​I4513|the 'Size attribute]] and the fact that not all Ada compilers are created equal.+While messing around with [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3741|Ada.Calendar]],​ a need to output the return value of [[http://​adaic.org/​standards/​05rm/​html/​RM-9-6.html#​I3747|Ada.Calendar.Clock]] as a [[http://​adaic.org/​standards/​05rm/​html/​RM-3-6-3.html#​I1889|String]],​ took me on an adventure in the land of [[http://​adaic.org/​standards/​05rm/​html/​RM-11-4-2.html|pragma Assert]], [[http://​adaic.org/​standards/​05rm/​html/​RM-13-3.html#​I4496|the '​Address attribute]],​ [[http://​adaic.org/​standards/​05rm/​html/​RM-13-3.html#​I4513|the 'Size attribute]], [[http://​www.adaic.org/​resources/​add_content/​standards/​05rm/​html/​RM-13-9.html|Ada.Unchecked_Conversion]] and the fact that not all Ada compilers are created equal.
  
 =====  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 16: Line 16:
 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:
  
 <code ada> <code ada>
Line 28: Line 28:
  
 <code ada> <code ada>
-function ​Time_Image ​+function ​Time_Image_One
   (Item : in Ada.Calendar.Time)   (Item : in Ada.Calendar.Time)
    ​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;
    for Time_Stamp'​Address use Item'​Address;​    for Time_Stamp'​Address use Item'​Address;​
 begin begin
-   ​return Trim (Source => Time'Image (Time_Stamp),​+   ​return Trim (Source => New_Time'Image (Time_Stamp),​
                 Side   => Ada.Strings.Left);​                 Side   => Ada.Strings.Left);​
-end Time_Image;+end Time_Image_One;
 </​code>​ </​code>​
  
Line 48: Line 48:
  
 <code ada> <code ada>
-type Time is mod 2 ** 64;+type New_Time ​is mod 2 ** 64;
 </​code>​ </​code>​
  
Line 54: Line 54:
  
 <code ada> <code ada>
-pragma Assert (Time'Size = Item'​Size);​+pragma Assert (New_Time'Size = Item'​Size);​
 </​code>​ </​code>​
  
Line 64: Line 64:
  
 <code ada> <code ada>
-Time_Stamp : Time;+Time_Stamp : New_Time;
 for Time_Stamp'​Address use Item'​Address;​ for Time_Stamp'​Address use Item'​Address;​
 </​code>​ </​code>​
Line 73: Line 73:
  
 <code ada> <code ada>
-return Trim (Source => Time'Image (Time_Stamp),​+return Trim (Source => New_Time'Image (Time_Stamp),​
              ​Side ​  => Ada.Strings.Left);​              ​Side ​  => Ada.Strings.Left);​
 </​code>​ </​code>​
Line 79: 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: 
 + 
 +<code ada> 
 +function Time_Image_Two 
 +  (Item : in Ada.Calendar.Time) 
 +   ​return String 
 +is 
 +   type New_Time is mod 2 ** 64; 
 +   ​pragma Assert (New_Time'​Size = Ada.Calendar.Time'​Size);​ 
 + 
 +   ​function To_Time 
 +   is new Ada.Unchecked_Conversion (Source => Ada.Calendar.Time,​  
 +                                    Target => New_Time);​ 
 + 
 +   ​Time_Stamp : constant New_Time := To_Time (Item); 
 +begin 
 +   ​return Trim (Source => New_Time'​Image (Time_Stamp),​ 
 +                Side   => Ada.Strings.Left);​ 
 +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//:​ 
 + 
 +<code ada> 
 +with Ada.Calendar;​ 
 +with Ada.Strings.Fixed;​ 
 +with Ada.Text_IO;​ 
 +with Ada.Unchecked_Conversion;​ 
 + 
 +procedure Time_Image_Test is 
 +   use Ada.Strings.Fixed;​ 
 +   use Ada.Text_IO;​ 
 + 
 +   ​---------------------- 
 +   ​-- ​ Time_Image_One ​ -- 
 +   ​---------------------- 
 + 
 +   ​function Time_Image_One 
 +     (Item : in Ada.Calendar.Time) 
 +      return String 
 +   is 
 +      type New_Time is mod 2 ** 64; 
 +      pragma Assert (New_Time'​Size = Item'​Size);​ 
 + 
 +      Time_Stamp : New_Time; 
 +      for Time_Stamp'​Address use Item'​Address;​ 
 +   ​begin 
 +      return Trim (Source => New_Time'​Image (Time_Stamp),​ 
 +                   ​Side ​  => Ada.Strings.Left);​ 
 +   end Time_Image_One;​ 
 +    
 +   ​---------------------- 
 +   ​-- ​ Time_Image_Two ​ -- 
 +   ​---------------------- 
 +    
 +   ​function Time_Image_Two 
 +     (Item : in Ada.Calendar.Time) 
 +      return String 
 +   is 
 +      type New_Time is mod 2 ** 64; 
 +      pragma Assert (New_Time'​Size = Ada.Calendar.Time'​Size);​ 
 + 
 +      function To_Time 
 +      is new Ada.Unchecked_Conversion (Source => Ada.Calendar.Time,​  
 +                                       ​Target => New_Time);​ 
 + 
 +      Time_Stamp : constant New_Time := To_Time (Item); 
 +   ​begin 
 +      return Trim (Source => New_Time'​Image (Time_Stamp),​ 
 +                   ​Side ​  => Ada.Strings.Left);​ 
 +   end Time_Image_Two;​ 
 +    
 +   Now : Ada.Calendar.Time := Ada.Calendar.Clock;​ 
 +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.
  

Navigation