How to print a generic type in ada?

Question

i am currently trying to print ("Ada.Text_IO.Put") a generic type, but this always fails with errors like that:

missing argument for parameter "Item" in call to "Put" declared at a-tiinio.ads:60, instance at a-inteio.ads:18
expected type "Standard.Integer"
found private type "My_Type" defined at testtype.ads:2

These errors make sense but I dont know how to print my values. The following lines show my generic type.

generic
    type My_Type is private;
    with function "+"(Left: My_Type; Right: My_Type) return My_Type;

package TestType is
    ...
end TestType;

Thanks for any help!


Show source
| generics   | ada   | printing   | put   2017-01-06 23:01 2 Answers

Answers ( 2 )

  1. 2017-01-07 04:01

    You can require another generic parameter such as the following:

    with function image(Item : in My_Type) return String;
    

    Then simply print the string output by the Image function.

    An example of an actual parameter might be:

    image => Integer'Image
    
  2. 2017-01-07 10:01

    The point of a generic being that "it" works with any type, and that of Text_IO being that it works with types known when calling its subprograms, i.e. strings, you need something else generic for printing any type. So, either pass a special function that transforms from your type to String, as answered by Jim Rogers. Or, pass a generic formal package together with My_Type, for printing. For example.

    generic
        type Any_Type is private;
    package Any_Type_IO is
        procedure Put (Item : Any_Type);
        procedure Get (Item : out Any_Type);
    end Any_Type_IO;
    
    with Any_Type_IO;
    generic
        type My_Type is private;
        with function "+"(Left: My_Type; Right: My_Type) return My_Type;
        with package Printer is new Any_Type_Io (Any_Type => My_Type);
    package TestType is
        procedure Run_Test;
    end TestType;
    

    So, together with a type to become a generic actual type of TestType, there will be a package to become a generic actual package of TestType. They match. Within an instance of TestType, you can then use them together.

    type T is range 1 .. 10;
    package T_IO is new Any_Type_IO (T);
    
    package My_Test_Instance is new TestType
      (My_Type => T,
       "+"     => "+",
       Printer => T_IO);
    

    If you provide a printing package such as Any_Type_IO, then printing becomes generic in both senses: it is the job of any matching printing package, and it must also match a generic formal package in the Ada sense.

◀ Go back